aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorGrant Likely <grant.likely@secretlab.ca>2010-06-18 13:10:01 -0400
committerGrant Likely <grant.likely@secretlab.ca>2010-07-05 18:14:25 -0400
commitb83da291b4c73eaddc20e2edb614123a6d681b3b (patch)
treede3388516ccdc635b93839492279fed3ca7e20d0 /arch/powerpc
parentb6295c8b85fe83e5679b7b8bebe4df85deebebfc (diff)
of/powerpc: Move Powermac irq quirk code into powermac pic driver code
The code that figures out what is wrong with the powermac irq device tree data belongs with the rest of the powermac irq code. This patch moves it out of prom_parse.c and into powermac/pic.c so that it is only compiled in when actually needed. Signed-off-by: Grant Likely <grant.likely@secretlab.ca> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Stephen Rothwell <sfr@canb.auug.org.au>
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/include/asm/prom.h24
-rw-r--r--arch/powerpc/kernel/prom_parse.c85
-rw-r--r--arch/powerpc/platforms/powermac/pic.c72
3 files changed, 81 insertions, 100 deletions
diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h
index 47d41b67c94d..4486765db6e7 100644
--- a/arch/powerpc/include/asm/prom.h
+++ b/arch/powerpc/include/asm/prom.h
@@ -109,18 +109,24 @@ extern const void *of_get_mac_address(struct device_node *np);
109 * OF interrupt mapping 109 * OF interrupt mapping
110 */ 110 */
111 111
112/**
113 * of_irq_map_init - Initialize the irq remapper
114 * @flags: flags defining workarounds to enable
115 *
116 * Some machines have bugs in the device-tree which require certain workarounds
117 * to be applied. Call this before any interrupt mapping attempts to enable
118 * those workarounds.
119 */
120#define OF_IMAP_OLDWORLD_MAC 0x00000001 112#define OF_IMAP_OLDWORLD_MAC 0x00000001
121#define OF_IMAP_NO_PHANDLE 0x00000002 113#define OF_IMAP_NO_PHANDLE 0x00000002
122 114
123extern void of_irq_map_init(unsigned int flags); 115#if defined(CONFIG_PPC32) && defined(CONFIG_PPC_PMAC)
116/* Workarounds only needed for 32bit powermac machines */
117extern unsigned int of_irq_workarounds;
118extern struct device_node *of_irq_dflt_pic;
119extern int of_irq_map_oldworld(struct device_node *device, int index,
120 struct of_irq *out_irq);
121#else
122#define of_irq_workarounds (0)
123#define of_irq_dflt_pic (NULL)
124static inline int of_irq_map_oldworld(struct device_node *device, int index,
125 struct of_irq *out_irq)
126{
127 return -EINVAL;
128}
129#endif
124 130
125/** 131/**
126 * of_irq_map_raw - Low level interrupt tree parsing 132 * of_irq_map_raw - Low level interrupt tree parsing
diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c
index 8362620c9e6f..dfa6de6572bb 100644
--- a/arch/powerpc/kernel/prom_parse.c
+++ b/arch/powerpc/kernel/prom_parse.c
@@ -682,9 +682,6 @@ void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
682 * Interrupt remapper 682 * Interrupt remapper
683 */ 683 */
684 684
685static unsigned int of_irq_workarounds;
686static struct device_node *of_irq_dflt_pic;
687
688static struct device_node *of_irq_find_parent(struct device_node *child) 685static struct device_node *of_irq_find_parent(struct device_node *child)
689{ 686{
690 struct device_node *p; 687 struct device_node *p;
@@ -710,44 +707,6 @@ static struct device_node *of_irq_find_parent(struct device_node *child)
710 return p; 707 return p;
711} 708}
712 709
713/* This doesn't need to be called if you don't have any special workaround
714 * flags to pass
715 */
716void of_irq_map_init(unsigned int flags)
717{
718 of_irq_workarounds = flags;
719
720 /* OldWorld, don't bother looking at other things */
721 if (flags & OF_IMAP_OLDWORLD_MAC)
722 return;
723
724 /* If we don't have phandles, let's try to locate a default interrupt
725 * controller (happens when booting with BootX). We do a first match
726 * here, hopefully, that only ever happens on machines with one
727 * controller.
728 */
729 if (flags & OF_IMAP_NO_PHANDLE) {
730 struct device_node *np;
731
732 for_each_node_with_property(np, "interrupt-controller") {
733 /* Skip /chosen/interrupt-controller */
734 if (strcmp(np->name, "chosen") == 0)
735 continue;
736 /* It seems like at least one person on this planet wants
737 * to use BootX on a machine with an AppleKiwi controller
738 * which happens to pretend to be an interrupt
739 * controller too.
740 */
741 if (strcmp(np->name, "AppleKiwi") == 0)
742 continue;
743 /* I think we found one ! */
744 of_irq_dflt_pic = np;
745 break;
746 }
747 }
748
749}
750
751int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize, 710int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize,
752 const u32 *addr, struct of_irq *out_irq) 711 const u32 *addr, struct of_irq *out_irq)
753{ 712{
@@ -922,50 +881,6 @@ int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize,
922} 881}
923EXPORT_SYMBOL_GPL(of_irq_map_raw); 882EXPORT_SYMBOL_GPL(of_irq_map_raw);
924 883
925#if defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32)
926static int of_irq_map_oldworld(struct device_node *device, int index,
927 struct of_irq *out_irq)
928{
929 const u32 *ints = NULL;
930 int intlen;
931
932 /*
933 * Old machines just have a list of interrupt numbers
934 * and no interrupt-controller nodes. We also have dodgy
935 * cases where the APPL,interrupts property is completely
936 * missing behind pci-pci bridges and we have to get it
937 * from the parent (the bridge itself, as apple just wired
938 * everything together on these)
939 */
940 while (device) {
941 ints = of_get_property(device, "AAPL,interrupts", &intlen);
942 if (ints != NULL)
943 break;
944 device = device->parent;
945 if (device && strcmp(device->type, "pci") != 0)
946 break;
947 }
948 if (ints == NULL)
949 return -EINVAL;
950 intlen /= sizeof(u32);
951
952 if (index >= intlen)
953 return -EINVAL;
954
955 out_irq->controller = NULL;
956 out_irq->specifier[0] = ints[index];
957 out_irq->size = 1;
958
959 return 0;
960}
961#else /* defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32) */
962static int of_irq_map_oldworld(struct device_node *device, int index,
963 struct of_irq *out_irq)
964{
965 return -EINVAL;
966}
967#endif /* !(defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32)) */
968
969int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq) 884int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq)
970{ 885{
971 struct device_node *p; 886 struct device_node *p;
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c
index 630a533d0e59..890d5f72b198 100644
--- a/arch/powerpc/platforms/powermac/pic.c
+++ b/arch/powerpc/platforms/powermac/pic.c
@@ -46,6 +46,10 @@ struct pmac_irq_hw {
46 unsigned int level; 46 unsigned int level;
47}; 47};
48 48
49/* Workaround flags for 32bit powermac machines */
50unsigned int of_irq_workarounds;
51struct device_node *of_irq_dflt_pic;
52
49/* Default addresses */ 53/* Default addresses */
50static volatile struct pmac_irq_hw __iomem *pmac_irq_hw[4]; 54static volatile struct pmac_irq_hw __iomem *pmac_irq_hw[4];
51 55
@@ -428,6 +432,42 @@ static void __init pmac_pic_probe_oldstyle(void)
428 setup_irq(irq_create_mapping(NULL, 20), &xmon_action); 432 setup_irq(irq_create_mapping(NULL, 20), &xmon_action);
429#endif 433#endif
430} 434}
435
436int of_irq_map_oldworld(struct device_node *device, int index,
437 struct of_irq *out_irq)
438{
439 const u32 *ints = NULL;
440 int intlen;
441
442 /*
443 * Old machines just have a list of interrupt numbers
444 * and no interrupt-controller nodes. We also have dodgy
445 * cases where the APPL,interrupts property is completely
446 * missing behind pci-pci bridges and we have to get it
447 * from the parent (the bridge itself, as apple just wired
448 * everything together on these)
449 */
450 while (device) {
451 ints = of_get_property(device, "AAPL,interrupts", &intlen);
452 if (ints != NULL)
453 break;
454 device = device->parent;
455 if (device && strcmp(device->type, "pci") != 0)
456 break;
457 }
458 if (ints == NULL)
459 return -EINVAL;
460 intlen /= sizeof(u32);
461
462 if (index >= intlen)
463 return -EINVAL;
464
465 out_irq->controller = NULL;
466 out_irq->specifier[0] = ints[index];
467 out_irq->size = 1;
468
469 return 0;
470}
431#endif /* CONFIG_PPC32 */ 471#endif /* CONFIG_PPC32 */
432 472
433static void pmac_u3_cascade(unsigned int irq, struct irq_desc *desc) 473static void pmac_u3_cascade(unsigned int irq, struct irq_desc *desc)
@@ -559,19 +599,39 @@ static int __init pmac_pic_probe_mpic(void)
559 599
560void __init pmac_pic_init(void) 600void __init pmac_pic_init(void)
561{ 601{
562 unsigned int flags = 0;
563
564 /* We configure the OF parsing based on our oldworld vs. newworld 602 /* We configure the OF parsing based on our oldworld vs. newworld
565 * platform type and wether we were booted by BootX. 603 * platform type and wether we were booted by BootX.
566 */ 604 */
567#ifdef CONFIG_PPC32 605#ifdef CONFIG_PPC32
568 if (!pmac_newworld) 606 if (!pmac_newworld)
569 flags |= OF_IMAP_OLDWORLD_MAC; 607 of_irq_workarounds |= OF_IMAP_OLDWORLD_MAC;
570 if (of_get_property(of_chosen, "linux,bootx", NULL) != NULL) 608 if (of_get_property(of_chosen, "linux,bootx", NULL) != NULL)
571 flags |= OF_IMAP_NO_PHANDLE; 609 of_irq_workarounds |= OF_IMAP_NO_PHANDLE;
572#endif /* CONFIG_PPC_32 */
573 610
574 of_irq_map_init(flags); 611 /* If we don't have phandles on a newworld, then try to locate a
612 * default interrupt controller (happens when booting with BootX).
613 * We do a first match here, hopefully, that only ever happens on
614 * machines with one controller.
615 */
616 if (pmac_newworld && (of_irq_workarounds & OF_IMAP_NO_PHANDLE)) {
617 struct device_node *np;
618
619 for_each_node_with_property(np, "interrupt-controller") {
620 /* Skip /chosen/interrupt-controller */
621 if (strcmp(np->name, "chosen") == 0)
622 continue;
623 /* It seems like at least one person wants
624 * to use BootX on a machine with an AppleKiwi
625 * controller which happens to pretend to be an
626 * interrupt controller too. */
627 if (strcmp(np->name, "AppleKiwi") == 0)
628 continue;
629 /* I think we found one ! */
630 of_irq_dflt_pic = np;
631 break;
632 }
633 }
634#endif /* CONFIG_PPC32 */
575 635
576 /* We first try to detect Apple's new Core99 chipset, since mac-io 636 /* We first try to detect Apple's new Core99 chipset, since mac-io
577 * is quite different on those machines and contains an IBM MPIC2. 637 * is quite different on those machines and contains an IBM MPIC2.