aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/mach-common/ints-priority-sc.c
diff options
context:
space:
mode:
authorMichael Hennerich <michael.hennerich@analog.com>2007-07-12 04:17:18 -0400
committerBryan Wu <bryan.wu@analog.com>2007-07-12 04:17:18 -0400
commit34e0fc89bdc1e6f50032dc43ed23167f5dbad6da (patch)
treeb76cb79b0e2b7254b0942de510c1ce459df83567 /arch/blackfin/mach-common/ints-priority-sc.c
parent1f83b8f148a1eb967d2a628cbb741cd56fb54572 (diff)
Blackfin arch: Enable BF54x PIN/GPIO interrupts
Signed-off-bu: Michael Hennerich <michael.hennerich@analog.com> Signed-off-by: Bryan Wu <bryan.wu@analog.com>
Diffstat (limited to 'arch/blackfin/mach-common/ints-priority-sc.c')
-rw-r--r--arch/blackfin/mach-common/ints-priority-sc.c339
1 files changed, 309 insertions, 30 deletions
diff --git a/arch/blackfin/mach-common/ints-priority-sc.c b/arch/blackfin/mach-common/ints-priority-sc.c
index 9f962f9df087..09373c94a436 100644
--- a/arch/blackfin/mach-common/ints-priority-sc.c
+++ b/arch/blackfin/mach-common/ints-priority-sc.c
@@ -88,14 +88,13 @@ 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 % 32); 100 ivg_table[irq_pos].isrflag = 1 << (irqn % 32);
@@ -222,7 +221,7 @@ static struct irq_chip bfin_generic_error_irqchip = {
222}; 221};
223 222
224static void bfin_demux_error_irq(unsigned int int_err_irq, 223static void bfin_demux_error_irq(unsigned int int_err_irq,
225 struct irq_desc *intb_desc) 224 struct irq_desc *intb_desc)
226{ 225{
227 int irq = 0; 226 int irq = 0;
228 227
@@ -286,8 +285,8 @@ static void bfin_demux_error_irq(unsigned int int_err_irq,
286 } 285 }
287 286
288 pr_debug("IRQ %d:" 287 pr_debug("IRQ %d:"
289 " MASKED PERIPHERAL ERROR INTERRUPT ASSERTED\n", 288 " MASKED PERIPHERAL ERROR INTERRUPT ASSERTED\n",
290 irq); 289 irq);
291 } 290 }
292 } else 291 } else
293 printk(KERN_ERR 292 printk(KERN_ERR
@@ -295,11 +294,10 @@ static void bfin_demux_error_irq(unsigned int int_err_irq,
295 " INTERRUPT ASSERTED BUT NO SOURCE FOUND\n", 294 " INTERRUPT ASSERTED BUT NO SOURCE FOUND\n",
296 __FUNCTION__, __FILE__, __LINE__); 295 __FUNCTION__, __FILE__, __LINE__);
297 296
298
299} 297}
300#endif /* BF537_GENERIC_ERROR_INT_DEMUX */ 298#endif /* BF537_GENERIC_ERROR_INT_DEMUX */
301 299
302#ifdef CONFIG_IRQCHIP_DEMUX_GPIO 300#if defined(CONFIG_IRQCHIP_DEMUX_GPIO) && !defined(CONFIG_BF54x)
303 301
304static unsigned short gpio_enabled[gpio_bank(MAX_BLACKFIN_GPIOS)]; 302static unsigned short gpio_enabled[gpio_bank(MAX_BLACKFIN_GPIOS)];
305static unsigned short gpio_edge_triggered[gpio_bank(MAX_BLACKFIN_GPIOS)]; 303static unsigned short gpio_edge_triggered[gpio_bank(MAX_BLACKFIN_GPIOS)];
@@ -377,8 +375,7 @@ static int bfin_gpio_irq_type(unsigned int irq, unsigned int type)
377 } 375 }
378 376
379 if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING | 377 if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING |
380 IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) 378 IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) {
381 {
382 if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) { 379 if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) {
383 ret = gpio_request(gpionr, NULL); 380 ret = gpio_request(gpionr, NULL);
384 if (ret) 381 if (ret)
@@ -423,7 +420,6 @@ static int bfin_gpio_irq_type(unsigned int irq, unsigned int type)
423 return 0; 420 return 0;
424} 421}
425 422
426
427static struct irq_chip bfin_gpio_irqchip = { 423static struct irq_chip bfin_gpio_irqchip = {
428 .ack = bfin_gpio_ack_irq, 424 .ack = bfin_gpio_ack_irq,
429 .mask = bfin_gpio_mask_irq, 425 .mask = bfin_gpio_mask_irq,
@@ -435,7 +431,7 @@ static struct irq_chip bfin_gpio_irqchip = {
435}; 431};
436 432
437static void bfin_demux_gpio_irq(unsigned int intb_irq, 433static void bfin_demux_gpio_irq(unsigned int intb_irq,
438 struct irq_desc *intb_desc) 434 struct irq_desc *intb_desc)
439{ 435{
440 u16 i; 436 u16 i;
441 437
@@ -443,8 +439,7 @@ static void bfin_demux_gpio_irq(unsigned int intb_irq,
443 int irq = IRQ_PF0 + i; 439 int irq = IRQ_PF0 + i;
444 int flag_d = get_gpiop_data(i); 440 int flag_d = get_gpiop_data(i);
445 int mask = 441 int mask =
446 flag_d & (gpio_enabled[gpio_bank(i)] & 442 flag_d & (gpio_enabled[gpio_bank(i)] & get_gpiop_maska(i));
447 get_gpiop_maska(i));
448 443
449 while (mask) { 444 while (mask) {
450 if (mask & 1) { 445 if (mask & 1) {
@@ -457,6 +452,255 @@ static void bfin_demux_gpio_irq(unsigned int intb_irq,
457 } 452 }
458} 453}
459 454
455#else /* CONFIG_IRQCHIP_DEMUX_GPIO */
456
457#define NR_PINT_SYS_IRQS 4
458#define NR_PINT_BITS 32
459#define NR_PINTS 160
460#define IRQ_NOT_AVAIL 0xFF
461
462#define PINT_2_BANK(x) ((x) >> 5)
463#define PINT_2_BIT(x) ((x) & 0x1F)
464#define PINT_BIT(x) (1 << (PINT_2_BIT(x)))
465
466static unsigned char irq2pint_lut[NR_PINTS];
467static unsigned short pint2irq_lut[NR_PINT_SYS_IRQS * NR_PINT_BITS];
468
469struct pin_int_t {
470 unsigned int mask_set;
471 unsigned int mask_clear;
472 unsigned int request;
473 unsigned int assign;
474 unsigned int edge_set;
475 unsigned int edge_clear;
476 unsigned int invert_set;
477 unsigned int invert_clear;
478 unsigned int pinstate;
479 unsigned int latch;
480};
481
482static struct pin_int_t *pint[NR_PINT_SYS_IRQS] = {
483 (struct pin_int_t *)PINT0_MASK_SET,
484 (struct pin_int_t *)PINT1_MASK_SET,
485 (struct pin_int_t *)PINT2_MASK_SET,
486 (struct pin_int_t *)PINT3_MASK_SET,
487};
488
489unsigned short get_irq_base(u8 bank, u8 bmap)
490{
491
492 u16 irq_base;
493
494 if (bank < 2) { /*PA-PB */
495 irq_base = IRQ_PA0 + bmap * 16;
496 } else { /*PC-PJ */
497 irq_base = IRQ_PC0 + bmap * 16;
498 }
499
500 return irq_base;
501
502}
503
504 /* Whenever PINTx_ASSIGN is altered init_pint_lut() must be executed! */
505void init_pint_lut(void)
506{
507 u16 bank, bit, irq_base, bit_pos;
508 u32 pint_assign;
509 u8 bmap;
510
511 memset(irq2pint_lut, IRQ_NOT_AVAIL, sizeof(irq2pint_lut));
512
513 for (bank = 0; bank < NR_PINT_SYS_IRQS; bank++) {
514
515 pint_assign = pint[bank]->assign;
516
517 for (bit = 0; bit < NR_PINT_BITS; bit++) {
518
519 bmap = (pint_assign >> ((bit / 8) * 8)) & 0xFF;
520
521 irq_base = get_irq_base(bank, bmap);
522
523 irq_base += (bit % 8) + ((bit / 8) & 1 ? 8 : 0);
524 bit_pos = bit + bank * NR_PINT_BITS;
525
526 pint2irq_lut[bit_pos] = irq_base;
527 irq2pint_lut[irq_base - SYS_IRQS] = bit_pos;
528
529 }
530
531 }
532
533}
534
535static unsigned short gpio_enabled[gpio_bank(MAX_BLACKFIN_GPIOS)];
536
537static void bfin_gpio_ack_irq(unsigned int irq)
538{
539 u8 pint_val = irq2pint_lut[irq - SYS_IRQS];
540
541 pint[PINT_2_BANK(pint_val)]->request = PINT_BIT(pint_val);
542 SSYNC();
543}
544
545static void bfin_gpio_mask_ack_irq(unsigned int irq)
546{
547 u8 pint_val = irq2pint_lut[irq - SYS_IRQS];
548
549 pint[PINT_2_BANK(pint_val)]->request = PINT_BIT(pint_val);
550 pint[PINT_2_BANK(pint_val)]->mask_clear = PINT_BIT(pint_val);
551 SSYNC();
552}
553
554static void bfin_gpio_mask_irq(unsigned int irq)
555{
556 u8 pint_val = irq2pint_lut[irq - SYS_IRQS];
557
558 pint[PINT_2_BANK(pint_val)]->mask_clear = PINT_BIT(pint_val);
559 SSYNC();
560}
561
562static void bfin_gpio_unmask_irq(unsigned int irq)
563{
564 u8 pint_val = irq2pint_lut[irq - SYS_IRQS];
565
566 pint[PINT_2_BANK(pint_val)]->request = PINT_BIT(pint_val);
567 pint[PINT_2_BANK(pint_val)]->mask_set = PINT_BIT(pint_val);
568 SSYNC();
569}
570
571static unsigned int bfin_gpio_irq_startup(unsigned int irq)
572{
573 unsigned int ret;
574 u16 gpionr = irq - IRQ_PA0;
575 u8 pint_val = irq2pint_lut[irq - SYS_IRQS];
576
577 if (pint_val == IRQ_NOT_AVAIL)
578 return -ENODEV;
579
580 if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) {
581 ret = gpio_request(gpionr, NULL);
582 if (ret)
583 return ret;
584 }
585
586 gpio_enabled[gpio_bank(gpionr)] |= gpio_bit(gpionr);
587 bfin_gpio_unmask_irq(irq);
588
589 return ret;
590}
591
592static void bfin_gpio_irq_shutdown(unsigned int irq)
593{
594 bfin_gpio_mask_irq(irq);
595 gpio_free(irq - IRQ_PA0);
596 gpio_enabled[gpio_bank(irq - IRQ_PA0)] &= ~gpio_bit(irq - IRQ_PA0);
597}
598
599static int bfin_gpio_irq_type(unsigned int irq, unsigned int type)
600{
601
602 unsigned int ret;
603 u16 gpionr = irq - IRQ_PA0;
604 u8 pint_val = irq2pint_lut[irq - SYS_IRQS];
605
606 if (pint_val == IRQ_NOT_AVAIL)
607 return -ENODEV;
608
609 if (type == IRQ_TYPE_PROBE) {
610 /* only probe unenabled GPIO interrupt lines */
611 if (gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))
612 return 0;
613 type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
614 }
615
616 if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING |
617 IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) {
618 if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) {
619 ret = gpio_request(gpionr, NULL);
620 if (ret)
621 return ret;
622 }
623
624 gpio_enabled[gpio_bank(gpionr)] |= gpio_bit(gpionr);
625 } else {
626 gpio_enabled[gpio_bank(gpionr)] &= ~gpio_bit(gpionr);
627 return 0;
628 }
629
630 gpio_direction_input(gpionr);
631
632 if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) {
633 pint[PINT_2_BANK(pint_val)]->edge_set = PINT_BIT(pint_val);
634 } else {
635 pint[PINT_2_BANK(pint_val)]->edge_clear = PINT_BIT(pint_val);
636 }
637
638 if ((type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_LEVEL_LOW)))
639 pint[PINT_2_BANK(pint_val)]->invert_set = PINT_BIT(pint_val); /* low or falling edge denoted by one */
640 else
641 pint[PINT_2_BANK(pint_val)]->invert_set = PINT_BIT(pint_val); /* high or rising edge denoted by zero */
642
643 if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))
644 pint[PINT_2_BANK(pint_val)]->invert_set = PINT_BIT(pint_val);
645 else
646 pint[PINT_2_BANK(pint_val)]->invert_set = PINT_BIT(pint_val);
647
648 SSYNC();
649
650 if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))
651 set_irq_handler(irq, handle_edge_irq);
652 else
653 set_irq_handler(irq, handle_level_irq);
654
655 return 0;
656}
657
658static struct irq_chip bfin_gpio_irqchip = {
659 .ack = bfin_gpio_ack_irq,
660 .mask = bfin_gpio_mask_irq,
661 .mask_ack = bfin_gpio_mask_ack_irq,
662 .unmask = bfin_gpio_unmask_irq,
663 .set_type = bfin_gpio_irq_type,
664 .startup = bfin_gpio_irq_startup,
665 .shutdown = bfin_gpio_irq_shutdown
666};
667
668static void bfin_demux_gpio_irq(unsigned int intb_irq,
669 struct irq_desc *intb_desc)
670{
671 u8 bank, pint_val;
672 u32 request, irq;
673
674 switch (intb_irq) {
675 case IRQ_PINT0:
676 bank = 0;
677 break;
678 case IRQ_PINT2:
679 bank = 2;
680 break;
681 case IRQ_PINT3:
682 bank = 3;
683 break;
684 case IRQ_PINT1:
685 bank = 1;
686 break;
687 }
688
689 pint_val = bank * NR_PINT_BITS;
690
691 request = pint[bank]->request;
692
693 while (request) {
694 if (request & 1) {
695 irq = pint2irq_lut[pint_val];
696 struct irq_desc *desc = irq_desc + irq;
697 desc->handle_irq(irq, desc);
698 }
699 pint_val++;
700 request >>= 1;
701 }
702
703}
460#endif /* CONFIG_IRQCHIP_DEMUX_GPIO */ 704#endif /* CONFIG_IRQCHIP_DEMUX_GPIO */
461 705
462/* 706/*
@@ -502,7 +746,18 @@ int __init init_arch_irq(void)
502 bfin_write_EVT15(evt_system_call); 746 bfin_write_EVT15(evt_system_call);
503 CSYNC(); 747 CSYNC();
504 748
505 for (irq = 0; irq < SYS_IRQS; irq++) { 749#if defined(CONFIG_IRQCHIP_DEMUX_GPIO) && defined(CONFIG_BF54x)
750#ifdef CONFIG_PINTx_REASSIGN
751 pint[0]->assign = CONFIG_PINT0_ASSIGN;
752 pint[1]->assign = CONFIG_PINT1_ASSIGN;
753 pint[2]->assign = CONFIG_PINT2_ASSIGN;
754 pint[3]->assign = CONFIG_PINT3_ASSIGN;
755#endif
756 /* Whenever PINTx_ASSIGN is altered init_pint_lut() must be executed! */
757 init_pint_lut();
758#endif
759
760 for (irq = 0; irq <= SYS_IRQS; irq++) {
506 if (irq <= IRQ_CORETMR) 761 if (irq <= IRQ_CORETMR)
507 set_irq_chip(irq, &bfin_core_irqchip); 762 set_irq_chip(irq, &bfin_core_irqchip);
508 else 763 else
@@ -511,20 +766,42 @@ int __init init_arch_irq(void)
511 if (irq != IRQ_GENERIC_ERROR) { 766 if (irq != IRQ_GENERIC_ERROR) {
512#endif 767#endif
513 768
769 switch (irq) {
514#ifdef CONFIG_IRQCHIP_DEMUX_GPIO 770#ifdef CONFIG_IRQCHIP_DEMUX_GPIO
515 if ((irq != IRQ_PROG_INTA) /*PORT F & G MASK_A Interrupt*/ 771#ifndef CONFIG_BF54x
516# if defined(BF537_FAMILY) && !(defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)) 772 case IRQ_PROG_INTA:
517 && (irq != IRQ_MAC_RX) /*PORT H MASK_A Interrupt*/ 773 set_irq_chained_handler(irq,
518# endif 774 bfin_demux_gpio_irq);
519 ) { 775 break;
776#if defined(BF537_FAMILY) && !(defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE))
777 case IRQ_MAC_RX:
778 set_irq_chained_handler(irq,
779 bfin_demux_gpio_irq);
780 break;
520#endif 781#endif
521 set_irq_handler(irq, handle_simple_irq); 782#else
522#ifdef CONFIG_IRQCHIP_DEMUX_GPIO 783 case IRQ_PINT0:
523 } else {
524 set_irq_chained_handler(irq, 784 set_irq_chained_handler(irq,
525 bfin_demux_gpio_irq); 785 bfin_demux_gpio_irq);
526 } 786 break;
787 case IRQ_PINT1:
788 set_irq_chained_handler(irq,
789 bfin_demux_gpio_irq);
790 break;
791 case IRQ_PINT2:
792 set_irq_chained_handler(irq,
793 bfin_demux_gpio_irq);
794 break;
795 case IRQ_PINT3:
796 set_irq_chained_handler(irq,
797 bfin_demux_gpio_irq);
798 break;
799#endif /*CONFIG_BF54x */
527#endif 800#endif
801 default:
802 set_irq_handler(irq, handle_simple_irq);
803 break;
804 }
528 805
529#ifdef BF537_GENERIC_ERROR_INT_DEMUX 806#ifdef BF537_GENERIC_ERROR_INT_DEMUX
530 } else { 807 } else {
@@ -540,7 +817,11 @@ int __init init_arch_irq(void)
540#endif 817#endif
541 818
542#ifdef CONFIG_IRQCHIP_DEMUX_GPIO 819#ifdef CONFIG_IRQCHIP_DEMUX_GPIO
820#ifndef CONFIG_BF54x
543 for (irq = IRQ_PF0; irq < NR_IRQS; irq++) { 821 for (irq = IRQ_PF0; irq < NR_IRQS; irq++) {
822#else
823 for (irq = IRQ_PA0; irq < NR_IRQS; irq++) {
824#endif
544 set_irq_chip(irq, &bfin_gpio_irqchip); 825 set_irq_chip(irq, &bfin_gpio_irqchip);
545 /* if configured as edge, then will be changed to do_edge_IRQ */ 826 /* if configured as edge, then will be changed to do_edge_IRQ */
546 set_irq_handler(irq, handle_level_irq); 827 set_irq_handler(irq, handle_level_irq);
@@ -553,8 +834,7 @@ int __init init_arch_irq(void)
553 bfin_write_ILAT(ilat); 834 bfin_write_ILAT(ilat);
554 CSYNC(); 835 CSYNC();
555 836
556 printk(KERN_INFO 837 printk(KERN_INFO "Configuring Blackfin Priority Driven Interrupts\n");
557 "Configuring Blackfin Priority Driven Interrupts\n");
558 /* IMASK=xxx is equivalent to STI xx or irq_flags=xx, 838 /* IMASK=xxx is equivalent to STI xx or irq_flags=xx,
559 * local_irq_enable() 839 * local_irq_enable()
560 */ 840 */
@@ -565,14 +845,13 @@ int __init init_arch_irq(void)
565 /* Enable interrupts IVG7-15 */ 845 /* Enable interrupts IVG7-15 */
566 irq_flags = irq_flags | IMASK_IVG15 | 846 irq_flags = irq_flags | IMASK_IVG15 |
567 IMASK_IVG14 | IMASK_IVG13 | IMASK_IVG12 | IMASK_IVG11 | 847 IMASK_IVG14 | IMASK_IVG13 | IMASK_IVG12 | IMASK_IVG11 |
568 IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 | 848 IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 | IMASK_IVGHW;
569 IMASK_IVGHW;
570 849
571 return 0; 850 return 0;
572} 851}
573 852
574#ifdef CONFIG_DO_IRQ_L1 853#ifdef CONFIG_DO_IRQ_L1
575void do_irq(int vec, struct pt_regs *fp)__attribute__((l1_text)); 854void do_irq(int vec, struct pt_regs *fp) __attribute__((l1_text));
576#endif 855#endif
577 856
578void do_irq(int vec, struct pt_regs *fp) 857void do_irq(int vec, struct pt_regs *fp)
@@ -595,7 +874,7 @@ void do_irq(int vec, struct pt_regs *fp)
595 atomic_inc(&num_spurious); 874 atomic_inc(&num_spurious);
596 return; 875 return;
597 } 876 }
598 if (sic_status[(ivg->irqno - IVG7)/32] & ivg->isrflag) 877 if (sic_status[(ivg->irqno - IVG7) / 32] & ivg->isrflag)
599 break; 878 break;
600 } 879 }
601#else 880#else