aboutsummaryrefslogtreecommitdiff
path: root/hw/lpc-uart.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2014-10-09 13:15:32 +1100
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2014-10-09 13:15:32 +1100
commit72f080a3b1bdc6f3a0843f0c98579848fdd2a682 (patch)
treebea470c969ffd0da8a0581e2358f41f8b44be881 /hw/lpc-uart.c
parent1b73ac736790f9aa951d855f6bdb9380437a6da8 (diff)
downloadskiboot-72f080a3b1bdc6f3a0843f0c98579848fdd2a682.zip
skiboot-72f080a3b1bdc6f3a0843f0c98579848fdd2a682.tar.gz
skiboot-72f080a3b1bdc6f3a0843f0c98579848fdd2a682.tar.bz2
uart: Exploit Tx FIFO
When THRE is 1, we can write up to 16 bytes, so let's make good use of it Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'hw/lpc-uart.c')
-rw-r--r--hw/lpc-uart.c28
1 files changed, 18 insertions, 10 deletions
diff --git a/hw/lpc-uart.c b/hw/lpc-uart.c
index f6037e1..8391866 100644
--- a/hw/lpc-uart.c
+++ b/hw/lpc-uart.c
@@ -23,6 +23,7 @@
#include <processor.h>
#include <fsp-elog.h>
#include <trace.h>
+#include <cpu.h>
DEFINE_LOG_ENTRY(OPAL_RC_UART_INIT, OPAL_PLATFORM_ERR_EVT, OPAL_UART,
OPAL_CEC_HARDWARE, OPAL_PREDICTIVE_ERR_GENERAL,
@@ -55,6 +56,7 @@ DEFINE_LOG_ENTRY(OPAL_RC_UART_INIT, OPAL_PLATFORM_ERR_EVT, OPAL_UART,
static uint32_t uart_base;
static bool has_irq, irq_disabled;
+static uint8_t tx_room;
/*
* We implement a simple buffer to buffer input data as some bugs in
@@ -92,22 +94,28 @@ static inline void uart_write(unsigned int reg, uint8_t val)
lpc_outb(val, uart_base + reg);
}
+static void uart_wait_tx_room(void)
+{
+ while ((uart_read(REG_LSR) & LSR_THRE) == 0)
+ cpu_relax();
+ /* FIFO is 16 entries */
+ tx_room = 16;
+}
+
static size_t uart_con_write(const char *buf, size_t len)
{
size_t written = 0;
while(written < len) {
- while ((uart_read(REG_LSR) & LSR_THRE) == 0) {
- int i = 0;
-
- /* Give the simulator some breathing space */
- for (; i < 1000; ++i)
- smt_very_low();
+ if (tx_room == 0) {
+ uart_wait_tx_room();
+ if (tx_room == 0)
+ return written;
+ } else {
+ uart_write(REG_THR, buf[written++]);
+ tx_room--;
}
- smt_medium();
- uart_write(REG_THR, buf[written++]);
- };
-
+ }
return written;
}