diff options
author | Geert Uytterhoeven <geert+renesas@glider.be> | 2015-05-26 07:34:02 -0400 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2015-06-01 10:55:25 -0400 |
commit | ffb8e44bd7617ede81d526d33d13d96a2c6a6e20 (patch) | |
tree | 08dceb61e75f5e0b3715d8fa93de8583b268afcd /drivers/gpio | |
parent | 08b085a07efe12568d86dff064e6f089e2971744 (diff) |
gpio: pcf857x: Check for irq_set_irq_wake() failures
If an interrupt controller doesn't support wake-up configuration,
irq_set_irq_wake() returns an error code. Then any subsequent call
trying to deconfigure wake-up will cause an imbalance, and a warning
will be printed:
WARNING: CPU: 1 PID: 1341 at kernel/irq/manage.c:540 irq_set_irq_wake+0x
Unbalanced IRQ 26 wake disable
To fix this, refrain from any further parent interrupt controller
(de)configuration if irq_set_irq_wake() failed.
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/gpio')
-rw-r--r-- | drivers/gpio/gpio-pcf857x.c | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/drivers/gpio/gpio-pcf857x.c b/drivers/gpio/gpio-pcf857x.c index 945f0cda8529..83db0e19ec7e 100644 --- a/drivers/gpio/gpio-pcf857x.c +++ b/drivers/gpio/gpio-pcf857x.c | |||
@@ -91,6 +91,7 @@ struct pcf857x { | |||
91 | spinlock_t slock; /* protect irq demux */ | 91 | spinlock_t slock; /* protect irq demux */ |
92 | unsigned out; /* software latch */ | 92 | unsigned out; /* software latch */ |
93 | unsigned status; /* current status */ | 93 | unsigned status; /* current status */ |
94 | unsigned int irq_parent; | ||
94 | 95 | ||
95 | int (*write)(struct i2c_client *client, unsigned data); | 96 | int (*write)(struct i2c_client *client, unsigned data); |
96 | int (*read)(struct i2c_client *client); | 97 | int (*read)(struct i2c_client *client); |
@@ -217,9 +218,19 @@ static unsigned int noop_ret(struct irq_data *data) | |||
217 | static int pcf857x_irq_set_wake(struct irq_data *data, unsigned int on) | 218 | static int pcf857x_irq_set_wake(struct irq_data *data, unsigned int on) |
218 | { | 219 | { |
219 | struct pcf857x *gpio = irq_data_get_irq_chip_data(data); | 220 | struct pcf857x *gpio = irq_data_get_irq_chip_data(data); |
221 | int error = 0; | ||
222 | |||
223 | if (gpio->irq_parent) { | ||
224 | error = irq_set_irq_wake(gpio->irq_parent, on); | ||
225 | if (error) { | ||
226 | dev_dbg(&gpio->client->dev, | ||
227 | "irq %u doesn't support irq_set_wake\n", | ||
228 | gpio->irq_parent); | ||
229 | gpio->irq_parent = 0; | ||
230 | } | ||
231 | } | ||
220 | 232 | ||
221 | irq_set_irq_wake(gpio->client->irq, on); | 233 | return error; |
222 | return 0; | ||
223 | } | 234 | } |
224 | 235 | ||
225 | static struct irq_chip pcf857x_irq_chip = { | 236 | static struct irq_chip pcf857x_irq_chip = { |
@@ -364,6 +375,7 @@ static int pcf857x_probe(struct i2c_client *client, | |||
364 | 375 | ||
365 | gpiochip_set_chained_irqchip(&gpio->chip, &pcf857x_irq_chip, | 376 | gpiochip_set_chained_irqchip(&gpio->chip, &pcf857x_irq_chip, |
366 | client->irq, NULL); | 377 | client->irq, NULL); |
378 | gpio->irq_parent = client->irq; | ||
367 | } | 379 | } |
368 | 380 | ||
369 | /* Let platform code set up the GPIOs and their users. | 381 | /* Let platform code set up the GPIOs and their users. |