]> err.no Git - linux-2.6/commitdiff
sparc: sunzilog uart order
authorRobert Reif <reif@earthlink.net>
Thu, 24 Apr 2008 10:37:51 +0000 (03:37 -0700)
committerDavid S. Miller <davem@davemloft.net>
Thu, 24 Apr 2008 10:37:51 +0000 (03:37 -0700)
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>
drivers/serial/sunzilog.c

index cb2e405063794f97922aaa6f5eaf9e0d77a15302..3271379a36dbc8b8cf8daede92fad77a5680e4a3 100644 (file)
@@ -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_device *op, const struct of_device_id *m
                                   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_device *op, const struct of_device_id *m
                       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_driver = {
 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;
        }