diff options
author | 2007-08-20 09:47:41 +0100 | |
---|---|---|
committer | 2007-10-12 21:14:49 +0100 | |
commit | e259a3aecbfb61981175ddc7fc02dd180da7d73e (patch) | |
tree | fb265b5c377f2e82b3cf8d3b0805ff9ba17df891 /drivers/serial | |
parent | [ARM] pxa: make pxa timer initialisation select clock rate at runtime (diff) | |
download | linux-e259a3aecbfb61981175ddc7fc02dd180da7d73e.tar.gz linux-e259a3aecbfb61981175ddc7fc02dd180da7d73e.tar.bz2 linux-e259a3aecbfb61981175ddc7fc02dd180da7d73e.zip |
[ARM] pxa: convert PXA serial drivers to use platform resources
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'drivers/serial')
-rw-r--r-- | drivers/serial/pxa.c | 139 |
1 files changed, 61 insertions, 78 deletions
diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c index e9c6cb391a23..59889f6a86b2 100644 --- a/drivers/serial/pxa.c +++ b/drivers/serial/pxa.c @@ -582,7 +582,7 @@ serial_pxa_type(struct uart_port *port) #ifdef CONFIG_SERIAL_PXA_CONSOLE -static struct uart_pxa_port serial_pxa_ports[]; +static struct uart_pxa_port *serial_pxa_ports[4]; static struct uart_driver serial_pxa_reg; #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) @@ -632,7 +632,7 @@ static void serial_pxa_console_putchar(struct uart_port *port, int ch) static void serial_pxa_console_write(struct console *co, const char *s, unsigned int count) { - struct uart_pxa_port *up = &serial_pxa_ports[co->index]; + struct uart_pxa_port *up = serial_pxa_ports[co->index]; unsigned int ier; /* @@ -662,7 +662,9 @@ serial_pxa_console_setup(struct console *co, char *options) if (co->index == -1 || co->index >= serial_pxa_reg.nr) co->index = 0; - up = &serial_pxa_ports[co->index]; + up = serial_pxa_ports[co->index]; + if (!up) + return -ENODEV; if (options) uart_parse_options(options, &baud, &parity, &bits, &flow); @@ -680,15 +682,6 @@ static struct console serial_pxa_console = { .data = &serial_pxa_reg, }; -static int __init -serial_pxa_console_init(void) -{ - register_console(&serial_pxa_console); - return 0; -} - -console_initcall(serial_pxa_console_init); - #define PXA_CONSOLE &serial_pxa_console #else #define PXA_CONSOLE NULL @@ -714,73 +707,13 @@ struct uart_ops serial_pxa_pops = { .verify_port = serial_pxa_verify_port, }; -static struct uart_pxa_port serial_pxa_ports[] = { - { /* FFUART */ - .name = "FFUART", - .cken = CKEN_FFUART, - .port = { - .type = PORT_PXA, - .iotype = UPIO_MEM, - .membase = (void *)&FFUART, - .mapbase = __PREG(FFUART), - .irq = IRQ_FFUART, - .uartclk = 921600 * 16, - .fifosize = 64, - .ops = &serial_pxa_pops, - .line = 0, - }, - }, { /* BTUART */ - .name = "BTUART", - .cken = CKEN_BTUART, - .port = { - .type = PORT_PXA, - .iotype = UPIO_MEM, - .membase = (void *)&BTUART, - .mapbase = __PREG(BTUART), - .irq = IRQ_BTUART, - .uartclk = 921600 * 16, - .fifosize = 64, - .ops = &serial_pxa_pops, - .line = 1, - }, - }, { /* STUART */ - .name = "STUART", - .cken = CKEN_STUART, - .port = { - .type = PORT_PXA, - .iotype = UPIO_MEM, - .membase = (void *)&STUART, - .mapbase = __PREG(STUART), - .irq = IRQ_STUART, - .uartclk = 921600 * 16, - .fifosize = 64, - .ops = &serial_pxa_pops, - .line = 2, - }, - }, { /* HWUART */ - .name = "HWUART", - .cken = CKEN_HWUART, - .port = { - .type = PORT_PXA, - .iotype = UPIO_MEM, - .membase = (void *)&HWUART, - .mapbase = __PREG(HWUART), - .irq = IRQ_HWUART, - .uartclk = 921600 * 16, - .fifosize = 64, - .ops = &serial_pxa_pops, - .line = 3, - }, - } -}; - static struct uart_driver serial_pxa_reg = { .owner = THIS_MODULE, .driver_name = "PXA serial", .dev_name = "ttyS", .major = TTY_MAJOR, .minor = 64, - .nr = ARRAY_SIZE(serial_pxa_ports), + .nr = 4, .cons = PXA_CONSOLE, }; @@ -806,10 +739,60 @@ static int serial_pxa_resume(struct platform_device *dev) static int serial_pxa_probe(struct platform_device *dev) { - serial_pxa_ports[dev->id].port.dev = &dev->dev; - uart_add_one_port(&serial_pxa_reg, &serial_pxa_ports[dev->id].port); - platform_set_drvdata(dev, &serial_pxa_ports[dev->id]); + struct uart_pxa_port *sport; + struct resource *mmres, *irqres; + int ret; + + mmres = platform_get_resource(dev, IORESOURCE_MEM, 0); + irqres = platform_get_resource(dev, IORESOURCE_IRQ, 0); + if (!mmres || !irqres) + return -ENODEV; + + sport = kzalloc(sizeof(struct uart_pxa_port), GFP_KERNEL); + if (!sport) + return -ENOMEM; + + sport->port.type = PORT_PXA; + sport->port.iotype = UPIO_MEM; + sport->port.mapbase = mmres->start; + sport->port.irq = irqres->start; + sport->port.fifosize = 64; + sport->port.ops = &serial_pxa_pops; + sport->port.line = dev->id; + sport->port.dev = &dev->dev; + sport->port.flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF; + sport->port.uartclk = 921600 * 16; + + /* + * Is it worth keeping this? + */ + if (mmres->start == __PREG(FFUART)) + sport->name = "FFUART"; + else if (mmres->start == __PREG(BTUART)) + sport->name = "BTUART"; + else if (mmres->start == __PREG(STUART)) + sport->name = "STUART"; + else if (mmres->start == __PREG(HWUART)) + sport->name = "HWUART"; + else + sport->name = "???"; + + sport->port.membase = ioremap(mmres->start, mmres->end - mmres->start + 1); + if (!sport->port.membase) { + ret = -ENOMEM; + goto err_free; + } + + serial_pxa_ports[dev->id] = sport; + + uart_add_one_port(&serial_pxa_reg, &sport->port); + platform_set_drvdata(dev, sport); + return 0; + + err_free: + kfree(sport); + return ret; } static int serial_pxa_remove(struct platform_device *dev) @@ -818,8 +801,8 @@ static int serial_pxa_remove(struct platform_device *dev) platform_set_drvdata(dev, NULL); - if (sport) - uart_remove_one_port(&serial_pxa_reg, &sport->port); + uart_remove_one_port(&serial_pxa_reg, &sport->port); + kfree(sport); return 0; } |