gpio: pca953x: Configure wake-up path when wake-up is enabled

If a device is part of the wake-up path, it should indicate this by
setting its power.wakeup_path field.  This allows the genpd core code to
keep the device enabled during system suspend when needed.

As regulators powering devices are not handled by genpd, the driver
handles these itself, and thus must skip regulator control when the
device is part of the wake-up path.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
This commit is contained in:
Geert Uytterhoeven 2019-03-20 11:39:27 +01:00 committed by Linus Walleij
parent a71a81e797
commit f70fbc15ba

View File

@ -153,6 +153,7 @@ struct pca953x_chip {
u8 irq_trig_fall[MAX_BANK]; u8 irq_trig_fall[MAX_BANK];
struct irq_chip irq_chip; struct irq_chip irq_chip;
#endif #endif
atomic_t wakeup_path;
struct i2c_client *client; struct i2c_client *client;
struct gpio_chip gpio_chip; struct gpio_chip gpio_chip;
@ -581,6 +582,11 @@ 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 gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct pca953x_chip *chip = gpiochip_get_data(gc); struct pca953x_chip *chip = gpiochip_get_data(gc);
if (on)
atomic_inc(&chip->wakeup_path);
else
atomic_dec(&chip->wakeup_path);
return irq_set_irq_wake(chip->client->irq, on); return irq_set_irq_wake(chip->client->irq, on);
} }
@ -1100,7 +1106,10 @@ static int pca953x_suspend(struct device *dev)
regcache_cache_only(chip->regmap, true); regcache_cache_only(chip->regmap, true);
regulator_disable(chip->regulator); if (atomic_read(&chip->wakeup_path))
device_set_wakeup_path(dev);
else
regulator_disable(chip->regulator);
return 0; return 0;
} }
@ -1110,10 +1119,12 @@ static int pca953x_resume(struct device *dev)
struct pca953x_chip *chip = dev_get_drvdata(dev); struct pca953x_chip *chip = dev_get_drvdata(dev);
int ret; int ret;
ret = regulator_enable(chip->regulator); if (!atomic_read(&chip->wakeup_path)) {
if (ret != 0) { ret = regulator_enable(chip->regulator);
dev_err(dev, "Failed to enable regulator: %d\n", ret); if (ret != 0) {
return 0; dev_err(dev, "Failed to enable regulator: %d\n", ret);
return 0;
}
} }
regcache_cache_only(chip->regmap, false); regcache_cache_only(chip->regmap, false);