aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/powermac
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2006-07-03 07:36:01 -0400
committerPaul Mackerras <paulus@samba.org>2006-07-03 07:36:01 -0400
commit0ebfff1491ef85d41ddf9c633834838be144f69f (patch)
tree5b469a6d61a9fcfbf94e7b6d411e544dbdec8dec /arch/powerpc/platforms/powermac
parentf63e115fb50db39706b955b81e3375ef6bab2268 (diff)
[POWERPC] Add new interrupt mapping core and change platforms to use it
This adds the new irq remapper core and removes the old one. Because there are some fundamental conflicts with the old code, like the value of NO_IRQ which I'm now setting to 0 (as per discussions with Linus), etc..., this commit also changes the relevant platform and driver code over to use the new remapper (so as not to cause difficulties later in bisecting). This patch removes the old pre-parsing of the open firmware interrupt tree along with all the bogus assumptions it made to try to renumber interrupts according to the platform. This is all to be handled by the new code now. For the pSeries XICS interrupt controller, a single remapper host is created for the whole machine regardless of how many interrupt presentation and source controllers are found, and it's set to match any device node that isn't a 8259. That works fine on pSeries and avoids having to deal with some of the complexities of split source controllers vs. presentation controllers in the pSeries device trees. The powerpc i8259 PIC driver now always requests the legacy interrupt range. It also has the feature of being able to match any device node (including NULL) if passed no device node as an input. That will help porting over platforms with broken device-trees like Pegasos who don't have a proper interrupt tree. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/platforms/powermac')
-rw-r--r--arch/powerpc/platforms/powermac/bootx_init.c4
-rw-r--r--arch/powerpc/platforms/powermac/low_i2c.c9
-rw-r--r--arch/powerpc/platforms/powermac/nvram.c5
-rw-r--r--arch/powerpc/platforms/powermac/pci.c68
-rw-r--r--arch/powerpc/platforms/powermac/pfunc_base.c13
-rw-r--r--arch/powerpc/platforms/powermac/pic.c328
-rw-r--r--arch/powerpc/platforms/powermac/pmac.h2
-rw-r--r--arch/powerpc/platforms/powermac/setup.c3
8 files changed, 191 insertions, 241 deletions
diff --git a/arch/powerpc/platforms/powermac/bootx_init.c b/arch/powerpc/platforms/powermac/bootx_init.c
index 5685ad9e88e8..e63d52f227ee 100644
--- a/arch/powerpc/platforms/powermac/bootx_init.c
+++ b/arch/powerpc/platforms/powermac/bootx_init.c
@@ -162,6 +162,8 @@ static void __init bootx_add_chosen_props(unsigned long base,
162{ 162{
163 u32 val; 163 u32 val;
164 164
165 bootx_dt_add_prop("linux,bootx", NULL, 0, mem_end);
166
165 if (bootx_info->kernelParamsOffset) { 167 if (bootx_info->kernelParamsOffset) {
166 char *args = (char *)((unsigned long)bootx_info) + 168 char *args = (char *)((unsigned long)bootx_info) +
167 bootx_info->kernelParamsOffset; 169 bootx_info->kernelParamsOffset;
@@ -228,7 +230,7 @@ static void __init bootx_scan_dt_build_strings(unsigned long base,
228 230
229 if (!strcmp(namep, "/chosen")) { 231 if (!strcmp(namep, "/chosen")) {
230 DBG(" detected /chosen ! adding properties names !\n"); 232 DBG(" detected /chosen ! adding properties names !\n");
231 bootx_dt_add_string("linux,platform", mem_end); 233 bootx_dt_add_string("linux,bootx", mem_end);
232 bootx_dt_add_string("linux,stdout-path", mem_end); 234 bootx_dt_add_string("linux,stdout-path", mem_end);
233 bootx_dt_add_string("linux,initrd-start", mem_end); 235 bootx_dt_add_string("linux,initrd-start", mem_end);
234 bootx_dt_add_string("linux,initrd-end", mem_end); 236 bootx_dt_add_string("linux,initrd-end", mem_end);
diff --git a/arch/powerpc/platforms/powermac/low_i2c.c b/arch/powerpc/platforms/powermac/low_i2c.c
index ceafaf52a668..8677f50c2586 100644
--- a/arch/powerpc/platforms/powermac/low_i2c.c
+++ b/arch/powerpc/platforms/powermac/low_i2c.c
@@ -522,10 +522,11 @@ static struct pmac_i2c_host_kw *__init kw_i2c_host_init(struct device_node *np)
522 host->speed = KW_I2C_MODE_25KHZ; 522 host->speed = KW_I2C_MODE_25KHZ;
523 break; 523 break;
524 } 524 }
525 if (np->n_intrs > 0) 525 host->irq = irq_of_parse_and_map(np, 0);
526 host->irq = np->intrs[0].line; 526 if (host->irq == NO_IRQ)
527 else 527 printk(KERN_WARNING
528 host->irq = NO_IRQ; 528 "low_i2c: Failed to map interrupt for %s\n",
529 np->full_name);
529 530
530 host->base = ioremap((*addrp), 0x1000); 531 host->base = ioremap((*addrp), 0x1000);
531 if (host->base == NULL) { 532 if (host->base == NULL) {
diff --git a/arch/powerpc/platforms/powermac/nvram.c b/arch/powerpc/platforms/powermac/nvram.c
index 41fa2409482a..6a36ea9bf673 100644
--- a/arch/powerpc/platforms/powermac/nvram.c
+++ b/arch/powerpc/platforms/powermac/nvram.c
@@ -29,6 +29,8 @@
29#include <asm/machdep.h> 29#include <asm/machdep.h>
30#include <asm/nvram.h> 30#include <asm/nvram.h>
31 31
32#include "pmac.h"
33
32#define DEBUG 34#define DEBUG
33 35
34#ifdef DEBUG 36#ifdef DEBUG
@@ -80,9 +82,6 @@ static int nvram_partitions[3];
80// XXX Turn that into a sem 82// XXX Turn that into a sem
81static DEFINE_SPINLOCK(nv_lock); 83static DEFINE_SPINLOCK(nv_lock);
82 84
83extern int pmac_newworld;
84extern int system_running;
85
86static int (*core99_write_bank)(int bank, u8* datas); 85static int (*core99_write_bank)(int bank, u8* datas);
87static int (*core99_erase_bank)(int bank); 86static int (*core99_erase_bank)(int bank);
88 87
diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c
index d524a915aa86..556b349797e8 100644
--- a/arch/powerpc/platforms/powermac/pci.c
+++ b/arch/powerpc/platforms/powermac/pci.c
@@ -46,6 +46,9 @@ static int has_uninorth;
46static struct pci_controller *u3_agp; 46static struct pci_controller *u3_agp;
47static struct pci_controller *u4_pcie; 47static struct pci_controller *u4_pcie;
48static struct pci_controller *u3_ht; 48static struct pci_controller *u3_ht;
49#define has_second_ohare 0
50#else
51static int has_second_ohare;
49#endif /* CONFIG_PPC64 */ 52#endif /* CONFIG_PPC64 */
50 53
51extern u8 pci_cache_line_size; 54extern u8 pci_cache_line_size;
@@ -647,6 +650,33 @@ static void __init init_p2pbridge(void)
647 early_write_config_word(hose, bus, devfn, PCI_BRIDGE_CONTROL, val); 650 early_write_config_word(hose, bus, devfn, PCI_BRIDGE_CONTROL, val);
648} 651}
649 652
653static void __init init_second_ohare(void)
654{
655 struct device_node *np = of_find_node_by_name(NULL, "pci106b,7");
656 unsigned char bus, devfn;
657 unsigned short cmd;
658
659 if (np == NULL)
660 return;
661
662 /* This must run before we initialize the PICs since the second
663 * ohare hosts a PIC that will be accessed there.
664 */
665 if (pci_device_from_OF_node(np, &bus, &devfn) == 0) {
666 struct pci_controller* hose =
667 pci_find_hose_for_OF_device(np);
668 if (!hose) {
669 printk(KERN_ERR "Can't find PCI hose for OHare2 !\n");
670 return;
671 }
672 early_read_config_word(hose, bus, devfn, PCI_COMMAND, &cmd);
673 cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
674 cmd &= ~PCI_COMMAND_IO;
675 early_write_config_word(hose, bus, devfn, PCI_COMMAND, cmd);
676 }
677 has_second_ohare = 1;
678}
679
650/* 680/*
651 * Some Apple desktop machines have a NEC PD720100A USB2 controller 681 * Some Apple desktop machines have a NEC PD720100A USB2 controller
652 * on the motherboard. Open Firmware, on these, will disable the 682 * on the motherboard. Open Firmware, on these, will disable the
@@ -688,9 +718,6 @@ static void __init fixup_nec_usb2(void)
688 " EHCI, fixing up...\n"); 718 " EHCI, fixing up...\n");
689 data &= ~1UL; 719 data &= ~1UL;
690 early_write_config_dword(hose, bus, devfn, 0xe4, data); 720 early_write_config_dword(hose, bus, devfn, 0xe4, data);
691 early_write_config_byte(hose, bus,
692 devfn | 2, PCI_INTERRUPT_LINE,
693 nec->intrs[0].line);
694 } 721 }
695 } 722 }
696} 723}
@@ -958,32 +985,28 @@ static int __init add_bridge(struct device_node *dev)
958 return 0; 985 return 0;
959} 986}
960 987
961static void __init pcibios_fixup_OF_interrupts(void) 988void __init pmac_pcibios_fixup(void)
962{ 989{
963 struct pci_dev* dev = NULL; 990 struct pci_dev* dev = NULL;
964 991
965 /*
966 * Open Firmware often doesn't initialize the
967 * PCI_INTERRUPT_LINE config register properly, so we
968 * should find the device node and apply the interrupt
969 * obtained from the OF device-tree
970 */
971 for_each_pci_dev(dev) { 992 for_each_pci_dev(dev) {
972 struct device_node *node; 993 /* Read interrupt from the device-tree */
973 node = pci_device_to_OF_node(dev); 994 pci_read_irq_line(dev);
974 /* this is the node, see if it has interrupts */ 995
975 if (node && node->n_intrs > 0) 996 /* Fixup interrupt for the modem/ethernet combo controller.
976 dev->irq = node->intrs[0].line; 997 * on machines with a second ohare chip.
977 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); 998 * The number in the device tree (27) is bogus (correct for
999 * the ethernet-only board but not the combo ethernet/modem
1000 * board). The real interrupt is 28 on the second controller
1001 * -> 28+32 = 60.
1002 */
1003 if (has_second_ohare &&
1004 dev->vendor == PCI_VENDOR_ID_DEC &&
1005 dev->device == PCI_DEVICE_ID_DEC_TULIP_PLUS)
1006 dev->irq = irq_create_mapping(NULL, 60, 0);
978 } 1007 }
979} 1008}
980 1009
981void __init pmac_pcibios_fixup(void)
982{
983 /* Fixup interrupts according to OF tree */
984 pcibios_fixup_OF_interrupts();
985}
986
987#ifdef CONFIG_PPC64 1010#ifdef CONFIG_PPC64
988static void __init pmac_fixup_phb_resources(void) 1011static void __init pmac_fixup_phb_resources(void)
989{ 1012{
@@ -1071,6 +1094,7 @@ void __init pmac_pci_init(void)
1071 1094
1072#else /* CONFIG_PPC64 */ 1095#else /* CONFIG_PPC64 */
1073 init_p2pbridge(); 1096 init_p2pbridge();
1097 init_second_ohare();
1074 fixup_nec_usb2(); 1098 fixup_nec_usb2();
1075 1099
1076 /* We are still having some issues with the Xserve G4, enabling 1100 /* We are still having some issues with the Xserve G4, enabling
diff --git a/arch/powerpc/platforms/powermac/pfunc_base.c b/arch/powerpc/platforms/powermac/pfunc_base.c
index d6eab8b3f7de..6d66359ec8c8 100644
--- a/arch/powerpc/platforms/powermac/pfunc_base.c
+++ b/arch/powerpc/platforms/powermac/pfunc_base.c
@@ -24,19 +24,18 @@ static irqreturn_t macio_gpio_irq(int irq, void *data, struct pt_regs *regs)
24 24
25static int macio_do_gpio_irq_enable(struct pmf_function *func) 25static int macio_do_gpio_irq_enable(struct pmf_function *func)
26{ 26{
27 if (func->node->n_intrs < 1) 27 unsigned int irq = irq_of_parse_and_map(func->node, 0);
28 if (irq == NO_IRQ)
28 return -EINVAL; 29 return -EINVAL;
29 30 return request_irq(irq, macio_gpio_irq, 0, func->node->name, func);
30 return request_irq(func->node->intrs[0].line, macio_gpio_irq, 0,
31 func->node->name, func);
32} 31}
33 32
34static int macio_do_gpio_irq_disable(struct pmf_function *func) 33static int macio_do_gpio_irq_disable(struct pmf_function *func)
35{ 34{
36 if (func->node->n_intrs < 1) 35 unsigned int irq = irq_of_parse_and_map(func->node, 0);
36 if (irq == NO_IRQ)
37 return -EINVAL; 37 return -EINVAL;
38 38 free_irq(irq, func);
39 free_irq(func->node->intrs[0].line, func);
40 return 0; 39 return 0;
41} 40}
42 41
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c
index 58a4c7b90b8b..3d328bc1f7e0 100644
--- a/arch/powerpc/platforms/powermac/pic.c
+++ b/arch/powerpc/platforms/powermac/pic.c
@@ -65,13 +65,11 @@ static u32 level_mask[4];
65 65
66static DEFINE_SPINLOCK(pmac_pic_lock); 66static DEFINE_SPINLOCK(pmac_pic_lock);
67 67
68#define GATWICK_IRQ_POOL_SIZE 10
69static struct interrupt_info gatwick_int_pool[GATWICK_IRQ_POOL_SIZE];
70
71#define NR_MASK_WORDS ((NR_IRQS + 31) / 32) 68#define NR_MASK_WORDS ((NR_IRQS + 31) / 32)
72static unsigned long ppc_lost_interrupts[NR_MASK_WORDS]; 69static unsigned long ppc_lost_interrupts[NR_MASK_WORDS];
73static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS]; 70static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS];
74static int pmac_irq_cascade = -1; 71static int pmac_irq_cascade = -1;
72static struct irq_host *pmac_pic_host;
75 73
76static void __pmac_retrigger(unsigned int irq_nr) 74static void __pmac_retrigger(unsigned int irq_nr)
77{ 75{
@@ -86,18 +84,16 @@ static void __pmac_retrigger(unsigned int irq_nr)
86 } 84 }
87} 85}
88 86
89static void pmac_mask_and_ack_irq(unsigned int irq_nr) 87static void pmac_mask_and_ack_irq(unsigned int virq)
90{ 88{
91 unsigned long bit = 1UL << (irq_nr & 0x1f); 89 unsigned int src = irq_map[virq].hwirq;
92 int i = irq_nr >> 5; 90 unsigned long bit = 1UL << (virq & 0x1f);
91 int i = virq >> 5;
93 unsigned long flags; 92 unsigned long flags;
94 93
95 if ((unsigned)irq_nr >= max_irqs)
96 return;
97
98 spin_lock_irqsave(&pmac_pic_lock, flags); 94 spin_lock_irqsave(&pmac_pic_lock, flags);
99 __clear_bit(irq_nr, ppc_cached_irq_mask); 95 __clear_bit(src, ppc_cached_irq_mask);
100 if (__test_and_clear_bit(irq_nr, ppc_lost_interrupts)) 96 if (__test_and_clear_bit(src, ppc_lost_interrupts))
101 atomic_dec(&ppc_n_lost_interrupts); 97 atomic_dec(&ppc_n_lost_interrupts);
102 out_le32(&pmac_irq_hw[i]->enable, ppc_cached_irq_mask[i]); 98 out_le32(&pmac_irq_hw[i]->enable, ppc_cached_irq_mask[i]);
103 out_le32(&pmac_irq_hw[i]->ack, bit); 99 out_le32(&pmac_irq_hw[i]->ack, bit);
@@ -110,17 +106,15 @@ static void pmac_mask_and_ack_irq(unsigned int irq_nr)
110 spin_unlock_irqrestore(&pmac_pic_lock, flags); 106 spin_unlock_irqrestore(&pmac_pic_lock, flags);
111} 107}
112 108
113static void pmac_ack_irq(unsigned int irq_nr) 109static void pmac_ack_irq(unsigned int virq)
114{ 110{
115 unsigned long bit = 1UL << (irq_nr & 0x1f); 111 unsigned int src = irq_map[virq].hwirq;
116 int i = irq_nr >> 5; 112 unsigned long bit = 1UL << (src & 0x1f);
113 int i = src >> 5;
117 unsigned long flags; 114 unsigned long flags;
118 115
119 if ((unsigned)irq_nr >= max_irqs)
120 return;
121
122 spin_lock_irqsave(&pmac_pic_lock, flags); 116 spin_lock_irqsave(&pmac_pic_lock, flags);
123 if (__test_and_clear_bit(irq_nr, ppc_lost_interrupts)) 117 if (__test_and_clear_bit(src, ppc_lost_interrupts))
124 atomic_dec(&ppc_n_lost_interrupts); 118 atomic_dec(&ppc_n_lost_interrupts);
125 out_le32(&pmac_irq_hw[i]->ack, bit); 119 out_le32(&pmac_irq_hw[i]->ack, bit);
126 (void)in_le32(&pmac_irq_hw[i]->ack); 120 (void)in_le32(&pmac_irq_hw[i]->ack);
@@ -157,48 +151,51 @@ static void __pmac_set_irq_mask(unsigned int irq_nr, int nokicklost)
157/* When an irq gets requested for the first client, if it's an 151/* When an irq gets requested for the first client, if it's an
158 * edge interrupt, we clear any previous one on the controller 152 * edge interrupt, we clear any previous one on the controller
159 */ 153 */
160static unsigned int pmac_startup_irq(unsigned int irq_nr) 154static unsigned int pmac_startup_irq(unsigned int virq)
161{ 155{
162 unsigned long flags; 156 unsigned long flags;
163 unsigned long bit = 1UL << (irq_nr & 0x1f); 157 unsigned int src = irq_map[virq].hwirq;
164 int i = irq_nr >> 5; 158 unsigned long bit = 1UL << (src & 0x1f);
159 int i = src >> 5;
165 160
166 spin_lock_irqsave(&pmac_pic_lock, flags); 161 spin_lock_irqsave(&pmac_pic_lock, flags);
167 if ((irq_desc[irq_nr].status & IRQ_LEVEL) == 0) 162 if ((irq_desc[virq].status & IRQ_LEVEL) == 0)
168 out_le32(&pmac_irq_hw[i]->ack, bit); 163 out_le32(&pmac_irq_hw[i]->ack, bit);
169 __set_bit(irq_nr, ppc_cached_irq_mask); 164 __set_bit(src, ppc_cached_irq_mask);
170 __pmac_set_irq_mask(irq_nr, 0); 165 __pmac_set_irq_mask(src, 0);
171 spin_unlock_irqrestore(&pmac_pic_lock, flags); 166 spin_unlock_irqrestore(&pmac_pic_lock, flags);
172 167
173 return 0; 168 return 0;
174} 169}
175 170
176static void pmac_mask_irq(unsigned int irq_nr) 171static void pmac_mask_irq(unsigned int virq)
177{ 172{
178 unsigned long flags; 173 unsigned long flags;
174 unsigned int src = irq_map[virq].hwirq;
179 175
180 spin_lock_irqsave(&pmac_pic_lock, flags); 176 spin_lock_irqsave(&pmac_pic_lock, flags);
181 __clear_bit(irq_nr, ppc_cached_irq_mask); 177 __clear_bit(src, ppc_cached_irq_mask);
182 __pmac_set_irq_mask(irq_nr, 0); 178 __pmac_set_irq_mask(src, 0);
183 spin_unlock_irqrestore(&pmac_pic_lock, flags); 179 spin_unlock_irqrestore(&pmac_pic_lock, flags);
184} 180}
185 181
186static void pmac_unmask_irq(unsigned int irq_nr) 182static void pmac_unmask_irq(unsigned int virq)
187{ 183{
188 unsigned long flags; 184 unsigned long flags;
185 unsigned int src = irq_map[virq].hwirq;
189 186
190 spin_lock_irqsave(&pmac_pic_lock, flags); 187 spin_lock_irqsave(&pmac_pic_lock, flags);
191 __set_bit(irq_nr, ppc_cached_irq_mask); 188 __set_bit(src, ppc_cached_irq_mask);
192 __pmac_set_irq_mask(irq_nr, 0); 189 __pmac_set_irq_mask(src, 0);
193 spin_unlock_irqrestore(&pmac_pic_lock, flags); 190 spin_unlock_irqrestore(&pmac_pic_lock, flags);
194} 191}
195 192
196static int pmac_retrigger(unsigned int irq_nr) 193static int pmac_retrigger(unsigned int virq)
197{ 194{
198 unsigned long flags; 195 unsigned long flags;
199 196
200 spin_lock_irqsave(&pmac_pic_lock, flags); 197 spin_lock_irqsave(&pmac_pic_lock, flags);
201 __pmac_retrigger(irq_nr); 198 __pmac_retrigger(irq_map[virq].hwirq);
202 spin_unlock_irqrestore(&pmac_pic_lock, flags); 199 spin_unlock_irqrestore(&pmac_pic_lock, flags);
203 return 1; 200 return 1;
204} 201}
@@ -238,7 +235,7 @@ static irqreturn_t gatwick_action(int cpl, void *dev_id, struct pt_regs *regs)
238 return rc; 235 return rc;
239} 236}
240 237
241static int pmac_get_irq(struct pt_regs *regs) 238static unsigned int pmac_pic_get_irq(struct pt_regs *regs)
242{ 239{
243 int irq; 240 int irq;
244 unsigned long bits = 0; 241 unsigned long bits = 0;
@@ -250,7 +247,7 @@ static int pmac_get_irq(struct pt_regs *regs)
250 /* IPI's are a hack on the powersurge -- Cort */ 247 /* IPI's are a hack on the powersurge -- Cort */
251 if ( smp_processor_id() != 0 ) { 248 if ( smp_processor_id() != 0 ) {
252 psurge_smp_message_recv(regs); 249 psurge_smp_message_recv(regs);
253 return -2; /* ignore, already handled */ 250 return NO_IRQ_IGNORE; /* ignore, already handled */
254 } 251 }
255#endif /* CONFIG_SMP */ 252#endif /* CONFIG_SMP */
256 spin_lock_irqsave(&pmac_pic_lock, flags); 253 spin_lock_irqsave(&pmac_pic_lock, flags);
@@ -266,133 +263,9 @@ static int pmac_get_irq(struct pt_regs *regs)
266 break; 263 break;
267 } 264 }
268 spin_unlock_irqrestore(&pmac_pic_lock, flags); 265 spin_unlock_irqrestore(&pmac_pic_lock, flags);
269 266 if (unlikely(irq < 0))
270 return irq; 267 return NO_IRQ;
271} 268 return irq_linear_revmap(pmac_pic_host, irq);
272
273/* This routine will fix some missing interrupt values in the device tree
274 * on the gatwick mac-io controller used by some PowerBooks
275 *
276 * Walking of OF nodes could use a bit more fixing up here, but it's not
277 * very important as this is all boot time code on static portions of the
278 * device-tree.
279 *
280 * However, the modifications done to "intrs" will have to be removed and
281 * replaced with proper updates of the "interrupts" properties or
282 * AAPL,interrupts, yet to be decided, once the dynamic parsing is there.
283 */
284static void __init pmac_fix_gatwick_interrupts(struct device_node *gw,
285 int irq_base)
286{
287 struct device_node *node;
288 int count;
289
290 memset(gatwick_int_pool, 0, sizeof(gatwick_int_pool));
291 count = 0;
292 for (node = NULL; (node = of_get_next_child(gw, node)) != NULL;) {
293 /* Fix SCC */
294 if ((strcasecmp(node->name, "escc") == 0) && node->child) {
295 if (node->child->n_intrs < 3) {
296 node->child->intrs = &gatwick_int_pool[count];
297 count += 3;
298 }
299 node->child->n_intrs = 3;
300 node->child->intrs[0].line = 15+irq_base;
301 node->child->intrs[1].line = 4+irq_base;
302 node->child->intrs[2].line = 5+irq_base;
303 printk(KERN_INFO "irq: fixed SCC on gatwick"
304 " (%d,%d,%d)\n",
305 node->child->intrs[0].line,
306 node->child->intrs[1].line,
307 node->child->intrs[2].line);
308 }
309 /* Fix media-bay & left SWIM */
310 if (strcasecmp(node->name, "media-bay") == 0) {
311 struct device_node* ya_node;
312
313 if (node->n_intrs == 0)
314 node->intrs = &gatwick_int_pool[count++];
315 node->n_intrs = 1;
316 node->intrs[0].line = 29+irq_base;
317 printk(KERN_INFO "irq: fixed media-bay on gatwick"
318 " (%d)\n", node->intrs[0].line);
319
320 ya_node = node->child;
321 while(ya_node) {
322 if (strcasecmp(ya_node->name, "floppy") == 0) {
323 if (ya_node->n_intrs < 2) {
324 ya_node->intrs = &gatwick_int_pool[count];
325 count += 2;
326 }
327 ya_node->n_intrs = 2;
328 ya_node->intrs[0].line = 19+irq_base;
329 ya_node->intrs[1].line = 1+irq_base;
330 printk(KERN_INFO "irq: fixed floppy on second controller (%d,%d)\n",
331 ya_node->intrs[0].line, ya_node->intrs[1].line);
332 }
333 if (strcasecmp(ya_node->name, "ata4") == 0) {
334 if (ya_node->n_intrs < 2) {
335 ya_node->intrs = &gatwick_int_pool[count];
336 count += 2;
337 }
338 ya_node->n_intrs = 2;
339 ya_node->intrs[0].line = 14+irq_base;
340 ya_node->intrs[1].line = 3+irq_base;
341 printk(KERN_INFO "irq: fixed ide on second controller (%d,%d)\n",
342 ya_node->intrs[0].line, ya_node->intrs[1].line);
343 }
344 ya_node = ya_node->sibling;
345 }
346 }
347 }
348 if (count > 10) {
349 printk("WARNING !! Gatwick interrupt pool overflow\n");
350 printk(" GATWICK_IRQ_POOL_SIZE = %d\n", GATWICK_IRQ_POOL_SIZE);
351 printk(" requested = %d\n", count);
352 }
353}
354
355/*
356 * The PowerBook 3400/2400/3500 can have a combo ethernet/modem
357 * card which includes an ohare chip that acts as a second interrupt
358 * controller. If we find this second ohare, set it up and fix the
359 * interrupt value in the device tree for the ethernet chip.
360 */
361static void __init enable_second_ohare(struct device_node *np)
362{
363 unsigned char bus, devfn;
364 unsigned short cmd;
365 struct device_node *ether;
366
367 /* This code doesn't strictly belong here, it could be part of
368 * either the PCI initialisation or the feature code. It's kept
369 * here for historical reasons.
370 */
371 if (pci_device_from_OF_node(np, &bus, &devfn) == 0) {
372 struct pci_controller* hose =
373 pci_find_hose_for_OF_device(np);
374 if (!hose) {
375 printk(KERN_ERR "Can't find PCI hose for OHare2 !\n");
376 return;
377 }
378 early_read_config_word(hose, bus, devfn, PCI_COMMAND, &cmd);
379 cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
380 cmd &= ~PCI_COMMAND_IO;
381 early_write_config_word(hose, bus, devfn, PCI_COMMAND, cmd);
382 }
383
384 /* Fix interrupt for the modem/ethernet combo controller. The number
385 * in the device tree (27) is bogus (correct for the ethernet-only
386 * board but not the combo ethernet/modem board).
387 * The real interrupt is 28 on the second controller -> 28+32 = 60.
388 */
389 ether = of_find_node_by_name(NULL, "pci1011,14");
390 if (ether && ether->n_intrs > 0) {
391 ether->intrs[0].line = 60;
392 printk(KERN_INFO "irq: Fixed ethernet IRQ to %d\n",
393 ether->intrs[0].line);
394 }
395 of_node_put(ether);
396} 269}
397 270
398#ifdef CONFIG_XMON 271#ifdef CONFIG_XMON
@@ -411,6 +284,50 @@ static struct irqaction gatwick_cascade_action = {
411 .name = "cascade", 284 .name = "cascade",
412}; 285};
413 286
287static int pmac_pic_host_match(struct irq_host *h, struct device_node *node)
288{
289 /* We match all, we don't always have a node anyway */
290 return 1;
291}
292
293static int pmac_pic_host_map(struct irq_host *h, unsigned int virq,
294 irq_hw_number_t hw, unsigned int flags)
295{
296 struct irq_desc *desc = get_irq_desc(virq);
297 int level;
298
299 if (hw >= max_irqs)
300 return -EINVAL;
301
302 /* Mark level interrupts, set delayed disable for edge ones and set
303 * handlers
304 */
305 level = !!(level_mask[hw >> 5] & (1UL << (hw & 0x1f)));
306 if (level)
307 desc->status |= IRQ_LEVEL;
308 else
309 desc->status |= IRQ_DELAYED_DISABLE;
310 set_irq_chip_and_handler(virq, &pmac_pic, level ?
311 handle_level_irq : handle_edge_irq);
312 return 0;
313}
314
315static int pmac_pic_host_xlate(struct irq_host *h, struct device_node *ct,
316 u32 *intspec, unsigned int intsize,
317 irq_hw_number_t *out_hwirq,
318 unsigned int *out_flags)
319
320{
321 *out_hwirq = *intspec;
322 return 0;
323}
324
325static struct irq_host_ops pmac_pic_host_ops = {
326 .match = pmac_pic_host_match,
327 .map = pmac_pic_host_map,
328 .xlate = pmac_pic_host_xlate,
329};
330
414static void __init pmac_pic_probe_oldstyle(void) 331static void __init pmac_pic_probe_oldstyle(void)
415{ 332{
416 int i; 333 int i;
@@ -420,7 +337,7 @@ static void __init pmac_pic_probe_oldstyle(void)
420 struct resource r; 337 struct resource r;
421 338
422 /* Set our get_irq function */ 339 /* Set our get_irq function */
423 ppc_md.get_irq = pmac_get_irq; 340 ppc_md.get_irq = pmac_pic_get_irq;
424 341
425 /* 342 /*
426 * Find the interrupt controller type & node 343 * Find the interrupt controller type & node
@@ -438,7 +355,6 @@ static void __init pmac_pic_probe_oldstyle(void)
438 if (slave) { 355 if (slave) {
439 max_irqs = 64; 356 max_irqs = 64;
440 level_mask[1] = OHARE_LEVEL_MASK; 357 level_mask[1] = OHARE_LEVEL_MASK;
441 enable_second_ohare(slave);
442 } 358 }
443 } else if ((master = of_find_node_by_name(NULL, "mac-io")) != NULL) { 359 } else if ((master = of_find_node_by_name(NULL, "mac-io")) != NULL) {
444 max_irqs = max_real_irqs = 64; 360 max_irqs = max_real_irqs = 64;
@@ -462,21 +378,18 @@ static void __init pmac_pic_probe_oldstyle(void)
462 max_irqs = 128; 378 max_irqs = 128;
463 level_mask[2] = HEATHROW_LEVEL_MASK; 379 level_mask[2] = HEATHROW_LEVEL_MASK;
464 level_mask[3] = 0; 380 level_mask[3] = 0;
465 pmac_fix_gatwick_interrupts(slave, max_real_irqs);
466 } 381 }
467 } 382 }
468 BUG_ON(master == NULL); 383 BUG_ON(master == NULL);
469 384
470 /* Mark level interrupts and set handlers */ 385 /*
471 for (i = 0; i < max_irqs; i++) { 386 * Allocate an irq host
472 int level = !!(level_mask[i >> 5] & (1UL << (i & 0x1f))); 387 */
473 if (level) 388 pmac_pic_host = irq_alloc_host(IRQ_HOST_MAP_LINEAR, max_irqs,
474 irq_desc[i].status |= IRQ_LEVEL; 389 &pmac_pic_host_ops,
475 else 390 max_irqs);
476 irq_desc[i].status |= IRQ_DELAYED_DISABLE; 391 BUG_ON(pmac_pic_host == NULL);
477 set_irq_chip_and_handler(i, &pmac_pic, level ? 392 irq_set_default_host(pmac_pic_host);
478 handle_level_irq : handle_edge_irq);
479 }
480 393
481 /* Get addresses of first controller if we have a node for it */ 394 /* Get addresses of first controller if we have a node for it */
482 BUG_ON(of_address_to_resource(master, 0, &r)); 395 BUG_ON(of_address_to_resource(master, 0, &r));
@@ -503,7 +416,7 @@ static void __init pmac_pic_probe_oldstyle(void)
503 pmac_irq_hw[i++] = 416 pmac_irq_hw[i++] =
504 (volatile struct pmac_irq_hw __iomem *) 417 (volatile struct pmac_irq_hw __iomem *)
505 (addr + 0x10); 418 (addr + 0x10);
506 pmac_irq_cascade = slave->intrs[0].line; 419 pmac_irq_cascade = irq_of_parse_and_map(slave, 0);
507 420
508 printk(KERN_INFO "irq: Found slave Apple PIC %s for %d irqs" 421 printk(KERN_INFO "irq: Found slave Apple PIC %s for %d irqs"
509 " cascade: %d\n", slave->full_name, 422 " cascade: %d\n", slave->full_name,
@@ -516,12 +429,12 @@ static void __init pmac_pic_probe_oldstyle(void)
516 out_le32(&pmac_irq_hw[i]->enable, 0); 429 out_le32(&pmac_irq_hw[i]->enable, 0);
517 430
518 /* Hookup cascade irq */ 431 /* Hookup cascade irq */
519 if (slave) 432 if (slave && pmac_irq_cascade != NO_IRQ)
520 setup_irq(pmac_irq_cascade, &gatwick_cascade_action); 433 setup_irq(pmac_irq_cascade, &gatwick_cascade_action);
521 434
522 printk(KERN_INFO "irq: System has %d possible interrupts\n", max_irqs); 435 printk(KERN_INFO "irq: System has %d possible interrupts\n", max_irqs);
523#ifdef CONFIG_XMON 436#ifdef CONFIG_XMON
524 setup_irq(20, &xmon_action); 437 setup_irq(irq_create_mapping(NULL, 20, 0), &xmon_action);
525#endif 438#endif
526} 439}
527#endif /* CONFIG_PPC32 */ 440#endif /* CONFIG_PPC32 */
@@ -530,16 +443,11 @@ static void pmac_u3_cascade(unsigned int irq, struct irq_desc *desc,
530 struct pt_regs *regs) 443 struct pt_regs *regs)
531{ 444{
532 struct mpic *mpic = desc->handler_data; 445 struct mpic *mpic = desc->handler_data;
533 unsigned int max = 100;
534 446
535 while(max--) { 447 unsigned int cascade_irq = mpic_get_one_irq(mpic, regs);
536 int cascade_irq = mpic_get_one_irq(mpic, regs); 448 if (cascade_irq != NO_IRQ)
537 if (max == 99)
538 desc->chip->eoi(irq);
539 if (irq < 0)
540 break;
541 generic_handle_irq(cascade_irq, regs); 449 generic_handle_irq(cascade_irq, regs);
542 }; 450 desc->chip->eoi(irq);
543} 451}
544 452
545static void __init pmac_pic_setup_mpic_nmi(struct mpic *mpic) 453static void __init pmac_pic_setup_mpic_nmi(struct mpic *mpic)
@@ -549,21 +457,20 @@ static void __init pmac_pic_setup_mpic_nmi(struct mpic *mpic)
549 int nmi_irq; 457 int nmi_irq;
550 458
551 pswitch = of_find_node_by_name(NULL, "programmer-switch"); 459 pswitch = of_find_node_by_name(NULL, "programmer-switch");
552 if (pswitch && pswitch->n_intrs) { 460 if (pswitch) {
553 nmi_irq = pswitch->intrs[0].line; 461 nmi_irq = irq_of_parse_and_map(pswitch, 0);
554 mpic_irq_set_priority(nmi_irq, 9); 462 if (nmi_irq != NO_IRQ) {
555 setup_irq(nmi_irq, &xmon_action); 463 mpic_irq_set_priority(nmi_irq, 9);
464 setup_irq(nmi_irq, &xmon_action);
465 }
466 of_node_put(pswitch);
556 } 467 }
557 of_node_put(pswitch);
558#endif /* defined(CONFIG_XMON) && defined(CONFIG_PPC32) */ 468#endif /* defined(CONFIG_XMON) && defined(CONFIG_PPC32) */
559} 469}
560 470
561static struct mpic * __init pmac_setup_one_mpic(struct device_node *np, 471static struct mpic * __init pmac_setup_one_mpic(struct device_node *np,
562 int master) 472 int master)
563{ 473{
564 unsigned char senses[128];
565 int offset = master ? 0 : 128;
566 int count = master ? 128 : 124;
567 const char *name = master ? " MPIC 1 " : " MPIC 2 "; 474 const char *name = master ? " MPIC 1 " : " MPIC 2 ";
568 struct resource r; 475 struct resource r;
569 struct mpic *mpic; 476 struct mpic *mpic;
@@ -576,8 +483,6 @@ static struct mpic * __init pmac_setup_one_mpic(struct device_node *np,
576 483
577 pmac_call_feature(PMAC_FTR_ENABLE_MPIC, np, 0, 0); 484 pmac_call_feature(PMAC_FTR_ENABLE_MPIC, np, 0, 0);
578 485
579 prom_get_irq_senses(senses, offset, offset + count);
580
581 flags |= MPIC_WANTS_RESET; 486 flags |= MPIC_WANTS_RESET;
582 if (get_property(np, "big-endian", NULL)) 487 if (get_property(np, "big-endian", NULL))
583 flags |= MPIC_BIG_ENDIAN; 488 flags |= MPIC_BIG_ENDIAN;
@@ -588,8 +493,7 @@ static struct mpic * __init pmac_setup_one_mpic(struct device_node *np,
588 if (master && (flags & MPIC_BIG_ENDIAN)) 493 if (master && (flags & MPIC_BIG_ENDIAN))
589 flags |= MPIC_BROKEN_U3; 494 flags |= MPIC_BROKEN_U3;
590 495
591 mpic = mpic_alloc(r.start, flags, 0, offset, count, master ? 252 : 0, 496 mpic = mpic_alloc(np, r.start, flags, 0, 0, name);
592 senses, count, name);
593 if (mpic == NULL) 497 if (mpic == NULL)
594 return NULL; 498 return NULL;
595 499
@@ -602,6 +506,7 @@ static int __init pmac_pic_probe_mpic(void)
602{ 506{
603 struct mpic *mpic1, *mpic2; 507 struct mpic *mpic1, *mpic2;
604 struct device_node *np, *master = NULL, *slave = NULL; 508 struct device_node *np, *master = NULL, *slave = NULL;
509 unsigned int cascade;
605 510
606 /* We can have up to 2 MPICs cascaded */ 511 /* We can have up to 2 MPICs cascaded */
607 for (np = NULL; (np = of_find_node_by_type(np, "open-pic")) 512 for (np = NULL; (np = of_find_node_by_type(np, "open-pic"))
@@ -638,8 +543,15 @@ static int __init pmac_pic_probe_mpic(void)
638 of_node_put(master); 543 of_node_put(master);
639 544
640 /* No slave, let's go out */ 545 /* No slave, let's go out */
641 if (slave == NULL || slave->n_intrs < 1) 546 if (slave == NULL)
547 return 0;
548
549 /* Get/Map slave interrupt */
550 cascade = irq_of_parse_and_map(slave, 0);
551 if (cascade == NO_IRQ) {
552 printk(KERN_ERR "Failed to map cascade IRQ\n");
642 return 0; 553 return 0;
554 }
643 555
644 mpic2 = pmac_setup_one_mpic(slave, 0); 556 mpic2 = pmac_setup_one_mpic(slave, 0);
645 if (mpic2 == NULL) { 557 if (mpic2 == NULL) {
@@ -647,8 +559,8 @@ static int __init pmac_pic_probe_mpic(void)
647 of_node_put(slave); 559 of_node_put(slave);
648 return 0; 560 return 0;
649 } 561 }
650 set_irq_data(slave->intrs[0].line, mpic2); 562 set_irq_data(cascade, mpic2);
651 set_irq_chained_handler(slave->intrs[0].line, pmac_u3_cascade); 563 set_irq_chained_handler(cascade, pmac_u3_cascade);
652 564
653 of_node_put(slave); 565 of_node_put(slave);
654 return 0; 566 return 0;
@@ -657,6 +569,19 @@ static int __init pmac_pic_probe_mpic(void)
657 569
658void __init pmac_pic_init(void) 570void __init pmac_pic_init(void)
659{ 571{
572 unsigned int flags = 0;
573
574 /* We configure the OF parsing based on our oldworld vs. newworld
575 * platform type and wether we were booted by BootX.
576 */
577#ifdef CONFIG_PPC32
578 if (!pmac_newworld)
579 flags |= OF_IMAP_OLDWORLD_MAC;
580 if (get_property(of_chosen, "linux,bootx", NULL) != NULL)
581 flags |= OF_IMAP_NO_PHANDLE;
582 of_irq_map_init(flags);
583#endif /* CONFIG_PPC_32 */
584
660 /* We first try to detect Apple's new Core99 chipset, since mac-io 585 /* We first try to detect Apple's new Core99 chipset, since mac-io
661 * is quite different on those machines and contains an IBM MPIC2. 586 * is quite different on those machines and contains an IBM MPIC2.
662 */ 587 */
@@ -679,6 +604,7 @@ unsigned long sleep_save_mask[2];
679 604
680/* This used to be passed by the PMU driver but that link got 605/* This used to be passed by the PMU driver but that link got
681 * broken with the new driver model. We use this tweak for now... 606 * broken with the new driver model. We use this tweak for now...
607 * We really want to do things differently though...
682 */ 608 */
683static int pmacpic_find_viaint(void) 609static int pmacpic_find_viaint(void)
684{ 610{
@@ -692,7 +618,7 @@ static int pmacpic_find_viaint(void)
692 np = of_find_node_by_name(NULL, "via-pmu"); 618 np = of_find_node_by_name(NULL, "via-pmu");
693 if (np == NULL) 619 if (np == NULL)
694 goto not_found; 620 goto not_found;
695 viaint = np->intrs[0].line; 621 viaint = irq_of_parse_and_map(np, 0);;
696#endif /* CONFIG_ADB_PMU */ 622#endif /* CONFIG_ADB_PMU */
697 623
698not_found: 624not_found:
diff --git a/arch/powerpc/platforms/powermac/pmac.h b/arch/powerpc/platforms/powermac/pmac.h
index 21c7b0f8f329..94e7b24b840b 100644
--- a/arch/powerpc/platforms/powermac/pmac.h
+++ b/arch/powerpc/platforms/powermac/pmac.h
@@ -12,6 +12,8 @@
12 12
13struct rtc_time; 13struct rtc_time;
14 14
15extern int pmac_newworld;
16
15extern long pmac_time_init(void); 17extern long pmac_time_init(void);
16extern unsigned long pmac_get_boot_time(void); 18extern unsigned long pmac_get_boot_time(void);
17extern void pmac_get_rtc_time(struct rtc_time *); 19extern void pmac_get_rtc_time(struct rtc_time *);
diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c
index 8654b5f07836..31a9da769fa2 100644
--- a/arch/powerpc/platforms/powermac/setup.c
+++ b/arch/powerpc/platforms/powermac/setup.c
@@ -613,9 +613,6 @@ static void __init pmac_init_early(void)
613 udbg_adb_init(!!strstr(cmd_line, "btextdbg")); 613 udbg_adb_init(!!strstr(cmd_line, "btextdbg"));
614 614
615#ifdef CONFIG_PPC64 615#ifdef CONFIG_PPC64
616 /* Setup interrupt mapping options */
617 ppc64_interrupt_controller = IC_OPEN_PIC;
618
619 iommu_init_early_dart(); 616 iommu_init_early_dart();
620#endif 617#endif
621} 618}