aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/sysdev/mpic.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2006-07-10 07:44:43 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-07-10 16:24:20 -0400
commit06fe98e6369330d522705d5e67a2eddac2fd5bba (patch)
treef8f2e31087634f91a1d797a1c218be9c5325654a /arch/powerpc/sysdev/mpic.c
parent6e99e4582861578fb00d84d085f8f283569f51dd (diff)
[PATCH] powerpc: fix MPIC OF tree parsing on Apple quad g5
The quad g5 currently doesn't boot due to two problems. This patch fixes the first one: Apple new way of doing interrupt specifiers in OF for devices using the HT APIC isn't properly parsed by the new MPIC driver code. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Paul Mackerras <paulus@samba.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/powerpc/sysdev/mpic.c')
-rw-r--r--arch/powerpc/sysdev/mpic.c38
1 files changed, 28 insertions, 10 deletions
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index c39c4a0b1cda..6e0281afa6c3 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -204,7 +204,7 @@ static void mpic_startup_ht_interrupt(struct mpic *mpic, unsigned int source,
204 if (fixup->base == NULL) 204 if (fixup->base == NULL)
205 return; 205 return;
206 206
207 DBG("startup_ht_interrupt(%u, %u) index: %d\n", 207 DBG("startup_ht_interrupt(0x%x, 0x%x) index: %d\n",
208 source, irqflags, fixup->index); 208 source, irqflags, fixup->index);
209 spin_lock_irqsave(&mpic->fixup_lock, flags); 209 spin_lock_irqsave(&mpic->fixup_lock, flags);
210 /* Enable and configure */ 210 /* Enable and configure */
@@ -227,7 +227,7 @@ static void mpic_shutdown_ht_interrupt(struct mpic *mpic, unsigned int source,
227 if (fixup->base == NULL) 227 if (fixup->base == NULL)
228 return; 228 return;
229 229
230 DBG("shutdown_ht_interrupt(%u, %u)\n", source, irqflags); 230 DBG("shutdown_ht_interrupt(0x%x, 0x%x)\n", source, irqflags);
231 231
232 /* Disable */ 232 /* Disable */
233 spin_lock_irqsave(&mpic->fixup_lock, flags); 233 spin_lock_irqsave(&mpic->fixup_lock, flags);
@@ -588,8 +588,8 @@ static int mpic_set_irq_type(unsigned int virq, unsigned int flow_type)
588 struct irq_desc *desc = get_irq_desc(virq); 588 struct irq_desc *desc = get_irq_desc(virq);
589 unsigned int vecpri, vold, vnew; 589 unsigned int vecpri, vold, vnew;
590 590
591 pr_debug("mpic: set_irq_type(mpic:@%p,virq:%d,src:%d,type:0x%x)\n", 591 DBG("mpic: set_irq_type(mpic:@%p,virq:%d,src:0x%x,type:0x%x)\n",
592 mpic, virq, src, flow_type); 592 mpic, virq, src, flow_type);
593 593
594 if (src >= mpic->irq_count) 594 if (src >= mpic->irq_count)
595 return -EINVAL; 595 return -EINVAL;
@@ -661,15 +661,16 @@ static int mpic_host_map(struct irq_host *h, unsigned int virq,
661 struct mpic *mpic = h->host_data; 661 struct mpic *mpic = h->host_data;
662 struct irq_chip *chip; 662 struct irq_chip *chip;
663 663
664 pr_debug("mpic: map virq %d, hwirq 0x%lx\n", virq, hw); 664 DBG("mpic: map virq %d, hwirq 0x%lx\n", virq, hw);
665 665
666 if (hw == MPIC_VEC_SPURRIOUS) 666 if (hw == MPIC_VEC_SPURRIOUS)
667 return -EINVAL; 667 return -EINVAL;
668
668#ifdef CONFIG_SMP 669#ifdef CONFIG_SMP
669 else if (hw >= MPIC_VEC_IPI_0) { 670 else if (hw >= MPIC_VEC_IPI_0) {
670 WARN_ON(!(mpic->flags & MPIC_PRIMARY)); 671 WARN_ON(!(mpic->flags & MPIC_PRIMARY));
671 672
672 pr_debug("mpic: mapping as IPI\n"); 673 DBG("mpic: mapping as IPI\n");
673 set_irq_chip_data(virq, mpic); 674 set_irq_chip_data(virq, mpic);
674 set_irq_chip_and_handler(virq, &mpic->hc_ipi, 675 set_irq_chip_and_handler(virq, &mpic->hc_ipi,
675 handle_percpu_irq); 676 handle_percpu_irq);
@@ -689,7 +690,7 @@ static int mpic_host_map(struct irq_host *h, unsigned int virq,
689 chip = &mpic->hc_ht_irq; 690 chip = &mpic->hc_ht_irq;
690#endif /* CONFIG_MPIC_BROKEN_U3 */ 691#endif /* CONFIG_MPIC_BROKEN_U3 */
691 692
692 pr_debug("mpic: mapping to irq chip @%p\n", chip); 693 DBG("mpic: mapping to irq chip @%p\n", chip);
693 694
694 set_irq_chip_data(virq, mpic); 695 set_irq_chip_data(virq, mpic);
695 set_irq_chip_and_handler(virq, chip, handle_fasteoi_irq); 696 set_irq_chip_and_handler(virq, chip, handle_fasteoi_irq);
@@ -713,11 +714,28 @@ static int mpic_host_xlate(struct irq_host *h, struct device_node *ct,
713 }; 714 };
714 715
715 *out_hwirq = intspec[0]; 716 *out_hwirq = intspec[0];
716 if (intsize > 1 && intspec[1] < 4) 717 if (intsize > 1) {
717 *out_flags = map_mpic_senses[intspec[1]]; 718 u32 mask = 0x3;
718 else 719
720 /* Apple invented a new race of encoding on machines with
721 * an HT APIC. They encode, among others, the index within
722 * the HT APIC. We don't care about it here since thankfully,
723 * it appears that they have the APIC already properly
724 * configured, and thus our current fixup code that reads the
725 * APIC config works fine. However, we still need to mask out
726 * bits in the specifier to make sure we only get bit 0 which
727 * is the level/edge bit (the only sense bit exposed by Apple),
728 * as their bit 1 means something else.
729 */
730 if (machine_is(powermac))
731 mask = 0x1;
732 *out_flags = map_mpic_senses[intspec[1] & mask];
733 } else
719 *out_flags = IRQ_TYPE_NONE; 734 *out_flags = IRQ_TYPE_NONE;
720 735
736 DBG("mpic: xlate (%d cells: 0x%08x 0x%08x) to line 0x%lx sense 0x%x\n",
737 intsize, intspec[0], intspec[1], *out_hwirq, *out_flags);
738
721 return 0; 739 return 0;
722} 740}
723 741