From 2a88ccfa080ffee7a11869bc9760c67c3eae4b58 Mon Sep 17 00:00:00 2001 From: Imre Kaloz Date: Wed, 28 Jan 2009 15:24:43 +0000 Subject: [PATCH] add further fixes for the optional Cambria UART - thanks, Chris SVN-Revision: 14243 --- .../191-cambria_optional_uart.patch | 111 +++++++++++++++--- 1 file changed, 94 insertions(+), 17 deletions(-) diff --git a/target/linux/ixp4xx/patches-2.6.28/191-cambria_optional_uart.patch b/target/linux/ixp4xx/patches-2.6.28/191-cambria_optional_uart.patch index 946d685a19..e7531542b2 100644 --- a/target/linux/ixp4xx/patches-2.6.28/191-cambria_optional_uart.patch +++ b/target/linux/ixp4xx/patches-2.6.28/191-cambria_optional_uart.patch @@ -8,7 +8,7 @@ struct cambria_board_info { unsigned char *model; -@@ -127,6 +128,43 @@ static struct platform_device cambria_ua +@@ -127,6 +128,45 @@ static struct platform_device cambria_ua .resource = &cambria_uart_resource, }; @@ -27,16 +27,18 @@ + +static struct plat_serial8250_port cambria_optional_uart_data[] = { + { -+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_BUGGY_UART, -+ .iotype = UPIO_MEM, ++ .flags = UPF_BOOT_AUTOCONF, ++ .iotype = UPIO_MEM_DELAY, + .regshift = 0, + .uartclk = 1843200, ++ .rw_delay = 2, + }, + { -+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_BUGGY_UART, -+ .iotype = UPIO_MEM, ++ .flags = UPF_BOOT_AUTOCONF, ++ .iotype = UPIO_MEM_DELAY, + .regshift = 0, + .uartclk = 1843200, ++ .rw_delay = 2, + }, + { }, +}; @@ -52,17 +54,17 @@ static struct resource cambria_pata_resources[] = { { .flags = IORESOURCE_MEM -@@ -283,6 +321,19 @@ static void __init cambria_gw23xx_setup( +@@ -283,6 +323,19 @@ static void __init cambria_gw23xx_setup( static void __init cambria_gw2350_setup(void) { -+ *IXP4XX_EXP_CS2 = 0xbfff0003; ++ *IXP4XX_EXP_CS2 = 0xBFFF3C43; + set_irq_type(IRQ_IXP4XX_GPIO3, IRQ_TYPE_EDGE_RISING); + cambria_optional_uart_data[0].mapbase = 0x52FF0000; + cambria_optional_uart_data[0].membase = (void __iomem *)ioremap(0x52FF0000, 0x0fff); + cambria_optional_uart_data[0].irq = IRQ_IXP4XX_GPIO3; + -+ *IXP4XX_EXP_CS3 = 0xbfff0003; ++ *IXP4XX_EXP_CS3 = 0xBFFF3C43; + set_irq_type(IRQ_IXP4XX_GPIO4, IRQ_TYPE_EDGE_RISING); + cambria_optional_uart_data[1].mapbase = 0x53FF0000; + cambria_optional_uart_data[1].membase = (void __iomem *)ioremap(0x53FF0000, 0x0fff); @@ -72,18 +74,11 @@ platform_device_register(&cambria_npec_device); platform_device_register(&cambria_npea_device); -@@ -290,10 +341,26 @@ static void __init cambria_gw2350_setup( - platform_device_register(&cambria_usb1_device); - - platform_device_register(&cambria_gpio_leds_device); -+ -+ *IXP4XX_EXP_CS2 = 0xBFFF3C43; -+ *IXP4XX_EXP_CS3 = 0xBFFF3C43; - } +@@ -294,6 +347,19 @@ static void __init cambria_gw2350_setup( static void __init cambria_gw2358_setup(void) { -+ *IXP4XX_EXP_CS3 = 0xbfff0003; ++ *IXP4XX_EXP_CS3 = 0xBFFF3C433; + set_irq_type(IRQ_IXP4XX_GPIO3, IRQ_TYPE_EDGE_RISING); + cambria_optional_uart_data[0].mapbase = 0x53FC0000; + cambria_optional_uart_data[0].membase = (void __iomem *)ioremap(0x53FC0000, 0x0fff); @@ -99,3 +94,85 @@ platform_device_register(&cambria_npec_device); platform_device_register(&cambria_npea_device); +--- a/include/linux/serial_8250.h ++++ b/include/linux/serial_8250.h +@@ -26,6 +26,7 @@ struct plat_serial8250_port { + void *private_data; + unsigned char regshift; /* register shift */ + unsigned char iotype; /* UPIO_* */ ++ unsigned int rw_delay; /* udelay for slower busses IXP4XX Expansion Bus */ + unsigned char hub6; + upf_t flags; /* UPF_* flags */ + }; +--- a/include/linux/serial_core.h ++++ b/include/linux/serial_core.h +@@ -262,6 +262,7 @@ struct uart_port { + #define UPIO_TSI (5) /* Tsi108/109 type IO */ + #define UPIO_DWAPB (6) /* DesignWare APB UART */ + #define UPIO_RM9000 (7) /* RM9000 type IO */ ++#define UPIO_MEM_DELAY (8) + + unsigned int read_status_mask; /* driver specific */ + unsigned int ignore_status_mask; /* driver specific */ +@@ -301,6 +302,7 @@ struct uart_port { + + unsigned int mctrl; /* current modem ctrl settings */ + unsigned int timeout; /* character-based timeout */ ++ unsigned int rw_delay; /* udelay for slow busses, IXP4XX Expansion Bus */ + unsigned int type; /* port type */ + const struct uart_ops *ops; + unsigned int custom_divisor; +--- a/drivers/serial/8250.c ++++ b/drivers/serial/8250.c +@@ -373,6 +373,8 @@ static unsigned int serial_in(struct uar + outb(up->port.hub6 - 1 + offset, up->port.iobase); + return inb(up->port.iobase + 1); + ++ case UPIO_MEM_DELAY: ++ udelay(up->port.rw_delay); + case UPIO_MEM: + case UPIO_DWAPB: + return readb(up->port.membase + offset); +@@ -411,6 +413,8 @@ serial_out(struct uart_8250_port *up, in + outb(value, up->port.iobase + 1); + break; + ++ case UPIO_MEM_DELAY: ++ udelay(up->port.rw_delay); + case UPIO_MEM: + writeb(value, up->port.membase + offset); + break; +@@ -2823,6 +2827,7 @@ static int __devinit serial8250_probe(st + port.hub6 = p->hub6; + port.private_data = p->private_data; + port.dev = &dev->dev; ++ port.rw_delay = p->rw_delay; + if (share_irqs) + port.flags |= UPF_SHARE_IRQ; + ret = serial8250_register_port(&port); +@@ -2972,6 +2977,7 @@ int serial8250_register_port(struct uart + uart->port.iotype = port->iotype; + uart->port.flags = port->flags | UPF_BOOT_AUTOCONF; + uart->port.mapbase = port->mapbase; ++ uart->port.rw_delay = port->rw_delay; + uart->port.private_data = port->private_data; + if (port->dev) + uart->port.dev = port->dev; +--- a/drivers/serial/serial_core.c ++++ b/drivers/serial/serial_core.c +@@ -2161,6 +2161,7 @@ uart_report_port(struct uart_driver *drv + snprintf(address, sizeof(address), + "I/O 0x%lx offset 0x%x", port->iobase, port->hub6); + break; ++ case UPIO_MEM_DELAY: + case UPIO_MEM: + case UPIO_MEM32: + case UPIO_AU: +@@ -2577,6 +2578,7 @@ int uart_match_port(struct uart_port *po + case UPIO_HUB6: + return (port1->iobase == port2->iobase) && + (port1->hub6 == port2->hub6); ++ case UPIO_MEM_DELAY: + case UPIO_MEM: + case UPIO_MEM32: + case UPIO_AU: -- 2.30.2