aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/mach-common
diff options
context:
space:
mode:
authorMichael Hennerich <michael.hennerich@analog.com>2007-12-24 05:51:34 -0500
committerBryan Wu <bryan.wu@analog.com>2007-12-24 05:51:34 -0500
commit8baf560b4c901fb554d15e056aaa7f34b2345be5 (patch)
tree2a0da7e0777c0ffc68657c894cd9bc9d9e0846ce /arch/blackfin/mach-common
parent471b9a6c7304d5f59503d111e71e60a7e19fb9a0 (diff)
[Blackfin] arch: Enable both edge triggered GPIO IRQs on BF54x and use irq_to_gpio()
Signed-off-by: Michael Hennerich <michael.hennerich@analog.com> Signed-off-by: Bryan Wu <bryan.wu@analog.com>
Diffstat (limited to 'arch/blackfin/mach-common')
-rw-r--r--arch/blackfin/mach-common/ints-priority-sc.c67
1 files changed, 46 insertions, 21 deletions
diff --git a/arch/blackfin/mach-common/ints-priority-sc.c b/arch/blackfin/mach-common/ints-priority-sc.c
index 36ef4d17dd35..dec42acb5de0 100644
--- a/arch/blackfin/mach-common/ints-priority-sc.c
+++ b/arch/blackfin/mach-common/ints-priority-sc.c
@@ -483,6 +483,10 @@ static void bfin_demux_gpio_irq(unsigned int intb_irq,
483static unsigned char irq2pint_lut[NR_PINTS]; 483static unsigned char irq2pint_lut[NR_PINTS];
484static unsigned char pint2irq_lut[NR_PINT_SYS_IRQS * NR_PINT_BITS]; 484static unsigned char pint2irq_lut[NR_PINT_SYS_IRQS * NR_PINT_BITS];
485 485
486static unsigned int gpio_both_edge_triggered[NR_PINT_SYS_IRQS];
487static unsigned short gpio_enabled[gpio_bank(MAX_BLACKFIN_GPIOS)];
488
489
486struct pin_int_t { 490struct pin_int_t {
487 unsigned int mask_set; 491 unsigned int mask_set;
488 unsigned int mask_clear; 492 unsigned int mask_clear;
@@ -549,13 +553,20 @@ void init_pint_lut(void)
549 553
550} 554}
551 555
552static unsigned short gpio_enabled[gpio_bank(MAX_BLACKFIN_GPIOS)];
553
554static void bfin_gpio_ack_irq(unsigned int irq) 556static void bfin_gpio_ack_irq(unsigned int irq)
555{ 557{
556 u8 pint_val = irq2pint_lut[irq - SYS_IRQS]; 558 u8 pint_val = irq2pint_lut[irq - SYS_IRQS];
559 u32 pintbit = PINT_BIT(pint_val);
560 u8 bank = PINT_2_BANK(pint_val);
561
562 if (unlikely(gpio_both_edge_triggered[bank] & pintbit)) {
563 if (pint[bank]->invert_set & pintbit)
564 pint[bank]->invert_clear = pintbit;
565 else
566 pint[bank]->invert_set = pintbit;
567 }
568 pint[bank]->request = pintbit;
557 569
558 pint[PINT_2_BANK(pint_val)]->request = PINT_BIT(pint_val);
559 SSYNC(); 570 SSYNC();
560} 571}
561 572
@@ -565,6 +576,13 @@ static void bfin_gpio_mask_ack_irq(unsigned int irq)
565 u32 pintbit = PINT_BIT(pint_val); 576 u32 pintbit = PINT_BIT(pint_val);
566 u8 bank = PINT_2_BANK(pint_val); 577 u8 bank = PINT_2_BANK(pint_val);
567 578
579 if (unlikely(gpio_both_edge_triggered[bank] & pintbit)) {
580 if (pint[bank]->invert_set & pintbit)
581 pint[bank]->invert_clear = pintbit;
582 else
583 pint[bank]->invert_set = pintbit;
584 }
585
568 pint[bank]->request = pintbit; 586 pint[bank]->request = pintbit;
569 pint[bank]->mask_clear = pintbit; 587 pint[bank]->mask_clear = pintbit;
570 SSYNC(); 588 SSYNC();
@@ -593,7 +611,7 @@ static unsigned int bfin_gpio_irq_startup(unsigned int irq)
593{ 611{
594 unsigned int ret; 612 unsigned int ret;
595 char buf[8]; 613 char buf[8];
596 u16 gpionr = irq - IRQ_PA0; 614 u16 gpionr = irq_to_gpio(irq);
597 u8 pint_val = irq2pint_lut[irq - SYS_IRQS]; 615 u8 pint_val = irq2pint_lut[irq - SYS_IRQS];
598 616
599 if (pint_val == IRQ_NOT_AVAIL) { 617 if (pint_val == IRQ_NOT_AVAIL) {
@@ -618,9 +636,11 @@ static unsigned int bfin_gpio_irq_startup(unsigned int irq)
618 636
619static void bfin_gpio_irq_shutdown(unsigned int irq) 637static void bfin_gpio_irq_shutdown(unsigned int irq)
620{ 638{
639 u16 gpionr = irq_to_gpio(irq);
640
621 bfin_gpio_mask_irq(irq); 641 bfin_gpio_mask_irq(irq);
622 gpio_free(irq - IRQ_PA0); 642 gpio_free(gpionr);
623 gpio_enabled[gpio_bank(irq - IRQ_PA0)] &= ~gpio_bit(irq - IRQ_PA0); 643 gpio_enabled[gpio_bank(gpionr)] &= ~gpio_bit(gpionr);
624} 644}
625 645
626static int bfin_gpio_irq_type(unsigned int irq, unsigned int type) 646static int bfin_gpio_irq_type(unsigned int irq, unsigned int type)
@@ -628,7 +648,7 @@ static int bfin_gpio_irq_type(unsigned int irq, unsigned int type)
628 648
629 unsigned int ret; 649 unsigned int ret;
630 char buf[8]; 650 char buf[8];
631 u16 gpionr = irq - IRQ_PA0; 651 u16 gpionr = irq_to_gpio(irq);
632 u8 pint_val = irq2pint_lut[irq - SYS_IRQS]; 652 u8 pint_val = irq2pint_lut[irq - SYS_IRQS];
633 u32 pintbit = PINT_BIT(pint_val); 653 u32 pintbit = PINT_BIT(pint_val);
634 u8 bank = PINT_2_BANK(pint_val); 654 u8 bank = PINT_2_BANK(pint_val);
@@ -660,28 +680,33 @@ static int bfin_gpio_irq_type(unsigned int irq, unsigned int type)
660 680
661 gpio_direction_input(gpionr); 681 gpio_direction_input(gpionr);
662 682
663 if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) {
664 pint[bank]->edge_set = pintbit;
665 } else {
666 pint[bank]->edge_clear = pintbit;
667 }
668
669 if ((type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_LEVEL_LOW))) 683 if ((type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_LEVEL_LOW)))
670 pint[bank]->invert_set = pintbit; /* low or falling edge denoted by one */ 684 pint[bank]->invert_set = pintbit; /* low or falling edge denoted by one */
671 else 685 else
672 pint[bank]->invert_set = pintbit; /* high or rising edge denoted by zero */ 686 pint[bank]->invert_clear = pintbit; /* high or rising edge denoted by zero */
673 687
674 if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) 688 if ((type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))
675 pint[bank]->invert_set = pintbit; 689 == (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) {
676 else
677 pint[bank]->invert_set = pintbit;
678 690
679 SSYNC(); 691 gpio_both_edge_triggered[bank] |= pintbit;
680 692
681 if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) 693 if (gpio_get_value(gpionr))
694 pint[bank]->invert_set = pintbit;
695 else
696 pint[bank]->invert_clear = pintbit;
697 } else {
698 gpio_both_edge_triggered[bank] &= ~pintbit;
699 }
700
701 if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) {
702 pint[bank]->edge_set = pintbit;
682 set_irq_handler(irq, handle_edge_irq); 703 set_irq_handler(irq, handle_edge_irq);
683 else 704 } else {
705 pint[bank]->edge_clear = pintbit;
684 set_irq_handler(irq, handle_level_irq); 706 set_irq_handler(irq, handle_level_irq);
707 }
708
709 SSYNC();
685 710
686 return 0; 711 return 0;
687} 712}