aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio
diff options
context:
space:
mode:
authorGeert Uytterhoeven <geert+renesas@glider.be>2015-05-26 07:34:02 -0400
committerLinus Walleij <linus.walleij@linaro.org>2015-06-01 10:55:25 -0400
commitffb8e44bd7617ede81d526d33d13d96a2c6a6e20 (patch)
tree08dceb61e75f5e0b3715d8fa93de8583b268afcd /drivers/gpio
parent08b085a07efe12568d86dff064e6f089e2971744 (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.c16
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)
217static int pcf857x_irq_set_wake(struct irq_data *data, unsigned int on) 218static 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
225static struct irq_chip pcf857x_irq_chip = { 236static 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.