summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Chen <peter.chen@freescale.com>2015-07-02 09:41:03 +0800
committerLi Jun <jun.li@freescale.com>2015-07-16 08:26:05 +0800
commit62e467e6d27aeb1d13ce3cd025deb44300308a60 (patch)
treed43aad05fe2c3a6f73bd8f86e6a75f0cc7be0d41
parentb4b0a9056bb2413bc57d11c7e720aae708c79435 (diff)
MLK-11183-1 usb: chipidea: host: fix NULL pointer problem for fast load/unload module
The interrupt may occur (due to remove process may block interrupt) after we remove hcd, in that case, we should not call hcd's interrupt handler, otherwise, below NULL pointer dereference will occur, the reason for this is we call free_irq later than hcd's. So after hcd has been removed, we should not call hcd interrupt handler. ci_hdrc ci_hdrc.0: remove, state 1 usb usb1: USB disconnect, device number 1 ci_hdrc ci_hdrc.0: USB bus 1 deregistered [<800691e8>] (handle_irq_event) from [<8006c02c>] (handle_fasteoi_irq+0x84/0x14c) [<8006c02c>] (handle_fasteoi_irq) from [<800687f4>] (generic_handle_irq+0x2c/0x3c) [<800687f4>] (generic_handle_irq) from [<8000ed4c>] (handle_IRQ+0x40/0x90) [<8000ed4c>] (handle_IRQ) from [<8000856c>] (gic_handle_irq+0x2c/0x5c) [<8000856c>] (gic_handle_irq) from [<80012240>] (__irq_svc+0x40/0x70) Exception stack(0x80db1f18 to 0x80db1f60) 1f00: 80db1f60 3b9aca00 1f20: 06f86934 0000000d 80dbe1c8 80dbe1c8 ee71e0d0 00000000 06f5bb01 0000000d 1f40: 80db0000 00000000 00000017 80db1f60 00000009 8049c19c 000d0013 ffffffff [<80012240>] (__irq_svc) from [<8049c19c>] (cpuidle_enter_state+0x54/0xe4) [<8049c19c>] (cpuidle_enter_state) from [<8049c2e0>] (cpuidle_idle_call+0xb4/0x14c) [<8049c2e0>] (cpuidle_idle_call) from [<8000f07c>] (arch_cpu_idle+0x8/0x44) [<8000f07c>] (arch_cpu_idle) from [<8006876c>] (cpu_startup_entry+0x100/0x14c) [<8006876c>] (cpu_startup_entry) from [<80d52b10>] (start_kernel+0x350/0x35c) --[ end trace 1160f590a7b228b3 ]-- Unable to handle kernel NULL pointer dereference at virtual address 000000b0 pgd = 80004000 [000000b0] *pgd=00000000 Internal error: Oops: 17 1 PREEMPT SMP ARM Modules linked in: ci_hdrc_imx usbmisc_imx ci_hdrc udc_core ehci_hcd phy_mxs_usb mxc_v4l2_capture ipu_bg_overlay_sdc ipu_still ipu_prp_enc adv7180_tvin ipu_csi_enc v4l2_int_device ipu_fg_overlay_sdc mxc_mlb mxc_dcic evbug [last unloaded: phy_mxs_usb] CPU: 0 PID: 0 Comm: swapper/0 Tainted: G W 3.14.38-usb-host-otg-02047-ga4dec77 #13 task: 80dbbae8 ti: 80db0000 task.ti: 80db0000 PC is at usb_hcd_irq+0x4/0x38 LR is at handle_irq_event_percpu+0x50/0x180 pc : [<8040eed8>] lr : [<8006907c>] psr: a00d0193 sp : 80db1e98 ip : fffffffa fp : 00000000 r10: 80e1f13f r9 : d8009900 r8 : 0000004b r7 : 00000000 r6 : 00000000 r5 : d800995c r4 : d8f2dec0 r3 : d2234010 r2 : d2234010 r1 : 00000000 r0 : 0000004b Flags: NzCv IRQs off FIQs on Mode SVC_32 ISA ARM Segment kernel Control: 10c53c7d Table: 6920004a DAC: 00000015 Process swapper/0 (pid: 0, stack limit = 0x80db0238) Stack: (0x80db1e98 to 0x80db2000) 1e80: d2234010 8006907c 1ea0: 0000004b ee71da00 d8009900 d800995c d8f2dec0 f4a00100 06f5bb01 0000000d 1ec0: 80db0000 800691e8 d8009900 d800995c 00000000 8006c02c 8006bfa8 0000004b 1ee0: 0000004b 800687f4 80dace54 8000ed4c f4a0010c 80db8970 80db1f18 8000856c 1f00: 00000009 8049c19c 000d0013 ffffffff 80db1f4c 80012240 80db1f60 3b9aca00 1f20: 06f86934 0000000d 80dbe1c8 80dbe1c8 ee71e0d0 00000000 06f5bb01 0000000d 1f40: 80db0000 00000000 00000017 80db1f60 00000009 8049c19c 000d0013 ffffffff 1f60: 06f86934 0000000d 80dc4a54 ee71e0d0 80db8574 ee71e0d0 00000000 00000000 1f80: 00000000 80e797f8 80dbe1c8 8049c2e0 00000000 80db0000 80db8574 806fe48c 1fa0: 80db0038 80e1f13d 80e1f13d 8000f07c 00000000 8006876c ffffffff 80d52b10 1fc0: ffffffff ffffffff 80d5258c 00000000 00000000 80d9ef30 00000000 10c53c7d 1fe0: 80db84fc 80d9ef2c 80dbcb80 1000406a 412fc09a 10008074 00000000 00000000 [<8040eed8>] (usb_hcd_irq) from [<8006907c>] (handle_irq_event_percpu+0x50/0x180) [<8006907c>] (handle_irq_event_percpu) from [<800691e8>] (handle_irq_event+0x3c/0x5c) [<800691e8>] (handle_irq_event) from [<8006c02c>] (handle_fasteoi_irq+0x84/0x14c) [<8006c02c>] (handle_fasteoi_irq) from [<800687f4>] (generic_handle_irq+0x2c/0x3c) [<800687f4>] (generic_handle_irq) from [<8000ed4c>] (handle_IRQ+0x40/0x90) [<8000ed4c>] (handle_IRQ) from [<8000856c>] (gic_handle_irq+0x2c/0x5c) [<8000856c>] (gic_handle_irq) from [<80012240>] (__irq_svc+0x40/0x70) Exception stack(0x80db1f18 to 0x80db1f60) 1f00: 80db1f60 3b9aca00 1f20: 06f86934 0000000d 80dbe1c8 80dbe1c8 ee71e0d0 00000000 06f5bb01 0000000d 1f40: 80db0000 00000000 00000017 80db1f60 00000009 8049c19c 000d0013 ffffffff [<80012240>] (__irq_svc) from [<8049c19c>] (cpuidle_enter_state+0x54/0xe4) [<8049c19c>] (cpuidle_enter_state) from [<8049c2e0>] (cpuidle_idle_call+0xb4/0x14c) [<8049c2e0>] (cpuidle_idle_call) from [<8000f07c>] (arch_cpu_idle+0x8/0x44) [<8000f07c>] (arch_cpu_idle) from [<8006876c>] (cpu_startup_entry+0x100/0x14c) [<8006876c>] (cpu_startup_entry) from [<80d52b10>] (start_kernel+0x350/0x35c) Code: 11a002a0 03a00001 e12fff1e e92d4008 (e59130b0) --[ end trace 1160f590a7b228b4 ]-- Kernel panic - not syncing: Fatal exception in interrupt CPU2: stopping CPU: 2 PID: 1483 Comm: modprobe Tainted: G D W 3.14.38-usb-host-otg-02047-ga4dec77 #13 [<80014a68>] (unwind_backtrace) from [<80011758>] (show_stack+0x10/0x14) [<80011758>] (show_stack) from [<806f5fe8>] (dump_stack+0x7c/0xbc) [<806f5fe8>] (dump_stack) from [<800139f0>] (handle_IPI+0x144/0x158) [<800139f0>] (handle_IPI) from [<80008598>] (gic_handle_irq+0x58/0x5c) [<80008598>] (gic_handle_irq) from [<80012240>] (__irq_svc+0x40/0x70) Exception stack(0xd96c5dc0 to 0xd96c5e08) 5dc0: d800995c 0000004b 00000000 00072004 d8f2dec0 d8009900 d800995c 0000004b 5de0: d800995c a00f0013 00000000 010f2280 fffffffa d96c5e08 00000000 8006926c 5e00: 000f0013 ffffffff [<80012240>] (__irq_svc) from [<8006926c>] (synchronize_irq+0x18/0xa8) [<8006926c>] (synchronize_irq) from [<800696dc>] (__free_irq+0xfc/0x1c4) [<800696dc>] (__free_irq) from [<80069838>] (free_irq+0x4c/0xa4) [<80069838>] (free_irq) from [<8034b760>] (release_nodes+0x16c/0x1cc) [<8034b760>] (release_nodes) from [<803487ec>] (__device_release_driver+0x78/0xcc) [<803487ec>] (__device_release_driver) from [<8034885c>] (device_release_driver+0x1c/0x28) [<8034885c>] (device_release_driver) from [<8034827c>] (bus_remove_device+0xdc/0x108) [<8034827c>] (bus_remove_device) from [<80345788>] (device_del+0x100/0x1a4) [<80345788>] (device_del) from [<8034a218>] (platform_device_del+0x18/0x9c) [<8034a218>] (platform_device_del) from [<8034a2a8>] (platform_device_unregister+0xc/0x20) [<8034a2a8>] (platform_device_unregister) from [<7f61932c>] (ci_hdrc_remove_device+0xc/0x20 [ci_hdrc]) [<7f61932c>] (ci_hdrc_remove_device [ci_hdrc]) from [<7f631260>] (ci_hdrc_imx_remove+0x2c/0xdc [ci_hdrc_imx]) [<7f631260>] (ci_hdrc_imx_remove [ci_hdrc_imx]) from [<8034a350>] (platform_drv_remove+0x18/0x30) [<8034a350>] (platform_drv_remove) from [<803487e4>] (__device_release_driver+0x70/0xcc) [<803487e4>] (__device_release_driver) from [<80348ef4>] (driver_detach+0xac/0xb0) [<80348ef4>] (driver_detach) from [<803484e4>] (bus_remove_driver+0x4c/0xa0) [<803484e4>] (bus_remove_driver) from [<80084158>] (SyS_delete_module+0x11c/0x17c) [<80084158>] (SyS_delete_module) from [<8000e460>] (ret_fast_syscall+0x0/0x30) CPU3: stopping CPU: 3 PID: 0 Comm: swapper/3 Tainted: G D W 3.14.38-usb-host-otg-02047-ga4dec77 #13 [<80014a68>] (unwind_backtrace) from [<80011758>] (show_stack+0x10/0x14) [<80011758>] (show_stack) from [<806f5fe8>] (dump_stack+0x7c/0xbc) [<806f5fe8>] (dump_stack) from [<800139f0>] (handle_IPI+0x144/0x158) [<800139f0>] (handle_IPI) from [<80008598>] (gic_handle_irq+0x58/0x5c) [<80008598>] (gic_handle_irq) from [<80012240>] (__irq_svc+0x40/0x70) Exception stack(0xd80b1f50 to 0xd80b1f98) 1f40: d80b1f98 3b9aca00 256aed09 0000000d 1f60: 80dbe1c8 80dbe1c8 ee7360d0 00000000 25477984 0000000d d80b0000 00000000 1f80: 00000017 d80b1f98 00000009 8049c19c 00070013 ffffffff [<80012240>] (__irq_svc) from [<8049c19c>] (cpuidle_enter_state+0x54/0xe4) [<8049c19c>] (cpuidle_enter_state) from [<8049c2e0>] (cpuidle_idle_call+0xb4/0x14c) [<8049c2e0>] (cpuidle_idle_call) from [<8000f07c>] (arch_cpu_idle+0x8/0x44) [<8000f07c>] (arch_cpu_idle) from [<8006876c>] (cpu_startup_entry+0x100/0x14c) [<8006876c>] (cpu_startup_entry) from [<10008624>] (0x10008624) CPU1: stopping Signed-off-by: Peter Chen <peter.chen@freescale.com> Signed-off-by: Li Jun <jun.li@freescale.com> (cherry picked from commit 402f2d38e22007e931dc3dd52a69c0fed88452bf)
-rw-r--r--drivers/usb/chipidea/host.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c
index 963ab3867086..80af4c22aaf9 100644
--- a/drivers/usb/chipidea/host.c
+++ b/drivers/usb/chipidea/host.c
@@ -247,7 +247,10 @@ done:
static irqreturn_t host_irq(struct ci_hdrc *ci)
{
- return usb_hcd_irq(ci->irq, ci->hcd);
+ if (ci->hcd)
+ return usb_hcd_irq(ci->irq, ci->hcd);
+ else
+ return IRQ_NONE;
}
static int host_start(struct ci_hdrc *ci)
@@ -457,8 +460,11 @@ static void ci_hdrc_host_resume(struct ci_hdrc *ci, bool power_lost)
void ci_hdrc_host_destroy(struct ci_hdrc *ci)
{
- if (ci->role == CI_ROLE_HOST && ci->hcd)
+ if (ci->role == CI_ROLE_HOST && ci->hcd) {
+ disable_irq_nosync(ci->irq);
host_stop(ci);
+ enable_irq(ci->irq);
+ }
}
static int ci_ehci_bus_suspend(struct usb_hcd *hcd)