[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen master] ns16550: support DesignWare 8250



commit 50417cd978aa54930d065ac1f139f935d14af76d
Author:     Ian Campbell <ian.campbell@xxxxxxxxxx>
AuthorDate: Fri Sep 20 17:18:35 2013 +0100
Commit:     Ian Campbell <ian.campbell@xxxxxxxxxx>
CommitDate: Sat Sep 21 16:27:45 2013 +0100

    ns16550: support DesignWare 8250
    
    This hardware has an additional feature which signals an error if you try to
    write LCR while the UART is busy. We need to clear this error during setup,
    otherwise LCR.DLAB doesn't get set and we cannot read/write the divisor.
    
    This has been tested on the cubieboard2
    
    Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
    Acked-by: Keir Fraser <keir@xxxxxxx>
    Cc: jbeulich@xxxxxxxx
---
 xen/drivers/char/ns16550.c  |   14 ++++++++++++++
 xen/include/xen/8250-uart.h |    2 ++
 2 files changed, 16 insertions(+), 0 deletions(-)

diff --git a/xen/drivers/char/ns16550.c b/xen/drivers/char/ns16550.c
index 45da924..5892eb7 100644
--- a/xen/drivers/char/ns16550.c
+++ b/xen/drivers/char/ns16550.c
@@ -61,6 +61,7 @@ static struct ns16550 {
     struct timer resume_timer;
     unsigned int timeout_ms;
     bool_t intr_works;
+    bool_t dw_usr_bsy;
 #ifdef HAS_PCI
     /* PCI card parameters. */
     unsigned int pb_bdf[3]; /* pci bridge BDF */
@@ -237,6 +238,16 @@ static void ns16550_setup_preirq(struct ns16550 *uart)
     /* No interrupts. */
     ns_write_reg(uart, UART_IER, 0);
 
+    if ( uart->dw_usr_bsy &&
+         (ns_read_reg(uart, UART_IIR) & UART_IIR_BSY) == UART_IIR_BSY )
+    {
+        /* DesignWare 8250 detects if LCR is written while the UART is
+         * busy and raises a "busy detect" interrupt. Read the UART
+         * Status Register to clear this state.
+         */
+        ns_read_reg(uart, UART_USR);
+    }
+
     /* Line control and baud-rate generator. */
     ns_write_reg(uart, UART_LCR, lcr | UART_LCR_DLAB);
     if ( uart->baud != BAUD_AUTO )
@@ -787,6 +798,8 @@ static int __init ns16550_uart_dt_init(struct 
dt_device_node *dev,
     /* The common bit of the driver mostly deals with irq not dt_irq. */
     uart->irq = uart->dt_irq.irq;
 
+    uart->dw_usr_bsy = dt_device_is_compatible(dev, "snps,dw-apb-uart");
+
     uart->vuart.base_addr = uart->io_base;
     uart->vuart.size = uart->io_size;
     uart->vuart.data_off = UART_THR <<uart->reg_shift;
@@ -804,6 +817,7 @@ static int __init ns16550_uart_dt_init(struct 
dt_device_node *dev,
 static const char const *ns16550_dt_compat[] __initconst =
 {
     "ns16550",
+    "snps,dw-apb-uart",
     NULL
 };
 
diff --git a/xen/include/xen/8250-uart.h b/xen/include/xen/8250-uart.h
index 8693d15..a682bae 100644
--- a/xen/include/xen/8250-uart.h
+++ b/xen/include/xen/8250-uart.h
@@ -32,6 +32,7 @@
 #define UART_MCR          0x04    /* Modem control        */
 #define UART_LSR          0x05    /* line status          */
 #define UART_MSR          0x06    /* Modem status         */
+#define UART_USR          0x1f    /* Status register (DW) */
 #define UART_DLL          0x00    /* divisor latch (ls) (DLAB=1) */
 #define UART_DLM          0x01    /* divisor latch (ms) (DLAB=1) */
 
@@ -48,6 +49,7 @@
 #define UART_IIR_RDA      0x04    /*  - rx data recv'd    */
 #define UART_IIR_THR      0x02    /*  - tx reg. empty     */
 #define UART_IIR_MSI      0x00    /*  - MODEM status      */
+#define UART_IIR_BSY      0x07    /*  - busy detect (DW) */
 
 /* FIFO Control Register */
 #define UART_FCR_ENABLE   0x01    /* enable FIFO          */
--
generated by git-patchbot for /home/xen/git/xen.git#master

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.