summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2013-09-10 10:09:41 -0700
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2013-09-11 19:46:10 +0000
commit6b1dace9f456d5b1b160402866045c3659e665e0 (patch)
tree6e63bbea7bf6ec8a601c839af64a0a40091caf13
parenteff7a1910a60b1d30b10257fd4a12b5ed1402594 (diff)
downloadchrome-ec-6b1dace9f456d5b1b160402866045c3659e665e0.tar.gz
Split uart_process() into input and output processing
This is a precursor to DMA-based UART transfers, which require different processing for DMA vs PIO output types. BUG=chrome-os-partner:20485 BRANCH=pit TEST=Boot pit; verify EC console still works. Change-Id: I6d6f55561eeebe9bd2928b2bfb25278c86f689d1 Signed-off-by: Randall Spangler <rspangler@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/168811 Reviewed-by: Bill Richardson <wfrichar@chromium.org>
-rw-r--r--chip/host/uart.c7
-rw-r--r--chip/lm4/uart.c3
-rw-r--r--chip/stm32/uart.c3
-rw-r--r--common/uart_buffering.c79
-rw-r--r--include/uart.h16
5 files changed, 51 insertions, 57 deletions
diff --git a/chip/host/uart.c b/chip/host/uart.c
index b6369df426..770ea8c0ef 100644
--- a/chip/host/uart.c
+++ b/chip/host/uart.c
@@ -69,8 +69,10 @@ static void trigger_interrupt(void)
* TODO: Check global interrupt status when we have
* interrupt support.
*/
- if (!int_disabled)
- uart_process();
+ if (!int_disabled) {
+ uart_process_input();
+ uart_process_output();
+ }
}
int uart_init_done(void)
@@ -185,5 +187,6 @@ void *uart_monitor_stdin(void *d)
void uart_init(void)
{
pthread_create(&input_thread, NULL, uart_monitor_stdin, NULL);
+ stopped = 1; /* Not transmitting yet */
init_done = 1;
}
diff --git a/chip/lm4/uart.c b/chip/lm4/uart.c
index 17443d9848..c7d320928c 100644
--- a/chip/lm4/uart.c
+++ b/chip/lm4/uart.c
@@ -103,7 +103,8 @@ static void uart_ec_interrupt(void)
/* Read input FIFO until empty, then fill output FIFO */
- uart_process();
+ uart_process_input();
+ uart_process_output();
}
DECLARE_IRQ(LM4_IRQ_UART0, uart_ec_interrupt, 1);
diff --git a/chip/stm32/uart.c b/chip/stm32/uart.c
index dab5231845..42461b2a90 100644
--- a/chip/stm32/uart.c
+++ b/chip/stm32/uart.c
@@ -96,7 +96,8 @@ static void uart_interrupt(void)
STM32_USART_CR1(UARTN) &= ~STM32_USART_CR1_TXEIE;
/* Read input FIFO until empty, then fill output FIFO */
- uart_process();
+ uart_process_input();
+ uart_process_output();
/*
* Re-enable TX empty interrupt only if it was not disabled by
diff --git a/common/uart_buffering.c b/common/uart_buffering.c
index 2ccb967e81..1394b3d457 100644
--- a/common/uart_buffering.c
+++ b/common/uart_buffering.c
@@ -65,23 +65,23 @@ static int __tx_char(void *context, int c)
return 0;
}
-/**
- * Copy output from buffer until TX fifo full or output buffer empty.
- *
- * May be called from interrupt context.
- */
-static void fill_tx_fifo(void)
+void uart_process_output(void)
{
+ if (uart_suspended)
+ return;
+
+ /* Copy output from buffer until TX fifo full or output buffer empty */
while (uart_tx_ready() && (tx_buf_head != tx_buf_tail)) {
uart_write_char(tx_buf[tx_buf_tail]);
tx_buf_tail = TX_BUF_NEXT(tx_buf_tail);
}
+
+ /* If output buffer is empty, disable transmit interrupt */
+ if (tx_buf_tail == tx_buf_head)
+ uart_tx_stop();
}
-/**
- * Helper for UART processing.
- */
-void uart_process(void)
+void uart_process_input(void)
{
int got_input = 0;
@@ -110,16 +110,6 @@ void uart_process(void)
if (got_input)
console_has_input();
-
- if (uart_suspended)
- return;
-
- /* Copy output from buffer until TX fifo full or output buffer empty */
- fill_tx_fifo();
-
- /* If output buffer is empty, disable transmit interrupt */
- if (tx_buf_tail == tx_buf_head)
- uart_tx_stop();
}
int uart_putc(int c)
@@ -174,34 +164,27 @@ void uart_flush_output(void)
if (uart_suspended)
return;
- /*
- * If we're in interrupt context, copy output explicitly, since the
- * UART interrupt may not be able to preempt this one.
- */
- if (in_interrupt_context()) {
- do {
- /* Copy until TX fifo full or output buffer empty */
- fill_tx_fifo();
-
- /* Wait for transmit FIFO empty */
- uart_tx_flush();
- } while (tx_buf_head != tx_buf_tail);
- return;
- }
-
- /* Wait for buffer to empty */
+ /* Loop until buffer is empty */
while (tx_buf_head != tx_buf_tail) {
- /*
- * It's possible we're in some other interrupt, and the
- * previous context was doing a printf() or puts() but hadn't
- * enabled the UART interrupt. Check if the interrupt is
- * disabled, and if so, re-enable and trigger it. Note that
- * this check is inside the while loop, so we'll be safe even
- * if the context switches away from us to another partial
- * printf() and back.
- */
- if (uart_tx_stopped())
+ if (in_interrupt_context()) {
+ /*
+ * Explicitly process UART output, since the UART
+ * interrupt may not be able to preempt the interrupt
+ * we're in now.
+ */
+ uart_process_output();
+ } else if (uart_tx_stopped()) {
+ /*
+ * It's possible we switched from a previous context
+ * which was doing a printf() or puts() but hadn't
+ * enabled the UART interrupt. Check if the interrupt
+ * is disabled, and if so, re-enable and trigger it.
+ * Note that this check is inside the while loop, so
+ * we'll be safe even if the context switches away from
+ * us to another partial printf() and back.
+ */
uart_tx_start();
+ }
}
/* Wait for transmit FIFO empty */
@@ -214,7 +197,7 @@ void uart_flush_input(void)
uart_disable_interrupt();
/* Empty the hardware FIFO */
- uart_process();
+ uart_process_input();
/* Clear the input buffer */
rx_buf_tail = rx_buf_head;
@@ -231,7 +214,7 @@ int uart_getc(void)
uart_disable_interrupt();
/* Call interrupt handler to empty the hardware FIFO */
- uart_process();
+ uart_process_input();
if (rx_buf_tail == rx_buf_head) {
c = -1; /* No pending input */
diff --git a/include/uart.h b/include/uart.h
index 05d4aee036..fa50645270 100644
--- a/include/uart.h
+++ b/include/uart.h
@@ -178,14 +178,20 @@ void uart_tx_stop(void);
int uart_tx_stopped(void);
/**
- * Helper for UART processing.
+ * Helper for processing UART input.
*
- * Reads the input FIFO until empty, then fills the output FIFO until the
- * transmit buffer is empty or the FIFO full.
+ * Reads the input FIFO until empty. Intended to be called from the driver
+ * interrupt handler.
+ */
+void uart_process_input(void);
+
+/**
+ * Helper for processing UART output.
*
- * Designed to be called from the driver interrupt handler.
+ * Fills the output FIFO until the transmit buffer is empty or the FIFO full.
+ * Intended to be called from the driver interrupt handler.
*/
-void uart_process(void);
+void uart_process_output(void);
/*
* COMx functions