linux-gpio.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/2] gpio: pcf857x: Propagate wake-up setting to parent irq controller
@ 2014-12-10 13:36 Geert Uytterhoeven
  2014-12-10 13:36 ` [PATCH 2/2] [RFC] genirq: Set IRQCHIP_SKIP_SET_WAKE for no_irq_chip and dummy_irq_chip Geert Uytterhoeven
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Geert Uytterhoeven @ 2014-12-10 13:36 UTC (permalink / raw)
  To: Linus Walleij, Alexandre Courbot, Thomas Gleixner
  Cc: Santosh Shilimkar, Ingo Molnar, linux-gpio, linux-sh,
	linux-kernel, Geert Uytterhoeven

The pcf857x GPIO and interrupt controller uses dummy_irq_chip, which
does not implement irq_chip.irq_set_wake() and does not set
IRQCHIP_SKIP_SET_WAKE.

This causes two s2ram issues if wake-up is enabled for the pcf857x GPIO
pins:
  1. During resume from s2ram, the following warning is printed:

     WARNING: CPU: 0 PID: 1046 at kernel/irq/manage.c:537 irq_set_irq_wake+0x9c/0xf8()
     Unbalanced IRQ 113 wake disable

  2. Wake-up through the pcf857x GPIO pins may fail, as the parent
     interrupt controller may be suspended.

Migrate the pcf857x GPIO and interrupt controller from dummy_irq_chip to
its own irq_chip. This irq chip implements irq_chip.irq_set_wake() to
propagate its wake-up setting to the parent interrupt controller.

This fixes wake-up through gpio-keys on sh73a0/kzm9g, where the pcf857x
interrupt is cascaded to irq-renesas-intc-irqpin, and the latter must
not be suspended when wake-up is enabled.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
 drivers/gpio/gpio-pcf857x.c | 33 ++++++++++++++++++++++++++++++++-
 1 file changed, 32 insertions(+), 1 deletion(-)

diff --git a/drivers/gpio/gpio-pcf857x.c b/drivers/gpio/gpio-pcf857x.c
index 236708ad0a5ba0ab..22dbecb004cf6c5b 100644
--- a/drivers/gpio/gpio-pcf857x.c
+++ b/drivers/gpio/gpio-pcf857x.c
@@ -218,14 +218,45 @@ static irqreturn_t pcf857x_irq(int irq, void *data)
 	return IRQ_HANDLED;
 }
 
+/*
+ * NOP functions
+ */
+static void noop(struct irq_data *data) { }
+
+static unsigned int noop_ret(struct irq_data *data)
+{
+	return 0;
+}
+
+static int pcf857x_irq_set_wake(struct irq_data *data, unsigned int on)
+{
+	struct pcf857x *gpio = irq_data_get_irq_chip_data(data);
+
+	irq_set_irq_wake(gpio->client->irq, on);
+	return 0;
+}
+
+static struct irq_chip pcf857x_irq_chip = {
+	.name		= "pcf857x",
+	.irq_startup	= noop_ret,
+	.irq_shutdown	= noop,
+	.irq_enable	= noop,
+	.irq_disable	= noop,
+	.irq_ack	= noop,
+	.irq_mask	= noop,
+	.irq_unmask	= noop,
+	.irq_set_wake	= pcf857x_irq_set_wake,
+};
+
 static int pcf857x_irq_domain_map(struct irq_domain *domain, unsigned int irq,
 				 irq_hw_number_t hw)
 {
 	struct pcf857x *gpio = domain->host_data;
 
 	irq_set_chip_and_handler(irq,
-				 &dummy_irq_chip,
+				 &pcf857x_irq_chip,
 				 handle_level_irq);
+	irq_set_chip_data(irq, gpio);
 #ifdef CONFIG_ARM
 	set_irq_flags(irq, IRQF_VALID);
 #else
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 2/2] [RFC] genirq: Set IRQCHIP_SKIP_SET_WAKE for no_irq_chip and dummy_irq_chip
  2014-12-10 13:36 [PATCH 1/2] gpio: pcf857x: Propagate wake-up setting to parent irq controller Geert Uytterhoeven
@ 2014-12-10 13:36 ` Geert Uytterhoeven
  2014-12-17  6:01 ` [PATCH 1/2] gpio: pcf857x: Propagate wake-up setting to parent irq controller Alexandre Courbot
  2015-01-13 14:26 ` Linus Walleij
  2 siblings, 0 replies; 5+ messages in thread
