Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[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>

authored by

Benjamin Herrenschmidt and committed by
Linus Torvalds
06fe98e6 6e99e458

+28 -10
+28 -10
arch/powerpc/sysdev/mpic.c
··· 204 204 if (fixup->base == NULL) 205 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 208 source, irqflags, fixup->index); 209 209 spin_lock_irqsave(&mpic->fixup_lock, flags); 210 210 /* Enable and configure */ ··· 227 227 if (fixup->base == NULL) 228 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 232 /* Disable */ 233 233 spin_lock_irqsave(&mpic->fixup_lock, flags); ··· 588 588 struct irq_desc *desc = get_irq_desc(virq); 589 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", 592 - mpic, virq, src, flow_type); 591 + DBG("mpic: set_irq_type(mpic:@%p,virq:%d,src:0x%x,type:0x%x)\n", 592 + mpic, virq, src, flow_type); 593 593 594 594 if (src >= mpic->irq_count) 595 595 return -EINVAL; ··· 661 661 struct mpic *mpic = h->host_data; 662 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 666 if (hw == MPIC_VEC_SPURRIOUS) 667 667 return -EINVAL; 668 + 668 669 #ifdef CONFIG_SMP 669 670 else if (hw >= MPIC_VEC_IPI_0) { 670 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 674 set_irq_chip_data(virq, mpic); 674 675 set_irq_chip_and_handler(virq, &mpic->hc_ipi, 675 676 handle_percpu_irq); ··· 690 689 chip = &mpic->hc_ht_irq; 691 690 #endif /* CONFIG_MPIC_BROKEN_U3 */ 692 691 693 - pr_debug("mpic: mapping to irq chip @%p\n", chip); 692 + DBG("mpic: mapping to irq chip @%p\n", chip); 694 693 695 694 set_irq_chip_data(virq, mpic); 696 695 set_irq_chip_and_handler(virq, chip, handle_fasteoi_irq); ··· 714 713 }; 715 714 716 715 *out_hwirq = intspec[0]; 717 - if (intsize > 1 && intspec[1] < 4) 718 - *out_flags = map_mpic_senses[intspec[1]]; 719 - else 716 + if (intsize > 1) { 717 + u32 mask = 0x3; 718 + 719 + /* Apple invented a new race of encoding on machines with 720 + * an HT APIC. They encode, among others, the index within 721 + * the HT APIC. We don't care about it here since thankfully, 722 + * it appears that they have the APIC already properly 723 + * configured, and thus our current fixup code that reads the 724 + * APIC config works fine. However, we still need to mask out 725 + * bits in the specifier to make sure we only get bit 0 which 726 + * is the level/edge bit (the only sense bit exposed by Apple), 727 + * as their bit 1 means something else. 728 + */ 729 + if (machine_is(powermac)) 730 + mask = 0x1; 731 + *out_flags = map_mpic_senses[intspec[1] & mask]; 732 + } else 720 733 *out_flags = IRQ_TYPE_NONE; 734 + 735 + DBG("mpic: xlate (%d cells: 0x%08x 0x%08x) to line 0x%lx sense 0x%x\n", 736 + intsize, intspec[0], intspec[1], *out_hwirq, *out_flags); 721 737 722 738 return 0; 723 739 }