diff options
Diffstat (limited to 'arch/powerpc/kernel/legacy_serial.c')
| -rw-r--r-- | arch/powerpc/kernel/legacy_serial.c | 57 |
1 files changed, 33 insertions, 24 deletions
diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/kernel/legacy_serial.c index 4cf0b971976b..7e98e778b52f 100644 --- a/arch/powerpc/kernel/legacy_serial.c +++ b/arch/powerpc/kernel/legacy_serial.c | |||
| @@ -28,6 +28,7 @@ static struct legacy_serial_info { | |||
| 28 | struct device_node *np; | 28 | struct device_node *np; |
| 29 | unsigned int speed; | 29 | unsigned int speed; |
| 30 | unsigned int clock; | 30 | unsigned int clock; |
| 31 | int irq_check_parent; | ||
| 31 | phys_addr_t taddr; | 32 | phys_addr_t taddr; |
| 32 | } legacy_serial_infos[MAX_LEGACY_SERIAL_PORTS]; | 33 | } legacy_serial_infos[MAX_LEGACY_SERIAL_PORTS]; |
| 33 | static unsigned int legacy_serial_count; | 34 | static unsigned int legacy_serial_count; |
| @@ -36,7 +37,7 @@ static int legacy_serial_console = -1; | |||
| 36 | static int __init add_legacy_port(struct device_node *np, int want_index, | 37 | static int __init add_legacy_port(struct device_node *np, int want_index, |
| 37 | int iotype, phys_addr_t base, | 38 | int iotype, phys_addr_t base, |
| 38 | phys_addr_t taddr, unsigned long irq, | 39 | phys_addr_t taddr, unsigned long irq, |
| 39 | upf_t flags) | 40 | upf_t flags, int irq_check_parent) |
| 40 | { | 41 | { |
| 41 | u32 *clk, *spd, clock = BASE_BAUD * 16; | 42 | u32 *clk, *spd, clock = BASE_BAUD * 16; |
| 42 | int index; | 43 | int index; |
| @@ -68,7 +69,7 @@ static int __init add_legacy_port(struct device_node *np, int want_index, | |||
| 68 | if (legacy_serial_infos[index].np != 0) { | 69 | if (legacy_serial_infos[index].np != 0) { |
| 69 | /* if we still have some room, move it, else override */ | 70 | /* if we still have some room, move it, else override */ |
| 70 | if (legacy_serial_count < MAX_LEGACY_SERIAL_PORTS) { | 71 | if (legacy_serial_count < MAX_LEGACY_SERIAL_PORTS) { |
| 71 | printk(KERN_INFO "Moved legacy port %d -> %d\n", | 72 | printk(KERN_DEBUG "Moved legacy port %d -> %d\n", |
| 72 | index, legacy_serial_count); | 73 | index, legacy_serial_count); |
| 73 | legacy_serial_ports[legacy_serial_count] = | 74 | legacy_serial_ports[legacy_serial_count] = |
| 74 | legacy_serial_ports[index]; | 75 | legacy_serial_ports[index]; |
| @@ -76,7 +77,7 @@ static int __init add_legacy_port(struct device_node *np, int want_index, | |||
| 76 | legacy_serial_infos[index]; | 77 | legacy_serial_infos[index]; |
| 77 | legacy_serial_count++; | 78 | legacy_serial_count++; |
| 78 | } else { | 79 | } else { |
| 79 | printk(KERN_INFO "Replacing legacy port %d\n", index); | 80 | printk(KERN_DEBUG "Replacing legacy port %d\n", index); |
| 80 | } | 81 | } |
| 81 | } | 82 | } |
| 82 | 83 | ||
| @@ -95,10 +96,11 @@ static int __init add_legacy_port(struct device_node *np, int want_index, | |||
| 95 | legacy_serial_infos[index].np = of_node_get(np); | 96 | legacy_serial_infos[index].np = of_node_get(np); |
| 96 | legacy_serial_infos[index].clock = clock; | 97 | legacy_serial_infos[index].clock = clock; |
| 97 | legacy_serial_infos[index].speed = spd ? *spd : 0; | 98 | legacy_serial_infos[index].speed = spd ? *spd : 0; |
| 99 | legacy_serial_infos[index].irq_check_parent = irq_check_parent; | ||
| 98 | 100 | ||
| 99 | printk(KERN_INFO "Found legacy serial port %d for %s\n", | 101 | printk(KERN_DEBUG "Found legacy serial port %d for %s\n", |
| 100 | index, np->full_name); | 102 | index, np->full_name); |
| 101 | printk(KERN_INFO " %s=%llx, taddr=%llx, irq=%lx, clk=%d, speed=%d\n", | 103 | printk(KERN_DEBUG " %s=%llx, taddr=%llx, irq=%lx, clk=%d, speed=%d\n", |
| 102 | (iotype == UPIO_PORT) ? "port" : "mem", | 104 | (iotype == UPIO_PORT) ? "port" : "mem", |
| 103 | (unsigned long long)base, (unsigned long long)taddr, irq, | 105 | (unsigned long long)base, (unsigned long long)taddr, irq, |
| 104 | legacy_serial_ports[index].uartclk, | 106 | legacy_serial_ports[index].uartclk, |
| @@ -126,11 +128,13 @@ static int __init add_legacy_soc_port(struct device_node *np, | |||
| 126 | return -1; | 128 | return -1; |
| 127 | 129 | ||
| 128 | addr = of_translate_address(soc_dev, addrp); | 130 | addr = of_translate_address(soc_dev, addrp); |
| 131 | if (addr == OF_BAD_ADDR) | ||
| 132 | return -1; | ||
| 129 | 133 | ||
| 130 | /* Add port, irq will be dealt with later. We passed a translated | 134 | /* Add port, irq will be dealt with later. We passed a translated |
| 131 | * IO port value. It will be fixed up later along with the irq | 135 | * IO port value. It will be fixed up later along with the irq |
| 132 | */ | 136 | */ |
| 133 | return add_legacy_port(np, -1, UPIO_MEM, addr, addr, NO_IRQ, flags); | 137 | return add_legacy_port(np, -1, UPIO_MEM, addr, addr, NO_IRQ, flags, 0); |
| 134 | } | 138 | } |
| 135 | 139 | ||
| 136 | static int __init add_legacy_isa_port(struct device_node *np, | 140 | static int __init add_legacy_isa_port(struct device_node *np, |
| @@ -141,6 +145,8 @@ static int __init add_legacy_isa_port(struct device_node *np, | |||
| 141 | int index = -1; | 145 | int index = -1; |
| 142 | phys_addr_t taddr; | 146 | phys_addr_t taddr; |
| 143 | 147 | ||
| 148 | DBG(" -> add_legacy_isa_port(%s)\n", np->full_name); | ||
| 149 | |||
| 144 | /* Get the ISA port number */ | 150 | /* Get the ISA port number */ |
| 145 | reg = (u32 *)get_property(np, "reg", NULL); | 151 | reg = (u32 *)get_property(np, "reg", NULL); |
| 146 | if (reg == NULL) | 152 | if (reg == NULL) |
| @@ -161,9 +167,12 @@ static int __init add_legacy_isa_port(struct device_node *np, | |||
| 161 | 167 | ||
| 162 | /* Translate ISA address */ | 168 | /* Translate ISA address */ |
| 163 | taddr = of_translate_address(np, reg); | 169 | taddr = of_translate_address(np, reg); |
| 170 | if (taddr == OF_BAD_ADDR) | ||
| 171 | return -1; | ||
| 164 | 172 | ||
| 165 | /* Add port, irq will be dealt with later */ | 173 | /* Add port, irq will be dealt with later */ |
| 166 | return add_legacy_port(np, index, UPIO_PORT, reg[1], taddr, NO_IRQ, UPF_BOOT_AUTOCONF); | 174 | return add_legacy_port(np, index, UPIO_PORT, reg[1], taddr, |
| 175 | NO_IRQ, UPF_BOOT_AUTOCONF, 0); | ||
| 167 | 176 | ||
| 168 | } | 177 | } |
| 169 | 178 | ||
| @@ -176,6 +185,8 @@ static int __init add_legacy_pci_port(struct device_node *np, | |||
| 176 | unsigned int flags; | 185 | unsigned int flags; |
| 177 | int iotype, index = -1, lindex = 0; | 186 | int iotype, index = -1, lindex = 0; |
| 178 | 187 | ||
| 188 | DBG(" -> add_legacy_pci_port(%s)\n", np->full_name); | ||
| 189 | |||
| 179 | /* We only support ports that have a clock frequency properly | 190 | /* We only support ports that have a clock frequency properly |
| 180 | * encoded in the device-tree (that is have an fcode). Anything | 191 | * encoded in the device-tree (that is have an fcode). Anything |
| 181 | * else can't be used that early and will be normally probed by | 192 | * else can't be used that early and will be normally probed by |
| @@ -194,6 +205,8 @@ static int __init add_legacy_pci_port(struct device_node *np, | |||
| 194 | /* We only support BAR 0 for now */ | 205 | /* We only support BAR 0 for now */ |
| 195 | iotype = (flags & IORESOURCE_MEM) ? UPIO_MEM : UPIO_PORT; | 206 | iotype = (flags & IORESOURCE_MEM) ? UPIO_MEM : UPIO_PORT; |
| 196 | addr = of_translate_address(pci_dev, addrp); | 207 | addr = of_translate_address(pci_dev, addrp); |
| 208 | if (addr == OF_BAD_ADDR) | ||
| 209 | return -1; | ||
| 197 | 210 | ||
| 198 | /* Set the IO base to the same as the translated address for MMIO, | 211 | /* Set the IO base to the same as the translated address for MMIO, |
| 199 | * or to the domain local IO base for PIO (it will be fixed up later) | 212 | * or to the domain local IO base for PIO (it will be fixed up later) |
| @@ -231,7 +244,8 @@ static int __init add_legacy_pci_port(struct device_node *np, | |||
| 231 | /* Add port, irq will be dealt with later. We passed a translated | 244 | /* Add port, irq will be dealt with later. We passed a translated |
| 232 | * IO port value. It will be fixed up later along with the irq | 245 | * IO port value. It will be fixed up later along with the irq |
| 233 | */ | 246 | */ |
| 234 | return add_legacy_port(np, index, iotype, base, addr, NO_IRQ, UPF_BOOT_AUTOCONF); | 247 | return add_legacy_port(np, index, iotype, base, addr, NO_IRQ, |
| 248 | UPF_BOOT_AUTOCONF, np != pci_dev); | ||
| 235 | } | 249 | } |
| 236 | #endif | 250 | #endif |
| 237 | 251 | ||
| @@ -362,27 +376,22 @@ static void __init fixup_port_irq(int index, | |||
| 362 | struct device_node *np, | 376 | struct device_node *np, |
| 363 | struct plat_serial8250_port *port) | 377 | struct plat_serial8250_port *port) |
| 364 | { | 378 | { |
| 379 | unsigned int virq; | ||
| 380 | |||
| 365 | DBG("fixup_port_irq(%d)\n", index); | 381 | DBG("fixup_port_irq(%d)\n", index); |
| 366 | 382 | ||
| 367 | /* Check for interrupts in that node */ | 383 | virq = irq_of_parse_and_map(np, 0); |
| 368 | if (np->n_intrs > 0) { | 384 | if (virq == NO_IRQ && legacy_serial_infos[index].irq_check_parent) { |
| 369 | port->irq = np->intrs[0].line; | 385 | np = of_get_parent(np); |
| 370 | DBG(" port %d (%s), irq=%d\n", | 386 | if (np == NULL) |
| 371 | index, np->full_name, port->irq); | 387 | return; |
| 372 | return; | 388 | virq = irq_of_parse_and_map(np, 0); |
| 389 | of_node_put(np); | ||
| 373 | } | 390 | } |
| 374 | 391 | if (virq == NO_IRQ) | |
| 375 | /* Check for interrupts in the parent */ | ||
| 376 | np = of_get_parent(np); | ||
| 377 | if (np == NULL) | ||
| 378 | return; | 392 | return; |
| 379 | 393 | ||
| 380 | if (np->n_intrs > 0) { | 394 | port->irq = virq; |
| 381 | port->irq = np->intrs[0].line; | ||
| 382 | DBG(" port %d (%s), irq=%d\n", | ||
| 383 | index, np->full_name, port->irq); | ||
| 384 | } | ||
| 385 | of_node_put(np); | ||
| 386 | } | 395 | } |
| 387 | 396 | ||
| 388 | static void __init fixup_port_pio(int index, | 397 | static void __init fixup_port_pio(int index, |
