diff options
| author | Linus Walleij <linus.walleij@linaro.org> | 2014-03-25 05:44:09 -0400 |
|---|---|---|
| committer | Linus Walleij <linus.walleij@linaro.org> | 2014-03-26 05:31:33 -0400 |
| commit | e0bc34a3dada03a48ff5501381ff7fdef885ed25 (patch) | |
| tree | 646ef286908d6635f28bb994e19f5fe1f83fc50e | |
| parent | 8d5b24bd30c23930e666813ea0adc4672ea58c62 (diff) | |
pinctrl: nomadik: convert driver to use gpiolib irqchip
This converts the Nomadik pin control driver to register its
chained irq handler and irqchip using the helpers in the
gpiolib core.
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
| -rw-r--r-- | drivers/pinctrl/Kconfig | 3 | ||||
| -rw-r--r-- | drivers/pinctrl/pinctrl-nomadik.c | 123 |
2 files changed, 36 insertions, 90 deletions
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 1e4e69384baa..a05087bd1955 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig | |||
| @@ -235,6 +235,9 @@ config PINCTRL_NOMADIK | |||
| 235 | depends on ARCH_U8500 || ARCH_NOMADIK | 235 | depends on ARCH_U8500 || ARCH_NOMADIK |
| 236 | select PINMUX | 236 | select PINMUX |
| 237 | select PINCONF | 237 | select PINCONF |
| 238 | select GPIOLIB | ||
| 239 | select OF_GPIO | ||
| 240 | select GPIOLIB_IRQCHIP | ||
| 238 | 241 | ||
| 239 | config PINCTRL_STN8815 | 242 | config PINCTRL_STN8815 |
| 240 | bool "STN8815 pin controller driver" | 243 | bool "STN8815 pin controller driver" |
diff --git a/drivers/pinctrl/pinctrl-nomadik.c b/drivers/pinctrl/pinctrl-nomadik.c index 98a36a0969f9..db0cc30c82de 100644 --- a/drivers/pinctrl/pinctrl-nomadik.c +++ b/drivers/pinctrl/pinctrl-nomadik.c | |||
| @@ -21,9 +21,6 @@ | |||
| 21 | #include <linux/gpio.h> | 21 | #include <linux/gpio.h> |
| 22 | #include <linux/spinlock.h> | 22 | #include <linux/spinlock.h> |
| 23 | #include <linux/interrupt.h> | 23 | #include <linux/interrupt.h> |
| 24 | #include <linux/irq.h> | ||
| 25 | #include <linux/irqdomain.h> | ||
| 26 | #include <linux/irqchip/chained_irq.h> | ||
| 27 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
| 28 | #include <linux/of_device.h> | 25 | #include <linux/of_device.h> |
| 29 | #include <linux/of_address.h> | 26 | #include <linux/of_address.h> |
| @@ -248,7 +245,6 @@ enum nmk_gpio_slpm { | |||
| 248 | 245 | ||
| 249 | struct nmk_gpio_chip { | 246 | struct nmk_gpio_chip { |
| 250 | struct gpio_chip chip; | 247 | struct gpio_chip chip; |
| 251 | struct irq_domain *domain; | ||
| 252 | void __iomem *addr; | 248 | void __iomem *addr; |
| 253 | struct clk *clk; | 249 | struct clk *clk; |
| 254 | unsigned int bank; | 250 | unsigned int bank; |
| @@ -419,7 +415,7 @@ nmk_gpio_disable_lazy_irq(struct nmk_gpio_chip *nmk_chip, unsigned offset) | |||
| 419 | u32 falling = nmk_chip->fimsc & BIT(offset); | 415 | u32 falling = nmk_chip->fimsc & BIT(offset); |
| 420 | u32 rising = nmk_chip->rimsc & BIT(offset); | 416 | u32 rising = nmk_chip->rimsc & BIT(offset); |
| 421 | int gpio = nmk_chip->chip.base + offset; | 417 | int gpio = nmk_chip->chip.base + offset; |
| 422 | int irq = irq_find_mapping(nmk_chip->domain, offset); | 418 | int irq = irq_find_mapping(nmk_chip->chip.irqdomain, offset); |
| 423 | struct irq_data *d = irq_get_irq_data(irq); | 419 | struct irq_data *d = irq_get_irq_data(irq); |
| 424 | 420 | ||
| 425 | if (!rising && !falling) | 421 | if (!rising && !falling) |
| @@ -647,11 +643,8 @@ static inline int nmk_gpio_get_bitmask(int gpio) | |||
| 647 | 643 | ||
| 648 | static void nmk_gpio_irq_ack(struct irq_data *d) | 644 | static void nmk_gpio_irq_ack(struct irq_data *d) |
| 649 | { | 645 | { |
| 650 | struct nmk_gpio_chip *nmk_chip; | 646 | struct gpio_chip *chip = irq_data_get_irq_chip_data(d); |
| 651 | 647 | struct nmk_gpio_chip *nmk_chip = container_of(chip, struct nmk_gpio_chip, chip); | |
| 652 | nmk_chip = irq_data_get_irq_chip_data(d); | ||
| 653 | if (!nmk_chip) | ||
| 654 | return; | ||
| 655 | 648 | ||
| 656 | clk_enable(nmk_chip->clk); | 649 | clk_enable(nmk_chip->clk); |
| 657 | writel(nmk_gpio_get_bitmask(d->hwirq), nmk_chip->addr + NMK_GPIO_IC); | 650 | writel(nmk_gpio_get_bitmask(d->hwirq), nmk_chip->addr + NMK_GPIO_IC); |
| @@ -848,26 +841,6 @@ static void nmk_gpio_irq_shutdown(struct irq_data *d) | |||
| 848 | clk_disable(nmk_chip->clk); | 841 | clk_disable(nmk_chip->clk); |
| 849 | } | 842 | } |
| 850 | 843 | ||
| 851 | static int nmk_gpio_irq_reqres(struct irq_data *d) | ||
| 852 | { | ||
| 853 | struct nmk_gpio_chip *nmk_chip = irq_data_get_irq_chip_data(d); | ||
| 854 | |||
| 855 | if (gpio_lock_as_irq(&nmk_chip->chip, d->hwirq)) { | ||
| 856 | dev_err(nmk_chip->chip.dev, | ||
| 857 | "unable to lock HW IRQ %lu for IRQ\n", | ||
| 858 | d->hwirq); | ||
| 859 | return -EINVAL; | ||
| 860 | } | ||
| 861 | return 0; | ||
| 862 | } | ||
| 863 | |||
| 864 | static void nmk_gpio_irq_relres(struct irq_data *d) | ||
| 865 | { | ||
| 866 | struct nmk_gpio_chip *nmk_chip = irq_data_get_irq_chip_data(d); | ||
| 867 | |||
| 868 | gpio_unlock_as_irq(&nmk_chip->chip, d->hwirq); | ||
| 869 | } | ||
| 870 | |||
| 871 | static struct irq_chip nmk_gpio_irq_chip = { | 844 | static struct irq_chip nmk_gpio_irq_chip = { |
| 872 | .name = "Nomadik-GPIO", | 845 | .name = "Nomadik-GPIO", |
| 873 | .irq_ack = nmk_gpio_irq_ack, | 846 | .irq_ack = nmk_gpio_irq_ack, |
| @@ -877,24 +850,21 @@ static struct irq_chip nmk_gpio_irq_chip = { | |||
| 877 | .irq_set_wake = nmk_gpio_irq_set_wake, | 850 | .irq_set_wake = nmk_gpio_irq_set_wake, |
| 878 | .irq_startup = nmk_gpio_irq_startup, | 851 | .irq_startup = nmk_gpio_irq_startup, |
| 879 | .irq_shutdown = nmk_gpio_irq_shutdown, | 852 | .irq_shutdown = nmk_gpio_irq_shutdown, |
| 880 | .irq_request_resources = nmk_gpio_irq_reqres, | ||
| 881 | .irq_release_resources = nmk_gpio_irq_relres, | ||
| 882 | .flags = IRQCHIP_MASK_ON_SUSPEND, | 853 | .flags = IRQCHIP_MASK_ON_SUSPEND, |
| 883 | }; | 854 | }; |
| 884 | 855 | ||
| 885 | static void __nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc, | 856 | static void __nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc, |
| 886 | u32 status) | 857 | u32 status) |
| 887 | { | 858 | { |
| 888 | struct nmk_gpio_chip *nmk_chip; | ||
| 889 | struct irq_chip *host_chip = irq_get_chip(irq); | 859 | struct irq_chip *host_chip = irq_get_chip(irq); |
| 860 | struct gpio_chip *chip = irq_desc_get_handler_data(desc); | ||
| 890 | 861 | ||
| 891 | chained_irq_enter(host_chip, desc); | 862 | chained_irq_enter(host_chip, desc); |
| 892 | 863 | ||
| 893 | nmk_chip = irq_get_handler_data(irq); | ||
| 894 | while (status) { | 864 | while (status) { |
| 895 | int bit = __ffs(status); | 865 | int bit = __ffs(status); |
| 896 | 866 | ||
| 897 | generic_handle_irq(irq_find_mapping(nmk_chip->domain, bit)); | 867 | generic_handle_irq(irq_find_mapping(chip->irqdomain, bit)); |
| 898 | status &= ~BIT(bit); | 868 | status &= ~BIT(bit); |
| 899 | } | 869 | } |
| 900 | 870 | ||
| @@ -903,9 +873,11 @@ static void __nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc, | |||
| 903 | 873 | ||
| 904 | static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) | 874 | static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) |
| 905 | { | 875 | { |
| 906 | struct nmk_gpio_chip *nmk_chip = irq_get_handler_data(irq); | 876 | struct gpio_chip *chip = irq_desc_get_handler_data(desc); |
| 877 | struct nmk_gpio_chip *nmk_chip = container_of(chip, struct nmk_gpio_chip, chip); | ||
| 907 | u32 status; | 878 | u32 status; |
| 908 | 879 | ||
| 880 | pr_err("PLONK IRQ %d\n", irq); | ||
| 909 | clk_enable(nmk_chip->clk); | 881 | clk_enable(nmk_chip->clk); |
| 910 | status = readl(nmk_chip->addr + NMK_GPIO_IS); | 882 | status = readl(nmk_chip->addr + NMK_GPIO_IS); |
| 911 | clk_disable(nmk_chip->clk); | 883 | clk_disable(nmk_chip->clk); |
| @@ -916,26 +888,13 @@ static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) | |||
| 916 | static void nmk_gpio_latent_irq_handler(unsigned int irq, | 888 | static void nmk_gpio_latent_irq_handler(unsigned int irq, |
| 917 | struct irq_desc *desc) | 889 | struct irq_desc *desc) |
| 918 | { | 890 | { |
| 919 | struct nmk_gpio_chip *nmk_chip = irq_get_handler_data(irq); | 891 | struct gpio_chip *chip = irq_desc_get_handler_data(desc); |
| 892 | struct nmk_gpio_chip *nmk_chip = container_of(chip, struct nmk_gpio_chip, chip); | ||
| 920 | u32 status = nmk_chip->get_latent_status(nmk_chip->bank); | 893 | u32 status = nmk_chip->get_latent_status(nmk_chip->bank); |
| 921 | 894 | ||
| 922 | __nmk_gpio_irq_handler(irq, desc, status); | 895 | __nmk_gpio_irq_handler(irq, desc, status); |
| 923 | } | 896 | } |
| 924 | 897 | ||
| 925 | static int nmk_gpio_init_irq(struct nmk_gpio_chip *nmk_chip) | ||
| 926 | { | ||
| 927 | irq_set_chained_handler(nmk_chip->parent_irq, nmk_gpio_irq_handler); | ||
| 928 | irq_set_handler_data(nmk_chip->parent_irq, nmk_chip); | ||
| 929 | |||
| 930 | if (nmk_chip->latent_parent_irq >= 0) { | ||
| 931 | irq_set_chained_handler(nmk_chip->latent_parent_irq, | ||
| 932 | nmk_gpio_latent_irq_handler); | ||
| 933 | irq_set_handler_data(nmk_chip->latent_parent_irq, nmk_chip); | ||
| 934 | } | ||
| 935 | |||
| 936 | return 0; | ||
| 937 | } | ||
| 938 | |||
| 939 | /* I/O Functions */ | 898 | /* I/O Functions */ |
| 940 | 899 | ||
| 941 | static int nmk_gpio_request(struct gpio_chip *chip, unsigned offset) | 900 | static int nmk_gpio_request(struct gpio_chip *chip, unsigned offset) |
| @@ -1014,14 +973,6 @@ static int nmk_gpio_make_output(struct gpio_chip *chip, unsigned offset, | |||
| 1014 | return 0; | 973 | return 0; |
| 1015 | } | 974 | } |
| 1016 | 975 | ||
| 1017 | static int nmk_gpio_to_irq(struct gpio_chip *chip, unsigned offset) | ||
