diff options
Diffstat (limited to 'arch/powerpc/kernel/prom.c')
-rw-r--r-- | arch/powerpc/kernel/prom.c | 40 |
1 files changed, 26 insertions, 14 deletions
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 16ac15e73b44..ab9b291dda54 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c | |||
@@ -296,13 +296,28 @@ static int __devinit map_interrupt(unsigned int **irq, struct device_node **ictr | |||
296 | return nintrc; | 296 | return nintrc; |
297 | } | 297 | } |
298 | 298 | ||
299 | static unsigned char map_isa_senses[4] = { | ||
300 | IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE, | ||
301 | IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE, | ||
302 | IRQ_SENSE_EDGE | IRQ_POLARITY_NEGATIVE, | ||
303 | IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE | ||
304 | }; | ||
305 | |||
306 | static unsigned char map_mpic_senses[4] = { | ||
307 | IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE, | ||
308 | IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE, | ||
309 | /* 2 seems to be used for the 8259 cascade... */ | ||
310 | IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE, | ||
311 | IRQ_SENSE_EDGE | IRQ_POLARITY_NEGATIVE, | ||
312 | }; | ||
313 | |||
299 | static int __devinit finish_node_interrupts(struct device_node *np, | 314 | static int __devinit finish_node_interrupts(struct device_node *np, |
300 | unsigned long *mem_start, | 315 | unsigned long *mem_start, |
301 | int measure_only) | 316 | int measure_only) |
302 | { | 317 | { |
303 | unsigned int *ints; | 318 | unsigned int *ints; |
304 | int intlen, intrcells, intrcount; | 319 | int intlen, intrcells, intrcount; |
305 | int i, j, n; | 320 | int i, j, n, sense; |
306 | unsigned int *irq, virq; | 321 | unsigned int *irq, virq; |
307 | struct device_node *ic; | 322 | struct device_node *ic; |
308 | 323 | ||
@@ -332,7 +347,8 @@ static int __devinit finish_node_interrupts(struct device_node *np, | |||
332 | 347 | ||
333 | for (i = 0; i < np->n_intrs; ++i) { | 348 | for (i = 0; i < np->n_intrs; ++i) { |
334 | np->intrs[i].line = *ints++; | 349 | np->intrs[i].line = *ints++; |
335 | np->intrs[i].sense = 1; | 350 | np->intrs[i].sense = IRQ_SENSE_LEVEL |
351 | | IRQ_POLARITY_NEGATIVE; | ||
336 | } | 352 | } |
337 | return 0; | 353 | return 0; |
338 | } | 354 | } |
@@ -359,19 +375,20 @@ static int __devinit finish_node_interrupts(struct device_node *np, | |||
359 | /* don't map IRQ numbers under a cascaded 8259 controller */ | 375 | /* don't map IRQ numbers under a cascaded 8259 controller */ |
360 | if (ic && device_is_compatible(ic, "chrp,iic")) { | 376 | if (ic && device_is_compatible(ic, "chrp,iic")) { |
361 | np->intrs[intrcount].line = irq[0]; | 377 | np->intrs[intrcount].line = irq[0]; |
378 | sense = (n > 1)? (irq[1] & 3): 3; | ||
379 | np->intrs[intrcount].sense = map_isa_senses[sense]; | ||
362 | } else { | 380 | } else { |
363 | #ifdef CONFIG_PPC64 | ||
364 | virq = virt_irq_create_mapping(irq[0]); | 381 | virq = virt_irq_create_mapping(irq[0]); |
382 | #ifdef CONFIG_PPC64 | ||
365 | if (virq == NO_IRQ) { | 383 | if (virq == NO_IRQ) { |
366 | printk(KERN_CRIT "Could not allocate interrupt" | 384 | printk(KERN_CRIT "Could not allocate interrupt" |
367 | " number for %s\n", np->full_name); | 385 | " number for %s\n", np->full_name); |
368 | continue; | 386 | continue; |
369 | } | 387 | } |
370 | virq = irq_offset_up(virq); | ||
371 | #else | ||
372 | virq = irq[0]; | ||
373 | #endif | 388 | #endif |
374 | np->intrs[intrcount].line = virq; | 389 | np->intrs[intrcount].line = irq_offset_up(virq); |
390 | sense = (n > 1)? (irq[1] & 3): 1; | ||
391 | np->intrs[intrcount].sense = map_mpic_senses[sense]; | ||
375 | } | 392 | } |
376 | 393 | ||
377 | #ifdef CONFIG_PPC64 | 394 | #ifdef CONFIG_PPC64 |
@@ -386,9 +403,6 @@ static int __devinit finish_node_interrupts(struct device_node *np, | |||
386 | break; | 403 | break; |
387 | } | 404 | } |
388 | #endif | 405 | #endif |
389 | np->intrs[intrcount].sense = 1; | ||
390 | if (n > 1) | ||
391 | np->intrs[intrcount].sense = irq[1]; | ||
392 | if (n > 2) { | 406 | if (n > 2) { |
393 | printk("hmmm, got %d intr cells for %s:", n, | 407 | printk("hmmm, got %d intr cells for %s:", n, |
394 | np->full_name); | 408 | np->full_name); |
@@ -1401,15 +1415,13 @@ void __init prom_get_irq_senses(unsigned char *senses, int off, int max) | |||
1401 | int i, j; | 1415 | int i, j; |
1402 | 1416 | ||
1403 | /* default to level-triggered */ | 1417 | /* default to level-triggered */ |
1404 | memset(senses, 1, max - off); | 1418 | memset(senses, IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE, max - off); |
1405 | 1419 | ||
1406 | for (np = allnodes; np != 0; np = np->allnext) { | 1420 | for (np = allnodes; np != 0; np = np->allnext) { |
1407 | for (j = 0; j < np->n_intrs; j++) { | 1421 | for (j = 0; j < np->n_intrs; j++) { |
1408 | i = np->intrs[j].line; | 1422 | i = np->intrs[j].line; |
1409 | if (i >= off && i < max) | 1423 | if (i >= off && i < max) |
1410 | senses[i-off] = np->intrs[j].sense ? | 1424 | senses[i-off] = np->intrs[j].sense; |
1411 | IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE : | ||
1412 | IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE; | ||
1413 | } | 1425 | } |
1414 | } | 1426 | } |
1415 | } | 1427 | } |