diff options
author | Jon Hunter <jon-hunter@ti.com> | 2013-03-01 12:22:47 -0500 |
---|---|---|
committer | Grant Likely <grant.likely@secretlab.ca> | 2013-03-05 20:12:25 -0500 |
commit | ede4d7a5b9835510fd1f724367f68d2fa4128453 (patch) | |
tree | d4b82eaef823472aed0a18d5e58718433dca7151 /drivers/gpio/gpio-omap.c | |
parent | 165b6c2f33860e13d20cd7ac5993ea3acfb5ea34 (diff) |
gpio/omap: convert gpio irq domain to linear mapping
Currently the OMAP GPIO driver uses a legacy mapping for the GPIO IRQ
domain. This is not necessary because we do not need to assign a
specific interrupt number to the GPIO IRQ domain. Therefore, convert
the OMAP GPIO driver to use a linear mapping instead.
Please note that this also allows to simplify the logic in the OMAP
gpio_irq_handler() routine, by using irq_find_mapping() to obtain the
virtual irq number from the GPIO bank and bank index.
Reported-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Jon Hunter <jon-hunter@ti.com>
Reviewed-by: Felipe Balbi <balbi@ti.com>
Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Acked-by: Kevin Hilman <khilman@linaro.org>
Tested-by: Javier Martinez Canillas <javier@dowhile0.org>
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Diffstat (limited to 'drivers/gpio/gpio-omap.c')
-rw-r--r-- | drivers/gpio/gpio-omap.c | 72 |
1 files changed, 31 insertions, 41 deletions
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 159f5c57eb45..c3598d143aa9 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c | |||
@@ -53,7 +53,6 @@ struct gpio_bank { | |||
53 | struct list_head node; | 53 | struct list_head node; |
54 | void __iomem *base; | 54 | void __iomem *base; |
55 | u16 irq; | 55 | u16 irq; |
56 | int irq_base; | ||
57 | struct irq_domain *domain; | 56 | struct irq_domain *domain; |
58 | u32 non_wakeup_gpios; | 57 | u32 non_wakeup_gpios; |
59 | u32 enabled_non_wakeup_gpios; | 58 | u32 enabled_non_wakeup_gpios; |
@@ -89,7 +88,14 @@ struct gpio_bank { | |||
89 | 88 | ||
90 | static int irq_to_gpio(struct gpio_bank *bank, unsigned int gpio_irq) | 89 | static int irq_to_gpio(struct gpio_bank *bank, unsigned int gpio_irq) |
91 | { | 90 | { |
92 | return gpio_irq - bank->irq_base + bank->chip.base; | 91 | return bank->chip.base + gpio_irq; |
92 | } | ||
93 | |||
94 | static int omap_gpio_to_irq(struct gpio_chip *chip, unsigned offset) | ||
95 | { | ||
96 | struct gpio_bank *bank = container_of(chip, struct gpio_bank, chip); | ||
97 | |||
98 | return irq_find_mapping(bank->domain, offset); | ||
93 | } | 99 | } |
94 | 100 | ||
95 | static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input) | 101 | static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input) |
@@ -427,7 +433,7 @@ static int gpio_irq_type(struct irq_data *d, unsigned type) | |||
427 | #endif | 433 | #endif |
428 | 434 | ||
429 | if (!gpio) | 435 | if (!gpio) |
430 | gpio = irq_to_gpio(bank, d->irq); | 436 | gpio = irq_to_gpio(bank, d->hwirq); |
431 | 437 | ||
432 | if (type & ~IRQ_TYPE_SENSE_MASK) | 438 | if (type & ~IRQ_TYPE_SENSE_MASK) |
433 | return -EINVAL; | 439 | return -EINVAL; |
@@ -580,7 +586,7 @@ static void _reset_gpio(struct gpio_bank *bank, int gpio) | |||
580 | static int gpio_wake_enable(struct irq_data *d, unsigned int enable) | 586 | static int gpio_wake_enable(struct irq_data *d, unsigned int enable) |
581 | { | 587 | { |
582 | struct gpio_bank *bank = irq_data_get_irq_chip_data(d); | 588 | struct gpio_bank *bank = irq_data_get_irq_chip_data(d); |
583 | unsigned int gpio = irq_to_gpio(bank, d->irq); | 589 | unsigned int gpio = irq_to_gpio(bank, d->hwirq); |
584 | 590 | ||
585 | return _set_gpio_wakeup(bank, gpio, enable); | 591 | return _set_gpio_wakeup(bank, gpio, enable); |
586 | } | 592 | } |
@@ -680,7 +686,7 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) | |||
680 | { | 686 | { |
681 | void __iomem *isr_reg = NULL; | 687 | void __iomem *isr_reg = NULL; |
682 | u32 isr; | 688 | u32 isr; |
683 | unsigned int gpio_irq, gpio_index; | 689 | unsigned int i; |
684 | struct gpio_bank *bank; | 690 | struct gpio_bank *bank; |
685 | int unmasked = 0; | 691 | int unmasked = 0; |
686 | struct irq_chip *chip = irq_desc_get_chip(desc); | 692 | struct irq_chip *chip = irq_desc_get_chip(desc); |
@@ -721,15 +727,10 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) | |||
721 | if (!isr) | 727 | if (!isr) |
722 | break; | 728 | break; |
723 | 729 | ||
724 | gpio_irq = bank->irq_base; | 730 | for (i = 0; isr != 0; isr >>= 1, i++) { |
725 | for (; isr != 0; isr >>= 1, gpio_irq++) { | ||
726 | int gpio = irq_to_gpio(bank, gpio_irq); | ||
727 | |||
728 | if (!(isr & 1)) | 731 | if (!(isr & 1)) |
729 | continue; | 732 | continue; |
730 | 733 | ||
731 | gpio_index = GPIO_INDEX(bank, gpio); | ||
732 | |||
733 | /* | 734 | /* |
734 | * Some chips can't respond to both rising and falling | 735 | * Some chips can't respond to both rising and falling |
735 | * at the same time. If this irq was requested with | 736 | * at the same time. If this irq was requested with |
@@ -737,10 +738,10 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) | |||
737 | * to respond to the IRQ for the opposite direction. | 738 | * to respond to the IRQ for the opposite direction. |
738 | * This will be indicated in the bank toggle_mask. | 739 | * This will be indicated in the bank toggle_mask. |
739 | */ | 740 | */ |
740 | if (bank->toggle_mask & (1 << gpio_index)) | 741 | if (bank->toggle_mask & (1 << i)) |
741 | _toggle_gpio_edge_triggering(bank, gpio_index); | 742 | _toggle_gpio_edge_triggering(bank, i); |
742 | 743 | ||
743 | generic_handle_irq(gpio_irq); | 744 | generic_handle_irq(irq_find_mapping(bank->domain, i)); |
744 | } | 745 | } |
745 | } | 746 | } |
746 | /* if bank has any level sensitive GPIO pin interrupt | 747 | /* if bank has any level sensitive GPIO pin interrupt |
@@ -756,7 +757,7 @@ exit: | |||
756 | static void gpio_irq_shutdown(struct irq_data *d) | 757 | static void gpio_irq_shutdown(struct irq_data *d) |
757 | { | 758 | { |
758 | struct gpio_bank *bank = irq_data_get_irq_chip_data(d); | 759 | struct gpio_bank *bank = irq_data_get_irq_chip_data(d); |
759 | unsigned int gpio = irq_to_gpio(bank, d->irq); | 760 | unsigned int gpio = irq_to_gpio(bank, d->hwirq); |
760 | unsigned long flags; | 761 | unsigned long flags; |
761 | 762 | ||
762 | spin_lock_irqsave(&bank->lock, flags); | 763 | spin_lock_irqsave(&bank->lock, flags); |
@@ -767,7 +768,7 @@ static void gpio_irq_shutdown(struct irq_data *d) | |||
767 | static void gpio_ack_irq(struct irq_data *d) | 768 | static void gpio_ack_irq(struct irq_data *d) |
768 | { | 769 | { |
769 | struct gpio_bank *bank = irq_data_get_irq_chip_data(d); | 770 | struct gpio_bank *bank = irq_data_get_irq_chip_data(d); |
770 | unsigned int gpio = irq_to_gpio(bank, d->irq); | 771 | unsigned int gpio = irq_to_gpio(bank, d->hwirq); |
771 | 772 | ||
772 | _clear_gpio_irqstatus(bank, gpio); | 773 | _clear_gpio_irqstatus(bank, gpio); |
773 | } | 774 | } |
@@ -775,7 +776,7 @@ static void gpio_ack_irq(struct irq_data *d) | |||
775 | static void gpio_mask_irq(struct irq_data *d) | 776 | static void gpio_mask_irq(struct irq_data *d) |
776 | { | 777 | { |
777 | struct gpio_bank *bank = irq_data_get_irq_chip_data(d); | 778 | struct gpio_bank *bank = irq_data_get_irq_chip_data(d); |
778 | unsigned int gpio = irq_to_gpio(bank, d->irq); | 779 | unsigned int gpio = irq_to_gpio(bank, d->hwirq); |
779 | unsigned long flags; | 780 | unsigned long flags; |
780 | 781 | ||
781 | spin_lock_irqsave(&bank->lock, flags); | 782 | spin_lock_irqsave(&bank->lock, flags); |
@@ -787,7 +788,7 @@ static void gpio_mask_irq(struct irq_data *d) | |||
787 | static void gpio_unmask_irq(struct irq_data *d) | 788 | static void gpio_unmask_irq(struct irq_data *d) |
788 | { | 789 | { |
789 | struct gpio_bank *bank = irq_data_get_irq_chip_data(d); | 790 | struct gpio_bank *bank = irq_data_get_irq_chip_data(d); |
790 | unsigned int gpio = irq_to_gpio(bank, d->irq); | 791 | unsigned int gpio = irq_to_gpio(bank, d->hwirq); |
791 | unsigned int irq_mask = GPIO_BIT(bank, gpio); | 792 | unsigned int irq_mask = GPIO_BIT(bank, gpio); |
792 | u32 trigger = irqd_get_trigger_type(d); | 793 | u32 trigger = irqd_get_trigger_type(d); |
793 | unsigned long flags; | 794 | unsigned long flags; |
@@ -953,14 +954,6 @@ static void gpio_set(struct gpio_chip *chip, unsigned offset, int value) | |||
953 | spin_unlock_irqrestore(&bank->lock, flags); | 954 | spin_unlock_irqrestore(&bank->lock, flags); |
954 | } | 955 | } |
955 | 956 | ||
956 | static int gpio_2irq(struct gpio_chip *chip, unsigned offset) | ||
957 | { | ||
958 | struct gpio_bank *bank; | ||
959 | |||
960 | bank = container_of(chip, struct gpio_bank, chip); | ||
961 | return bank->irq_base + offset; | ||
962 | } | ||
963 | |||
964 | /*---------------------------------------------------------------------*/ | 957 | /*---------------------------------------------------------------------*/ |
965 | 958 | ||
966 | static void __init omap_gpio_show_rev(struct gpio_bank *bank) | 959 | static void __init omap_gpio_show_rev(struct gpio_bank *bank) |
@@ -1057,7 +1050,7 @@ static void omap_gpio_chip_init(struct gpio_bank *bank) | |||
1057 | bank->chip.direction_output = gpio_output; | 1050 | bank->chip.direction_output = gpio_output; |
1058 | bank->chip.set_debounce = gpio_debounce; | 1051 | bank->chip.set_debounce = gpio_debounce; |
1059 | bank->chip.set = gpio_set; | 1052 | bank->chip.set = gpio_set; |
1060 | bank->chip.to_irq = gpio_2irq; | 1053 | bank->chip.to_irq = omap_gpio_to_irq; |
1061 | if (bank->is_mpuio) { | 1054 | if (bank->is_mpuio) { |
1062 | bank->chip.label = "mpuio"; | 1055 | bank->chip.label = "mpuio"; |
1063 | if (bank->regs->wkup_en) | 1056 | if (bank->regs->wkup_en) |
@@ -1072,15 +1065,16 @@ static void omap_gpio_chip_init(struct gpio_bank *bank) | |||
1072 | 1065 | ||
1073 | gpiochip_add(&bank->chip); | 1066 | gpiochip_add(&bank->chip); |
1074 | 1067 | ||
1075 | for (j = bank->irq_base; j < bank->irq_base + bank->width; j++) { | 1068 | for (j = 0; j < bank->width; j++) { |
1076 | irq_set_lockdep_class(j, &gpio_lock_class); | 1069 | int irq = irq_create_mapping(bank->domain, j); |
1077 | irq_set_chip_data(j, bank); | 1070 | irq_set_lockdep_class(irq, &gpio_lock_class); |
1071 | irq_set_chip_data(irq, bank); | ||
1078 | if (bank->is_mpuio) { | 1072 | if (bank->is_mpuio) { |
1079 | omap_mpuio_alloc_gc(bank, j, bank->width); | 1073 | omap_mpuio_alloc_gc(bank, irq, bank->width); |
1080 | } else { | 1074 | } else { |
1081 | irq_set_chip(j, &gpio_irq_chip); | 1075 | irq_set_chip_and_handler(irq, &gpio_irq_chip, |
1082 | irq_set_handler(j, handle_simple_irq); | 1076 | handle_simple_irq); |
1083 | set_irq_flags(j, IRQF_VALID); | 1077 | set_irq_flags(irq, IRQF_VALID); |
1084 | } | 1078 | } |
1085 | } | 1079 | } |
1086 | irq_set_chained_handler(bank->irq, gpio_irq_handler); | 1080 | irq_set_chained_handler(bank->irq, gpio_irq_handler); |
@@ -1130,14 +1124,10 @@ static int omap_gpio_probe(struct platform_device *pdev) | |||
1130 | bank->chip.of_node = of_node_get(node); | 1124 | bank->chip.of_node = of_node_get(node); |
1131 | #endif | 1125 | #endif |
1132 | 1126 | ||
1133 | bank->irq_base = irq_alloc_descs(-1, 0, bank->width, 0); | 1127 | bank->domain = irq_domain_add_linear(node, bank->width, |
1134 | if (bank->irq_base < 0) { | 1128 | &irq_domain_simple_ops, NULL); |
1135 | dev_err(dev, "Couldn't allocate IRQ numbers\n"); | 1129 | if (!bank->domain) |
1136 | return -ENODEV; | 1130 | return -ENODEV; |
1137 | } | ||
1138 | |||
1139 | bank->domain = irq_domain_add_legacy(node, bank->width, bank->irq_base, | ||
1140 | 0, &irq_domain_simple_ops, NULL); | ||
1141 | 1131 | ||
1142 | if (bank->regs->set_dataout && bank->regs->clr_dataout) | 1132 | if (bank->regs->set_dataout && bank->regs->clr_dataout) |
1143 | bank->set_dataout = _set_gpio_dataout_reg; | 1133 | bank->set_dataout = _set_gpio_dataout_reg; |