aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/legacy_serial.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2006-07-03 07:36:01 -0400
committerPaul Mackerras <paulus@samba.org>2006-07-03 07:36:01 -0400
commit0ebfff1491ef85d41ddf9c633834838be144f69f (patch)
tree5b469a6d61a9fcfbf94e7b6d411e544dbdec8dec /arch/powerpc/kernel/legacy_serial.c
parentf63e115fb50db39706b955b81e3375ef6bab2268 (diff)
[POWERPC] Add new interrupt mapping core and change platforms to use it
This adds the new irq remapper core and removes the old one. Because there are some fundamental conflicts with the old code, like the value of NO_IRQ which I'm now setting to 0 (as per discussions with Linus), etc..., this commit also changes the relevant platform and driver code over to use the new remapper (so as not to cause difficulties later in bisecting). This patch removes the old pre-parsing of the open firmware interrupt tree along with all the bogus assumptions it made to try to renumber interrupts according to the platform. This is all to be handled by the new code now. For the pSeries XICS interrupt controller, a single remapper host is created for the whole machine regardless of how many interrupt presentation and source controllers are found, and it's set to match any device node that isn't a 8259. That works fine on pSeries and avoids having to deal with some of the complexities of split source controllers vs. presentation controllers in the pSeries device trees. The powerpc i8259 PIC driver now always requests the legacy interrupt range. It also has the feature of being able to match any device node (including NULL) if passed no device node as an input. That will help porting over platforms with broken device-trees like Pegasos who don't have a proper interrupt tree. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/kernel/legacy_serial.c')
-rw-r--r--arch/powerpc/kernel/legacy_serial.c46
1 files changed, 22 insertions, 24 deletions
diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/kernel/legacy_serial.c
index a55056676ca4..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];
33static unsigned int legacy_serial_count; 34static unsigned int legacy_serial_count;
@@ -36,7 +37,7 @@ static int legacy_serial_console = -1;
36static int __init add_legacy_port(struct device_node *np, int want_index, 37static 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,
@@ -132,7 +134,7 @@ static int __init add_legacy_soc_port(struct device_node *np,
132 /* 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
133 * 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
134 */ 136 */
135 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);
136} 138}
137 139
138static int __init add_legacy_isa_port(struct device_node *np, 140static int __init add_legacy_isa_port(struct device_node *np,
@@ -170,7 +172,7 @@ static int __init add_legacy_isa_port(struct device_node *np,
170 172
171 /* Add port, irq will be dealt with later */ 173 /* Add port, irq will be dealt with later */
172 return add_legacy_port(np, index, UPIO_PORT, reg[1], taddr, 174 return add_legacy_port(np, index, UPIO_PORT, reg[1], taddr,
173 NO_IRQ, UPF_BOOT_AUTOCONF); 175 NO_IRQ, UPF_BOOT_AUTOCONF, 0);
174 176
175} 177}
176 178
@@ -242,7 +244,8 @@ static int __init add_legacy_pci_port(struct device_node *np,
242 /* 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
243 * 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
244 */ 246 */
245 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);
246} 249}
247#endif 250#endif
248 251
@@ -373,27 +376,22 @@ static void __init fixup_port_irq(int index,
373 struct device_node *np, 376 struct device_node *np,
374 struct plat_serial8250_port *port) 377 struct plat_serial8250_port *port)
375{ 378{
379 unsigned int virq;
380
376 DBG("fixup_port_irq(%d)\n", index); 381 DBG("fixup_port_irq(%d)\n", index);
377 382
378 /* Check for interrupts in that node */ 383 virq = irq_of_parse_and_map(np, 0);
379 if (np->n_intrs > 0) { 384 if (virq == NO_IRQ && legacy_serial_infos[index].irq_check_parent) {
380 port->irq = np->intrs[0].line; 385 np = of_get_parent(np);
381 DBG(" port %d (%s), irq=%d\n", 386 if (np == NULL)
382 index, np->full_name, port->irq); 387 return;
383 return; 388 virq = irq_of_parse_and_map(np, 0);
389 of_node_put(np);
384 } 390 }
385 391 if (virq == NO_IRQ)
386 /* Check for interrupts in the parent */
387 np = of_get_parent(np);
388 if (np == NULL)
389 return; 392 return;
390 393
391 if (np->n_intrs > 0) { 394 port->irq = virq;
392 port->irq = np->intrs[0].line;
393 DBG(" port %d (%s), irq=%d\n",
394 index, np->full_name, port->irq);
395 }
396 of_node_put(np);
397} 395}
398 396
399static void __init fixup_port_pio(int index, 397static void __init fixup_port_pio(int index,