From: Geert Uytterhoeven @ 2014-12-10 13:36 UTC (permalink / raw)
  To: Linus Walleij, Alexandre Courbot, Thomas Gleixner
  Cc: Santosh Shilimkar, Ingo Molnar, linux-gpio, linux-sh,
	linux-kernel, Geert Uytterhoeven

If no_irq_chip or dummy_irq_chip are used for wake up (e.g. gpio-keys
with a simple GPIO controller), the following warning is printed on
resume from s2ram:

    WANING: CPU: 0 PID: 1046 at kernel/irq/manage.c:537 irq_set_irq_wake+0x9c/0xf8()
    Unbalanced IRQ 113 wake disable

This happens because no_irq_chip and dummy_irq_chip do not implement
irq_chip.irq_set_wake(), causing set_irq_wake_real() to return -ENXIO,
and irq_set_irq_wake() to reset the wake_depth to zero.

Set IRQCHIP_SKIP_SET_WAKE to indicate that irq_chip.irq_set_wake() is
not implemented.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
Alternatively, can't we remove IRQCHIP_SKIP_SET_WAKE, and just check for
the presence of irq_chip.irq_set_wake()?
I'll be happy to send a patch to do that instead...

Is there anything that relies on this -ENXIO error code?
All irq_chip implementations that set IRQCHIP_SKIP_SET_WAKE do not
implement irq_chip.irq_set_wake(). There are probably more of them that
forgot to set IRQCHIP_SKIP_SET_WAKE though.
Am I missing something?
Commit 60f96b41f71d2a13 ("genirq: Add IRQCHIP_SKIP_SET_WAKE flag")
doesn't explain why adding the flag was chosen.

Thanks!
---
 kernel/irq/dummychip.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/kernel/irq/dummychip.c b/kernel/irq/dummychip.c
