diff options
author | Stephen Warren <swarren@nvidia.com> | 2013-09-06 19:17:13 -0400 |
---|---|---|
committer | Lee Jones <lee.jones@linaro.org> | 2013-10-23 11:20:39 -0400 |
commit | 234506ad3f28d5eea85f739f637cde6d9e8f5a88 (patch) | |
tree | 110d147e21a57a3f7562c43e2de9b419c60190e9 | |
parent | b5f90240e1ef0568a8c666da3c3be4c6a682c5a6 (diff) |
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>
-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 { | |||
124 | struct i2c_client *client; | 124 | struct i2c_client *client; |
125 | struct regmap *regmap; | 125 | struct regmap *regmap; |
126 | 126 | ||
127 | int irq; | ||
127 | struct irq_chip irq_chip; | 128 | struct irq_chip irq_chip; |
128 | struct mutex irq_lock; | 129 | struct mutex irq_lock; |
129 | int irq_base; | 130 | int irq_base; |
@@ -261,12 +262,23 @@ static void tps6586x_irq_sync_unlock(struct irq_data *data) | |||
261 | mutex_unlock(&tps6586x->irq_lock); | 262 | mutex_unlock(&tps6586x->irq_lock); |
262 | } | 263 | } |
263 | 264 | ||
265 | #ifdef CONFIG_PM_SLEEP | ||
266 | static int tps6586x_irq_set_wake(struct irq_data *irq_data, unsigned int on) | ||
267 | { | ||
268 | struct tps6586x *tps6586x = irq_data_get_irq_chip_data(irq_data); | ||
269 | return irq_set_irq_wake(tps6586x->irq, on); | ||
270 | } | ||
271 | #else | ||
272 | #define tps6586x_irq_set_wake NULL | ||
273 | #endif | ||
274 | |||
264 | static struct irq_chip tps6586x_irq_chip = { | 275 | static struct irq_chip tps6586x_irq_chip = { |
265 | .name = "tps6586x", | 276 | .name = "tps6586x", |
266 | .irq_bus_lock = tps6586x_irq_lock, | 277 | .irq_bus_lock = tps6586x_irq_lock, |
267 | .irq_bus_sync_unlock = tps6586x_irq_sync_unlock, | 278 | .irq_bus_sync_unlock = tps6586x_irq_sync_unlock, |
268 | .irq_disable = tps6586x_irq_disable, | 279 | .irq_disable = tps6586x_irq_disable, |
269 | .irq_enable = tps6586x_irq_enable, | 280 | .irq_enable = tps6586x_irq_enable, |
281 | .irq_set_wake = tps6586x_irq_set_wake, | ||
270 | }; | 282 | }; |
271 | 283 | ||
272 | static int tps6586x_irq_map(struct irq_domain *h, unsigned int virq, | 284 | 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, | |||
331 | int new_irq_base; | 343 | int new_irq_base; |
332 | int irq_num = ARRAY_SIZE(tps6586x_irqs); | 344 | int irq_num = ARRAY_SIZE(tps6586x_irqs); |
333 | 345 | ||
346 | tps6586x->irq = irq; | ||
347 | |||
334 | mutex_init(&tps6586x->irq_lock); | 348 | mutex_init(&tps6586x->irq_lock); |
335 | for (i = 0; i < 5; i++) { | 349 | for (i = 0; i < 5; i++) { |
336 | tps6586x->mask_reg[i] = 0xff; | 350 | tps6586x->mask_reg[i] = 0xff; |
@@ -360,10 +374,8 @@ static int tps6586x_irq_init(struct tps6586x *tps6586x, int irq, | |||
360 | ret = request_threaded_irq(irq, NULL, tps6586x_irq, IRQF_ONESHOT, | 374 | ret = request_threaded_irq(irq, NULL, tps6586x_irq, IRQF_ONESHOT, |
361 | "tps6586x", tps6586x); | 375 | "tps6586x", tps6586x); |
362 | 376 | ||
363 | if (!ret) { | 377 | if (!ret) |
364 | device_init_wakeup(tps6586x->dev, 1); | 378 | device_init_wakeup(tps6586x->dev, 1); |
365 | enable_irq_wake(irq); | ||
366 | } | ||
367 | 379 | ||
368 | return ret; | 380 | return ret; |
369 | } | 381 | } |