aboutsummaryrefslogtreecommitdiff
path: root/drivers/serial/ns16550.c
diff options
context:
space:
mode:
authorStefan Roese2017-08-16 17:37:15 +0200
committerBin Meng2017-08-24 11:00:47 +0800
commit7fded0ce0ff68551ceb631f98d60db162e49f80c (patch)
tree21e050ca8c5765f6fc0f7c59fbae76299241f0b1 /drivers/serial/ns16550.c
parent76e726502ec0230070640e3c4cd3dd930e5bb9e8 (diff)
Revert "serial: ns16550: Add RX interrupt buffer support"
This reverts commit 6822cf3ec7c8768b8727573b8f4b2cb3d870b881. As Bin Meng has tested and pointed out, we don't need the RX interrupt for the RX buffer support at all. Just reading all available characters into a buffer is sufficient to solve the problem with the dropped characters upon long lines pasted into the U-Boot prompt. Since this RX buffer support can be implemented in a generic way, without any device specifica (e.g. for the ns16550), I'll post a new patch with a new serial RX buffer support for DM, which all DM based serial drivers can use. Signed-off-by: Stefan Roese <sr@denx.de> Cc: Simon Glass <sjg@chromium.org> Cc: Bin Meng <bmeng.cn@gmail.com> Cc: Tom Rini <trini@konsulko.com> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Diffstat (limited to 'drivers/serial/ns16550.c')
-rw-r--r--drivers/serial/ns16550.c123
1 files changed, 5 insertions, 118 deletions
diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c
index 607a1b8c1de..c702304e79b 100644
--- a/drivers/serial/ns16550.c
+++ b/drivers/serial/ns16550.c
@@ -314,80 +314,6 @@ DEBUG_UART_FUNCS
#endif
#ifdef CONFIG_DM_SERIAL
-
-#if CONFIG_IS_ENABLED(SERIAL_IRQ_BUFFER)
-
-#define BUF_COUNT 256
-
-static void rx_fifo_to_buf(struct udevice *dev)
-{
- struct NS16550 *const com_port = dev_get_priv(dev);
- struct ns16550_platdata *plat = dev->platdata;
-
- /* Read all available chars into buffer */
- while ((serial_in(&com_port->lsr) & UART_LSR_DR)) {
- plat->buf[plat->wr_ptr++] = serial_in(&com_port->rbr);
- plat->wr_ptr %= BUF_COUNT;
- }
-}
-
-static int rx_pending(struct udevice *dev)
-{
- struct ns16550_platdata *plat = dev->platdata;
-
- /*
- * At startup it may happen, that some already received chars are
- * "stuck" in the RX FIFO, even with the interrupt enabled. This
- * RX FIFO flushing makes sure, that these chars are read out and
- * the RX interrupts works as expected.
- */
- rx_fifo_to_buf(dev);
-
- return plat->rd_ptr != plat->wr_ptr ? 1 : 0;
-}
-
-static int rx_get(struct udevice *dev)
-{
- struct ns16550_platdata *plat = dev->platdata;
- char val;
-
- val = plat->buf[plat->rd_ptr++];
- plat->rd_ptr %= BUF_COUNT;
-
- return val;
-}
-
-void ns16550_handle_irq(void *data)
-{
- struct udevice *dev = (struct udevice *)data;
- struct NS16550 *const com_port = dev_get_priv(dev);
-
- /* Check if interrupt is pending */
- if (serial_in(&com_port->iir) & UART_IIR_NO_INT)
- return;
-
- /* Flush all available characters from the RX FIFO into the RX buffer */
- rx_fifo_to_buf(dev);
-}
-
-#else /* CONFIG_SERIAL_IRQ_BUFFER */
-
-static int rx_pending(struct udevice *dev)
-{
- struct NS16550 *const com_port = dev_get_priv(dev);
-
- return serial_in(&com_port->lsr) & UART_LSR_DR ? 1 : 0;
-}
-
-static int rx_get(struct udevice *dev)
-{
- struct NS16550 *const com_port = dev_get_priv(dev);
-
- return serial_in(&com_port->rbr);
-}
-
-#endif /* CONFIG_SERIAL_IRQ_BUFFER */
-
static int ns16550_serial_putc(struct udevice *dev, const char ch)
{
struct NS16550 *const com_port = dev_get_priv(dev);
@@ -413,17 +339,19 @@ static int ns16550_serial_pending(struct udevice *dev, bool input)
struct NS16550 *const com_port = dev_get_priv(dev);
if (input)
- return rx_pending(dev);
+ return serial_in(&com_port->lsr) & UART_LSR_DR ? 1 : 0;
else
return serial_in(&com_port->lsr) & UART_LSR_THRE ? 0 : 1;
}
static int ns16550_serial_getc(struct udevice *dev)
{
- if (!ns16550_serial_pending(dev, true))
+ struct NS16550 *const com_port = dev_get_priv(dev);
+
+ if (!(serial_in(&com_port->lsr) & UART_LSR_DR))
return -EAGAIN;
- return rx_get(dev);
+ return serial_in(&com_port->rbr);
}
static int ns16550_serial_setbrg(struct udevice *dev, int baudrate)
@@ -446,39 +374,8 @@ int ns16550_serial_probe(struct udevice *dev)
com_port->plat = dev_get_platdata(dev);
NS16550_init(com_port, -1);
-#if CONFIG_IS_ENABLED(SERIAL_IRQ_BUFFER)
- if (gd->flags & GD_FLG_RELOC) {
- struct ns16550_platdata *plat = dev->platdata;
-
- /* Allocate the RX buffer */
- plat->buf = malloc(BUF_COUNT);
-
- /* Install the interrupt handler */
- irq_install_handler(plat->irq, ns16550_handle_irq, dev);
-
- /* Enable RX interrupts */
- serial_out(UART_IER_RDI, &com_port->ier);
- }
-#endif
-
- return 0;
-}
-
-#if CONFIG_IS_ENABLED(SERIAL_PRESENT) && \
- (!defined(CONFIG_TPL_BUILD) || defined(CONFIG_TPL_DM_SERIAL))
-static int ns16550_serial_remove(struct udevice *dev)
-{
-#if CONFIG_IS_ENABLED(SERIAL_IRQ_BUFFER)
- if (gd->flags & GD_FLG_RELOC) {
- struct ns16550_platdata *plat = dev->platdata;
-
- irq_free_handler(plat->irq);
- }
-#endif
-
return 0;
}
-#endif
#if CONFIG_IS_ENABLED(OF_CONTROL)
enum {
@@ -561,15 +458,6 @@ int ns16550_serial_ofdata_to_platdata(struct udevice *dev)
if (port_type == PORT_JZ4780)
plat->fcr |= UART_FCR_UME;
-#if CONFIG_IS_ENABLED(SERIAL_IRQ_BUFFER)
- plat->irq = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
- "interrupts", 0);
- if (!plat->irq) {
- debug("ns16550 interrupt not provided\n");
- return -EINVAL;
- }
-#endif
-
return 0;
}
#endif
@@ -617,7 +505,6 @@ U_BOOT_DRIVER(ns16550_serial) = {
#endif
.priv_auto_alloc_size = sizeof(struct NS16550),
.probe = ns16550_serial_probe,
- .remove = ns16550_serial_remove,
.ops = &ns16550_serial_ops,
.flags = DM_FLAG_PRE_RELOC,
};