diff options
Diffstat (limited to 'arch/powerpc/platforms/powermac/pic.c')
-rw-r--r-- | arch/powerpc/platforms/powermac/pic.c | 328 |
1 files changed, 127 insertions, 201 deletions
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 | ||
66 | static DEFINE_SPINLOCK(pmac_pic_lock); | 66 | static DEFINE_SPINLOCK(pmac_pic_lock); |
67 | 67 | ||
68 | #define GATWICK_IRQ_POOL_SIZE 10 | ||
69 | static 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) |
72 | static unsigned long ppc_lost_interrupts[NR_MASK_WORDS]; | 69 | static unsigned long ppc_lost_interrupts[NR_MASK_WORDS]; |
73 | static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS]; | 70 | static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS]; |
74 | static int pmac_irq_cascade = -1; | 71 | static int pmac_irq_cascade = -1; |
72 | static struct irq_host *pmac_pic_host; | ||
75 | 73 | ||
76 | static void __pmac_retrigger(unsigned int irq_nr) | 74 | static 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 | ||
89 | static void pmac_mask_and_ack_irq(unsigned int irq_nr) | 87 | static 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 | ||
113 | static void pmac_ack_irq(unsigned int irq_nr) | 109 | static 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 | */ |
160 | static unsigned int pmac_startup_irq(unsigned int irq_nr) | 154 | static 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 | ||
176 | static void pmac_mask_irq(unsigned int irq_nr) | 171 | static 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 | ||
186 | static void pmac_unmask_irq(unsigned int irq_nr) | 182 | static 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 | ||
196 | static int pmac_retrigger(unsigned int irq_nr) | 193 | static 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 | ||
241 | static int pmac_get_irq(struct pt_regs *regs) | 238 | static 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 | */ | ||
284 | static 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 | */ | ||
361 | static 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 | ||
287 | static 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 | |||
293 | static 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 | |||
315 | static 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 | |||
325 | static 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 | |||
414 | static void __init pmac_pic_probe_oldstyle(void) | 331 | static 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 | ||
545 | static void __init pmac_pic_setup_mpic_nmi(struct mpic *mpic) | 453 | static 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 | ||
561 | static struct mpic * __init pmac_setup_one_mpic(struct device_node *np, | 471 | static 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 | ||
658 | void __init pmac_pic_init(void) | 570 | void __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 | */ |
683 | static int pmacpic_find_viaint(void) | 609 | static 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 | ||
698 | not_found: | 624 | not_found: |