Skip to content

Commit f7d6788

Browse files
jerome-pouillergregkh
authored andcommitted
staging: wfx: ensure IRQ is ready before enabling it
[ Upstream commit 5e57c66 ] Since commit 5561770 ("staging: wfx: repair external IRQ for SDIO"), wfx_sdio_irq_subscribe() enforce the device to use IRQs. However, there is currently a race in this code. An IRQ may happen before the IRQ has been registered. The problem has observed during debug session when the device crashes before the IRQ set up: [ 1.546] wfx-sdio mmc0:0001:1: started firmware 3.12.2 "WF200_ASIC_WFM_(Jenkins)_FW3.12.2" (API: 3.7, keyset: C0, caps: 0x00000002) [ 2.559] wfx-sdio mmc0:0001:1: time out while polling control register [ 3.565] wfx-sdio mmc0:0001:1: chip is abnormally long to answer [ 6.563] wfx-sdio mmc0:0001:1: chip did not answer [ 6.568] wfx-sdio mmc0:0001:1: hardware request CONFIGURATION (0x09) on vif 2 returned error -110 [ 6.577] wfx-sdio mmc0:0001:1: PDS bytes 0 to 12: chip didn't reply (corrupted file?) [ 6.585] Unable to handle kernel NULL pointer dereference at virtual address 00000000 [ 6.592] pgd = c0004000 [ 6.595] [00000000] *pgd=00000000 [ 6.598] Internal error: Oops - BUG: 17 [#1] THUMB2 [ 6.603] Modules linked in: [ 6.606] CPU: 0 PID: 23 Comm: kworker/u2:1 Not tainted 3.18.19 #78 [ 6.612] Workqueue: kmmcd mmc_rescan [ 6.616] task: c176d100 ti: c0e50000 task.ti: c0e50000 [ 6.621] PC is at wake_up_process+0xa/0x14 [ 6.625] LR is at sdio_irq+0x61/0x250 [ 6.629] pc : [<c001e8ae>] lr : [<c00ec5bd>] psr: 600001b3 [ 6.629] sp : c0e51bd8 ip : c0e51cc8 fp : 00000001 [ 6.640] r10: 00000003 r9 : 00000000 r8 : c0003c34 [ 6.644] r7 : c0e51bd8 r6 : c0003c30 r5 : 00000001 r4 : c0e78c00 [ 6.651] r3 : 00000000 r2 : 00000000 r1 : 00000003 r0 : 00000000 [ 6.657] Flags: nZCv IRQs off FIQs on Mode SVC_32 ISA Thumb Segment kernel [ 6.664] Control: 50c53c7d Table: 11fd8059 DAC: 00000015 [ 6.670] Process kworker/u2:1 (pid: 23, stack limit = 0xc0e501b0) [ 6.676] Stack: (0xc0e51bd8 to 0xc0e52000) [...] [ 6.949] [<c001e8ae>] (wake_up_process) from [<c00ec5bd>] (sdio_irq+0x61/0x250) [ 6.956] [<c00ec5bd>] (sdio_irq) from [<c0025099>] (handle_irq_event_percpu+0x17/0x92) [ 6.964] [<c0025099>] (handle_irq_event_percpu) from [<c002512f>] (handle_irq_event+0x1b/0x24) [ 6.973] [<c002512f>] (handle_irq_event) from [<c0026577>] (handle_level_irq+0x5d/0x76) [ 6.981] [<c0026577>] (handle_level_irq) from [<c0024cc3>] (generic_handle_irq+0x13/0x1c) [ 6.989] [<c0024cc3>] (generic_handle_irq) from [<c0024dd9>] (__handle_domain_irq+0x31/0x48) [ 6.997] [<c0024dd9>] (__handle_domain_irq) from [<c0008359>] (ov_handle_irq+0x31/0xe0) [ 7.005] [<c0008359>] (ov_handle_irq) from [<c000af5b>] (__irq_svc+0x3b/0x5c) [ 7.013] Exception stack(0xc0e51c68 to 0xc0e51cb0) [...] [ 7.038] [<c000af5b>] (__irq_svc) from [<c01775aa>] (wait_for_common+0x9e/0xc4) [ 7.045] [<c01775aa>] (wait_for_common) from [<c00e1dc3>] (mmc_wait_for_req+0x4b/0xdc) [ 7.053] [<c00e1dc3>] (mmc_wait_for_req) from [<c00e1e83>] (mmc_wait_for_cmd+0x2f/0x34) [ 7.061] [<c00e1e83>] (mmc_wait_for_cmd) from [<c00e7b2b>] (mmc_io_rw_direct_host+0x71/0xac) [ 7.070] [<c00e7b2b>] (mmc_io_rw_direct_host) from [<c00e8f79>] (sdio_claim_irq+0x6b/0x116) [ 7.078] [<c00e8f79>] (sdio_claim_irq) from [<c00d8415>] (wfx_sdio_irq_subscribe+0x19/0x94) [ 7.086] [<c00d8415>] (wfx_sdio_irq_subscribe) from [<c00d5229>] (wfx_probe+0x189/0x2ac) [ 7.095] [<c00d5229>] (wfx_probe) from [<c00d83bf>] (wfx_sdio_probe+0x8f/0xcc) [ 7.102] [<c00d83bf>] (wfx_sdio_probe) from [<c00e7fbb>] (sdio_bus_probe+0x5f/0xa8) [ 7.109] [<c00e7fbb>] (sdio_bus_probe) from [<c00be229>] (driver_probe_device+0x59/0x134) [ 7.118] [<c00be229>] (driver_probe_device) from [<c00bd4d7>] (bus_for_each_drv+0x3f/0x4a) [ 7.126] [<c00bd4d7>] (bus_for_each_drv) from [<c00be1a5>] (device_attach+0x3b/0x52) [ 7.134] [<c00be1a5>] (device_attach) from [<c00bdc2b>] (bus_probe_device+0x17/0x4c) [ 7.141] [<c00bdc2b>] (bus_probe_device) from [<c00bcd69>] (device_add+0x2c5/0x334) [ 7.149] [<c00bcd69>] (device_add) from [<c00e80bf>] (sdio_add_func+0x23/0x44) [ 7.156] [<c00e80bf>] (sdio_add_func) from [<c00e79eb>] (mmc_attach_sdio+0x187/0x1ec) [ 7.164] [<c00e79eb>] (mmc_attach_sdio) from [<c00e31bd>] (mmc_rescan+0x18d/0x1fc) [ 7.172] [<c00e31bd>] (mmc_rescan) from [<c001a14f>] (process_one_work+0xd7/0x170) [ 7.179] [<c001a14f>] (process_one_work) from [<c001a59b>] (worker_thread+0x103/0x1bc) [ 7.187] [<c001a59b>] (worker_thread) from [<c001c731>] (kthread+0x7d/0x90) [ 7.194] [<c001c731>] (kthread) from [<c0008ce1>] (ret_from_fork+0x11/0x30) [ 7.201] Code: 2103 b580 2200 af00 (681b) 46bd [ 7.206] ---[ end trace 3ab50aced42eedb4 ]--- Signed-off-by: Jérôme Pouiller <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent f08c0d6 commit f7d6788

