aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/prom.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel/prom.c')
-rw-r--r--arch/powerpc/kernel/prom.c40
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
299static 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
306static 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
299static int __devinit finish_node_interrupts(struct device_node *np, 314static 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}