diff options
author | Linus Walleij <linus.walleij@linaro.org> | 2014-04-15 02:43:47 -0400 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2014-04-23 16:02:54 -0400 |
commit | 7420d2d09b1279996e06efa6792f9f13c1863b1e (patch) | |
tree | d01cbb724fd821faed02c1d1bd90adc78c7e8b33 /drivers/pinctrl/sirf | |
parent | c5eb757ca87d0fffcface683b8efda193cf3d4d4 (diff) |
pinctrl: sirf: switch driver to use gpiolib irqchip helpers
This switches the SiRF pinctrl driver over to using the gpiolib
irqchip helpers simplifying some of the code.
Signed-off-by: Barry Song <Baohua.Song@csr.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/pinctrl/sirf')
-rw-r--r-- | drivers/pinctrl/sirf/pinctrl-sirf.c | 89 |
1 files changed, 26 insertions, 63 deletions
diff --git a/drivers/pinctrl/sirf/pinctrl-sirf.c b/drivers/pinctrl/sirf/pinctrl-sirf.c index cb81b1558cef..c03dcc7729eb 100644 --- a/drivers/pinctrl/sirf/pinctrl-sirf.c +++ b/drivers/pinctrl/sirf/pinctrl-sirf.c | |||
@@ -14,8 +14,6 @@ | |||
14 | #include <linux/io.h> | 14 | #include <linux/io.h> |
15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
16 | #include <linux/err.h> | 16 | #include <linux/err.h> |
17 | #include <linux/irqdomain.h> | ||
18 | #include <linux/irqchip/chained_irq.h> | ||
19 | #include <linux/pinctrl/pinctrl.h> | 17 | #include <linux/pinctrl/pinctrl.h> |
20 | #include <linux/pinctrl/pinmux.h> | 18 | #include <linux/pinctrl/pinmux.h> |
21 | #include <linux/pinctrl/consumer.h> | 19 | #include <linux/pinctrl/consumer.h> |
@@ -27,7 +25,6 @@ | |||
27 | #include <linux/bitops.h> | 25 | #include <linux/bitops.h> |
28 | #include <linux/gpio.h> | 26 | #include <linux/gpio.h> |
29 | #include <linux/of_gpio.h> | 27 | #include <linux/of_gpio.h> |
30 | #include <asm/mach/irq.h> | ||
31 | 28 | ||
32 | #include "pinctrl-sirf.h" | 29 | #include "pinctrl-sirf.h" |
33 | 30 | ||
@@ -41,7 +38,6 @@ struct sirfsoc_gpio_bank { | |||
41 | 38 | ||
42 | struct sirfsoc_gpio_chip { | 39 | struct sirfsoc_gpio_chip { |
43 | struct of_mm_gpio_chip chip; | 40 | struct of_mm_gpio_chip chip; |
44 | struct irq_domain *domain; | ||
45 | bool is_marco; /* for marco, some registers are different with prima2 */ | 41 | bool is_marco; /* for marco, some registers are different with prima2 */ |
46 | struct sirfsoc_gpio_bank sgpio_bank[SIRFSOC_GPIO_NO_OF_BANKS]; | 42 | struct sirfsoc_gpio_bank sgpio_bank[SIRFSOC_GPIO_NO_OF_BANKS]; |
47 | }; | 43 | }; |
@@ -450,15 +446,11 @@ static inline struct sirfsoc_gpio_bank *sirfsoc_gpio_to_bank(unsigned int gpio) | |||
450 | return &sgpio_chip.sgpio_bank[gpio / SIRFSOC_GPIO_BANK_SIZE]; | 446 | return &sgpio_chip.sgpio_bank[gpio / SIRFSOC_GPIO_BANK_SIZE]; |
451 | } | 447 | } |
452 | 448 | ||
453 | static int sirfsoc_gpio_to_irq(struct gpio_chip *chip, unsigned offset) | ||
454 | { | ||
455 | return irq_create_mapping(sgpio_chip.domain, offset); | ||
456 | } | ||
457 | |||
458 | static inline int sirfsoc_gpio_to_bankoff(unsigned int gpio) | 449 | static inline int sirfsoc_gpio_to_bankoff(unsigned int gpio) |
459 | { | 450 | { |
460 | return gpio % SIRFSOC_GPIO_BANK_SIZE; | 451 | return gpio % SIRFSOC_GPIO_BANK_SIZE; |
461 | } | 452 | } |
453 | |||
462 | static void sirfsoc_gpio_irq_ack(struct irq_data *d) | 454 | static void sirfsoc_gpio_irq_ack(struct irq_data *d) |
463 | { | 455 | { |
464 | struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(d->hwirq); | 456 | struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(d->hwirq); |
@@ -566,38 +558,28 @@ static int sirfsoc_gpio_irq_type(struct irq_data *d, unsigned type) | |||
566 | return 0; | 558 | return 0; |
567 | } | 559 | } |
568 | 560 | ||
569 | static int sirfsoc_gpio_irq_reqres(struct irq_data *d) | ||
570 | { | ||
571 | if (gpio_lock_as_irq(&sgpio_chip.chip.gc, d->hwirq)) { | ||
572 | dev_err(sgpio_chip.chip.gc.dev, | ||
573 | "unable to lock HW IRQ %lu for IRQ\n", | ||
574 | d->hwirq); | ||
575 | return -EINVAL; | ||
576 | } | ||
577 | return 0; | ||
578 | } | ||
579 | |||
580 | static void sirfsoc_gpio_irq_relres(struct irq_data *d) | ||
581 | { | ||
582 | gpio_unlock_as_irq(&sgpio_chip.chip.gc, d->hwirq); | ||
583 | } | ||
584 | |||
585 | static struct irq_chip sirfsoc_irq_chip = { | 561 | static struct irq_chip sirfsoc_irq_chip = { |
586 | .name = "sirf-gpio-irq", | 562 | .name = "sirf-gpio-irq", |
587 | .irq_ack = sirfsoc_gpio_irq_ack, | 563 | .irq_ack = sirfsoc_gpio_irq_ack, |
588 | .irq_mask = sirfsoc_gpio_irq_mask, | 564 | .irq_mask = sirfsoc_gpio_irq_mask, |
589 | .irq_unmask = sirfsoc_gpio_irq_unmask, | 565 | .irq_unmask = sirfsoc_gpio_irq_unmask, |
590 | .irq_set_type = sirfsoc_gpio_irq_type, | 566 | .irq_set_type = sirfsoc_gpio_irq_type, |
591 | .irq_request_resources = sirfsoc_gpio_irq_reqres, | ||
592 | .irq_release_resources = sirfsoc_gpio_irq_relres, | ||
593 | }; | 567 | }; |
594 | 568 | ||
595 | static void sirfsoc_gpio_handle_irq(unsigned int irq, struct irq_desc *desc) | 569 | static void sirfsoc_gpio_handle_irq(unsigned int irq, struct irq_desc *desc) |
596 | { | 570 | { |
597 | struct sirfsoc_gpio_bank *bank = irq_get_handler_data(irq); | 571 | struct sirfsoc_gpio_bank *bank; |
598 | u32 status, ctrl; | 572 | u32 status, ctrl; |
599 | int idx = 0; | 573 | int idx = 0; |
600 | struct irq_chip *chip = irq_get_chip(irq); | 574 | struct irq_chip *chip = irq_get_chip(irq); |
575 | int i; | ||
576 | |||
577 | for (i = 0; i < SIRFSOC_GPIO_BANK_SIZE; i++) { | ||
578 | bank = &sgpio_chip.sgpio_bank[i]; | ||
579 | if (bank->parent_irq == irq) | ||
580 | break; | ||
581 | } | ||
582 | BUG_ON (i == SIRFSOC_GPIO_BANK_SIZE); | ||
601 | 583 | ||
602 | chained_irq_enter(chip, desc); | 584 | chained_irq_enter(chip, desc); |
603 | 585 | ||
@@ -620,7 +602,7 @@ static void sirfsoc_gpio_handle_irq(unsigned int irq, struct irq_desc *desc) | |||
620 | if ((status & 0x1) && (ctrl & SIRFSOC_GPIO_CTL_INTR_EN_MASK)) { | 602 | if ((status & 0x1) && (ctrl & SIRFSOC_GPIO_CTL_INTR_EN_MASK)) { |
621 | pr_debug("%s: gpio id %d idx %d happens\n", | 603 | pr_debug("%s: gpio id %d idx %d happens\n", |
622 | __func__, bank->id, idx); | 604 | __func__, bank->id, idx); |
623 | generic_handle_irq(irq_find_mapping(sgpio_chip.domain, idx + | 605 | generic_handle_irq(irq_find_mapping(sgpio_chip.chip.gc.irqdomain, idx + |
624 | bank->id * SIRFSOC_GPIO_BANK_SIZE)); | 606 | bank->id * SIRFSOC_GPIO_BANK_SIZE)); |
625 | } | 607 | } |
626 | 608 | ||
@@ -768,26 +750,6 @@ static void sirfsoc_gpio_set_value(struct gpio_chip *chip, unsigned offset, | |||
768 | spin_unlock_irqrestore(&bank->lock, flags); | 750 | spin_unlock_irqrestore(&bank->lock, flags); |
769 | } | 751 | } |
770 | 752 | ||
771 | static int sirfsoc_gpio_irq_map(struct irq_domain *d, unsigned int irq, | ||
772 | irq_hw_number_t hwirq) | ||
773 | { | ||
774 | struct sirfsoc_gpio_bank *bank = d->host_data; | ||
775 | |||
776 | if (!bank) | ||
777 | return -EINVAL; | ||
778 | |||
779 | irq_set_chip(irq, &sirfsoc_irq_chip); | ||
780 | irq_set_handler(irq, handle_level_irq); | ||
781 | set_irq_flags(irq, IRQF_VALID); | ||
782 | |||
783 | return 0; | ||
784 | } | ||
785 | |||
786 | static const struct irq_domain_ops sirfsoc_gpio_irq_simple_ops = { | ||
787 | .map = sirfsoc_gpio_irq_map, | ||
788 | .xlate = irq_domain_xlate_twocell, | ||
789 | }; | ||
790 | |||
791 | static void sirfsoc_gpio_set_pullup(const u32 *pullups) | 753 | static void sirfsoc_gpio_set_pullup(const u32 *pullups) |
792 | { | 754 | { |
793 | int i, n; | 755 | int i, n; |
@@ -826,7 +788,6 @@ static int sirfsoc_gpio_probe(struct device_node *np) | |||
826 | struct sirfsoc_gpio_bank *bank; | 788 | struct sirfsoc_gpio_bank *bank; |
827 | void __iomem *regs; | 789 | void __iomem *regs; |
828 | struct platform_device *pdev; | 790 | struct platform_device *pdev; |
829 | struct irq_domain *domain; | ||
830 | bool is_marco = false; | 791 | bool is_marco = false; |
831 | 792 | ||
832 | u32 pullups[SIRFSOC_GPIO_NO_OF_BANKS], pulldowns[SIRFSOC_GPIO_NO_OF_BANKS]; | 793 | u32 pullups[SIRFSOC_GPIO_NO_OF_BANKS], pulldowns[SIRFSOC_GPIO_NO_OF_BANKS]; |
@@ -842,21 +803,12 @@ static int sirfsoc_gpio_probe(struct device_node *np) | |||
842 | if (of_device_is_compatible(np, "sirf,marco-pinctrl")) | 803 | if (of_device_is_compatible(np, "sirf,marco-pinctrl")) |
843 | is_marco = 1; | 804 | is_marco = 1; |
844 | 805 | ||
845 | domain = irq_domain_add_linear(np, SIRFSOC_GPIO_BANK_SIZE * SIRFSOC_GPIO_NO_OF_BANKS, | ||
846 | &sirfsoc_gpio_irq_simple_ops, &sgpio_chip); | ||
847 | if (!domain) { | ||
848 | pr_err("%s: Failed to create irqdomain\n", np->full_name); | ||
849 | err = -ENOSYS; | ||
850 | goto out; | ||
851 | } | ||
852 | |||
853 | sgpio_chip.chip.gc.request = sirfsoc_gpio_request; | 806 | sgpio_chip.chip.gc.request = sirfsoc_gpio_request; |
854 | sgpio_chip.chip.gc.free = sirfsoc_gpio_free; | 807 | sgpio_chip.chip.gc.free = sirfsoc_gpio_free; |
855 | sgpio_chip.chip.gc.direction_input = sirfsoc_gpio_direction_input; | 808 | sgpio_chip.chip.gc.direction_input = sirfsoc_gpio_direction_input; |
856 | sgpio_chip.chip.gc.get = sirfsoc_gpio_get_value; | 809 | sgpio_chip.chip.gc.get = sirfsoc_gpio_get_value; |
857 | sgpio_chip.chip.gc.direction_output = sirfsoc_gpio_direction_output; | 810 | sgpio_chip.chip.gc.direction_output = sirfsoc_gpio_direction_output; |
858 | sgpio_chip.chip.gc.set = sirfsoc_gpio_set_value; | 811 | sgpio_chip.chip.gc.set = sirfsoc_gpio_set_value; |
859 | sgpio_chip.chip.gc.to_irq = sirfsoc_gpio_to_irq; | ||
860 | sgpio_chip.chip.gc.base = 0; | 812 | sgpio_chip.chip.gc.base = 0; |
861 | sgpio_chip.chip.gc.ngpio = SIRFSOC_GPIO_BANK_SIZE * SIRFSOC_GPIO_NO_OF_BANKS; | 813 | sgpio_chip.chip.gc.ngpio = SIRFSOC_GPIO_BANK_SIZE * SIRFSOC_GPIO_NO_OF_BANKS; |
862 | sgpio_chip.chip.gc.label = kstrdup(np->full_name, GFP_KERNEL); | 814 | sgpio_chip.chip.gc.label = kstrdup(np->full_name, GFP_KERNEL); |
@@ -866,15 +818,24 @@ static int sirfsoc_gpio_probe(struct device_node *np) | |||
866 | sgpio_chip.chip.gc.dev = &pdev->dev; | 818 | sgpio_chip.chip.gc.dev = &pdev->dev; |
867 | sgpio_chip.chip.regs = regs; | 819 | sgpio_chip.chip.regs = regs; |
868 | sgpio_chip.is_marco = is_marco; | 820 | sgpio_chip.is_marco = is_marco; |
869 | sgpio_chip.domain = domain; | ||
870 | 821 | ||
871 | err = gpiochip_add(&sgpio_chip.chip.gc); | 822 | err = gpiochip_add(&sgpio_chip.chip.gc); |
872 | if (err) { | 823 | if (err) { |
873 | pr_err("%s: error in probe function with status %d\n", | 824 | dev_err(&pdev->dev, "%s: error in probe function with status %d\n", |
874 | np->full_name, err); | 825 | np->full_name, err); |
875 | goto out; | 826 | goto out; |
876 | } | 827 | } |
877 | 828 | ||
829 | err = gpiochip_irqchip_add(&sgpio_chip.chip.gc, | ||
830 | &sirfsoc_irq_chip, | ||
831 | 0, handle_level_irq, | ||
832 | IRQ_TYPE_NONE); | ||
833 | if (err) { | ||
834 | dev_err(&pdev->dev, | ||
835 | "could not connect irqchip to gpiochip\n"); | ||
836 | goto out; | ||
837 | } | ||
838 | |||
878 | for (i = 0; i < SIRFSOC_GPIO_NO_OF_BANKS; i++) { | 839 | for (i = 0; i < SIRFSOC_GPIO_NO_OF_BANKS; i++) { |
879 | bank = &sgpio_chip.sgpio_bank[i]; | 840 | bank = &sgpio_chip.sgpio_bank[i]; |
880 | spin_lock_init(&bank->lock); | 841 | spin_lock_init(&bank->lock); |
@@ -884,8 +845,10 @@ static int sirfsoc_gpio_probe(struct device_node *np) | |||
884 | goto out; | 845 | goto out; |
885 | } | 846 | } |
886 | 847 | ||
887 | irq_set_chained_handler(bank->parent_irq, sirfsoc_gpio_handle_irq); | 848 | gpiochip_set_chained_irqchip(&sgpio_chip.chip.gc, |
888 | irq_set_handler_data(bank->parent_irq, bank); | 849 | &sirfsoc_irq_chip, |
850 | bank->parent_irq, | ||
851 | sirfsoc_gpio_handle_irq); | ||
889 | } | 852 | } |
890 | 853 | ||
891 | if (!of_property_read_u32_array(np, "sirf,pullups", pullups, | 854 | if (!of_property_read_u32_array(np, "sirf,pullups", pullups, |