diff options
Diffstat (limited to 'arch/powerpc/kernel/prom.c')
-rw-r--r-- | arch/powerpc/kernel/prom.c | 26 |
1 files changed, 23 insertions, 3 deletions
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 1b97e13657e5..977ee3adaf2d 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c | |||
@@ -298,6 +298,16 @@ static int __devinit finish_node_interrupts(struct device_node *np, | |||
298 | int i, j, n, sense; | 298 | int i, j, n, sense; |
299 | unsigned int *irq, virq; | 299 | unsigned int *irq, virq; |
300 | struct device_node *ic; | 300 | struct device_node *ic; |
301 | int trace = 0; | ||
302 | |||
303 | //#define TRACE(fmt...) do { if (trace) { printk(fmt); mdelay(1000); } } while(0) | ||
304 | #define TRACE(fmt...) | ||
305 | |||
306 | if (!strcmp(np->name, "smu-doorbell")) | ||
307 | trace = 1; | ||
308 | |||
309 | TRACE("Finishing SMU doorbell ! num_interrupt_controllers = %d\n", | ||
310 | num_interrupt_controllers); | ||
301 | 311 | ||
302 | if (num_interrupt_controllers == 0) { | 312 | if (num_interrupt_controllers == 0) { |
303 | /* | 313 | /* |
@@ -332,11 +342,12 @@ static int __devinit finish_node_interrupts(struct device_node *np, | |||
332 | } | 342 | } |
333 | 343 | ||
334 | ints = (unsigned int *) get_property(np, "interrupts", &intlen); | 344 | ints = (unsigned int *) get_property(np, "interrupts", &intlen); |
345 | TRACE("ints=%p, intlen=%d\n", ints, intlen); | ||
335 | if (ints == NULL) | 346 | if (ints == NULL) |
336 | return 0; | 347 | return 0; |
337 | intrcells = prom_n_intr_cells(np); | 348 | intrcells = prom_n_intr_cells(np); |
338 | intlen /= intrcells * sizeof(unsigned int); | 349 | intlen /= intrcells * sizeof(unsigned int); |
339 | 350 | TRACE("intrcells=%d, new intlen=%d\n", intrcells, intlen); | |
340 | np->intrs = prom_alloc(intlen * sizeof(*(np->intrs)), mem_start); | 351 | np->intrs = prom_alloc(intlen * sizeof(*(np->intrs)), mem_start); |
341 | if (!np->intrs) | 352 | if (!np->intrs) |
342 | return -ENOMEM; | 353 | return -ENOMEM; |
@@ -347,6 +358,7 @@ static int __devinit finish_node_interrupts(struct device_node *np, | |||
347 | intrcount = 0; | 358 | intrcount = 0; |
348 | for (i = 0; i < intlen; ++i, ints += intrcells) { | 359 | for (i = 0; i < intlen; ++i, ints += intrcells) { |
349 | n = map_interrupt(&irq, &ic, np, ints, intrcells); | 360 | n = map_interrupt(&irq, &ic, np, ints, intrcells); |
361 | TRACE("map, irq=%d, ic=%p, n=%d\n", irq, ic, n); | ||
350 | if (n <= 0) | 362 | if (n <= 0) |
351 | continue; | 363 | continue; |
352 | 364 | ||
@@ -357,6 +369,7 @@ static int __devinit finish_node_interrupts(struct device_node *np, | |||
357 | np->intrs[intrcount].sense = map_isa_senses[sense]; | 369 | np->intrs[intrcount].sense = map_isa_senses[sense]; |
358 | } else { | 370 | } else { |
359 | virq = virt_irq_create_mapping(irq[0]); | 371 | virq = virt_irq_create_mapping(irq[0]); |
372 | TRACE("virq=%d\n", virq); | ||
360 | #ifdef CONFIG_PPC64 | 373 | #ifdef CONFIG_PPC64 |
361 | if (virq == NO_IRQ) { | 374 | if (virq == NO_IRQ) { |
362 | printk(KERN_CRIT "Could not allocate interrupt" | 375 | printk(KERN_CRIT "Could not allocate interrupt" |
@@ -366,6 +379,12 @@ static int __devinit finish_node_interrupts(struct device_node *np, | |||
366 | #endif | 379 | #endif |
367 | np->intrs[intrcount].line = irq_offset_up(virq); | 380 | np->intrs[intrcount].line = irq_offset_up(virq); |
368 | sense = (n > 1)? (irq[1] & 3): 1; | 381 | sense = (n > 1)? (irq[1] & 3): 1; |
382 | |||
383 | /* Apple uses bits in there in a different way, let's | ||
384 | * only keep the real sense bit on macs | ||
385 | */ | ||
386 | if (_machine == PLATFORM_POWERMAC) | ||
387 | sense &= 0x1; | ||
369 | np->intrs[intrcount].sense = map_mpic_senses[sense]; | 388 | np->intrs[intrcount].sense = map_mpic_senses[sense]; |
370 | } | 389 | } |
371 | 390 | ||
@@ -375,12 +394,13 @@ static int __devinit finish_node_interrupts(struct device_node *np, | |||
375 | char *name = get_property(ic->parent, "name", NULL); | 394 | char *name = get_property(ic->parent, "name", NULL); |
376 | if (name && !strcmp(name, "u3")) | 395 | if (name && !strcmp(name, "u3")) |
377 | np->intrs[intrcount].line += 128; | 396 | np->intrs[intrcount].line += 128; |
378 | else if (!(name && !strcmp(name, "mac-io"))) | 397 | else if (!(name && (!strcmp(name, "mac-io") || |
398 | !strcmp(name, "u4")))) | ||
379 | /* ignore other cascaded controllers, such as | 399 | /* ignore other cascaded controllers, such as |
380 | the k2-sata-root */ | 400 | the k2-sata-root */ |
381 | break; | 401 | break; |
382 | } | 402 | } |
383 | #endif | 403 | #endif /* CONFIG_PPC64 */ |
384 | if (n > 2) { | 404 | if (n > 2) { |
385 | printk("hmmm, got %d intr cells for %s:", n, | 405 | printk("hmmm, got %d intr cells for %s:", n, |
386 | np->full_name); | 406 | np->full_name); |