From f628ba9e22e0fa32ac6270a0d696fe1509889540 Mon Sep 17 00:00:00 2001 From: Grygorii Strashko Date: Mon, 9 Oct 2017 17:16:05 -0500 Subject: gpiolib: drop irq_base field from gpio_chip struct Hence, the last user of irq_base field was removed by commit b4c495f03ae3 ("gpio: mockup: use irq_sim") it can be removed safely. Signed-off-by: Grygorii Strashko Signed-off-by: Linus Walleij --- include/linux/gpio/driver.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include/linux/gpio') diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index c97f8325e8bf..6bbda879fb8b 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h @@ -83,7 +83,6 @@ struct module; * @irqchip: GPIO IRQ chip impl, provided by GPIO driver * @irqdomain: Interrupt translation domain; responsible for mapping * between GPIO hwirq number and linux irq number - * @irq_base: first linux IRQ number assigned to GPIO IRQ chip (deprecated) * @irq_handler: the irq handler to use (often a predefined irq core function) * for GPIO IRQs, provided by GPIO driver * @irq_default_type: default IRQ triggering type applied during GPIO driver @@ -165,7 +164,6 @@ 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; unsigned int irq_chained_parent; -- cgit From eec1d566cdf94b57e8f5ba9fe60eea214929bcfc Mon Sep 17 00:00:00 2001 From: Lukas Wunner Date: Thu, 12 Oct 2017 12:40:10 +0200 Subject: gpio: Introduce ->get_multiple callback SPI-attached GPIO controllers typically read out all inputs in one go. If callers desire the values of multipe inputs, ideally a single readout should take place to return the desired values. However the current driver API only offers a ->get callback but no ->get_multiple (unlike ->set_multiple, which is present). Thus, to read multiple inputs, a full readout needs to be performed for every single value (barring driver-internal caching), which is inefficient. In fact, the lack of a ->get_multiple callback has been bemoaned repeatedly by the gpio subsystem maintainer: http://www.spinics.net/lists/linux-gpio/msg10571.html http://www.spinics.net/lists/devicetree/msg121734.html Introduce the missing callback. Add corresponding consumer functions such as gpiod_get_array_value(). Amend linehandle_ioctl() to take advantage of the newly added infrastructure. Update the documentation. Cc: Rojhalat Ibrahim Signed-off-by: Lukas Wunner Signed-off-by: Linus Walleij --- include/linux/gpio/consumer.h | 43 +++++++++++++++++++++++++++++++++++++++++++ include/linux/gpio/driver.h | 5 +++++ 2 files changed, 48 insertions(+) (limited to 'include/linux/gpio') diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h index 8f702fcbe485..d4920ec1f1da 100644 --- a/include/linux/gpio/consumer.h +++ b/include/linux/gpio/consumer.h @@ -99,10 +99,15 @@ int gpiod_direction_output_raw(struct gpio_desc *desc, int value); /* Value get/set from non-sleeping context */ int gpiod_get_value(const struct gpio_desc *desc); +int gpiod_get_array_value(unsigned int array_size, + struct gpio_desc **desc_array, int *value_array); void gpiod_set_value(struct gpio_desc *desc, int value); void gpiod_set_array_value(unsigned int array_size, struct gpio_desc **desc_array, int *value_array); int gpiod_get_raw_value(const struct gpio_desc *desc); +int gpiod_get_raw_array_value(unsigned int array_size, + struct gpio_desc **desc_array, + int *value_array); void gpiod_set_raw_value(struct gpio_desc *desc, int value); void gpiod_set_raw_array_value(unsigned int array_size, struct gpio_desc **desc_array, @@ -110,11 +115,17 @@ void gpiod_set_raw_array_value(unsigned int array_size, /* Value get/set from sleeping context */ int gpiod_get_value_cansleep(const struct gpio_desc *desc); +int gpiod_get_array_value_cansleep(unsigned int array_size, + struct gpio_desc **desc_array, + int *value_array); void gpiod_set_value_cansleep(struct gpio_desc *desc, int value); void gpiod_set_array_value_cansleep(unsigned int array_size, struct gpio_desc **desc_array, int *value_array); int gpiod_get_raw_value_cansleep(const struct gpio_desc *desc); +int gpiod_get_raw_array_value_cansleep(unsigned int array_size, + struct gpio_desc **desc_array, + int *value_array); void gpiod_set_raw_value_cansleep(struct gpio_desc *desc, int value); void gpiod_set_raw_array_value_cansleep(unsigned int array_size, struct gpio_desc **desc_array, @@ -305,6 +316,14 @@ static inline int gpiod_get_value(const struct gpio_desc *desc) WARN_ON(1); return 0; } +static inline int gpiod_get_array_value(unsigned int array_size, + struct gpio_desc **desc_array, + int *value_array) +{ + /* GPIO can never have been requested */ + WARN_ON(1); + return 0; +} static inline void gpiod_set_value(struct gpio_desc *desc, int value) { /* GPIO can never have been requested */ @@ -323,6 +342,14 @@ static inline int gpiod_get_raw_value(const struct gpio_desc *desc) WARN_ON(1); return 0; } +static inline int gpiod_get_raw_array_value(unsigned int array_size, + struct gpio_desc **desc_array, + int *value_array) +{ + /* GPIO can never have been requested */ + WARN_ON(1); + return 0; +} static inline void gpiod_set_raw_value(struct gpio_desc *desc, int value) { /* GPIO can never have been requested */ @@ -342,6 +369,14 @@ static inline int gpiod_get_value_cansleep(const struct gpio_desc *desc) WARN_ON(1); return 0; } +static inline int gpiod_get_array_value_cansleep(unsigned int array_size, + struct gpio_desc **desc_array, + int *value_array) +{ + /* GPIO can never have been requested */ + WARN_ON(1); + return 0; +} static inline void gpiod_set_value_cansleep(struct gpio_desc *desc, int value) { /* GPIO can never have been requested */ @@ -360,6 +395,14 @@ static inline int gpiod_get_raw_value_cansleep(const struct gpio_desc *desc) WARN_ON(1); return 0; } +static inline int gpiod_get_raw_array_value_cansleep(unsigned int array_size, + struct gpio_desc **desc_array, + int *value_array) +{ + /* GPIO can never have been requested */ + WARN_ON(1); + return 0; +} static inline void gpiod_set_raw_value_cansleep(struct gpio_desc *desc, int value) { diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index 6bbda879fb8b..bda95a9b7b8c 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h @@ -35,6 +35,8 @@ struct module; * @direction_input: configures signal "offset" as input, or returns error * @direction_output: configures signal "offset" as output, or returns error * @get: returns value for signal "offset", 0=low, 1=high, or negative error + * @get_multiple: reads values for multiple signals defined by "mask" and + * stores them in "bits", returns 0 on success or negative error * @set: assigns output value for signal "offset" * @set_multiple: assigns output values for multiple signals defined by "mask" * @set_config: optional hook for all kinds of settings. Uses the same @@ -125,6 +127,9 @@ struct gpio_chip { unsigned offset, int value); int (*get)(struct gpio_chip *chip, unsigned offset); + int (*get_multiple)(struct gpio_chip *chip, + unsigned long *mask, + unsigned long *bits); void (*set)(struct gpio_chip *chip, unsigned offset, int value); void (*set_multiple)(struct gpio_chip *chip, -- cgit From 2cbfca66ba5e00606bb0f24aba1e9cd8efe58849 Mon Sep 17 00:00:00 2001 From: Andrew Jeffery Date: Fri, 20 Oct 2017 13:27:58 +1030 Subject: gpio: Fix loose spelling Literally. I expect "lose" was meant here, rather than "loose", though you could feasibly use a somewhat uncommon definition of "loose" to mean what would be meant by "lose": "Loose the hounds" for instance, as in "Release the hounds". Substituting in "value" for "hounds" gives "release the value", and makes some sense, but futher substituting back to loose gives "loose the value" which overall just seems a bit anachronistic. Instead, use modern, pragmatic English and save a character. Cc: Russell Currey Signed-off-by: Andrew Jeffery Signed-off-by: Linus Walleij --- include/linux/gpio/machine.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux/gpio') diff --git a/include/linux/gpio/machine.h b/include/linux/gpio/machine.h index ba4ccfd900f9..5e9f294c29eb 100644 --- a/include/linux/gpio/machine.h +++ b/include/linux/gpio/machine.h @@ -10,7 +10,7 @@ enum gpio_lookup_flags { GPIO_OPEN_DRAIN = (1 << 1), GPIO_OPEN_SOURCE = (1 << 2), GPIO_SLEEP_MAINTAIN_VALUE = (0 << 3), - GPIO_SLEEP_MAY_LOOSE_VALUE = (1 << 3), + GPIO_SLEEP_MAY_LOSE_VALUE = (1 << 3), }; /** -- cgit From 24efd94bc38290dc1d9775a1e767ed4685d8a79b Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Fri, 20 Oct 2017 16:31:27 +0200 Subject: gpio: mmio: Make pin2mask() a private business The vtable call pin2mask() was introducing a vtable function call in every gpiochip callback for a generic MMIO GPIO chip. This was not exactly efficient. (Maybe link-time optimization could get rid of it, I don't know.) After removing all external calls into this API we can make it a boolean flag in the struct gpio_chip call and sink the function into the gpio-mmio driver yielding encapsulation and potential speedups. Cc: Anton Vorontsov Signed-off-by: Linus Walleij --- include/linux/gpio/driver.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'include/linux/gpio') diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index bda95a9b7b8c..ed04fa2a00a8 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h @@ -67,9 +67,9 @@ struct module; * registers. * @read_reg: reader function for generic GPIO * @write_reg: writer function for generic GPIO - * @pin2mask: some generic GPIO controllers work with the big-endian bits - * notation, e.g. in a 8-bits register, GPIO7 is the least significant - * bit. This callback assigns the right bit mask. + * @be_bits: if the generic GPIO has big endian bit order (bit 31 is representing + * line 0, bit 30 is line 1 ... bit 0 is line 31) this is set to true by the + * generic GPIO core. It is for internal housekeeping only. * @reg_dat: data (in) register for generic GPIO * @reg_set: output set register (out=high) for generic GPIO * @reg_clr: output clear register (out=low) for generic GPIO @@ -151,7 +151,7 @@ struct gpio_chip { #if IS_ENABLED(CONFIG_GPIO_GENERIC) unsigned long (*read_reg)(void __iomem *reg); void (*write_reg)(void __iomem *reg, unsigned long data); - unsigned long (*pin2mask)(struct gpio_chip *gc, unsigned int pin); + bool be_bits; void __iomem *reg_dat; void __iomem *reg_set; void __iomem *reg_clr; -- cgit From c44eafd79be666e7c81d22e215c945b27f2785f7 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Tue, 7 Nov 2017 19:15:45 +0100 Subject: gpio: Introduce struct gpio_irq_chip This new structure will be used to group all fields related to interrupt handling in a GPIO chip. Doing so will properly namespace these fields and make it easier to distinguish which fields are used for IRQ support. Signed-off-by: Thierry Reding Acked-by: Grygorii Strashko Signed-off-by: Linus Walleij --- include/linux/gpio/driver.h | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'include/linux/gpio') diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index ed04fa2a00a8..36a065521fa0 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h @@ -19,6 +19,36 @@ struct module; #ifdef CONFIG_GPIOLIB +#ifdef CONFIG_GPIOLIB_IRQCHIP +/** + * struct gpio_irq_chip - GPIO interrupt controller + */ +struct gpio_irq_chip { + /** + * @domain_ops: + * + * Table of interrupt domain operations for this IRQ chip. + */ + const struct irq_domain_ops *domain_ops; + + /** + * @parent_handler: + * + * The interrupt handler for the GPIO chip's parent interrupts, may be + * NULL if the parent interrupts are nested rather than cascaded. + */ + irq_flow_handler_t parent_handler; + + /** + * @parent_handler_data: + * + * Data associated, and passed to, the handler for the parent + * interrupt. + */ + void *parent_handler_data; +}; +#endif + /** * struct gpio_chip - abstract a GPIO controller * @label: a functional name for the GPIO device, such as a part @@ -176,6 +206,14 @@ struct gpio_chip { bool irq_need_valid_mask; unsigned long *irq_valid_mask; struct lock_class_key *lock_key; + + /** + * @irq: + * + * Integrates interrupt chip functionality with the GPIO chip. Can be + * used to handle IRQs for most practical cases. + */ + struct gpio_irq_chip irq; #endif #if defined(CONFIG_OF_GPIO) -- cgit From da80ff81a8f54611b834d73149f8ac0d59151c87 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Tue, 7 Nov 2017 19:15:46 +0100 Subject: gpio: Move irqchip into struct gpio_irq_chip In order to consolidate the multiple ways to associate an IRQ chip with a GPIO chip, move more fields into the new struct gpio_irq_chip. Signed-off-by: Thierry Reding Acked-by: Grygorii Strashko Signed-off-by: Linus Walleij --- include/linux/gpio/driver.h | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'include/linux/gpio') diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index 36a065521fa0..a79b3b18fadd 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h @@ -24,6 +24,13 @@ struct module; * struct gpio_irq_chip - GPIO interrupt controller */ struct gpio_irq_chip { + /** + * @chip: + * + * GPIO IRQ chip implementation, provided by GPIO driver. + */ + struct irq_chip *chip; + /** * @domain_ops: * @@ -47,6 +54,11 @@ struct gpio_irq_chip { */ void *parent_handler_data; }; + +static inline struct gpio_irq_chip *to_gpio_irq_chip(struct irq_chip *chip) +{ + return container_of(chip, struct gpio_irq_chip, chip); +} #endif /** @@ -112,7 +124,6 @@ struct gpio_irq_chip { * safely. * @bgpio_dir: shadowed direction register for generic GPIO to clear/set * direction safely. - * @irqchip: GPIO IRQ chip impl, provided by GPIO driver * @irqdomain: Interrupt translation domain; responsible for mapping * between GPIO hwirq number and linux irq number * @irq_handler: the irq handler to use (often a predefined irq core function) @@ -197,7 +208,6 @@ struct gpio_chip { * With CONFIG_GPIOLIB_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; -- cgit From f0fbe7bce733561b76a5b55c5f4625888acd3792 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Tue, 7 Nov 2017 19:15:47 +0100 Subject: gpio: Move irqdomain into struct gpio_irq_chip In order to consolidate the multiple ways to associate an IRQ chip with a GPIO chip, move more fields into the new struct gpio_irq_chip. Signed-off-by: Thierry Reding Acked-by: Grygorii Strashko Signed-off-by: Linus Walleij --- include/linux/gpio/driver.h | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'include/linux/gpio') diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index a79b3b18fadd..c5dfa8c0b829 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h @@ -31,6 +31,14 @@ struct gpio_irq_chip { */ struct irq_chip *chip; + /** + * @domain: + * + * Interrupt translation domain; responsible for mapping between GPIO + * hwirq number and Linux IRQ number. + */ + struct irq_domain *domain; + /** * @domain_ops: * @@ -124,8 +132,6 @@ static inline struct gpio_irq_chip *to_gpio_irq_chip(struct irq_chip *chip) * safely. * @bgpio_dir: shadowed direction register for generic GPIO to clear/set * direction safely. - * @irqdomain: Interrupt translation domain; responsible for mapping - * between GPIO hwirq number and linux irq number * @irq_handler: the irq handler to use (often a predefined irq core function) * for GPIO IRQs, provided by GPIO driver * @irq_default_type: default IRQ triggering type applied during GPIO driver @@ -208,7 +214,6 @@ struct gpio_chip { * With CONFIG_GPIOLIB_IRQCHIP we get an irqchip inside the gpiolib * to handle IRQs for most practical cases. */ - struct irq_domain *irqdomain; irq_flow_handler_t irq_handler; unsigned int irq_default_type; unsigned int irq_chained_parent; -- cgit From c7a0aa59524c5bb20bebaca360f7c5faaec6b806 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Tue, 7 Nov 2017 19:15:48 +0100 Subject: gpio: Move irq_handler to struct gpio_irq_chip In order to consolidate the multiple ways to associate an IRQ chip with a GPIO chip, move more fields into the new struct gpio_irq_chip. Signed-off-by: Thierry Reding Acked-by: Grygorii Strashko Signed-off-by: Linus Walleij --- include/linux/gpio/driver.h | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'include/linux/gpio') diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index c5dfa8c0b829..864f507e859b 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h @@ -46,6 +46,14 @@ struct gpio_irq_chip { */ const struct irq_domain_ops *domain_ops; + /** + * @handler: + * + * The IRQ handler to use (often a predefined IRQ core function) for + * GPIO IRQs, provided by GPIO driver. + */ + irq_flow_handler_t handler; + /** * @parent_handler: * @@ -132,8 +140,6 @@ static inline struct gpio_irq_chip *to_gpio_irq_chip(struct irq_chip *chip) * safely. * @bgpio_dir: shadowed direction register for generic GPIO to clear/set * direction safely. - * @irq_handler: the irq handler to use (often a predefined irq core function) - * for GPIO IRQs, provided by GPIO driver * @irq_default_type: default IRQ triggering type applied during GPIO driver * initialization, provided by GPIO driver * @irq_chained_parent: GPIO IRQ chip parent/bank linux irq number, @@ -214,7 +220,6 @@ struct gpio_chip { * With CONFIG_GPIOLIB_IRQCHIP we get an irqchip inside the gpiolib * to handle IRQs for most practical cases. */ - irq_flow_handler_t irq_handler; unsigned int irq_default_type; unsigned int irq_chained_parent; bool irq_nested; -- cgit From 3634eeb0fe9176e453c99834749dce21ea1305c1 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Tue, 7 Nov 2017 19:15:49 +0100 Subject: gpio: Move irq_default_type to struct gpio_irq_chip In order to consolidate the multiple ways to associate an IRQ chip with a GPIO chip, move more fields into the new struct gpio_irq_chip. Signed-off-by: Thierry Reding Acked-by: Grygorii Strashko Signed-off-by: Linus Walleij --- include/linux/gpio/driver.h | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'include/linux/gpio') diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index 864f507e859b..1367fa94105f 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h @@ -54,6 +54,14 @@ struct gpio_irq_chip { */ irq_flow_handler_t handler; + /** + * @default_type: + * + * Default IRQ triggering type applied during GPIO driver + * initialization, provided by GPIO driver. + */ + unsigned int default_type; + /** * @parent_handler: * @@ -140,8 +148,6 @@ static inline struct gpio_irq_chip *to_gpio_irq_chip(struct irq_chip *chip) * safely. * @bgpio_dir: shadowed direction register for generic GPIO to clear/set * direction safely. - * @irq_default_type: default IRQ triggering type applied during GPIO driver - * initialization, provided by GPIO driver * @irq_chained_parent: GPIO IRQ chip parent/bank linux irq number, * provided by GPIO driver for chained interrupt (not for nested * interrupts). @@ -220,7 +226,6 @@ struct gpio_chip { * With CONFIG_GPIOLIB_IRQCHIP we get an irqchip inside the gpiolib * to handle IRQs for most practical cases. */ - unsigned int irq_default_type; unsigned int irq_chained_parent; bool irq_nested; bool irq_need_valid_mask; -- cgit From 39e5f0969514fbfd6c235ac52586c72ca77cee00 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Tue, 7 Nov 2017 19:15:50 +0100 Subject: gpio: Move irq_chained_parent to struct gpio_irq_chip In order to consolidate the multiple ways to associate an IRQ chip with a GPIO chip, move more fields into the new struct gpio_irq_chip. Signed-off-by: Thierry Reding Acked-by: Grygorii Strashko Signed-off-by: Linus Walleij --- include/linux/gpio/driver.h | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'include/linux/gpio') diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index 1367fa94105f..86f00d908e90 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h @@ -77,6 +77,21 @@ struct gpio_irq_chip { * interrupt. */ void *parent_handler_data; + + /** + * @num_parents: + * + * The number of interrupt parents of a GPIO chip. + */ + unsigned int num_parents; + + /** + * @parents: + * + * A list of interrupt parents of a GPIO chip. This is owned by the + * driver, so the core will only reference this list, not modify it. + */ + unsigned int *parents; }; static inline struct gpio_irq_chip *to_gpio_irq_chip(struct irq_chip *chip) @@ -148,9 +163,6 @@ static inline struct gpio_irq_chip *to_gpio_irq_chip(struct irq_chip *chip) * safely. * @bgpio_dir: shadowed direction register for generic GPIO to clear/set * direction safely. - * @irq_chained_parent: GPIO IRQ chip parent/bank linux irq number, - * provided by GPIO driver for chained interrupt (not for nested - * interrupts). * @irq_nested: True if set the interrupt handling is nested. * @irq_need_valid_mask: If set core allocates @irq_valid_mask with all * bits set to one @@ -226,7 +238,6 @@ struct gpio_chip { * With CONFIG_GPIOLIB_IRQCHIP we get an irqchip inside the gpiolib * to handle IRQs for most practical cases. */ - unsigned int irq_chained_parent; bool irq_nested; bool irq_need_valid_mask; unsigned long *irq_valid_mask; -- cgit From dc6bafee86897419b0908e8d1e52ef46ca0ea487 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Tue, 7 Nov 2017 19:15:51 +0100 Subject: gpio: Move irq_nested into struct gpio_irq_chip In order to consolidate the multiple ways to associate an IRQ chip with a GPIO chip, move more fields into the new struct gpio_irq_chip. Signed-off-by: Thierry Reding Acked-by: Grygorii Strashko Signed-off-by: Linus Walleij --- include/linux/gpio/driver.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'include/linux/gpio') diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index 86f00d908e90..1c3d06fe54b1 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h @@ -92,6 +92,13 @@ struct gpio_irq_chip { * driver, so the core will only reference this list, not modify it. */ unsigned int *parents; + + /** + * @nested: + * + * True if set the interrupt handling is nested. + */ + bool nested; }; static inline struct gpio_irq_chip *to_gpio_irq_chip(struct irq_chip *chip) @@ -163,7 +170,6 @@ static inline struct gpio_irq_chip *to_gpio_irq_chip(struct irq_chip *chip) * safely. * @bgpio_dir: shadowed direction register for generic GPIO to clear/set * direction safely. - * @irq_nested: True if set the interrupt handling is nested. * @irq_need_valid_mask: If set core allocates @irq_valid_mask with all * bits set to one * @irq_valid_mask: If not %NULL holds bitmask of GPIOs which are valid to @@ -238,7 +244,6 @@ struct gpio_chip { * With CONFIG_GPIOLIB_IRQCHIP we get an irqchip inside the gpiolib * to handle IRQs for most practical cases. */ - bool irq_nested; bool irq_need_valid_mask; unsigned long *irq_valid_mask; struct lock_class_key *lock_key; -- cgit From dc7b0387ee894c115ef5ddcaaf794125d6d9058c Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Tue, 7 Nov 2017 19:15:52 +0100 Subject: gpio: Move irq_valid_mask into struct gpio_irq_chip In order to consolidate the multiple ways to associate an IRQ chip with a GPIO chip, move more fields into the new struct gpio_irq_chip. Signed-off-by: Thierry Reding Acked-by: Grygorii Strashko Signed-off-by: Linus Walleij --- include/linux/gpio/driver.h | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'include/linux/gpio') diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index 1c3d06fe54b1..067efcd4f46d 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h @@ -99,6 +99,21 @@ struct gpio_irq_chip { * True if set the interrupt handling is nested. */ bool nested; + + /** + * @need_valid_mask: + * + * If set core allocates @valid_mask with all bits set to one. + */ + bool need_valid_mask; + + /** + * @valid_mask: + * + * If not %NULL holds bitmask of GPIOs which are valid to be included + * in IRQ domain of the chip. + */ + unsigned long *valid_mask; }; static inline struct gpio_irq_chip *to_gpio_irq_chip(struct irq_chip *chip) @@ -170,10 +185,6 @@ static inline struct gpio_irq_chip *to_gpio_irq_chip(struct irq_chip *chip) * safely. * @bgpio_dir: shadowed direction register for generic GPIO to clear/set * direction safely. - * @irq_need_valid_mask: If set core allocates @irq_valid_mask with all - * bits set to one - * @irq_valid_mask: If not %NULL holds bitmask of GPIOs which are valid to - * be included in IRQ domain of the chip * @lock_key: per GPIO IRQ chip lockdep class * * A gpio_chip can help platforms abstract various sources of GPIOs so @@ -244,8 +255,6 @@ struct gpio_chip { * With CONFIG_GPIOLIB_IRQCHIP we get an irqchip inside the gpiolib * to handle IRQs for most practical cases. */ - bool irq_need_valid_mask; - unsigned long *irq_valid_mask; struct lock_class_key *lock_key; /** -- cgit From ca9df053fb2bb2fcc64f37a1668321c7e19edd04 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Tue, 7 Nov 2017 19:15:53 +0100 Subject: gpio: Move lock_key into struct gpio_irq_chip In order to consolidate the multiple ways to associate an IRQ chip with a GPIO chip, move more fields into the new struct gpio_irq_chip. Signed-off-by: Thierry Reding Acked-by: Grygorii Strashko Signed-off-by: Linus Walleij --- include/linux/gpio/driver.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'include/linux/gpio') diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index 067efcd4f46d..c363ee198ff9 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h @@ -62,6 +62,13 @@ struct gpio_irq_chip { */ unsigned int default_type; + /** + * @lock_key: + * + * Per GPIO IRQ chip lockdep class. + */ + struct lock_class_key *lock_key; + /** * @parent_handler: * @@ -185,7 +192,6 @@ static inline struct gpio_irq_chip *to_gpio_irq_chip(struct irq_chip *chip) * safely. * @bgpio_dir: shadowed direction register for generic GPIO to clear/set * direction safely. - * @lock_key: per GPIO IRQ chip lockdep class * * A gpio_chip can help platforms abstract various sources of GPIOs so * they can all be accessed through a common programing interface. @@ -255,7 +261,6 @@ struct gpio_chip { * With CONFIG_GPIOLIB_IRQCHIP we get an irqchip inside the gpiolib * to handle IRQs for most practical cases. */ - struct lock_class_key *lock_key; /** * @irq: -- cgit From e0d89728981393b7d694bd3419b7794b9882c92d Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Tue, 7 Nov 2017 19:15:54 +0100 Subject: gpio: Implement tighter IRQ chip integration Currently GPIO drivers are required to add the GPIO chip and its corresponding IRQ chip separately, which can result in a lot of boilerplate. Use the newly introduced struct gpio_irq_chip, embedded in struct gpio_chip, that drivers can fill in if they want the GPIO core to automatically register the IRQ chip associated with a GPIO chip. Signed-off-by: Thierry Reding Acked-by: Grygorii Strashko Signed-off-by: Linus Walleij --- include/linux/gpio/driver.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'include/linux/gpio') diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index c363ee198ff9..51fc7b023364 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h @@ -100,6 +100,13 @@ struct gpio_irq_chip { */ unsigned int *parents; + /** + * @map: + * + * A list of interrupt parents for each line of a GPIO chip. + */ + unsigned int *map; + /** * @nested: * -- cgit From 1b95b4eb567aab1cafcdcb14c60a7dd9d56236a9 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Tue, 7 Nov 2017 19:15:55 +0100 Subject: gpio: Export gpiochip_irq_{map,unmap}() Export these functions so that drivers can explicitly use these when setting up their IRQ domain. Signed-off-by: Thierry Reding Acked-by: Grygorii Strashko Signed-off-by: Linus Walleij --- include/linux/gpio/driver.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include/linux/gpio') diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index 51fc7b023364..bbe5c647f29d 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h @@ -367,6 +367,10 @@ int bgpio_init(struct gpio_chip *gc, struct device *dev, #ifdef CONFIG_GPIOLIB_IRQCHIP +int gpiochip_irq_map(struct irq_domain *d, unsigned int irq, + irq_hw_number_t hwirq); +void gpiochip_irq_unmap(struct irq_domain *d, unsigned int irq); + void gpiochip_set_chained_irqchip(struct gpio_chip *gpiochip, struct irq_chip *irqchip, unsigned int parent_irq, -- cgit From 60ed54cae8dc0f2d41cafbd477bbed6deb716615 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Tue, 7 Nov 2017 19:15:57 +0100 Subject: gpio: Disambiguate struct gpio_irq_chip.nested The nested field in struct gpio_irq_chip currently has two meanings. On one hand it marks an IRQ chip as being nested (as opposed to chained), while on the other hand it also means that an IRQ chip uses nested thread handlers. However, nested IRQ chips can already be identified by the fact that they don't pass a parent handler (the driver would instead already have installed a nested handler using request_irq()). Therefore, the only use for the nested attribute is to inform gpiolib that an IRQ chip uses nested thread handlers (as opposed to regular, non-threaded handlers). To clarify its purpose, rename the field to "threaded". Signed-off-by: Thierry Reding Acked-by: Grygorii Strashko Signed-off-by: Linus Walleij --- include/linux/gpio/driver.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'include/linux/gpio') diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index bbe5c647f29d..0a3fdd4d9d8d 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h @@ -108,11 +108,11 @@ struct gpio_irq_chip { unsigned int *map; /** - * @nested: + * @threaded: * - * True if set the interrupt handling is nested. + * True if set the interrupt handling uses nested threads. */ - bool nested; + bool threaded; /** * @need_valid_mask: @@ -385,7 +385,7 @@ int gpiochip_irqchip_add_key(struct gpio_chip *gpiochip, unsigned int first_irq, irq_flow_handler_t handler, unsigned int type, - bool nested, + bool threaded, struct lock_class_key *lock_key); #ifdef CONFIG_LOCKDEP -- cgit From 8302cf585288f75fd253f6b9a094d51ae371a3f3 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Tue, 7 Nov 2017 19:15:58 +0100 Subject: gpio: Introduce struct gpio_irq_chip.first Some GPIO chips cannot support sparse IRQ numbering and therefore need to manually allocate their interrupt descriptors statically. For these cases, a driver can pass the first allocated IRQ via the struct gpio_irq_chip's "first" field and thereby cause the IRQ domain to map all IRQs during initialization. Suggested-by: Grygorii Strashko Signed-off-by: Thierry Reding Acked-by: Grygorii Strashko Signed-off-by: Linus Walleij --- include/linux/gpio/driver.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'include/linux/gpio') diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index 0a3fdd4d9d8d..a77d4ada060c 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h @@ -128,6 +128,14 @@ struct gpio_irq_chip { * in IRQ domain of the chip. */ unsigned long *valid_mask; + + /** + * @first: + * + * Required for static IRQ allocation. If set, irq_domain_add_simple() + * will allocate and map all IRQs during initialization. + */ + unsigned int first; }; static inline struct gpio_irq_chip *to_gpio_irq_chip(struct irq_chip *chip) -- cgit From 959bc7b22bd25a3a907fbb9b26a1d0cbdf98ef40 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Tue, 7 Nov 2017 19:15:59 +0100 Subject: gpio: Automatically add lockdep keys In order to avoid lockdep boilerplate in individual drivers, turn the gpiochip_add_data() function into a macro that creates a unique class key for each driver. Note that this has the slight disadvantage of adding a key for each driver registered with the system. However, these keys are 8 bytes in size, which is negligible and a small price to pay for generic infrastructure. Suggested-by: Grygorii Strashko Signed-off-by: Thierry Reding Acked-by: Grygorii Strashko [renane __gpiochip_add_data() to gpiochip_add_data_with_key] Signed-off-by: Linus Walleij --- include/linux/gpio/driver.h | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) (limited to 'include/linux/gpio') diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index a77d4ada060c..8dd282c5167a 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h @@ -321,7 +321,41 @@ extern const char *gpiochip_is_requested(struct gpio_chip *chip, unsigned offset); /* add/remove chips */ -extern int gpiochip_add_data(struct gpio_chip *chip, void *data); +extern int gpiochip_add_data_with_key(struct gpio_chip *chip, void *data, + struct lock_class_key *lock_key); + +/** + * gpiochip_add_data() - register a gpio_chip + * @chip: the chip to register, with chip->base initialized + * @data: driver-private data associated with this chip + * + * Context: potentially before irqs will work + * + * When gpiochip_add_data() is called very early during boot, so that GPIOs + * can be freely used, the chip->parent device must be registered before + * the gpio framework's arch_initcall(). Otherwise sysfs initialization + * for GPIOs will fail rudely. + * + * gpiochip_add_data() must only be called after gpiolib initialization, + * ie after core_initcall(). + * + * If chip->base is negative, this requests dynamic assignment of + * a range of valid GPIOs. + * + * Returns: + * A negative errno if the chip can't be registered, such as because the + * chip->base is invalid or already associated with a different chip. + * Otherwise it returns zero as a success code. + */ +#ifdef CONFIG_LOCKDEP +#define gpiochip_add_data(chip, data) ({ \ + static struct lock_class_key key; \ + gpiochip_add_data_with_key(chip, data, &key); \ + }) +#else +#define gpiochip_add_data(chip, data) gpiochip_add_data_with_key(chip, data, NULL) +#endif + static inline int gpiochip_add(struct gpio_chip *chip) { return gpiochip_add_data(chip, NULL); -- cgit