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, |