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.c110
1 files changed, 66 insertions, 44 deletions
diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c
index a5dffc8d93a..bb10171132f 100644
--- a/arch/powerpc/platforms/chrp/setup.c
+++ b/arch/powerpc/platforms/chrp/setup.c
@@ -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,19 +315,13 @@ chrp_event_scan(unsigned long unused)
315 jiffies + event_scan_interval); 315 jiffies + event_scan_interval);
316} 316}
317 317
318void chrp_8259_cascade(unsigned int irq, struct irq_desc *desc, 318static void chrp_8259_cascade(unsigned int irq, struct irq_desc *desc,
319 struct pt_regs *regs) 319 struct pt_regs *regs)
320{ 320{
321 unsigned int max = 100; 321 unsigned int cascade_irq = i8259_irq(regs);
322 322 if (cascade_irq != NO_IRQ)
323 while(max--) { 323 generic_handle_irq(cascade_irq, regs);
324 int irq = i8259_irq(regs); 324 desc->chip->eoi(irq);
325 if (max == 99)
326 desc->chip->eoi(irq);
327 if (irq < 0)
328 break;
329 generic_handle_irq(irq, regs);
330 };
331} 325}
332 326
333/* 327/*
@@ -336,18 +330,17 @@ void chrp_8259_cascade(unsigned int irq, struct irq_desc *desc,
336static void __init chrp_find_openpic(void) 330static void __init chrp_find_openpic(void)
337{ 331{
338 struct device_node *np, *root; 332 struct device_node *np, *root;
339 int len, i, j, irq_count; 333 int len, i, j;
340 int isu_size, idu_size; 334 int isu_size, idu_size;
341 unsigned int *iranges, *opprop = NULL; 335 unsigned int *iranges, *opprop = NULL;
342 int oplen = 0; 336 int oplen = 0;
343 unsigned long opaddr; 337 unsigned long opaddr;
344 int na = 1; 338 int na = 1;
345 unsigned char init_senses[NR_IRQS - NUM_8259_INTERRUPTS];
346 339
347 np = find_type_devices("open-pic"); 340 np = of_find_node_by_type(NULL, "open-pic");
348 if (np == NULL) 341 if (np == NULL)
349 return; 342 return;
350 root = find_path_device("/"); 343 root = of_find_node_by_path("/");
351 if (root) { 344 if (root) {
352 opprop = (unsigned int *) get_property 345 opprop = (unsigned int *) get_property
353 (root, "platform-open-pic", &oplen); 346 (root, "platform-open-pic", &oplen);
@@ -358,19 +351,15 @@ static void __init chrp_find_openpic(void)
358 oplen /= na * sizeof(unsigned int); 351 oplen /= na * sizeof(unsigned int);
359 } else { 352 } else {
360 struct resource r; 353 struct resource r;
361 if (of_address_to_resource(np, 0, &r)) 354 if (of_address_to_resource(np, 0, &r)) {
362 return; 355 goto bail;
356 }
363 opaddr = r.start; 357 opaddr = r.start;
364 oplen = 0; 358 oplen = 0;
365 } 359 }
366 360
367 printk(KERN_INFO "OpenPIC at %lx\n", opaddr); 361 printk(KERN_INFO "OpenPIC at %lx\n", opaddr);
368 362
369 irq_count = NR_IRQS - NUM_ISA_INTERRUPTS - 4; /* leave room for IPIs */
370 prom_get_irq_senses(init_senses, NUM_ISA_INTERRUPTS, NR_IRQS - 4);
371 /* i8259 cascade is always positive level */
372 init_senses[0] = IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE;
373
374 iranges = (unsigned int *) get_property(np, "interrupt-ranges", &len); 363 iranges = (unsigned int *) get_property(np, "interrupt-ranges", &len);
375 if (iranges == NULL) 364 if (iranges == NULL)
376 len = 0; /* non-distributed mpic */ 365 len = 0; /* non-distributed mpic */
@@ -397,15 +386,12 @@ static void __init chrp_find_openpic(void)
397 if (len > 1) 386 if (len > 1)
398 isu_size = iranges[3]; 387 isu_size = iranges[3];
399 388
400 chrp_mpic = mpic_alloc(opaddr, MPIC_PRIMARY, 389 chrp_mpic = mpic_alloc(np, opaddr, MPIC_PRIMARY,
401 isu_size, NUM_ISA_INTERRUPTS, irq_count, 390 isu_size, 0, " MPIC ");
402 NR_IRQS - 4, init_senses, irq_count,
403 " MPIC ");
404 if (chrp_mpic == NULL) { 391 if (chrp_mpic == NULL) {
405 printk(KERN_ERR "Failed to allocate MPIC structure\n"); 392 printk(KERN_ERR "Failed to allocate MPIC structure\n");
406 return; 393 goto bail;
407 } 394 }
408
409 j = na - 1; 395 j = na - 1;
410 for (i = 1; i < len; ++i) { 396 for (i = 1; i < len; ++i) {
411 iranges += 2; 397 iranges += 2;
@@ -417,7 +403,10 @@ static void __init chrp_find_openpic(void)
417 } 403 }
418 404
419 mpic_init(chrp_mpic); 405 mpic_init(chrp_mpic);
420 set_irq_chained_handler(NUM_ISA_INTERRUPTS, chrp_8259_cascade); 406 ppc_md.get_irq = mpic_get_irq;
407 bail:
408 of_node_put(root);
409 of_node_put(np);
421} 410}
422 411
423#if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON) 412#if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON)
@@ -428,14 +417,34 @@ static struct irqaction xmon_irqaction = {
428}; 417};
429#endif 418#endif
430 419
431void __init chrp_init_IRQ(void) 420static void __init chrp_find_8259(void)
432{ 421{
433 struct device_node *np; 422 struct device_node *np, *pic = NULL;
434 unsigned long chrp_int_ack = 0; 423 unsigned long chrp_int_ack = 0;
435#if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON) 424 unsigned int cascade_irq;
436 struct device_node *kbd;
437#endif
438 425
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 }
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 */
439 for (np = find_devices("pci"); np != NULL; np = np->next) { 448 for (np = find_devices("pci"); np != NULL; np = np->next) {
440 unsigned int *addrp = (unsigned int *) 449 unsigned int *addrp = (unsigned int *)
441 get_property(np, "8259-interrupt-acknowledge", NULL); 450 get_property(np, "8259-interrupt-acknowledge", NULL);
@@ -446,11 +455,29 @@ void __init chrp_init_IRQ(void)
446 break; 455 break;
447 } 456 }
448 if (np == NULL) 457 if (np == NULL)
449 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}
450 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
451 chrp_find_openpic(); 479 chrp_find_openpic();
452 480 chrp_find_8259();
453 i8259_init(chrp_int_ack, 0);
454 481
455 if (_chrp_type == _CHRP_Pegasos) 482 if (_chrp_type == _CHRP_Pegasos)
456 ppc_md.get_irq = i8259_irq; 483 ppc_md.get_irq = i8259_irq;
@@ -535,10 +562,6 @@ static int __init chrp_probe(void)
535 DMA_MODE_READ = 0x44; 562 DMA_MODE_READ = 0x44;
536 DMA_MODE_WRITE = 0x48; 563 DMA_MODE_WRITE = 0x48;
537 isa_io_base = CHRP_ISA_IO_BASE; /* default value */ 564 isa_io_base = CHRP_ISA_IO_BASE; /* default value */
538 ppc_do_canonicalize_irqs = 1;
539
540 /* Assume we have an 8259... */
541 __irq_offset_value = NUM_ISA_INTERRUPTS;
542 565
543 return 1; 566 return 1;
544} 567}
@@ -550,7 +573,6 @@ define_machine(chrp) {
550 .init = chrp_init2, 573 .init = chrp_init2,
551 .show_cpuinfo = chrp_show_cpuinfo, 574 .show_cpuinfo = chrp_show_cpuinfo,
552 .init_IRQ = chrp_init_IRQ, 575 .init_IRQ = chrp_init_IRQ,
553 .get_irq = mpic_get_irq,
554 .pcibios_fixup = chrp_pcibios_fixup, 576 .pcibios_fixup = chrp_pcibios_fixup,
555 .restart = rtas_restart, 577 .restart = rtas_restart,
556 .power_off = rtas_power_off, 578 .power_off = rtas_power_off,