diff mbox

gpio: set parent irq on chained handlers

Message ID 1411732349-19178-1-git-send-email-linus.walleij@linaro.org
State Accepted
Commit 83141a771975f4e54402ab05e5cbbc3c56f45bdd
Headers show

Commit Message

Linus Walleij Sept. 26, 2014, 11:52 a.m. UTC
If the IRQ from the parent is nested the IRQ may need to be
resent under certain conditions. Currently the chained IRQ
handler in gpiolib does not handle connecting nested IRQs
but it is conceptually correct to indicate the actual parent
IRQ.

Reported-by: Grygorii Strashko <grygorii.strashko@ti.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/gpio/gpiolib.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

Comments

Grygorii Strashko Sept. 26, 2014, 12:20 p.m. UTC | #1
On 09/26/2014 02:52 PM, Linus Walleij wrote:
> If the IRQ from the parent is nested the IRQ may need to be
> resent under certain conditions. Currently the chained IRQ
> handler in gpiolib does not handle connecting nested IRQs

Seems there is still some misunderstanding ( - chained vs nested IRQs

> but it is conceptually correct to indicate the actual parent
> IRQ.
> 
> Reported-by: Grygorii Strashko <grygorii.strashko@ti.com>

+ Reported-by: Lothar Waßmann <LW@karo-electronics.de>

> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
>   drivers/gpio/gpiolib.c | 13 +++++++++++++
>   1 file changed, 13 insertions(+)
> 
> diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
> index 550e575c6ffb..9362b5b817af 100644
> --- a/drivers/gpio/gpiolib.c
> +++ b/drivers/gpio/gpiolib.c
> @@ -398,17 +398,30 @@ void gpiochip_set_chained_irqchip(struct gpio_chip *gpiochip,
>   				  int parent_irq,
>   				  irq_flow_handler_t parent_handler)
>   {
> +	unsigned int offset;
> +
>   	if (gpiochip->can_sleep) {
>   		chip_err(gpiochip, "you cannot have chained interrupts on a chip that may sleep\n");
>   		return;
>   	}


This function can't be called by gpio-pca953x.c driver  (

> +	if (!gpiochip->irqdomain) {
> +		chip_err(gpiochip, "called %s before setting up irqchip\n",
> +			 __func__);
> +		return;
> +	}
>   
>   	irq_set_chained_handler(parent_irq, parent_handler);
> +
>   	/*
>   	 * The parent irqchip is already using the chip_data for this
>   	 * irqchip, so our callbacks simply use the handler_data.
>   	 */
>   	irq_set_handler_data(parent_irq, gpiochip);
> +
> +	/* Set the parent IRQ for all affected IRQs */
> +	for (offset = 0; offset < gpiochip->ngpio; offset++)
> +		irq_set_parent(irq_find_mapping(gpiochip->irqdomain, offset),
> +			       parent_irq);
>   }
>   EXPORT_SYMBOL_GPL(gpiochip_set_chained_irqchip);
>   
> 

May be some simple helper can be added instead:
 void gpiochip_set_nested_irqchip(struct gpio_chip *gpiochip,
   				  int parent_irq)
  {
 	unsigned int offset;
 
   	if (!gpiochip->can_sleep && !chip->irq_not_threaded) {
   		chip_err(gpiochip, "you cannot have nested interrupts on a chip that can't sleep\n");
   		return;
   	}

	if (!gpiochip->irqdomain) {
		chip_err(gpiochip, "called %s before setting up irqchip\n",
			 __func__);
		return;
	}
 

	/* Set the parent IRQ for all affected IRQs */
	for (offset = 0; offset < gpiochip->ngpio; offset++)
		irq_set_parent(irq_find_mapping(gpiochip->irqdomain, offset),
			       parent_irq);
 }
 EXPORT_SYMBOL_GPL(gpiochip_set_nested_irqchip);
 
regards,
-grygorii
--
To unsubscribe from this list: send the line "unsubscribe linux-gpio" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Linus Walleij Sept. 26, 2014, 12:37 p.m. UTC | #2
On Fri, Sep 26, 2014 at 2:20 PM, Grygorii Strashko
<grygorii.strashko@ti.com> wrote:
> On 09/26/2014 02:52 PM, Linus Walleij wrote:
>> If the IRQ from the parent is nested the IRQ may need to be
>> resent under certain conditions. Currently the chained IRQ
>> handler in gpiolib does not handle connecting nested IRQs
>
> Seems there is still some misunderstanding ( - chained vs nested IRQs

Yeah trying to hash it out...

>> but it is conceptually correct to indicate the actual parent
>> IRQ.
>>
>> Reported-by: Grygorii Strashko <grygorii.strashko@ti.com>
>
> + Reported-by: Lothar Waßmann <LW@karo-electronics.de>

OK.

>>       if (gpiochip->can_sleep) {
>>               chip_err(gpiochip, "you cannot have chained interrupts on a chip that may sleep\n");
>>               return;
>>       }
>
>
> This function can't be called by gpio-pca953x.c driver  (

Yeah I'm toying around with solutions for this...

> May be some simple helper can be added instead:
>  void gpiochip_set_nested_irqchip(struct gpio_chip *gpiochip,
>                                   int parent_irq)

That's one option. I'm trying to come up with something that
duplicates as little code as possible.

Yours,
Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe linux-gpio" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 550e575c6ffb..9362b5b817af 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -398,17 +398,30 @@  void gpiochip_set_chained_irqchip(struct gpio_chip *gpiochip,
 				  int parent_irq,
 				  irq_flow_handler_t parent_handler)
 {
+	unsigned int offset;
+
 	if (gpiochip->can_sleep) {
 		chip_err(gpiochip, "you cannot have chained interrupts on a chip that may sleep\n");
 		return;
 	}
+	if (!gpiochip->irqdomain) {
+		chip_err(gpiochip, "called %s before setting up irqchip\n",
+			 __func__);
+		return;
+	}
 
 	irq_set_chained_handler(parent_irq, parent_handler);
+
 	/*
 	 * The parent irqchip is already using the chip_data for this
 	 * irqchip, so our callbacks simply use the handler_data.
 	 */
 	irq_set_handler_data(parent_irq, gpiochip);
+
+	/* Set the parent IRQ for all affected IRQs */
+	for (offset = 0; offset < gpiochip->ngpio; offset++)
+		irq_set_parent(irq_find_mapping(gpiochip->irqdomain, offset),
+			       parent_irq);
 }
 EXPORT_SYMBOL_GPL(gpiochip_set_chained_irqchip);