aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/chrp/setup.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/platforms/chrp/setup.c')
-rw-r--r--arch/powerpc/platforms/chrp/setup.c103
1 files changed, 70 insertions, 33 deletions
diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c
index 1f1771b212b4..538e337d63e2 100644
--- a/arch/powerpc/platforms/chrp/setup.c
+++ b/arch/powerpc/platforms/chrp/setup.c
@@ -24,7 +24,7 @@
24#include <linux/reboot.h> 24#include <linux/reboot.h>
25#include <linux/init.h> 25#include <linux/init.h>
26#include <linux/pci.h> 26#include <linux/pci.h>
27#include <linux/version.h> 27#include <linux/utsrelease.h>
28#include <linux/adb.h> 28#include <linux/adb.h>
29#include <linux/module.h> 29#include <linux/module.h>
30#include <linux/delay.h> 30#include <linux/delay.h>
@@ -59,7 +59,7 @@ void rtas_indicator_progress(char *, unsigned short);
59int _chrp_type; 59int _chrp_type;
60EXPORT_SYMBOL(_chrp_type); 60EXPORT_SYMBOL(_chrp_type);
61 61
62struct mpic *chrp_mpic; 62static struct mpic *chrp_mpic;
63 63
64/* Used for doing CHRP event-scans */ 64/* Used for doing CHRP event-scans */
65DEFINE_PER_CPU(struct timer_list, heartbeat_timer); 65DEFINE_PER_CPU(struct timer_list, heartbeat_timer);
@@ -315,24 +315,32 @@ chrp_event_scan(unsigned long unused)
315 jiffies + event_scan_interval); 315 jiffies + event_scan_interval);
316} 316}
317 317
318static void chrp_8259_cascade(unsigned int irq, struct irq_desc *desc,
319 struct pt_regs *regs)
320{
321 unsigned int cascade_irq = i8259_irq(regs);
322 if (cascade_irq != NO_IRQ)
323 generic_handle_irq(cascade_irq, regs);
324 desc->chip->eoi(irq);
325}
326
318/* 327/*
319 * Finds the open-pic node and sets up the mpic driver. 328 * Finds the open-pic node and sets up the mpic driver.
320 */ 329 */
321static void __init chrp_find_openpic(void) 330static void __init chrp_find_openpic(void)
322{ 331{
323 struct device_node *np, *root; 332 struct device_node *np, *root;
324 int len, i, j, irq_count; 333 int len, i, j;
325 int isu_size, idu_size; 334 int isu_size, idu_size;
326 unsigned int *iranges, *opprop = NULL; 335 unsigned int *iranges, *opprop = NULL;
327 int oplen = 0; 336 int oplen = 0;
328 unsigned long opaddr; 337 unsigned long opaddr;
329 int na = 1; 338 int na = 1;
330 unsigned char init_senses[NR_IRQS - NUM_8259_INTERRUPTS];
331 339
332 np = find_type_devices("open-pic"); 340 np = of_find_node_by_type(NULL, "open-pic");
333 if (np == NULL) 341 if (np == NULL)
334 return; 342 return;
335 root = find_path_device("/"); 343 root = of_find_node_by_path("/");
336 if (root) { 344 if (root) {
337 opprop = (unsigned int *) get_property 345 opprop = (unsigned int *) get_property
338 (root, "platform-open-pic", &oplen); 346 (root, "platform-open-pic", &oplen);
@@ -343,19 +351,15 @@ static void __init chrp_find_openpic(void)
343 oplen /= na * sizeof(unsigned int); 351 oplen /= na * sizeof(unsigned int);
344 } else { 352 } else {
345 struct resource r; 353 struct resource r;
346 if (of_address_to_resource(np, 0, &r)) 354 if (of_address_to_resource(np, 0, &r)) {
347 return; 355 goto bail;
356 }
348 opaddr = r.start; 357 opaddr = r.start;
349 oplen = 0; 358 oplen = 0;
350 } 359 }
351 360
352 printk(KERN_INFO "OpenPIC at %lx\n", opaddr); 361 printk(KERN_INFO "OpenPIC at %lx\n", opaddr);
353 362
354 irq_count = NR_IRQS - NUM_ISA_INTERRUPTS - 4; /* leave room for IPIs */
355 prom_get_irq_senses(init_senses, NUM_ISA_INTERRUPTS, NR_IRQS - 4);
356 /* i8259 cascade is always positive level */
357 init_senses[0] = IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE;
358
359 iranges = (unsigned int *) get_property(np, "interrupt-ranges", &len); 363 iranges = (unsigned int *) get_property(np, "interrupt-ranges", &len);
360 if (iranges == NULL) 364 if (iranges == NULL)
361 len = 0; /* non-distributed mpic */ 365 len = 0; /* non-distributed mpic */
@@ -382,15 +386,12 @@ static void __init chrp_find_openpic(void)
382 if (len > 1) 386 if (len > 1)
383 isu_size = iranges[3]; 387 isu_size = iranges[3];
384 388
385 chrp_mpic = mpic_alloc(opaddr, MPIC_PRIMARY, 389 chrp_mpic = mpic_alloc(np, opaddr, MPIC_PRIMARY,
386 isu_size, NUM_ISA_INTERRUPTS, irq_count, 390 isu_size, 0, " MPIC ");
387 NR_IRQS - 4, init_senses, irq_count,
388 " MPIC ");
389 if (chrp_mpic == NULL) { 391 if (chrp_mpic == NULL) {
390 printk(KERN_ERR "Failed to allocate MPIC structure\n"); 392 printk(KERN_ERR "Failed to allocate MPIC structure\n");
391 return; 393 goto bail;
392 } 394 }
393
394 j = na - 1; 395 j = na - 1;
395 for (i = 1; i < len; ++i) { 396 for (i = 1; i < len; ++i) {
396 iranges += 2; 397 iranges += 2;
@@ -402,7 +403,10 @@ static void __init chrp_find_openpic(void)
402 } 403 }
403 404
404 mpic_init(chrp_mpic); 405 mpic_init(chrp_mpic);
405 mpic_setup_cascade(NUM_ISA_INTERRUPTS, i8259_irq_cascade, NULL); 406 ppc_md.get_irq = mpic_get_irq;
407 bail:
408 of_node_put(root);
409 of_node_put(np);
406} 410}
407 411
408#if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON) 412#if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON)
@@ -413,14 +417,34 @@ static struct irqaction xmon_irqaction = {
413}; 417};
414#endif 418#endif
415 419
416void __init chrp_init_IRQ(void) 420static void __init chrp_find_8259(void)
417{ 421{
418 struct device_node *np; 422 struct device_node *np, *pic = NULL;
419 unsigned long chrp_int_ack = 0; 423 unsigned long chrp_int_ack = 0;
420#if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON) 424 unsigned int cascade_irq;
421 struct device_node *kbd; 425
422#endif 426 /* Look for cascade */
427 for_each_node_by_type(np, "interrupt-controller")
428 if (device_is_compatible(np, "chrp,iic")) {
429 pic = np;
430 break;
431 }
432 /* Ok, 8259 wasn't found. We need to handle the case where
433 * we have a pegasos that claims to be chrp but doesn't have
434 * a proper interrupt tree
435 */
436 if (pic == NULL && chrp_mpic != NULL) {
437 printk(KERN_ERR "i8259: Not found in device-tree"
438 " assuming no legacy interrupts\n");
439 return;
440 }
423 441
442 /* Look for intack. In a perfect world, we would look for it on
443 * the ISA bus that holds the 8259 but heh... Works that way. If
444 * we ever see a problem, we can try to re-use the pSeries code here.
445 * Also, Pegasos-type platforms don't have a proper node to start
446 * from anyway
447 */
424 for (np = find_devices("pci"); np != NULL; np = np->next) { 448 for (np = find_devices("pci"); np != NULL; np = np->next) {
425 unsigned int *addrp = (unsigned int *) 449 unsigned int *addrp = (unsigned int *)
426 get_property(np, "8259-interrupt-acknowledge", NULL); 450 get_property(np, "8259-interrupt-acknowledge", NULL);
@@ -431,11 +455,29 @@ void __init chrp_init_IRQ(void)
431 break; 455 break;
432 } 456 }
433 if (np == NULL) 457 if (np == NULL)
434 printk(KERN_ERR "Cannot find PCI interrupt acknowledge address\n"); 458 printk(KERN_WARNING "Cannot find PCI interrupt acknowledge"
459 " address, polling\n");
460
461 i8259_init(pic, chrp_int_ack);
462 if (ppc_md.get_irq == NULL)
463 ppc_md.get_irq = i8259_irq;
464 if (chrp_mpic != NULL) {
465 cascade_irq = irq_of_parse_and_map(pic, 0);
466 if (cascade_irq == NO_IRQ)
467 printk(KERN_ERR "i8259: failed to map cascade irq\n");
468 else
469 set_irq_chained_handler(cascade_irq,
470 chrp_8259_cascade);
471 }
472}
435 473
474void __init chrp_init_IRQ(void)
475{
476#if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON)
477 struct device_node *kbd;
478#endif
436 chrp_find_openpic(); 479 chrp_find_openpic();
437 480 chrp_find_8259();
438 i8259_init(chrp_int_ack, 0);
439 481
440 if (_chrp_type == _CHRP_Pegasos) 482 if (_chrp_type == _CHRP_Pegasos)
441 ppc_md.get_irq = i8259_irq; 483 ppc_md.get_irq = i8259_irq;
@@ -520,10 +562,6 @@ static int __init chrp_probe(void)
520 DMA_MODE_READ = 0x44; 562 DMA_MODE_READ = 0x44;
521 DMA_MODE_WRITE = 0x48; 563 DMA_MODE_WRITE = 0x48;
522 isa_io_base = CHRP_ISA_IO_BASE; /* default value */ 564 isa_io_base = CHRP_ISA_IO_BASE; /* default value */
523 ppc_do_canonicalize_irqs = 1;
524
525 /* Assume we have an 8259... */
526 __irq_offset_value = NUM_ISA_INTERRUPTS;
527 565
528 return 1; 566 return 1;
529} 567}
@@ -535,7 +573,6 @@ define_machine(chrp) {
535 .init = chrp_init2, 573 .init = chrp_init2,
536 .show_cpuinfo = chrp_show_cpuinfo, 574 .show_cpuinfo = chrp_show_cpuinfo,
537 .init_IRQ = chrp_init_IRQ, 575 .init_IRQ = chrp_init_IRQ,
538 .get_irq = mpic_get_irq,
539 .pcibios_fixup = chrp_pcibios_fixup, 576 .pcibios_fixup = chrp_pcibios_fixup,
540 .restart = rtas_restart, 577 .restart = rtas_restart,
541 .power_off = rtas_power_off, 578 .power_off = rtas_power_off,