From bb1e88ccb771492ac908ac295ec135efa1d53093 Mon Sep 17 00:00:00 2001 From: Alexandre Courbot Date: Sun, 9 Feb 2014 17:43:54 +0900 Subject: gpiolib: add gpiochip_get_desc() driver function Some drivers dealing with a gpio_chip might need to act on its descriptors directly; one example is pinctrl drivers that need to lock a GPIO for being used as IRQ using gpiod_lock_as_irq(). This patch exports a gpiochip_get_desc() function that returns the GPIO descriptor at the requested index. It also sweeps the gpio_to_chip() function out of the consumer interface since any holder of a gpio_chip reference can manipulate its GPIOs way beyond what a consumer should be allowed to do. As a result, gpio_chip is not visible anymore to simple GPIO consumers. Signed-off-by: Alexandre Courbot Reviewed-by: Mika Westerberg Reviewed-by: Jean-Jacques Hiblot Signed-off-by: Linus Walleij --- include/linux/gpio/driver.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'include/linux/gpio/driver.h') diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index a3e181e09636..9fe283642253 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h @@ -10,6 +10,8 @@ struct of_phandle_args; struct device_node; struct seq_file; +#ifdef CONFIG_GPIOLIB + /** * struct gpio_chip - abstract a GPIO controller * @label: for diagnostics @@ -129,6 +131,11 @@ extern struct gpio_chip *gpiochip_find(void *data, int gpiod_lock_as_irq(struct gpio_desc *desc); void gpiod_unlock_as_irq(struct gpio_desc *desc); +struct gpio_chip *gpiod_to_chip(const struct gpio_desc *desc); + +struct gpio_desc *gpiochip_get_desc(struct gpio_chip *chip, + u16 hwnum); + enum gpio_lookup_flags { GPIO_ACTIVE_HIGH = (0 << 0), GPIO_ACTIVE_LOW = (1 << 0), @@ -183,4 +190,15 @@ struct gpiod_lookup_table { void gpiod_add_lookup_table(struct gpiod_lookup_table *table); +#else /* CONFIG_GPIOLIB */ + +static inline struct gpio_chip *gpiod_to_chip(const struct gpio_desc *desc) +{ + /* GPIO can never have been requested */ + WARN_ON(1); + return ERR_PTR(-ENODEV); +} + +#endif /* CONFIG_GPIOLIB */ + #endif -- cgit v1.2.3 From 1425052097b53de841e064dc190a9009480c208c Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 25 Mar 2014 10:40:18 +0100 Subject: gpio: add IRQ chip helpers in gpiolib This provides a function gpiochip_irqchip_add() to set up an irqchip for a GPIO controller, and a function gpiochip_set_chained_irqchip() to chain it to a parent irqchip. Most GPIOs are of the type where a number of lines form a cascaded interrupt controller chained onto the primary system interrupt controller (or further down the chain) so let's add this helper and factor the code to request the lines to be used as IRQs, the .to_irq() function and the irqdomain into the core as well. Acked-by: Thomas Gleixner Acked-by: Alexandre Courbot Signed-off-by: Linus Walleij --- include/linux/gpio/driver.h | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'include/linux/gpio/driver.h') diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index 9fe283642253..c1c5c2368fc8 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h @@ -3,6 +3,9 @@ #include #include +#include +#include +#include struct device; struct gpio_desc; @@ -97,6 +100,17 @@ struct gpio_chip { bool can_sleep; bool exported; +#ifdef CONFIG_GPIOLIB_IRQCHIP + /* + * With CONFIG_GPIO_IRQCHIP we get an irqchip inside the gpiolib + * to handle IRQs for most practical cases. + */ + struct irq_chip *irqchip; + struct irq_domain *irqdomain; + irq_flow_handler_t irq_handler; + unsigned int irq_default_type; +#endif + #if defined(CONFIG_OF_GPIO) /* * If CONFIG_OF is enabled, then all GPIO controllers described in the @@ -190,6 +204,21 @@ struct gpiod_lookup_table { void gpiod_add_lookup_table(struct gpiod_lookup_table *table); +#ifdef CONFIG_GPIOLIB_IRQCHIP + +void gpiochip_set_chained_irqchip(struct gpio_chip *gpiochip, + struct irq_chip *irqchip, + int parent_irq, + irq_flow_handler_t parent_handler); + +int gpiochip_irqchip_add(struct gpio_chip *gpiochip, + struct irq_chip *irqchip, + unsigned int first_irq, + irq_flow_handler_t handler, + unsigned int type); + +#endif /* CONFIG_GPIO_IRQCHIP */ + #else /* CONFIG_GPIOLIB */ static inline struct gpio_chip *gpiod_to_chip(const struct gpio_desc *desc) -- cgit v1.2.3 From c3626fdea044cc97bfc035ebb048f7619acb6736 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Fri, 28 Mar 2014 20:42:01 +0100 Subject: gpio: unmap gpio irqs properly When using the irqchip helper inside the gpiolib, make sure the IRQs are unmapped/disposed before the irqdomain is removed as part of removing the gpiochip. Signed-off-by: Linus Walleij --- include/linux/gpio/driver.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux/gpio/driver.h') diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index c1c5c2368fc8..1827b43966d9 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h @@ -107,6 +107,7 @@ struct gpio_chip { */ struct irq_chip *irqchip; struct irq_domain *irqdomain; + unsigned int irq_base; irq_flow_handler_t irq_handler; unsigned int irq_default_type; #endif -- cgit v1.2.3