diff options
author | Stephen Warren <swarren@nvidia.com> | 2013-09-06 17:17:13 -0600 |
---|---|---|
committer | Lee Jones <lee.jones@linaro.org> | 2013-10-23 16:20:39 +0100 |
commit | 234506ad3f28d5eea85f739f637cde6d9e8f5a88 (patch) | |
tree | 110d147e21a57a3f7562c43e2de9b419c60190e9 /drivers/mfd/tps6586x.c | |
parent | b5f90240e1ef0568a8c666da3c3be4c6a682c5a6 (diff) | |
download | lwn-234506ad3f28d5eea85f739f637cde6d9e8f5a88.tar.gz lwn-234506ad3f28d5eea85f739f637cde6d9e8f5a88.zip |
mfd: tps6586x: Implement irq_set_wake
rtc-tps6586x calls enable/disable_irq_wake() during suspend/resume. Since
the main tps6586x irq_chip doesn't implement .irq_set_wake, this causes
the RTC's enable_irq_wake() to fail, and the disable_irq_wake() to spew a
WARN about unbalanced wake disable. Solve this by implementing
.irq_set_wake.
Also, I assume that enable_irq_wake() shouldn't be called unconditionally
in tps6586x_irq_init(), since this is now triggered by IRQ children
setting up their cascaded IRQs for wake. So, remove that.
Signed-off-by: Stephen Warren <swarren@nvidia.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
Diffstat (limited to 'drivers/mfd/tps6586x.c')
-rw-r--r-- | drivers/mfd/tps6586x.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/drivers/mfd/tps6586x.c b/drivers/mfd/tps6586x.c index f54fe4d4f77b..68906b17ee52 100644 --- a/drivers/mfd/tps6586x.c +++ b/drivers/mfd/tps6586x.c @@ -124,6 +124,7 @@ struct tps6586x { struct i2c_client *client; struct regmap *regmap; + int irq; struct irq_chip irq_chip; struct mutex irq_lock; int irq_base; @@ -261,12 +262,23 @@ static void tps6586x_irq_sync_unlock(struct irq_data *data) mutex_unlock(&tps6586x->irq_lock); } +#ifdef CONFIG_PM_SLEEP +static int tps6586x_irq_set_wake(struct irq_data *irq_data, unsigned int on) +{ + struct tps6586x *tps6586x = irq_data_get_irq_chip_data(irq_data); + return irq_set_irq_wake(tps6586x->irq, on); +} +#else +#define tps6586x_irq_set_wake NULL +#endif + static struct irq_chip tps6586x_irq_chip = { .name = "tps6586x", .irq_bus_lock = tps6586x_irq_lock, .irq_bus_sync_unlock = tps6586x_irq_sync_unlock, .irq_disable = tps6586x_irq_disable, .irq_enable = tps6586x_irq_enable, + .irq_set_wake = tps6586x_irq_set_wake, }; static int tps6586x_irq_map(struct irq_domain *h, unsigned int virq, @@ -331,6 +343,8 @@ static int tps6586x_irq_init(struct tps6586x *tps6586x, int irq, int new_irq_base; int irq_num = ARRAY_SIZE(tps6586x_irqs); + tps6586x->irq = irq; + mutex_init(&tps6586x->irq_lock); for (i = 0; i < 5; i++) { tps6586x->mask_reg[i] = 0xff; @@ -360,10 +374,8 @@ static int tps6586x_irq_init(struct tps6586x *tps6586x, int irq, ret = request_threaded_irq(irq, NULL, tps6586x_irq, IRQF_ONESHOT, "tps6586x", tps6586x); - if (!ret) { + if (!ret) device_init_wakeup(tps6586x->dev, 1); - enable_irq_wake(irq); - } return ret; } |