[ARM] 5541/1: serial/amba-pl011.c: add support for the modified port found in Nomadik
authorAlessandro Rubini <rubini@gnudd.com>
Thu, 4 Jun 2009 16:43:04 +0000 (17:43 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Thu, 4 Jun 2009 16:45:30 +0000 (17:45 +0100)
The Nomadik 8815 SoC has a slightly modified version of the PL011 block.
The patch uses the different ID value as a key to select a vendor
structure that is used to keep track of the differences, as suggested
by Russell King.

Signed-off-by: Alessandro Rubini <rubini@unipv.it>
Acked-by: Andrea Gallo <andrea.gallo@stericsson.com>
Acked-by: Linus Walleij <linus.walleij@stericsson.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
drivers/serial/amba-pl011.c
include/linux/amba/serial.h

index 4cfa1eb..8c5bda2 100644 (file)
@@ -70,6 +70,23 @@ struct uart_amba_port {
        struct clk              *clk;
        unsigned int            im;     /* interrupt mask */
        unsigned int            old_status;
+       unsigned int            ifls;   /* vendor-specific */
+};
+
+/* There is by now at least one vendor with differing details, so handle it */
+struct vendor_data {
+       unsigned int            ifls;
+       unsigned int            fifosize;
+};
+
+static struct vendor_data vendor_arm = {
+       .ifls                   = UART011_IFLS_RX4_8|UART011_IFLS_TX4_8,
+       .fifosize               = 16,
+};
+
+static struct vendor_data vendor_st = {
+       .ifls                   = UART011_IFLS_RX_HALF|UART011_IFLS_TX_HALF,
+       .fifosize               = 64,
 };
 
 static void pl011_stop_tx(struct uart_port *port)
@@ -360,8 +377,7 @@ static int pl011_startup(struct uart_port *port)
        if (retval)
                goto clk_dis;
 
-       writew(UART011_IFLS_RX4_8|UART011_IFLS_TX4_8,
-              uap->port.membase + UART011_IFLS);
+       writew(uap->ifls, uap->port.membase + UART011_IFLS);
 
        /*
         * Provoke TX FIFO interrupt into asserting.
@@ -732,6 +748,7 @@ static struct uart_driver amba_reg = {
 static int pl011_probe(struct amba_device *dev, struct amba_id *id)
 {
        struct uart_amba_port *uap;
+       struct vendor_data *vendor = id->data;
        void __iomem *base;
        int i, ret;
 
@@ -762,12 +779,13 @@ static int pl011_probe(struct amba_device *dev, struct amba_id *id)
                goto unmap;
        }
 
+       uap->ifls = vendor->ifls;
        uap->port.dev = &dev->dev;
        uap->port.mapbase = dev->res.start;
        uap->port.membase = base;
        uap->port.iotype = UPIO_MEM;
        uap->port.irq = dev->irq[0];
-       uap->port.fifosize = 16;
+       uap->port.fifosize = vendor->fifosize;
        uap->port.ops = &amba_pl011_pops;
        uap->port.flags = UPF_BOOT_AUTOCONF;
        uap->port.line = i;
@@ -812,6 +830,12 @@ static struct amba_id pl011_ids[] __initdata = {
        {
                .id     = 0x00041011,
                .mask   = 0x000fffff,
+               .data   = &vendor_arm,
+       },
+       {
+               .id     = 0x00380802,
+               .mask   = 0x00ffffff,
+               .data   = &vendor_st,
        },
        { 0, 0 },
 };
index 48ee32a..42949e2 100644 (file)
 #define UART011_IFLS_TX4_8     (2 << 0)
 #define UART011_IFLS_TX6_8     (3 << 0)
 #define UART011_IFLS_TX7_8     (4 << 0)
+/* special values for ST vendor with deeper fifo */
+#define UART011_IFLS_RX_HALF   (5 << 3)
+#define UART011_IFLS_TX_HALF   (5 << 0)
 
 #define UART011_OEIM           (1 << 10)       /* overrun error interrupt mask */
 #define UART011_BEIM           (1 << 9)        /* break error interrupt mask */