From 9139071b7188dc63e19ddf31fb748e35add79ebf Mon Sep 17 00:00:00 2001 From: Mary Ruthven Date: Wed, 25 May 2016 10:24:02 -0700 Subject: [PATCH] cr50: disable UART peripheral when the device is powered off. When the AP or EC is off, the RX line is low. Holding the UART RX line low causes an interrupt storm. This change disables the UART TX and RX on the peripheral when the device is powered off so the interrupts wont be triggered. BUG=chrome-os-partner:53514,b:28885578 BRANCH=none TEST=run taskinfo on cr50 and make sure the IRQ count for 181 is a reasonable number. Change-Id: I42c779253860a2b1dd27ab41fb7097c887cc23ff Signed-off-by: Mary Ruthven Reviewed-on: https://chromium-review.googlesource.com/347355 --- board/cr50/board.c | 8 +++++++- chip/g/uartn.c | 15 ++++++++++++++- chip/g/uartn.h | 6 ++++++ 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/board/cr50/board.c b/board/cr50/board.c index 706d1187bc..1513af2d6c 100644 --- a/board/cr50/board.c +++ b/board/cr50/board.c @@ -273,6 +273,10 @@ static void device_powered_off(enum device_type device, int uart) device_state_changed(device, DEVICE_STATE_OFF); + /* Disable RX and TX on the UART peripheral */ + uartn_disable(uart); + + /* Disconnect the TX pin from the UART peripheral */ uartn_tx_disconnect(uart); gpio_enable_interrupt(device_states[device].detect_on); @@ -332,6 +336,9 @@ static void device_powered_on(enum device_type device, int uart) /* Update the device state */ device_state_changed(device, DEVICE_STATE_ON); + /* Enable RX and TX on the UART peripheral */ + uartn_enable(uart); + /* Connect the TX pin to the UART TX Signal */ if (device_get_state(DEVICE_SERVO) != DEVICE_STATE_ON && !uartn_enabled(uart)) @@ -371,7 +378,6 @@ void device_state_on(enum gpio_signal signal) CPRINTS("Device not supported"); return; } - } void device_state_off(enum gpio_signal signal) diff --git a/chip/g/uartn.c b/chip/g/uartn.c index eac35d1577..17cd5e51b8 100644 --- a/chip/g/uartn.c +++ b/chip/g/uartn.c @@ -113,6 +113,19 @@ void uartn_enable_interrupt(int uart) } +/* Enable TX and RX. Disable HW flow control and loopback */ +void uartn_enable(int uart) +{ + /* TX and RX enable */ + GR_UART_CTRL(uart) = 0x03; +} + +/* Disable TX, RX, HW flow control, and loopback */ +void uartn_disable(int uart) +{ + GR_UART_CTRL(uart) = 0; +} + void uartn_init(int uart) { long long setting = (16 * (1 << UART_NCO_WIDTH) * @@ -131,7 +144,7 @@ void uartn_init(int uart) * TX enable, RX enable, HW flow control disabled, no * loopback */ - GR_UART_CTRL(uart) = 0x03; + uartn_enable(uart); /* enable RX interrupts in block */ /* Note: doesn't do anything unless turned on in NVIC */ diff --git a/chip/g/uartn.h b/chip/g/uartn.h index 50554f80bc..e13c2f6552 100644 --- a/chip/g/uartn.h +++ b/chip/g/uartn.h @@ -82,4 +82,10 @@ void uartn_tx_connect(int uart); /* Disable UART output */ void uartn_tx_disconnect(int uart); + +/* Enable TX and RX. Disable HW flow control and loopback */ +void uartn_enable(int uart); + +/* Disable TX, RX, HW flow control, and loopback */ +void uartn_disable(int uart); #endif /* __CROS_EC_UARTN_H */