File tree

1 file changed

+10
-7
lines changed

1 file changed

+10
-7
lines changed

drivers/staging/wfx/bus_sdio.c

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -120,19 +120,22 @@ static int wfx_sdio_irq_subscribe(void *priv)
120120
return ret;
121121
}
122122

123+
flags = irq_get_trigger_type(bus->of_irq);
124+
if (!flags)
125+
flags = IRQF_TRIGGER_HIGH;
126+
flags |= IRQF_ONESHOT;
127+
ret = devm_request_threaded_irq(&bus->func->dev, bus->of_irq, NULL,
128+
wfx_sdio_irq_handler_ext, flags,
129+
"wfx", bus);
130+
if (ret)
131+
return ret;
123132
sdio_claim_host(bus->func);
124133
cccr = sdio_f0_readb(bus->func, SDIO_CCCR_IENx, NULL);
125134
cccr |= BIT(0);
126135
cccr |= BIT(bus->func->num);
127136
sdio_f0_writeb(bus->func, cccr, SDIO_CCCR_IENx, NULL);
128137
sdio_release_host(bus->func);
129-
flags = irq_get_trigger_type(bus->of_irq);
130-
if (!flags)
131-
flags = IRQF_TRIGGER_HIGH;
132-
flags |= IRQF_ONESHOT;
133-
return devm_request_threaded_irq(&bus->func->dev, bus->of_irq, NULL,
134-
wfx_sdio_irq_handler_ext, flags,
135-
"wfx", bus);
138+
return 0;
136139
}
137140

138141
static int wfx_sdio_irq_unsubscribe(void *priv)

0 commit comments

Comments
 (0)