diff options
Diffstat (limited to 'arch/powerpc/platforms/powermac')
-rw-r--r-- | arch/powerpc/platforms/powermac/pic.c | 80 | ||||
-rw-r--r-- | arch/powerpc/platforms/powermac/setup.c | 8 | ||||
-rw-r--r-- | arch/powerpc/platforms/powermac/smp.c | 6 |
3 files changed, 22 insertions, 72 deletions
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c index 901bfbddc3dd..7761aabfc293 100644 --- a/arch/powerpc/platforms/powermac/pic.c +++ b/arch/powerpc/platforms/powermac/pic.c | |||
@@ -52,13 +52,8 @@ struct device_node *of_irq_dflt_pic; | |||
52 | /* Default addresses */ | 52 | /* Default addresses */ |
53 | static volatile struct pmac_irq_hw __iomem *pmac_irq_hw[4]; | 53 | static volatile struct pmac_irq_hw __iomem *pmac_irq_hw[4]; |
54 | 54 | ||
55 | #define GC_LEVEL_MASK 0x3ff00000 | ||
56 | #define OHARE_LEVEL_MASK 0x1ff00000 | ||
57 | #define HEATHROW_LEVEL_MASK 0x1ff00000 | ||
58 | |||
59 | static int max_irqs; | 55 | static int max_irqs; |
60 | static int max_real_irqs; | 56 | static int max_real_irqs; |
61 | static u32 level_mask[4]; | ||
62 | 57 | ||
63 | static DEFINE_RAW_SPINLOCK(pmac_pic_lock); | 58 | static DEFINE_RAW_SPINLOCK(pmac_pic_lock); |
64 | 59 | ||
@@ -217,8 +212,7 @@ static irqreturn_t gatwick_action(int cpl, void *dev_id) | |||
217 | for (irq = max_irqs; (irq -= 32) >= max_real_irqs; ) { | 212 | for (irq = max_irqs; (irq -= 32) >= max_real_irqs; ) { |
218 | int i = irq >> 5; | 213 | int i = irq >> 5; |
219 | bits = in_le32(&pmac_irq_hw[i]->event) | ppc_lost_interrupts[i]; | 214 | bits = in_le32(&pmac_irq_hw[i]->event) | ppc_lost_interrupts[i]; |
220 | /* We must read level interrupts from the level register */ | 215 | bits |= in_le32(&pmac_irq_hw[i]->level); |
221 | bits |= (in_le32(&pmac_irq_hw[i]->level) & level_mask[i]); | ||
222 | bits &= ppc_cached_irq_mask[i]; | 216 | bits &= ppc_cached_irq_mask[i]; |
223 | if (bits == 0) | 217 | if (bits == 0) |
224 | continue; | 218 | continue; |
@@ -248,8 +242,7 @@ static unsigned int pmac_pic_get_irq(void) | |||
248 | for (irq = max_real_irqs; (irq -= 32) >= 0; ) { | 242 | for (irq = max_real_irqs; (irq -= 32) >= 0; ) { |
249 | int i = irq >> 5; | 243 | int i = irq >> 5; |
250 | bits = in_le32(&pmac_irq_hw[i]->event) | ppc_lost_interrupts[i]; | 244 | bits = in_le32(&pmac_irq_hw[i]->event) | ppc_lost_interrupts[i]; |
251 | /* We must read level interrupts from the level register */ | 245 | bits |= in_le32(&pmac_irq_hw[i]->level); |
252 | bits |= (in_le32(&pmac_irq_hw[i]->level) & level_mask[i]); | ||
253 | bits &= ppc_cached_irq_mask[i]; | 246 | bits &= ppc_cached_irq_mask[i]; |
254 | if (bits == 0) | 247 | if (bits == 0) |
255 | continue; | 248 | continue; |
@@ -284,19 +277,14 @@ static int pmac_pic_host_match(struct irq_host *h, struct device_node *node) | |||
284 | static int pmac_pic_host_map(struct irq_host *h, unsigned int virq, | 277 | static int pmac_pic_host_map(struct irq_host *h, unsigned int virq, |
285 | irq_hw_number_t hw) | 278 | irq_hw_number_t hw) |
286 | { | 279 | { |
287 | int level; | ||
288 | |||
289 | if (hw >= max_irqs) | 280 | if (hw >= max_irqs) |
290 | return -EINVAL; | 281 | return -EINVAL; |
291 | 282 | ||
292 | /* Mark level interrupts, set delayed disable for edge ones and set | 283 | /* Mark level interrupts, set delayed disable for edge ones and set |
293 | * handlers | 284 | * handlers |
294 | */ | 285 | */ |
295 | level = !!(level_mask[hw >> 5] & (1UL << (hw & 0x1f))); | 286 | irq_set_status_flags(virq, IRQ_LEVEL); |
296 | if (level) | 287 | irq_set_chip_and_handler(virq, &pmac_pic, handle_level_irq); |
297 | irq_set_status_flags(virq, IRQ_LEVEL); | ||
298 | irq_set_chip_and_handler(virq, &pmac_pic, | ||
299 | level ? handle_level_irq : handle_edge_irq); | ||
300 | return 0; | 288 | return 0; |
301 | } | 289 | } |
302 | 290 | ||
@@ -334,21 +322,14 @@ static void __init pmac_pic_probe_oldstyle(void) | |||
334 | 322 | ||
335 | if ((master = of_find_node_by_name(NULL, "gc")) != NULL) { | 323 | if ((master = of_find_node_by_name(NULL, "gc")) != NULL) { |
336 | max_irqs = max_real_irqs = 32; | 324 | max_irqs = max_real_irqs = 32; |
337 | level_mask[0] = GC_LEVEL_MASK; | ||
338 | } else if ((master = of_find_node_by_name(NULL, "ohare")) != NULL) { | 325 | } else if ((master = of_find_node_by_name(NULL, "ohare")) != NULL) { |
339 | max_irqs = max_real_irqs = 32; | 326 | max_irqs = max_real_irqs = 32; |
340 | level_mask[0] = OHARE_LEVEL_MASK; | ||
341 | |||
342 | /* We might have a second cascaded ohare */ | 327 | /* We might have a second cascaded ohare */ |
343 | slave = of_find_node_by_name(NULL, "pci106b,7"); | 328 | slave = of_find_node_by_name(NULL, "pci106b,7"); |
344 | if (slave) { | 329 | if (slave) |
345 | max_irqs = 64; | 330 | max_irqs = 64; |
346 | level_mask[1] = OHARE_LEVEL_MASK; | ||
347 | } | ||
348 | } else if ((master = of_find_node_by_name(NULL, "mac-io")) != NULL) { | 331 | } else if ((master = of_find_node_by_name(NULL, "mac-io")) != NULL) { |
349 | max_irqs = max_real_irqs = 64; | 332 | max_irqs = max_real_irqs = 64; |
350 | level_mask[0] = HEATHROW_LEVEL_MASK; | ||
351 | level_mask[1] = 0; | ||
352 | 333 | ||
353 | /* We might have a second cascaded heathrow */ | 334 | /* We might have a second cascaded heathrow */ |
354 | slave = of_find_node_by_name(master, "mac-io"); | 335 | slave = of_find_node_by_name(master, "mac-io"); |
@@ -363,11 +344,8 @@ static void __init pmac_pic_probe_oldstyle(void) | |||
363 | } | 344 | } |
364 | 345 | ||
365 | /* We found a slave */ | 346 | /* We found a slave */ |
366 | if (slave) { | 347 | if (slave) |
367 | max_irqs = 128; | 348 | max_irqs = 128; |
368 | level_mask[2] = HEATHROW_LEVEL_MASK; | ||
369 | level_mask[3] = 0; | ||
370 | } | ||
371 | } | 349 | } |
372 | BUG_ON(master == NULL); | 350 | BUG_ON(master == NULL); |
373 | 351 | ||
@@ -464,18 +442,6 @@ int of_irq_map_oldworld(struct device_node *device, int index, | |||
464 | } | 442 | } |
465 | #endif /* CONFIG_PPC32 */ | 443 | #endif /* CONFIG_PPC32 */ |
466 | 444 | ||
467 | static void pmac_u3_cascade(unsigned int irq, struct irq_desc *desc) | ||
468 | { | ||
469 | struct irq_chip *chip = irq_desc_get_chip(desc); | ||
470 | struct mpic *mpic = irq_desc_get_handler_data(desc); | ||
471 | unsigned int cascade_irq = mpic_get_one_irq(mpic); | ||
472 | |||
473 | if (cascade_irq != NO_IRQ) | ||
474 | generic_handle_irq(cascade_irq); | ||
475 | |||
476 | chip->irq_eoi(&desc->irq_data); | ||
477 | } | ||
478 | |||
479 | static void __init pmac_pic_setup_mpic_nmi(struct mpic *mpic) | 445 | static void __init pmac_pic_setup_mpic_nmi(struct mpic *mpic) |
480 | { | 446 | { |
481 | #if defined(CONFIG_XMON) && defined(CONFIG_PPC32) | 447 | #if defined(CONFIG_XMON) && defined(CONFIG_PPC32) |
@@ -498,14 +464,8 @@ static struct mpic * __init pmac_setup_one_mpic(struct device_node *np, | |||
498 | int master) | 464 | int master) |
499 | { | 465 | { |
500 | const char *name = master ? " MPIC 1 " : " MPIC 2 "; | 466 | const char *name = master ? " MPIC 1 " : " MPIC 2 "; |
501 | struct resource r; | ||
502 | struct mpic *mpic; | 467 | struct mpic *mpic; |
503 | unsigned int flags = master ? MPIC_PRIMARY : 0; | 468 | unsigned int flags = master ? 0 : MPIC_SECONDARY; |
504 | int rc; | ||
505 | |||
506 | rc = of_address_to_resource(np, 0, &r); | ||
507 | if (rc) | ||
508 | return NULL; | ||
509 | 469 | ||
510 | pmac_call_feature(PMAC_FTR_ENABLE_MPIC, np, 0, 0); | 470 | pmac_call_feature(PMAC_FTR_ENABLE_MPIC, np, 0, 0); |
511 | 471 | ||
@@ -519,7 +479,7 @@ static struct mpic * __init pmac_setup_one_mpic(struct device_node *np, | |||
519 | if (master && (flags & MPIC_BIG_ENDIAN)) | 479 | if (master && (flags & MPIC_BIG_ENDIAN)) |
520 | flags |= MPIC_U3_HT_IRQS; | 480 | flags |= MPIC_U3_HT_IRQS; |
521 | 481 | ||
522 | mpic = mpic_alloc(np, r.start, flags, 0, 0, name); | 482 | mpic = mpic_alloc(np, 0, flags, 0, 0, name); |
523 | if (mpic == NULL) | 483 | if (mpic == NULL) |
524 | return NULL; | 484 | return NULL; |
525 | 485 | ||
@@ -532,7 +492,6 @@ static int __init pmac_pic_probe_mpic(void) | |||
532 | { | 492 | { |
533 | struct mpic *mpic1, *mpic2; | 493 | struct mpic *mpic1, *mpic2; |
534 | struct device_node *np, *master = NULL, *slave = NULL; | 494 | struct device_node *np, *master = NULL, *slave = NULL; |
535 | unsigned int cascade; | ||
536 | 495 | ||
537 | /* We can have up to 2 MPICs cascaded */ | 496 | /* We can have up to 2 MPICs cascaded */ |
538 | for (np = NULL; (np = of_find_node_by_type(np, "open-pic")) | 497 | for (np = NULL; (np = of_find_node_by_type(np, "open-pic")) |
@@ -568,27 +527,14 @@ static int __init pmac_pic_probe_mpic(void) | |||
568 | 527 | ||
569 | of_node_put(master); | 528 | of_node_put(master); |
570 | 529 | ||
571 | /* No slave, let's go out */ | 530 | /* Set up a cascaded controller, if present */ |
572 | if (slave == NULL) | 531 | if (slave) { |
573 | return 0; | 532 | mpic2 = pmac_setup_one_mpic(slave, 0); |
574 | 533 | if (mpic2 == NULL) | |
575 | /* Get/Map slave interrupt */ | 534 | printk(KERN_ERR "Failed to setup slave MPIC\n"); |
576 | cascade = irq_of_parse_and_map(slave, 0); | ||
577 | if (cascade == NO_IRQ) { | ||
578 | printk(KERN_ERR "Failed to map cascade IRQ\n"); | ||
579 | return 0; | ||
580 | } | ||
581 | |||
582 | mpic2 = pmac_setup_one_mpic(slave, 0); | ||
583 | if (mpic2 == NULL) { | ||
584 | printk(KERN_ERR "Failed to setup slave MPIC\n"); | ||
585 | of_node_put(slave); | 535 | of_node_put(slave); |
586 | return 0; | ||
587 | } | 536 | } |
588 | irq_set_handler_data(cascade, mpic2); | ||
589 | irq_set_chained_handler(cascade, pmac_u3_cascade); | ||
590 | 537 | ||
591 | of_node_put(slave); | ||
592 | return 0; | 538 | return 0; |
593 | } | 539 | } |
594 | 540 | ||
diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c index 96580b189ec2..970ea1de4298 100644 --- a/arch/powerpc/platforms/powermac/setup.c +++ b/arch/powerpc/platforms/powermac/setup.c | |||
@@ -494,11 +494,15 @@ static int __init pmac_declare_of_platform_devices(void) | |||
494 | return -1; | 494 | return -1; |
495 | 495 | ||
496 | np = of_find_node_by_name(NULL, "valkyrie"); | 496 | np = of_find_node_by_name(NULL, "valkyrie"); |
497 | if (np) | 497 | if (np) { |
498 | of_platform_device_create(np, "valkyrie", NULL); | 498 | of_platform_device_create(np, "valkyrie", NULL); |
499 | of_node_put(np); | ||
500 | } | ||
499 | np = of_find_node_by_name(NULL, "platinum"); | 501 | np = of_find_node_by_name(NULL, "platinum"); |
500 | if (np) | 502 | if (np) { |
501 | of_platform_device_create(np, "platinum", NULL); | 503 | of_platform_device_create(np, "platinum", NULL); |
504 | of_node_put(np); | ||
505 | } | ||
502 | np = of_find_node_by_type(NULL, "smu"); | 506 | np = of_find_node_by_type(NULL, "smu"); |
503 | if (np) { | 507 | if (np) { |
504 | of_platform_device_create(np, "smu", NULL); | 508 | of_platform_device_create(np, "smu", NULL); |
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c index 9b6a820bdd7d..44d769258ebf 100644 --- a/arch/powerpc/platforms/powermac/smp.c +++ b/arch/powerpc/platforms/powermac/smp.c | |||
@@ -200,7 +200,7 @@ static int psurge_secondary_ipi_init(void) | |||
200 | 200 | ||
201 | if (psurge_secondary_virq) | 201 | if (psurge_secondary_virq) |
202 | rc = request_irq(psurge_secondary_virq, psurge_ipi_intr, | 202 | rc = request_irq(psurge_secondary_virq, psurge_ipi_intr, |
203 | IRQF_PERCPU, "IPI", NULL); | 203 | IRQF_PERCPU | IRQF_NO_THREAD, "IPI", NULL); |
204 | 204 | ||
205 | if (rc) | 205 | if (rc) |
206 | pr_err("Failed to setup secondary cpu IPI\n"); | 206 | pr_err("Failed to setup secondary cpu IPI\n"); |
@@ -408,13 +408,13 @@ static int __init smp_psurge_kick_cpu(int nr) | |||
408 | 408 | ||
409 | static struct irqaction psurge_irqaction = { | 409 | static struct irqaction psurge_irqaction = { |
410 | .handler = psurge_ipi_intr, | 410 | .handler = psurge_ipi_intr, |
411 | .flags = IRQF_PERCPU, | 411 | .flags = IRQF_PERCPU | IRQF_NO_THREAD, |
412 | .name = "primary IPI", | 412 | .name = "primary IPI", |
413 | }; | 413 | }; |
414 | 414 | ||
415 | static void __init smp_psurge_setup_cpu(int cpu_nr) | 415 | static void __init smp_psurge_setup_cpu(int cpu_nr) |
416 | { | 416 | { |
417 | if (cpu_nr != 0) | 417 | if (cpu_nr != 0 || !psurge_start) |
418 | return; | 418 | return; |
419 | 419 | ||
420 | /* reset the entry point so if we get another intr we won't | 420 | /* reset the entry point so if we get another intr we won't |