diff options
author | Michael Hennerich <michael.hennerich@analog.com> | 2007-12-24 05:51:34 -0500 |
---|---|---|
committer | Bryan Wu <bryan.wu@analog.com> | 2007-12-24 05:51:34 -0500 |
commit | 8baf560b4c901fb554d15e056aaa7f34b2345be5 (patch) | |
tree | 2a0da7e0777c0ffc68657c894cd9bc9d9e0846ce | |
parent | 471b9a6c7304d5f59503d111e71e60a7e19fb9a0 (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>
-rw-r--r-- | arch/blackfin/mach-common/ints-priority-sc.c | 67 |
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, | |||
483 | static unsigned char irq2pint_lut[NR_PINTS]; | 483 | static unsigned char irq2pint_lut[NR_PINTS]; |
484 | static unsigned char pint2irq_lut[NR_PINT_SYS_IRQS * NR_PINT_BITS]; | 484 | static unsigned char pint2irq_lut[NR_PINT_SYS_IRQS * NR_PINT_BITS]; |
485 | 485 | ||
486 | static unsigned int gpio_both_edge_triggered[NR_PINT_SYS_IRQS]; | ||
487 | static unsigned short gpio_enabled[gpio_bank(MAX_BLACKFIN_GPIOS)]; | ||
488 | |||
489 | |||
486 | struct pin_int_t { | 490 | struct 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 | ||
552 | static unsigned short gpio_enabled[gpio_bank(MAX_BLACKFIN_GPIOS)]; | ||
553 | |||
554 | static void bfin_gpio_ack_irq(unsigned int irq) | 556 | static 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 | ||
619 | static void bfin_gpio_irq_shutdown(unsigned int irq) | 637 | static 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 | ||
626 | static int bfin_gpio_irq_type(unsigned int irq, unsigned int type) | 646 | static 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 | } |