index 988dc58e8847f6eb..326a67f2410bf95c 100644
--- a/kernel/irq/dummychip.c
+++ b/kernel/irq/dummychip.c
@@ -42,6 +42,7 @@ struct irq_chip no_irq_chip = {
 	.irq_enable	= noop,
 	.irq_disable	= noop,
 	.irq_ack	= ack_bad,
+	.flags		= IRQCHIP_SKIP_SET_WAKE,
 };
 
 /*
@@ -57,5 +58,6 @@ struct irq_chip dummy_irq_chip = {
 	.irq_ack	= noop,
 	.irq_mask	= noop,
 	.irq_unmask	= noop,
+	.flags		= IRQCHIP_SKIP_SET_WAKE,
 };
 EXPORT_SYMBOL_GPL(dummy_irq_chip);
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/2] gpio: pcf857x: Propagate wake-up setting to parent irq controller
  2014-12-10 13:36 [PATCH 1/2] gpio: pcf857x: Propagate wake-up setting to parent irq controller Geert Uytterhoeven
  2014-12-10 13:36 ` [PATCH 2/2] [RFC] genirq: Set IRQCHIP_SKIP_SET_WAKE for no_irq_chip and dummy_irq_chip Geert Uytterhoeven
@ 2014-12-17  6:01 ` Alexandre Courbot
  2014-12-17  8:13   ` Geert Uytterhoeven
  2015-01-13 14:26 ` Linus Walleij
  2 siblings, 1 reply; 5+ messages in thread
From: Alexandre Courbot @ 2014-12-17  6:01 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Linus Walleij, Thomas Gleixner, Santosh Shilimkar, Ingo Molnar,
	linux-gpio@vger.kernel.org, Linux-SH, Linux Kernel Mailing List

On Wed, Dec 10, 2014 at 10:36 PM, Geert Uytterhoeven
<geert+renesas@glider.be> wrote:
> The pcf857x GPIO and interrupt controller uses dummy_irq_chip, which
> does not implement irq_chip.irq_set_wake() and does not set
> IRQCHIP_SKIP_SET_WAKE.
>
> This causes two s2ram issues if wake-up is enabled for the pcf857x GPIO
> pins:
>   1. During resume from s2ram, the following warning is printed:
>
>      WARNING: CPU: 0 PID: 1046 at kernel/irq/manage.c:537 irq_set_irq_wake+0x9c/0xf8()
>      Unbalanced IRQ 113 wake disable
>
>   2. Wake-up through the pcf857x GPIO pins may fail, as the parent
>      interrupt controller may be suspended.
>
> Migrate the pcf857x GPIO and interrupt controller from dummy_irq_chip to
> its own irq_chip. This irq chip implements irq_chip.irq_set_wake() to
> propagate its wake-up setting to the parent interrupt controller.
>
> This fixes wake-up through gpio-keys on sh73a0/kzm9g, where the pcf857x
> interrupt is cascaded to irq-renesas-intc-irqpin, and the latter must
> not be suspended when wake-up is enabled.

I am not very familiar with the IRQ subsystem, but wouldn't it be
possible (and better) to try and fix/adapt dummy_irq_chip so it
displays the right behavior? At least your first point looks like an
issue with it.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/2] gpio: pcf857x: Propagate wake-up setting to parent irq controller
  2014-12-17  6:01 ` [PATCH 1/2] gpio: pcf857x: Propagate wake-up setting to parent irq controller Alexandre Courbot
@ 2014-12-17  8:13   ` Geert Uytterhoeven
  0 siblings, 0 replies; 5+ messages in thread
From: Geert Uytterhoeven @ 2014-12-17  8:13 UTC (permalink / raw)
  To: Alexandre Courbot
  Cc: Geert Uytterhoeven, Linus Walleij, Thomas Gleixner,
	Santosh Shilimkar, Ingo Molnar, linux-gpio@vger.kernel.org,
	Linux-SH, Linux Kernel Mailing List

Hi Alexandre,

On Wed, Dec 17, 2014 at 7:01 AM, Alexandre Courbot <gnurou@gmail.com> wrote:
> On Wed, Dec 10, 2014 at 10:36 PM, Geert Uytterhoeven
> <geert+renesas@glider.be> wrote:
>> The pcf857x GPIO and interrupt controller uses dummy_irq_chip, which
>> does not implement irq_chip.irq_set_wake() and does not set
>> IRQCHIP_SKIP_SET_WAKE.
>>
>> This causes two s2ram issues if wake-up is enabled for the pcf857x GPIO
>> pins:
>>   1. During resume from s2ram, the following warning is printed:
>>
>>      WARNING: CPU: 0 PID: 1046 at kernel/irq/manage.c:537 irq_set_irq_wake+0x9c/0xf8()
>>      Unbalanced IRQ 113 wake disable
>>
>>   2. Wake-up through the pcf857x GPIO pins may fail, as the parent
>>      interrupt controller may be suspended.
>>
>> Migrate the pcf857x GPIO and interrupt controller from dummy_irq_chip to
>> its own irq_chip. This irq chip implements irq_chip.irq_set_wake() to
>> propagate its wake-up setting to the parent interrupt controller.
>>
>> This fixes wake-up through gpio-keys on sh73a0/kzm9g, where the pcf857x
>> interrupt is cascaded to irq-renesas-intc-irqpin, and the latter must
>> not be suspended when wake-up is enabled.
>
> I am not very familiar with the IRQ subsystem, but wouldn't it be
> possible (and better) to try and fix/adapt dummy_irq_chip so it
> displays the right behavior? At least your first point looks like an
> issue with it.

I fixed dummy_irq_chip in the second patch of the series ("[PATCH 2/2] [RFC]
genirq: Set IRQCHIP_SKIP_SET_WAKE for no_irq_chip and dummy_irq_chip:).
But please note that that would fix the warning (issue 1) only.

Pcf857x still needs to propagate the wake-up setting to the parent interrupt
controller to avoid the parent from being suspended if wake-up is enabled
(issue 2). That cannot be done in dummy_irq_chip, as dummy_irq_chip doesn't
know it is cascaded to a parent interrupt controller, nor about the interrupt
number that is used for the cascade. That information is specific to the child
driver.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/2] gpio: pcf857x: Propagate wake-up setting to parent irq controller
  2014-12-10 13:36 [PATCH 1/2] gpio: pcf857x: Propagate wake-up setting to parent irq controller Geert Uytterhoeven
  2014-12-10 13:36 ` [PATCH 2/2] [RFC] genirq: Set IRQCHIP_SKIP_SET_WAKE for no_irq_chip and dummy_irq_chip Geert Uytterhoeven
  2014-12-17  6:01 ` [PATCH 1/2] gpio: pcf857x: Propagate wake-up setting to parent irq controller Alexandre Courbot
@ 2015-01-13 14:26 ` Linus Walleij
  2 siblings, 0 replies; 5+ messages in thread
From: Linus Walleij @ 2015-01-13 14:26 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Alexandre Courbot, Thomas Gleixner, Santosh Shilimkar,
	Ingo Molnar, linux-gpio@vger.kernel.org, linux-sh@vger.kernel.org,
	linux-kernel@vger.kernel.org

On Wed, Dec 10, 2014 at 2:36 PM, Geert Uytterhoeven
<geert+renesas@glider.be> wrote:

> The pcf857x GPIO and interrupt controller uses dummy_irq_chip, which
> does not implement irq_chip.irq_set_wake() and does not set
> IRQCHIP_SKIP_SET_WAKE.
>
> This causes two s2ram issues if wake-up is enabled for the pcf857x GPIO
> pins:
>   1. During resume from s2ram, the following warning is printed:
>
>      WARNING: CPU: 0 PID: 1046 at kernel/irq/manage.c:537 irq_set_irq_wake+0x9c/0xf8()
>      Unbalanced IRQ 113 wake disable
>
>   2. Wake-up through the pcf857x GPIO pins may fail, as the parent
>      interrupt controller may be suspended.
>
> Migrate the pcf857x GPIO and interrupt controller from dummy_irq_chip to
> its own irq_chip. This irq chip implements irq_chip.irq_set_wake() to
> propagate its wake-up setting to the parent interrupt controller.
>
> This fixes wake-up through gpio-keys on sh73a0/kzm9g, where the pcf857x
> interrupt is cascaded to irq-renesas-intc-irqpin, and the latter must
> not be suspended when wake-up is enabled.
>
> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
(...)
> +static struct irq_chip pcf857x_irq_chip = {
> +       .name           = "pcf857x",
> +       .irq_startup    = noop_ret,
> +       .irq_shutdown   = noop,
> +       .irq_enable     = noop,
> +       .irq_disable    = noop,
> +       .irq_ack        = noop,
> +       .irq_mask       = noop,
> +       .irq_unmask     = noop,
> +       .irq_set_wake   = pcf857x_irq_set_wake,
> +};

Argh this is so simplistic ... any GPIO irqchip worthy of it's name
shoult at least call gpiochip_lock_as_irq() in .irq_request_resources() and vice
versa mutatis mutandis in .irq_release_resources().

Isn't it possible to also migrate this to GPIOLIB_IRQCHIP when
you're at it can also cut out a big chunk of rusty code?

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2015-01-13 14:26 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-12-10 13:36 [PATCH 1/2] gpio: pcf857x: Propagate wake-up setting to parent irq controller Geert Uytterhoeven
2014-12-10 13:36 ` [PATCH 2/2] [RFC] genirq: Set IRQCHIP_SKIP_SET_WAKE for no_irq_chip and dummy_irq_chip Geert Uytterhoeven
2014-12-17  6:01 ` [PATCH 1/2] gpio: pcf857x: Propagate wake-up setting to parent irq controller Alexandre Courbot
2014-12-17  8:13   ` Geert Uytterhoeven
2015-01-13 14:26 ` Linus Walleij

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).