Top-posting to Thomas Petazzoni, he's been working on this driver
recently and is also on top of thing when it comes to wakeup.

Thomas, it would be great if you can take a look at this.

Yours,
Linus Walleij

On Tue, Feb 12, 2019 at 3:17 PM Geert Uytterhoeven
<geert+rene...@glider.be> wrote:
>
> Implement the irq_set_wake() method in the (optional) irq_chip of the
> GPIO expander, and propagate wake-up settings to the upstream interrupt
> controller.  This allows GPIOs connected to a PCA953X GPIO expander to
> serve as wake-up sources.
>
> Signed-off-by: Geert Uytterhoeven <geert+rene...@glider.be>
> ---
> Tested with a PCA9654 and gpio-keys on an R-Car Ebisu-4D board.
> ---
>  drivers/gpio/gpio-pca953x.c | 21 +++++++++++++++++++++
>  1 file changed, 21 insertions(+)
>
> diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c
> index de52f63863dbe59b..8dfb8e326b9d12ca 100644
> --- a/drivers/gpio/gpio-pca953x.c
> +++ b/drivers/gpio/gpio-pca953x.c
> @@ -151,6 +151,7 @@ struct pca953x_chip {
>         u8 irq_trig_raise[MAX_BANK];
>         u8 irq_trig_fall[MAX_BANK];
>         struct irq_chip irq_chip;
> +       unsigned int irq_parent;
>  #endif
>
>         struct i2c_client *client;
> @@ -513,6 +514,24 @@ static void pca953x_irq_unmask(struct irq_data *d)
>         chip->irq_mask[d->hwirq / BANK_SZ] |= 1 << (d->hwirq % BANK_SZ);
>  }
>
> +static int pca953x_irq_set_wake(struct irq_data *d, unsigned int on)
> +{
> +       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
> +       struct pca953x_chip *chip = gpiochip_get_data(gc);
> +       int error = 0;
> +
> +       if (chip->irq_parent) {
> +               error = irq_set_irq_wake(chip->irq_parent, on);
> +               if (error) {
> +                       dev_dbg(&chip->client->dev,
> +                               "irq %u doesn't support irq_set_wake\n",
> +                               chip->irq_parent);
> +                       chip->irq_parent = 0;
> +               }
> +       }
> +       return error;
> +}
> +
>  static void pca953x_irq_bus_lock(struct irq_data *d)
>  {
>         struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
> @@ -732,6 +751,7 @@ static int pca953x_irq_setup(struct pca953x_chip *chip,
>         irq_chip->name = dev_name(&chip->client->dev);
>         irq_chip->irq_mask = pca953x_irq_mask;
>         irq_chip->irq_unmask = pca953x_irq_unmask;
> +       irq_chip->irq_set_wake = pca953x_irq_set_wake;
>         irq_chip->irq_bus_lock = pca953x_irq_bus_lock;
>         irq_chip->irq_bus_sync_unlock = pca953x_irq_bus_sync_unlock;
>         irq_chip->irq_set_type = pca953x_irq_set_type;
> @@ -747,6 +767,7 @@ static int pca953x_irq_setup(struct pca953x_chip *chip,
>         }
>
>         gpiochip_set_nested_irqchip(&chip->gpio_chip, irq_chip, client->irq);
> +       chip->irq_parent = client->irq;
>
>         return 0;
>  }
> --
> 2.17.1
>

Reply via email to