diff options
Diffstat (limited to 'arch/blackfin/mach-common/ints-priority-sc.c')
-rw-r--r-- | arch/blackfin/mach-common/ints-priority-sc.c | 405 |
1 files changed, 369 insertions, 36 deletions
diff --git a/arch/blackfin/mach-common/ints-priority-sc.c b/arch/blackfin/mach-common/ints-priority-sc.c index 2cfc7d5aec5c..28a878c3577a 100644 --- a/arch/blackfin/mach-common/ints-priority-sc.c +++ b/arch/blackfin/mach-common/ints-priority-sc.c | |||
@@ -13,7 +13,7 @@ | |||
13 | * 2002 Arcturus Networks Inc. MaTed <mated@sympatico.ca> | 13 | * 2002 Arcturus Networks Inc. MaTed <mated@sympatico.ca> |
14 | * 2003 Metrowerks/Motorola | 14 | * 2003 Metrowerks/Motorola |
15 | * 2003 Bas Vermeulen <bas@buyways.nl> | 15 | * 2003 Bas Vermeulen <bas@buyways.nl> |
16 | * Copyright 2004-2006 Analog Devices Inc. | 16 | * Copyright 2004-2007 Analog Devices Inc. |
17 | * | 17 | * |
18 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ | 18 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ |
19 | * | 19 | * |
@@ -65,9 +65,9 @@ atomic_t num_spurious; | |||
65 | 65 | ||
66 | struct ivgx { | 66 | struct ivgx { |
67 | /* irq number for request_irq, available in mach-bf533/irq.h */ | 67 | /* irq number for request_irq, available in mach-bf533/irq.h */ |
68 | int irqno; | 68 | unsigned int irqno; |
69 | /* corresponding bit in the SIC_ISR register */ | 69 | /* corresponding bit in the SIC_ISR register */ |
70 | int isrflag; | 70 | unsigned int isrflag; |
71 | } ivg_table[NR_PERI_INTS]; | 71 | } ivg_table[NR_PERI_INTS]; |
72 | 72 | ||
73 | struct ivg_slice { | 73 | struct ivg_slice { |
@@ -88,17 +88,16 @@ static void __init search_IAR(void) | |||
88 | for (ivg = 0; ivg <= IVG13 - IVG7; ivg++) { | 88 | for (ivg = 0; ivg <= IVG13 - IVG7; ivg++) { |
89 | int irqn; | 89 | int irqn; |
90 | 90 | ||
91 | ivg7_13[ivg].istop = ivg7_13[ivg].ifirst = | 91 | ivg7_13[ivg].istop = ivg7_13[ivg].ifirst = &ivg_table[irq_pos]; |
92 | &ivg_table[irq_pos]; | ||
93 | 92 | ||
94 | for (irqn = 0; irqn < NR_PERI_INTS; irqn++) { | 93 | for (irqn = 0; irqn < NR_PERI_INTS; irqn++) { |
95 | int iar_shift = (irqn & 7) * 4; | 94 | int iar_shift = (irqn & 7) * 4; |
96 | if (ivg == | 95 | if (ivg == |
97 | (0xf & | 96 | (0xf & |
98 | bfin_read32((unsigned long *) SIC_IAR0 + | 97 | bfin_read32((unsigned long *)SIC_IAR0 + |
99 | (irqn >> 3)) >> iar_shift)) { | 98 | (irqn >> 3)) >> iar_shift)) { |
100 | ivg_table[irq_pos].irqno = IVG7 + irqn; | 99 | ivg_table[irq_pos].irqno = IVG7 + irqn; |
101 | ivg_table[irq_pos].isrflag = 1 << irqn; | 100 | ivg_table[irq_pos].isrflag = 1 << (irqn % 32); |
102 | ivg7_13[ivg].istop++; | 101 | ivg7_13[ivg].istop++; |
103 | irq_pos++; | 102 | irq_pos++; |
104 | } | 103 | } |
@@ -141,15 +140,31 @@ static void bfin_core_unmask_irq(unsigned int irq) | |||
141 | 140 | ||
142 | static void bfin_internal_mask_irq(unsigned int irq) | 141 | static void bfin_internal_mask_irq(unsigned int irq) |
143 | { | 142 | { |
143 | #ifndef CONFIG_BF54x | ||
144 | bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() & | 144 | bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() & |
145 | ~(1 << (irq - (IRQ_CORETMR + 1)))); | 145 | ~(1 << (irq - (IRQ_CORETMR + 1)))); |
146 | #else | ||
147 | unsigned mask_bank, mask_bit; | ||
148 | mask_bank = (irq - (IRQ_CORETMR + 1)) / 32; | ||
149 | mask_bit = (irq - (IRQ_CORETMR + 1)) % 32; | ||
150 | bfin_write_SIC_IMASK(mask_bank, bfin_read_SIC_IMASK(mask_bank) & | ||
151 | ~(1 << mask_bit)); | ||
152 | #endif | ||
146 | SSYNC(); | 153 | SSYNC(); |
147 | } | 154 | } |
148 | 155 | ||
149 | static void bfin_internal_unmask_irq(unsigned int irq) | 156 | static void bfin_internal_unmask_irq(unsigned int irq) |
150 | { | 157 | { |
158 | #ifndef CONFIG_BF54x | ||
151 | bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() | | 159 | bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() | |
152 | (1 << (irq - (IRQ_CORETMR + 1)))); | 160 | (1 << (irq - (IRQ_CORETMR + 1)))); |
161 | #else | ||
162 | unsigned mask_bank, mask_bit; | ||
163 | mask_bank = (irq - (IRQ_CORETMR + 1)) / 32; | ||
164 | mask_bit = (irq - (IRQ_CORETMR + 1)) % 32; | ||
165 | bfin_write_SIC_IMASK(mask_bank, bfin_read_SIC_IMASK(mask_bank) | | ||
166 | (1 << mask_bit)); | ||
167 | #endif | ||
153 | SSYNC(); | 168 | SSYNC(); |
154 | } | 169 | } |
155 | 170 | ||
@@ -206,7 +221,7 @@ static struct irq_chip bfin_generic_error_irqchip = { | |||
206 | }; | 221 | }; |
207 | 222 | ||
208 | static void bfin_demux_error_irq(unsigned int int_err_irq, | 223 | static void bfin_demux_error_irq(unsigned int int_err_irq, |
209 | struct irq_desc *intb_desc) | 224 | struct irq_desc *intb_desc) |
210 | { | 225 | { |
211 | int irq = 0; | 226 | int irq = 0; |
212 | 227 | ||
@@ -270,8 +285,8 @@ static void bfin_demux_error_irq(unsigned int int_err_irq, | |||
270 | } | 285 | } |
271 | 286 | ||
272 | pr_debug("IRQ %d:" | 287 | pr_debug("IRQ %d:" |
273 | " MASKED PERIPHERAL ERROR INTERRUPT ASSERTED\n", | 288 | " MASKED PERIPHERAL ERROR INTERRUPT ASSERTED\n", |
274 | irq); | 289 | irq); |
275 | } | 290 | } |
276 | } else | 291 | } else |
277 | printk(KERN_ERR | 292 | printk(KERN_ERR |
@@ -279,11 +294,10 @@ static void bfin_demux_error_irq(unsigned int int_err_irq, | |||
279 | " INTERRUPT ASSERTED BUT NO SOURCE FOUND\n", | 294 | " INTERRUPT ASSERTED BUT NO SOURCE FOUND\n", |
280 | __FUNCTION__, __FILE__, __LINE__); | 295 | __FUNCTION__, __FILE__, __LINE__); |
281 | 296 | ||
282 | |||
283 | } | 297 | } |
284 | #endif /* BF537_GENERIC_ERROR_INT_DEMUX */ | 298 | #endif /* BF537_GENERIC_ERROR_INT_DEMUX */ |
285 | 299 | ||
286 | #ifdef CONFIG_IRQCHIP_DEMUX_GPIO | 300 | #if defined(CONFIG_IRQCHIP_DEMUX_GPIO) && !defined(CONFIG_BF54x) |
287 | 301 | ||
288 | static unsigned short gpio_enabled[gpio_bank(MAX_BLACKFIN_GPIOS)]; | 302 | static unsigned short gpio_enabled[gpio_bank(MAX_BLACKFIN_GPIOS)]; |
289 | static unsigned short gpio_edge_triggered[gpio_bank(MAX_BLACKFIN_GPIOS)]; | 303 | static unsigned short gpio_edge_triggered[gpio_bank(MAX_BLACKFIN_GPIOS)]; |
@@ -361,8 +375,7 @@ static int bfin_gpio_irq_type(unsigned int irq, unsigned int type) | |||
361 | } | 375 | } |
362 | 376 | ||
363 | if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING | | 377 | if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING | |
364 | IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) | 378 | IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) { |
365 | { | ||
366 | if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) { | 379 | if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) { |
367 | ret = gpio_request(gpionr, NULL); | 380 | ret = gpio_request(gpionr, NULL); |
368 | if (ret) | 381 | if (ret) |
@@ -407,7 +420,6 @@ static int bfin_gpio_irq_type(unsigned int irq, unsigned int type) | |||
407 | return 0; | 420 | return 0; |
408 | } | 421 | } |
409 | 422 | ||
410 | |||
411 | static struct irq_chip bfin_gpio_irqchip = { | 423 | static struct irq_chip bfin_gpio_irqchip = { |
412 | .ack = bfin_gpio_ack_irq, | 424 | .ack = bfin_gpio_ack_irq, |
413 | .mask = bfin_gpio_mask_irq, | 425 | .mask = bfin_gpio_mask_irq, |
@@ -419,20 +431,20 @@ static struct irq_chip bfin_gpio_irqchip = { | |||
419 | }; | 431 | }; |
420 | 432 | ||
421 | static void bfin_demux_gpio_irq(unsigned int intb_irq, | 433 | static void bfin_demux_gpio_irq(unsigned int intb_irq, |
422 | struct irq_desc *intb_desc) | 434 | struct irq_desc *intb_desc) |
423 | { | 435 | { |
424 | u16 i; | 436 | u16 i; |
437 | struct irq_desc *desc; | ||
425 | 438 | ||
426 | for (i = 0; i < MAX_BLACKFIN_GPIOS; i+=16) { | 439 | for (i = 0; i < MAX_BLACKFIN_GPIOS; i += 16) { |
427 | int irq = IRQ_PF0 + i; | 440 | int irq = IRQ_PF0 + i; |
428 | int flag_d = get_gpiop_data(i); | 441 | int flag_d = get_gpiop_data(i); |
429 | int mask = | 442 | int mask = |
430 | flag_d & (gpio_enabled[gpio_bank(i)] & | 443 | flag_d & (gpio_enabled[gpio_bank(i)] & get_gpiop_maska(i)); |
431 | get_gpiop_maska(i)); | ||
432 | 444 | ||
433 | while (mask) { | 445 | while (mask) { |
434 | if (mask & 1) { | 446 | if (mask & 1) { |
435 | struct irq_desc *desc = irq_desc + irq; | 447 | desc = irq_desc + irq; |
436 | desc->handle_irq(irq, desc); | 448 | desc->handle_irq(irq, desc); |
437 | } | 449 | } |
438 | irq++; | 450 | irq++; |
@@ -441,6 +453,264 @@ static void bfin_demux_gpio_irq(unsigned int intb_irq, | |||
441 | } | 453 | } |
442 | } | 454 | } |
443 | 455 | ||
456 | #else /* CONFIG_IRQCHIP_DEMUX_GPIO */ | ||
457 | |||
458 | #define NR_PINT_SYS_IRQS 4 | ||
459 | #define NR_PINT_BITS 32 | ||
460 | #define NR_PINTS 160 | ||
461 | #define IRQ_NOT_AVAIL 0xFF | ||
462 | |||
463 | #define PINT_2_BANK(x) ((x) >> 5) | ||
464 | #define PINT_2_BIT(x) ((x) & 0x1F) | ||
465 | #define PINT_BIT(x) (1 << (PINT_2_BIT(x))) | ||
466 | |||
467 | static unsigned char irq2pint_lut[NR_PINTS]; | ||
468 | static unsigned char pint2irq_lut[NR_PINT_SYS_IRQS * NR_PINT_BITS]; | ||
469 | |||
470 | struct pin_int_t { | ||
471 | unsigned int mask_set; | ||
472 | unsigned int mask_clear; | ||
473 | unsigned int request; | ||
474 | unsigned int assign; | ||
475 | unsigned int edge_set; | ||
476 | unsigned int edge_clear; | ||
477 | unsigned int invert_set; | ||
478 | unsigned int invert_clear; | ||
479 | unsigned int pinstate; | ||
480 | unsigned int latch; | ||
481 | }; | ||
482 | |||
483 | static struct pin_int_t *pint[NR_PINT_SYS_IRQS] = { | ||
484 | (struct pin_int_t *)PINT0_MASK_SET, | ||
485 | (struct pin_int_t *)PINT1_MASK_SET, | ||
486 | (struct pin_int_t *)PINT2_MASK_SET, | ||
487 | (struct pin_int_t *)PINT3_MASK_SET, | ||
488 | }; | ||
489 | |||
490 | unsigned short get_irq_base(u8 bank, u8 bmap) | ||
491 | { | ||
492 | |||
493 | u16 irq_base; | ||
494 | |||
495 | if (bank < 2) { /*PA-PB */ | ||
496 | irq_base = IRQ_PA0 + bmap * 16; | ||
497 | } else { /*PC-PJ */ | ||
498 | irq_base = IRQ_PC0 + bmap * 16; | ||
499 | } | ||
500 | |||
501 | return irq_base; | ||
502 | |||
503 | } | ||
504 | |||
505 | /* Whenever PINTx_ASSIGN is altered init_pint_lut() must be executed! */ | ||
506 | void init_pint_lut(void) | ||
507 | { | ||
508 | u16 bank, bit, irq_base, bit_pos; | ||
509 | u32 pint_assign; | ||
510 | u8 bmap; | ||
511 | |||
512 | memset(irq2pint_lut, IRQ_NOT_AVAIL, sizeof(irq2pint_lut)); | ||
513 | |||
514 | for (bank = 0; bank < NR_PINT_SYS_IRQS; bank++) { | ||
515 | |||
516 | pint_assign = pint[bank]->assign; | ||
517 | |||
518 | for (bit = 0; bit < NR_PINT_BITS; bit++) { | ||
519 | |||
520 | bmap = (pint_assign >> ((bit / 8) * 8)) & 0xFF; | ||
521 | |||
522 | irq_base = get_irq_base(bank, bmap); | ||
523 | |||
524 | irq_base += (bit % 8) + ((bit / 8) & 1 ? 8 : 0); | ||
525 | bit_pos = bit + bank * NR_PINT_BITS; | ||
526 | |||
527 | pint2irq_lut[bit_pos] = irq_base - SYS_IRQS; | ||
528 | irq2pint_lut[irq_base - SYS_IRQS] = bit_pos; | ||
529 | |||
530 | } | ||
531 | |||
532 | } | ||
533 | |||
534 | } | ||
535 | |||
536 | static unsigned short gpio_enabled[gpio_bank(MAX_BLACKFIN_GPIOS)]; | ||
537 | |||
538 | static void bfin_gpio_ack_irq(unsigned int irq) | ||
539 | { | ||
540 | u8 pint_val = irq2pint_lut[irq - SYS_IRQS]; | ||
541 | |||
542 | pint[PINT_2_BANK(pint_val)]->request = PINT_BIT(pint_val); | ||
543 | SSYNC(); | ||
544 | } | ||
545 | |||
546 | static void bfin_gpio_mask_ack_irq(unsigned int irq) | ||
547 | { | ||
548 | u8 pint_val = irq2pint_lut[irq - SYS_IRQS]; | ||
549 | u32 pintbit = PINT_BIT(pint_val); | ||
550 | u8 bank = PINT_2_BANK(pint_val); | ||
551 | |||
552 | pint[bank]->request = pintbit; | ||
553 | pint[bank]->mask_clear = pintbit; | ||
554 | SSYNC(); | ||
555 | } | ||
556 | |||
557 | static void bfin_gpio_mask_irq(unsigned int irq) | ||
558 | { | ||
559 | u8 pint_val = irq2pint_lut[irq - SYS_IRQS]; | ||
560 | |||
561 | pint[PINT_2_BANK(pint_val)]->mask_clear = PINT_BIT(pint_val); | ||
562 | SSYNC(); | ||
563 | } | ||
564 | |||
565 | static void bfin_gpio_unmask_irq(unsigned int irq) | ||
566 | { | ||
567 | u8 pint_val = irq2pint_lut[irq - SYS_IRQS]; | ||
568 | u32 pintbit = PINT_BIT(pint_val); | ||
569 | u8 bank = PINT_2_BANK(pint_val); | ||
570 | |||
571 | pint[bank]->request = pintbit; | ||
572 | pint[bank]->mask_set = pintbit; | ||
573 | SSYNC(); | ||
574 | } | ||
575 | |||
576 | static unsigned int bfin_gpio_irq_startup(unsigned int irq) | ||
577 | { | ||
578 | unsigned int ret; | ||
579 | u16 gpionr = irq - IRQ_PA0; | ||
580 | u8 pint_val = irq2pint_lut[irq - SYS_IRQS]; | ||
581 | |||
582 | if (pint_val == IRQ_NOT_AVAIL) | ||
583 | return -ENODEV; | ||
584 | |||
585 | if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) { | ||
586 | ret = gpio_request(gpionr, NULL); | ||
587 | if (ret) | ||
588 | return ret; | ||
589 | } | ||
590 | |||
591 | gpio_enabled[gpio_bank(gpionr)] |= gpio_bit(gpionr); | ||
592 | bfin_gpio_unmask_irq(irq); | ||
593 | |||
594 | return ret; | ||
595 | } | ||
596 | |||
597 | static void bfin_gpio_irq_shutdown(unsigned int irq) | ||
598 | { | ||
599 | bfin_gpio_mask_irq(irq); | ||
600 | gpio_free(irq - IRQ_PA0); | ||
601 | gpio_enabled[gpio_bank(irq - IRQ_PA0)] &= ~gpio_bit(irq - IRQ_PA0); | ||
602 | } | ||
603 | |||
604 | static int bfin_gpio_irq_type(unsigned int irq, unsigned int type) | ||
605 | { | ||
606 | |||
607 | unsigned int ret; | ||
608 | u16 gpionr = irq - IRQ_PA0; | ||
609 | u8 pint_val = irq2pint_lut[irq - SYS_IRQS]; | ||
610 | u32 pintbit = PINT_BIT(pint_val); | ||
611 | u8 bank = PINT_2_BANK(pint_val); | ||
612 | |||
613 | if (pint_val == IRQ_NOT_AVAIL) | ||
614 | return -ENODEV; | ||
615 | |||
616 | if (type == IRQ_TYPE_PROBE) { | ||
617 | /* only probe unenabled GPIO interrupt lines */ | ||
618 | if (gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr)) | ||
619 | return 0; | ||
620 | type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING; | ||
621 | } | ||
622 | |||
623 | if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING | | ||
624 | IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) { | ||
625 | if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) { | ||
626 | ret = gpio_request(gpionr, NULL); | ||
627 | if (ret) | ||
628 | return ret; | ||
629 | } | ||
630 | |||
631 | gpio_enabled[gpio_bank(gpionr)] |= gpio_bit(gpionr); | ||
632 | } else { | ||
633 | gpio_enabled[gpio_bank(gpionr)] &= ~gpio_bit(gpionr); | ||
634 | return 0; | ||
635 | } | ||
636 | |||
637 | gpio_direction_input(gpionr); | ||
638 | |||
639 | if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) { | ||
640 | pint[bank]->edge_set = pintbit; | ||
641 | } else { | ||
642 | pint[bank]->edge_clear = pintbit; | ||
643 | } | ||
644 | |||
645 | if ((type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_LEVEL_LOW))) | ||
646 | pint[bank]->invert_set = pintbit; /* low or falling edge denoted by one */ | ||
647 | else | ||
648 | pint[bank]->invert_set = pintbit; /* high or rising edge denoted by zero */ | ||
649 | |||
650 | if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) | ||
651 | pint[bank]->invert_set = pintbit; | ||
652 | else | ||
653 | pint[bank]->invert_set = pintbit; | ||
654 | |||
655 | SSYNC(); | ||
656 | |||
657 | if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) | ||
658 | set_irq_handler(irq, handle_edge_irq); | ||
659 | else | ||
660 | set_irq_handler(irq, handle_level_irq); | ||
661 | |||
662 | return 0; | ||
663 | } | ||
664 | |||
665 | static struct irq_chip bfin_gpio_irqchip = { | ||
666 | .ack = bfin_gpio_ack_irq, | ||
667 | .mask = bfin_gpio_mask_irq, | ||
668 | .mask_ack = bfin_gpio_mask_ack_irq, | ||
669 | .unmask = bfin_gpio_unmask_irq, | ||
670 | .set_type = bfin_gpio_irq_type, | ||
671 | .startup = bfin_gpio_irq_startup, | ||
672 | .shutdown = bfin_gpio_irq_shutdown | ||
673 | }; | ||
674 | |||
675 | static void bfin_demux_gpio_irq(unsigned int intb_irq, | ||
676 | struct irq_desc *intb_desc) | ||
677 | { | ||
678 | u8 bank, pint_val; | ||
679 | u32 request, irq; | ||
680 | struct irq_desc *desc; | ||
681 | |||
682 | switch (intb_irq) { | ||
683 | case IRQ_PINT0: | ||
684 | bank = 0; | ||
685 | break; | ||
686 | case IRQ_PINT2: | ||
687 | bank = 2; | ||
688 | break; | ||
689 | case IRQ_PINT3: | ||
690 | bank = 3; | ||
691 | break; | ||
692 | case IRQ_PINT1: | ||
693 | bank = 1; | ||
694 | break; | ||
695 | default: | ||
696 | return; | ||
697 | } | ||
698 | |||
699 | pint_val = bank * NR_PINT_BITS; | ||
700 | |||
701 | request = pint[bank]->request; | ||
702 | |||
703 | while (request) { | ||
704 | if (request & 1) { | ||
705 | irq = pint2irq_lut[pint_val] + SYS_IRQS; | ||
706 | desc = irq_desc + irq; | ||
707 | desc->handle_irq(irq, desc); | ||
708 | } | ||
709 | pint_val++; | ||
710 | request >>= 1; | ||
711 | } | ||
712 | |||
713 | } | ||
444 | #endif /* CONFIG_IRQCHIP_DEMUX_GPIO */ | 714 | #endif /* CONFIG_IRQCHIP_DEMUX_GPIO */ |
445 | 715 | ||
446 | /* | 716 | /* |
@@ -452,7 +722,18 @@ int __init init_arch_irq(void) | |||
452 | int irq; | 722 | int irq; |
453 | unsigned long ilat = 0; | 723 | unsigned long ilat = 0; |
454 | /* Disable all the peripheral intrs - page 4-29 HW Ref manual */ | 724 | /* Disable all the peripheral intrs - page 4-29 HW Ref manual */ |
725 | #ifdef CONFIG_BF54x | ||
726 | bfin_write_SIC_IMASK0(SIC_UNMASK_ALL); | ||
727 | bfin_write_SIC_IMASK1(SIC_UNMASK_ALL); | ||
728 | bfin_write_SIC_IMASK2(SIC_UNMASK_ALL); | ||
729 | bfin_write_SIC_IWR0(IWR_ENABLE_ALL); | ||
730 | bfin_write_SIC_IWR1(IWR_ENABLE_ALL); | ||
731 | bfin_write_SIC_IWR2(IWR_ENABLE_ALL); | ||
732 | #else | ||
455 | bfin_write_SIC_IMASK(SIC_UNMASK_ALL); | 733 | bfin_write_SIC_IMASK(SIC_UNMASK_ALL); |
734 | bfin_write_SIC_IWR(IWR_ENABLE_ALL); | ||
735 | #endif | ||
736 | |||
456 | SSYNC(); | 737 | SSYNC(); |
457 | 738 | ||
458 | local_irq_disable(); | 739 | local_irq_disable(); |
@@ -475,7 +756,18 @@ int __init init_arch_irq(void) | |||
475 | bfin_write_EVT15(evt_system_call); | 756 | bfin_write_EVT15(evt_system_call); |
476 | CSYNC(); | 757 | CSYNC(); |
477 | 758 | ||
478 | for (irq = 0; irq < SYS_IRQS; irq++) { | 759 | #if defined(CONFIG_IRQCHIP_DEMUX_GPIO) && defined(CONFIG_BF54x) |
760 | #ifdef CONFIG_PINTx_REASSIGN | ||
761 | pint[0]->assign = CONFIG_PINT0_ASSIGN; | ||
762 | pint[1]->assign = CONFIG_PINT1_ASSIGN; | ||
763 | pint[2]->assign = CONFIG_PINT2_ASSIGN; | ||
764 | pint[3]->assign = CONFIG_PINT3_ASSIGN; | ||
765 | #endif | ||
766 | /* Whenever PINTx_ASSIGN is altered init_pint_lut() must be executed! */ | ||
767 | init_pint_lut(); | ||
768 | #endif | ||
769 | |||
770 | for (irq = 0; irq <= SYS_IRQS; irq++) { | ||
479 | if (irq <= IRQ_CORETMR) | 771 | if (irq <= IRQ_CORETMR) |
480 | set_irq_chip(irq, &bfin_core_irqchip); | 772 | set_irq_chip(irq, &bfin_core_irqchip); |
481 | else | 773 | else |
@@ -484,20 +776,42 @@ int __init init_arch_irq(void) | |||
484 | if (irq != IRQ_GENERIC_ERROR) { | 776 | if (irq != IRQ_GENERIC_ERROR) { |
485 | #endif | 777 | #endif |
486 | 778 | ||
779 | switch (irq) { | ||
487 | #ifdef CONFIG_IRQCHIP_DEMUX_GPIO | 780 | #ifdef CONFIG_IRQCHIP_DEMUX_GPIO |
488 | if ((irq != IRQ_PROG_INTA) /*PORT F & G MASK_A Interrupt*/ | 781 | #ifndef CONFIG_BF54x |
489 | # if defined(BF537_FAMILY) && !(defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)) | 782 | case IRQ_PROG_INTA: |
490 | && (irq != IRQ_MAC_RX) /*PORT H MASK_A Interrupt*/ | 783 | set_irq_chained_handler(irq, |
491 | # endif | 784 | bfin_demux_gpio_irq); |
492 | ) { | 785 | break; |
786 | #if defined(BF537_FAMILY) && !(defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)) | ||
787 | case IRQ_MAC_RX: | ||
788 | set_irq_chained_handler(irq, | ||
789 | bfin_demux_gpio_irq); | ||
790 | break; | ||
493 | #endif | 791 | #endif |
494 | set_irq_handler(irq, handle_simple_irq); | 792 | #else |
495 | #ifdef CONFIG_IRQCHIP_DEMUX_GPIO | 793 | case IRQ_PINT0: |
496 | } else { | ||
497 | set_irq_chained_handler(irq, | 794 | set_irq_chained_handler(irq, |
498 | bfin_demux_gpio_irq); | 795 | bfin_demux_gpio_irq); |
499 | } | 796 | break; |
797 | case IRQ_PINT1: | ||
798 | set_irq_chained_handler(irq, | ||
799 | bfin_demux_gpio_irq); | ||
800 | break; | ||
801 | case IRQ_PINT2: | ||
802 | set_irq_chained_handler(irq, | ||
803 | bfin_demux_gpio_irq); | ||
804 | break; | ||
805 | case IRQ_PINT3: | ||
806 | set_irq_chained_handler(irq, | ||
807 | bfin_demux_gpio_irq); | ||
808 | break; | ||
809 | #endif /*CONFIG_BF54x */ | ||
500 | #endif | 810 | #endif |
811 | default: | ||
812 | set_irq_handler(irq, handle_simple_irq); | ||
813 | break; | ||
814 | } | ||
501 | 815 | ||
502 | #ifdef BF537_GENERIC_ERROR_INT_DEMUX | 816 | #ifdef BF537_GENERIC_ERROR_INT_DEMUX |
503 | } else { | 817 | } else { |
@@ -513,7 +827,11 @@ int __init init_arch_irq(void) | |||
513 | #endif | 827 | #endif |
514 | 828 | ||
515 | #ifdef CONFIG_IRQCHIP_DEMUX_GPIO | 829 | #ifdef CONFIG_IRQCHIP_DEMUX_GPIO |
830 | #ifndef CONFIG_BF54x | ||
516 | for (irq = IRQ_PF0; irq < NR_IRQS; irq++) { | 831 | for (irq = IRQ_PF0; irq < NR_IRQS; irq++) { |
832 | #else | ||
833 | for (irq = IRQ_PA0; irq < NR_IRQS; irq++) { | ||
834 | #endif | ||
517 | set_irq_chip(irq, &bfin_gpio_irqchip); | 835 | set_irq_chip(irq, &bfin_gpio_irqchip); |
518 | /* if configured as edge, then will be changed to do_edge_IRQ */ | 836 | /* if configured as edge, then will be changed to do_edge_IRQ */ |
519 | set_irq_handler(irq, handle_level_irq); | 837 | set_irq_handler(irq, handle_level_irq); |
@@ -526,8 +844,7 @@ int __init init_arch_irq(void) | |||
526 | bfin_write_ILAT(ilat); | 844 | bfin_write_ILAT(ilat); |
527 | CSYNC(); | 845 | CSYNC(); |
528 | 846 | ||
529 | printk(KERN_INFO | 847 | printk(KERN_INFO "Configuring Blackfin Priority Driven Interrupts\n"); |
530 | "Configuring Blackfin Priority Driven Interrupts\n"); | ||
531 | /* IMASK=xxx is equivalent to STI xx or irq_flags=xx, | 848 | /* IMASK=xxx is equivalent to STI xx or irq_flags=xx, |
532 | * local_irq_enable() | 849 | * local_irq_enable() |
533 | */ | 850 | */ |
@@ -538,14 +855,13 @@ int __init init_arch_irq(void) | |||
538 | /* Enable interrupts IVG7-15 */ | 855 | /* Enable interrupts IVG7-15 */ |
539 | irq_flags = irq_flags | IMASK_IVG15 | | 856 | irq_flags = irq_flags | IMASK_IVG15 | |
540 | IMASK_IVG14 | IMASK_IVG13 | IMASK_IVG12 | IMASK_IVG11 | | 857 | IMASK_IVG14 | IMASK_IVG13 | IMASK_IVG12 | IMASK_IVG11 | |
541 | IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 | | 858 | IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 | IMASK_IVGHW; |
542 | IMASK_IVGHW; | ||
543 | 859 | ||
544 | return 0; | 860 | return 0; |
545 | } | 861 | } |
546 | 862 | ||
547 | #ifdef CONFIG_DO_IRQ_L1 | 863 | #ifdef CONFIG_DO_IRQ_L1 |
548 | void do_irq(int vec, struct pt_regs *fp)__attribute__((l1_text)); | 864 | void do_irq(int vec, struct pt_regs *fp) __attribute__((l1_text)); |
549 | #endif | 865 | #endif |
550 | 866 | ||
551 | void do_irq(int vec, struct pt_regs *fp) | 867 | void do_irq(int vec, struct pt_regs *fp) |
@@ -555,9 +871,25 @@ void do_irq(int vec, struct pt_regs *fp) | |||
555 | } else { | 871 | } else { |
556 | struct ivgx *ivg = ivg7_13[vec - IVG7].ifirst; | 872 | struct ivgx *ivg = ivg7_13[vec - IVG7].ifirst; |
557 | struct ivgx *ivg_stop = ivg7_13[vec - IVG7].istop; | 873 | struct ivgx *ivg_stop = ivg7_13[vec - IVG7].istop; |
558 | unsigned long sic_status; | 874 | #ifdef CONFIG_BF54x |
875 | unsigned long sic_status[3]; | ||
559 | 876 | ||
560 | SSYNC(); | 877 | SSYNC(); |
878 | sic_status[0] = bfin_read_SIC_ISR(0) & bfin_read_SIC_IMASK(0); | ||
879 | sic_status[1] = bfin_read_SIC_ISR(1) & bfin_read_SIC_IMASK(1); | ||
880 | sic_status[2] = bfin_read_SIC_ISR(2) & bfin_read_SIC_IMASK(2); | ||
881 | |||
882 | for (;; ivg++) { | ||
883 | if (ivg >= ivg_stop) { | ||
884 | atomic_inc(&num_spurious); | ||
885 | return; | ||
886 | } | ||
887 | if (sic_status[(ivg->irqno - IVG7) / 32] & ivg->isrflag) | ||
888 | break; | ||
889 | } | ||
890 | #else | ||
891 | unsigned long sic_status; | ||
892 | SSYNC(); | ||
561 | sic_status = bfin_read_SIC_IMASK() & bfin_read_SIC_ISR(); | 893 | sic_status = bfin_read_SIC_IMASK() & bfin_read_SIC_ISR(); |
562 | 894 | ||
563 | for (;; ivg++) { | 895 | for (;; ivg++) { |
@@ -567,6 +899,7 @@ void do_irq(int vec, struct pt_regs *fp) | |||
567 | } else if (sic_status & ivg->isrflag) | 899 | } else if (sic_status & ivg->isrflag) |
568 | break; | 900 | break; |
569 | } | 901 | } |
902 | #endif | ||
570 | vec = ivg->irqno; | 903 | vec = ivg->irqno; |
571 | } | 904 | } |
572 | asm_do_IRQ(vec, fp); | 905 | asm_do_IRQ(vec, fp); |