linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / arch / powerpc / kernel / legacy_serial.c
index 40a3929..c7a799a 100644 (file)
@@ -1,3 +1,4 @@
+#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/serial.h>
 #include <linux/serial_8250.h>
@@ -28,7 +29,6 @@ static struct legacy_serial_info {
        struct device_node              *np;
        unsigned int                    speed;
        unsigned int                    clock;
-       int                             irq_check_parent;
        phys_addr_t                     taddr;
 } legacy_serial_infos[MAX_LEGACY_SERIAL_PORTS];
 static unsigned int legacy_serial_count;
@@ -37,7 +37,7 @@ static int legacy_serial_console = -1;
 static int __init add_legacy_port(struct device_node *np, int want_index,
                                  int iotype, phys_addr_t base,
                                  phys_addr_t taddr, unsigned long irq,
-                                 upf_t flags, int irq_check_parent)
+                                 unsigned int flags)
 {
        u32 *clk, *spd, clock = BASE_BAUD * 16;
        int index;
@@ -69,7 +69,7 @@ static int __init add_legacy_port(struct device_node *np, int want_index,
        if (legacy_serial_infos[index].np != 0) {
                /* if we still have some room, move it, else override */
                if (legacy_serial_count < MAX_LEGACY_SERIAL_PORTS) {
-                       printk(KERN_DEBUG "Moved legacy port %d -> %d\n",
+                       printk(KERN_INFO "Moved legacy port %d -> %d\n",
                               index, legacy_serial_count);
                        legacy_serial_ports[legacy_serial_count] =
                                legacy_serial_ports[index];
@@ -77,7 +77,7 @@ static int __init add_legacy_port(struct device_node *np, int want_index,
                                legacy_serial_infos[index];
                        legacy_serial_count++;
                } else {
-                       printk(KERN_DEBUG "Replacing legacy port %d\n", index);
+                       printk(KERN_INFO "Replacing legacy port %d\n", index);
                }
        }
 
@@ -96,11 +96,10 @@ static int __init add_legacy_port(struct device_node *np, int want_index,
        legacy_serial_infos[index].np = of_node_get(np);
        legacy_serial_infos[index].clock = clock;
        legacy_serial_infos[index].speed = spd ? *spd : 0;
-       legacy_serial_infos[index].irq_check_parent = irq_check_parent;
 
-       printk(KERN_DEBUG "Found legacy serial port %d for %s\n",
+       printk(KERN_INFO "Found legacy serial port %d for %s\n",
               index, np->full_name);
-       printk(KERN_DEBUG "  %s=%llx, taddr=%llx, irq=%lx, clk=%d, speed=%d\n",
+       printk(KERN_INFO "  %s=%llx, taddr=%llx, irq=%lx, clk=%d, speed=%d\n",
               (iotype == UPIO_PORT) ? "port" : "mem",
               (unsigned long long)base, (unsigned long long)taddr, irq,
               legacy_serial_ports[index].uartclk,
@@ -112,10 +111,9 @@ static int __init add_legacy_port(struct device_node *np, int want_index,
 static int __init add_legacy_soc_port(struct device_node *np,
                                      struct device_node *soc_dev)
 {
-       u64 addr;
+       phys_addr_t addr;
        u32 *addrp;
-       upf_t flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ;
-       struct device_node *tsi = of_get_parent(np);
+       unsigned int flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ;
 
        /* We only support ports that have a clock frequency properly
         * encoded in the device-tree.
@@ -129,16 +127,11 @@ static int __init add_legacy_soc_port(struct device_node *np,
                return -1;
 
        addr = of_translate_address(soc_dev, addrp);
-       if (addr == OF_BAD_ADDR)
-               return -1;
 
        /* Add port, irq will be dealt with later. We passed a translated
         * IO port value. It will be fixed up later along with the irq
         */
-       if (tsi && !strcmp(tsi->type, "tsi-bridge"))
-               return add_legacy_port(np, -1, UPIO_TSI, addr, addr, NO_IRQ, flags, 0);
-       else
-               return add_legacy_port(np, -1, UPIO_MEM, addr, addr, NO_IRQ, flags, 0);
+       return add_legacy_port(np, -1, UPIO_MEM, addr, addr, NO_IRQ, flags);
 }
 
 static int __init add_legacy_isa_port(struct device_node *np,
@@ -147,9 +140,7 @@ static int __init add_legacy_isa_port(struct device_node *np,
        u32 *reg;
        char *typep;
        int index = -1;
-       u64 taddr;
-
-       DBG(" -> add_legacy_isa_port(%s)\n", np->full_name);
+       phys_addr_t taddr;
 
        /* Get the ISA port number */
        reg = (u32 *)get_property(np, "reg", NULL);
@@ -169,17 +160,11 @@ static int __init add_legacy_isa_port(struct device_node *np,
        if (typep && *typep == 'S')
                index = simple_strtol(typep+1, NULL, 0) - 1;
 
-       /* Translate ISA address. If it fails, we still register the port
-        * with no translated address so that it can be picked up as an IO
-        * port later by the serial driver
-        */
+       /* Translate ISA address */
        taddr = of_translate_address(np, reg);
-       if (taddr == OF_BAD_ADDR)
-               taddr = 0;
 
        /* Add port, irq will be dealt with later */
-       return add_legacy_port(np, index, UPIO_PORT, reg[1], taddr,
-                              NO_IRQ, UPF_BOOT_AUTOCONF, 0);
+       return add_legacy_port(np, index, UPIO_PORT, reg[1], taddr, NO_IRQ, UPF_BOOT_AUTOCONF);
 
 }
 
@@ -187,13 +172,11 @@ static int __init add_legacy_isa_port(struct device_node *np,
 static int __init add_legacy_pci_port(struct device_node *np,
                                      struct device_node *pci_dev)
 {
-       u64 addr, base;
+       phys_addr_t addr, base;
        u32 *addrp;
        unsigned int flags;
        int iotype, index = -1, lindex = 0;
 
-       DBG(" -> add_legacy_pci_port(%s)\n", np->full_name);
-
        /* We only support ports that have a clock frequency properly
         * encoded in the device-tree (that is have an fcode). Anything
         * else can't be used that early and will be normally probed by
@@ -212,8 +195,6 @@ static int __init add_legacy_pci_port(struct device_node *np,
        /* We only support BAR 0 for now */
        iotype = (flags & IORESOURCE_MEM) ? UPIO_MEM : UPIO_PORT;
        addr = of_translate_address(pci_dev, addrp);
-       if (addr == OF_BAD_ADDR)
-               return -1;
 
        /* Set the IO base to the same as the translated address for MMIO,
         * or to the domain local IO base for PIO (it will be fixed up later)
@@ -251,28 +232,10 @@ static int __init add_legacy_pci_port(struct device_node *np,
        /* Add port, irq will be dealt with later. We passed a translated
         * IO port value. It will be fixed up later along with the irq
         */
-       return add_legacy_port(np, index, iotype, base, addr, NO_IRQ,
-                              UPF_BOOT_AUTOCONF, np != pci_dev);
+       return add_legacy_port(np, index, iotype, base, addr, NO_IRQ, UPF_BOOT_AUTOCONF);
 }
 #endif
 
-static void __init setup_legacy_serial_console(int console)
-{
-       struct legacy_serial_info *info =
-               &legacy_serial_infos[console];
-       void __iomem *addr;
-
-       if (info->taddr == 0)
-               return;
-       addr = ioremap(info->taddr, 0x1000);
-       if (addr == NULL)
-               return;
-       if (info->speed == 0)
-               info->speed = udbg_probe_uart_speed(addr, info->clock);
-       DBG("default console speed = %d\n", info->speed);
-       udbg_init_uart(addr, info->speed, info->clock);
-}
-
 /*
  * This is called very early, as part of setup_system() or eventually
  * setup_arch(), basically before anything else in this file. This function
@@ -322,17 +285,6 @@ void __init find_legacy_serial_ports(void)
                of_node_put(isa);
        }
 
-       /* First fill our array with tsi-bridge ports */
-       for (np = NULL; (np = of_find_compatible_node(np, "serial", "ns16550")) != NULL;) {
-               struct device_node *tsi = of_get_parent(np);
-               if (tsi && !strcmp(tsi->type, "tsi-bridge")) {
-                       index = add_legacy_soc_port(np, np);
-                       if (index >= 0 && np == stdout)
-                               legacy_serial_console = index;
-               }
-               of_node_put(tsi);
-       }
-
 #ifdef CONFIG_PCI
        /* Next, try to locate PCI ports */
        for (np = NULL; (np = of_find_all_nodes(np));) {
@@ -366,8 +318,25 @@ void __init find_legacy_serial_ports(void)
 #endif
 
        DBG("legacy_serial_console = %d\n", legacy_serial_console);
-       if (legacy_serial_console >= 0)
-               setup_legacy_serial_console(legacy_serial_console);
+
+       /* udbg is 64 bits only for now, that will change soon though ... */
+       while (legacy_serial_console >= 0) {
+               struct legacy_serial_info *info =
+                       &legacy_serial_infos[legacy_serial_console];
+               void __iomem *addr;
+
+               if (info->taddr == 0)
+                       break;
+               addr = ioremap(info->taddr, 0x1000);
+               if (addr == NULL)
+                       break;
+               if (info->speed == 0)
+                       info->speed = udbg_probe_uart_speed(addr, info->clock);
+               DBG("default console speed = %d\n", info->speed);
+               udbg_init_uart(addr, info->speed, info->clock);
+               break;
+       }
+
        DBG(" <- find_legacy_serial_port()\n");
 }
 
@@ -383,22 +352,27 @@ static void __init fixup_port_irq(int index,
                                  struct device_node *np,
                                  struct plat_serial8250_port *port)
 {
-       unsigned int virq;
-
        DBG("fixup_port_irq(%d)\n", index);
 
-       virq = irq_of_parse_and_map(np, 0);
-       if (virq == NO_IRQ && legacy_serial_infos[index].irq_check_parent) {
-               np = of_get_parent(np);
-               if (np == NULL)
-                       return;
-               virq = irq_of_parse_and_map(np, 0);
-               of_node_put(np);
+       /* Check for interrupts in that node */
+       if (np->n_intrs > 0) {
+               port->irq = np->intrs[0].line;
+               DBG(" port %d (%s), irq=%d\n",
+                   index, np->full_name, port->irq);
+               return;
        }
-       if (virq == NO_IRQ)
+
+       /* Check for interrupts in the parent */
+       np = of_get_parent(np);
+       if (np == NULL)
                return;
 
-       port->irq = virq;
+       if (np->n_intrs > 0) {
+               port->irq = np->intrs[0].line;
+               DBG(" port %d (%s), irq=%d\n",
+                   index, np->full_name, port->irq);
+       }
+       of_node_put(np);
 }
 
 static void __init fixup_port_pio(int index,
@@ -468,7 +442,7 @@ static int __init serial_dev_init(void)
                        fixup_port_irq(i, np, port);
                if (port->iotype == UPIO_PORT)
                        fixup_port_pio(i, np, port);
-               if ((port->iotype == UPIO_MEM) || (port->iotype == UPIO_TSI))
+               if (port->iotype == UPIO_MEM)
                        fixup_port_mmio(i, np, port);
        }