| From d696c0e9694ebd3ef13a0fbb44beac690dee6e6b Mon Sep 17 00:00:00 2001 |
| From: Robert Reif <reif@earthlink.net> |
| Date: Thu, 24 Apr 2008 03:37:51 -0700 |
| Subject: sparc: sunzilog uart order |
| |
| From: Robert Reif <reif@earthlink.net> |
| |
| [ Upstream commit: 227739bf4c110bbd02d0c0f13b272c32de406e4c ] |
| |
| I have a sparcstation 20 clone with a lot of on board serial ports. |
| The serial core code assumes that uarts are assigned contiguously |
| and that may not be the case when there are multiple zs devices |
| present. This patch insures that uart chips are placed in front of |
| keyboard/mouse chips in the port table. |
| |
| ffd37420: ttyS0 at MMIO 0xf1100000 (irq = 44) is a zs (ESCC) |
| Console: ttyS0 (SunZilog zs0) |
| console [ttyS0] enabled |
| ffd37420: ttyS1 at MMIO 0xf1100004 (irq = 44) is a zs (ESCC) |
| ffd37500: Keyboard at MMIO 0xf1000000 (irq = 44) is a zs |
| ffd37500: Mouse at MMIO 0xf1000004 (irq = 44) is a zs |
| ffd3c5c0: ttyS2 at MMIO 0xf1100008 (irq = 44) is a zs (ESCC) |
| ffd3c5c0: ttyS3 at MMIO 0xf110000c (irq = 44) is a zs (ESCC) |
| ffd3c6a0: ttyS4 at MMIO 0xf1100010 (irq = 44) is a zs (ESCC) |
| ffd3c6a0: ttyS5 at MMIO 0xf1100014 (irq = 44) is a zs (ESCC) |
| ffd3c780: ttyS6 at MMIO 0xf1100018 (irq = 44) is a zs (ESCC) |
| ffd3c780: ttyS7 at MMIO 0xf110001c (irq = 44) is a zs (ESCC) |
| |
| Signed-off-by: Robert Reif <reif@earthlink.net> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| |
| --- |
| drivers/serial/sunzilog.c | 30 +++++++++++++++++------------- |
| 1 file changed, 17 insertions(+), 13 deletions(-) |
| |
| --- a/drivers/serial/sunzilog.c |
| +++ b/drivers/serial/sunzilog.c |
| @@ -1015,6 +1015,7 @@ static struct uart_ops sunzilog_pops = { |
| .verify_port = sunzilog_verify_port, |
| }; |
| |
| +static int uart_chip_count; |
| static struct uart_sunzilog_port *sunzilog_port_table; |
| static struct zilog_layout __iomem **sunzilog_chip_regs; |
| |
| @@ -1350,16 +1351,22 @@ static int zilog_irq = -1; |
| |
| static int __devinit zs_probe(struct of_device *op, const struct of_device_id *match) |
| { |
| - static int inst; |
| + static int kbm_inst, uart_inst; |
| + int inst; |
| struct uart_sunzilog_port *up; |
| struct zilog_layout __iomem *rp; |
| - int keyboard_mouse; |
| + int keyboard_mouse = 0; |
| int err; |
| |
| - keyboard_mouse = 0; |
| if (of_find_property(op->node, "keyboard", NULL)) |
| keyboard_mouse = 1; |
| |
| + /* uarts must come before keyboards/mice */ |
| + if (keyboard_mouse) |
| + inst = uart_chip_count + kbm_inst; |
| + else |
| + inst = uart_inst; |
| + |
| sunzilog_chip_regs[inst] = of_ioremap(&op->resource[0], 0, |
| sizeof(struct zilog_layout), |
| "zs"); |
| @@ -1427,6 +1434,7 @@ static int __devinit zs_probe(struct of_ |
| rp, sizeof(struct zilog_layout)); |
| return err; |
| } |
| + uart_inst++; |
| } else { |
| printk(KERN_INFO "%s: Keyboard at MMIO 0x%llx (irq = %d) " |
| "is a %s\n", |
| @@ -1438,12 +1446,11 @@ static int __devinit zs_probe(struct of_ |
| op->dev.bus_id, |
| (unsigned long long) up[1].port.mapbase, |
| op->irqs[0], sunzilog_type(&up[1].port)); |
| + kbm_inst++; |
| } |
| |
| dev_set_drvdata(&op->dev, &up[0]); |
| |
| - inst++; |
| - |
| return 0; |
| } |
| |
| @@ -1491,28 +1498,25 @@ static struct of_platform_driver zs_driv |
| static int __init sunzilog_init(void) |
| { |
| struct device_node *dp; |
| - int err, uart_count; |
| - int num_keybms; |
| + int err; |
| + int num_keybms = 0; |
| int num_sunzilog = 0; |
| |
| - num_keybms = 0; |
| for_each_node_by_name(dp, "zs") { |
| num_sunzilog++; |
| if (of_find_property(dp, "keyboard", NULL)) |
| num_keybms++; |
| } |
| |
| - uart_count = 0; |
| if (num_sunzilog) { |
| - int uart_count; |
| - |
| err = sunzilog_alloc_tables(num_sunzilog); |
| if (err) |
| goto out; |
| |
| - uart_count = (num_sunzilog * 2) - (2 * num_keybms); |
| + uart_chip_count = num_sunzilog - num_keybms; |
| |
| - err = sunserial_register_minors(&sunzilog_reg, uart_count); |
| + err = sunserial_register_minors(&sunzilog_reg, |
| + uart_chip_count * 2); |
| if (err) |
| goto out_free_tables; |
| } |