From e6b698f69adce0119b5f5ed00789d1a0e0af975f Mon Sep 17 00:00:00 2001 From: George Cherian Date: Fri, 23 May 2014 11:27:26 +0530 Subject: gpio: pcf857x: Avoid calling irq_domain_cleanup twice Currently irq_domain_cleanup is called twice if irq_domain_init fails. This causes the following crash. Unable to handle kernel paging request at virtual address 00100104 pgd = c0004000 [00100104] *pgd=00000000 Internal error: Oops: 805 [#1] SMP ARM Modules linked in: CPU: 0 PID: 6 Comm: kworker/u4:0 Not tainted 3.12.15-01889-gedd10a8-dirty #4 Workqueue: deferwq deferred_probe_work_func task: ed0ee800 ti: ed116000 task.ti: ed116000 PC is at irq_domain_remove+0x3c/0x8c LR is at 0x0 pc : [] lr : [<00000000>] psr: a0000013 sp : ed117b50 ip : 00100100 fp : ed117b64 r10: ed5d1a04 r9 : 00000008 r8 : 00000000 r7 : ffffffea r6 : ed5d1a20 r5 : ed5d1a00 r4 : ed5e7540 r3 : 00200200 r2 : 00100100 r1 : c08aa180 r0 : 00200200 Flags: NzCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment kernel Control: 10c53c7d Table: 8000406a DAC: 00000017 Process kworker/u4:0 (pid: 6, stack limit = 0xed116248) Stack: (0xed117b50 to 0xed118000) 7b40: 0000016b ed5d5f10 ed117b74 ed117b68 7b60: c02c8910 c0089704 ed117bb4 ed117b78 c02c8e14 c02c8900 ed5d1a04 ed5d4e80 ... ... fe0: 00000000 00000000 00000000 00000000 00000013 00000000 384a13ea 1590210a Backtrace: [] (irq_domain_remove+0x0/0x8c) from [] (pcf857x_irq_domain_cleanup+0x1c/0x20) r4:ed5d5f10 r3:0000016b [] (pcf857x_irq_domain_cleanup+0x0/0x20) from [] (pcf857x_probe+0x2a8/0x364) [] (pcf857x_probe+0x0/0x364) from [] (i2c_device_probe+0x80/0xc0) [] (i2c_device_probe+0x0/0xc0) from [] (driver_probe_device+0x104/0x240) r6:00000000 r5:ed5d1a20 r4:c08c709c r3:c047872c [] (driver_probe_device+0x0/0x240) from [] (__device_attach+0x48/0x4c) r7:ed4fc480 r6:c036c510 r5:ed5d1a20 r4:c0866bb8 [] (__device_attach+0x0/0x4c) from [] (bus_for_each_drv+0x4c/0x94) r5:ed5d1a20 r4:00000000 [] (bus_for_each_drv+0x0/0x94) from [] (device_attach+0x78/0x90) r6:c087fe50 r5:ed5d1a54 r4:ed5d1a20 [] (device_attach+0x0/0x90) from [] (bus_probe_device+0x8c/0xb4) r6:c087fe50 r5:ed5d1a20 r4:ed5d1a20 r3:ed17e1c0 [] (bus_probe_device+0x0/0xb4) from [] (device_add+0x34c/0x624) r6:ed5d1a28 r5:00000000 r4:ed5d1a20 r3:fffffffe [] (device_add+0x0/0x624) from [] (device_register+0x1c/0x20) ... ... [] (process_one_work+0x0/0x37c) from [] (worker_thread+0x13c/0x3c4) [] (worker_thread+0x0/0x3c4) from [] (kthread+0xac/0xb8) [] (kthread+0x0/0xb8) from [] (ret_from_fork+0x14/0x3c) r7:00000000 r6:00000000 r5:c0067040 r4:ed105d20 Code: e59fc04c e591e000 e59f0048 e154000e (e5823004) ---[ end trace 59dd1e90032c4217 ]--- Signed-off-by: George Cherian Reviewed-by: Alexandre Courbot Signed-off-by: Linus Walleij --- drivers/gpio/gpio-pcf857x.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers/gpio/gpio-pcf857x.c') diff --git a/drivers/gpio/gpio-pcf857x.c b/drivers/gpio/gpio-pcf857x.c index 82735822bc9d..5acffed10e77 100644 --- a/drivers/gpio/gpio-pcf857x.c +++ b/drivers/gpio/gpio-pcf857x.c @@ -319,7 +319,7 @@ static int pcf857x_probe(struct i2c_client *client, status = pcf857x_irq_domain_init(gpio, client); if (status < 0) { dev_err(&client->dev, "irq_domain init failed\n"); - goto fail; + goto fail_irq_domain; } } @@ -414,12 +414,13 @@ static int pcf857x_probe(struct i2c_client *client, return 0; fail: - dev_dbg(&client->dev, "probe error %d for '%s'\n", - status, client->name); - if (client->irq) pcf857x_irq_domain_cleanup(gpio); +fail_irq_domain: + dev_dbg(&client->dev, "probe error %d for '%s'\n", + status, client->name); + return status; } -- cgit v1.2.3