[PATCH v2] usb: host: xhci-plat: keep runtime active when remove host

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



While remove host(e.g. for USB role switch from host to device), if
runtime pm is enabled by user, below oops are occurs at dwc3
and cdns3 platform. Keep the xhci-plat device being active during
remove host fixes them.

oops1:
Unable to handle kernel NULL pointer dereference at virtual address 0000000000000240
Mem abort info:
  ESR = 0x96000004
xhci-hcd xhci-hcd.1.auto: // Halt the HC
xhci-hcd xhci-hcd.1.auto: // Reset the HC
xhci-hcd xhci-hcd.1.auto: Wait for controller to be ready for doorbell rings
  EC = 0x25: DABT (current EL), IL = 32 bits
  SET = 0, FnV = 0
  EA = 0, S1PTW = 0
Data abort info:
  ISV = 0, ISS = 0x00000004
xhci-hcd xhci-hcd.1.auto: // Disabling event ring interrupts
  CM = 0, WnR = 0
user pgtable: 4k pages, 48-bit VAs, pgdp=00000001b7b18000
xhci-hcd xhci-hcd.1.auto: cleaning up memory
xhci-hcd xhci-hcd.1.auto: Freed event ring
xhci-hcd xhci-hcd.1.auto: Freed command ring
[0000000000000240] pgd=0000000000000000
Internal error: Oops: 96000004 [#1] PREEMPT SMP
Modules linked in:
CPU: 0 PID: 5 Comm: kworker/0:0 Not tainted 5.4.3-00107-g64d454a-dirty #1219
Hardware name: FSL i.MX8MP EVK (DT)
Workqueue: pm pm_runtime_work
pstate: 60000005 (nZCv daif -PAN -UAO)
pc : xhci_suspend+0x34/0x698
lr : xhci_plat_runtime_suspend+0x2c/0x38
sp : ffff800011ddbbc0
x29: ffff800011ddbbc0 x28: 0000000000000000
x27: 0000000000000008 x26: ffff800011b28000
x25: ffff80001012b328 x24: ffff800011ddbd48
x23: 0000000000000000 x22: ffff80001076ed78
x21: ffff000177896000 x20: ffff0001714ebce4
x19: ffff000177896000 x18: ffffffffffffffff
x17: 0000000000000000 x16: 0000000000000000
x15: ffff800011b288c8 x14: 0000000000000261
x13: 0000000000000001 x12: 0000000000000001
x11: 0000000000000000 x10: 00000000000009c0
x9 : ffff800011ddbd40 x8 : fefefefefefefeff
x7 : 0000000000000000 x6 : 000000003ca92688
x5 : 00ffffffffffffff x4 : 001b6b0b00000000
x3 : ffff0001714ebc10 x2 : 0000000000000000
x1 : 0000000000000001 x0 : ffff000177896250
Call trace:
 xhci_suspend+0x34/0x698
 xhci_plat_runtime_suspend+0x2c/0x38
 pm_generic_runtime_suspend+0x28/0x40
 __rpm_callback+0xd8/0x138
 rpm_callback+0x24/0x98
 rpm_suspend+0xe0/0x448
 rpm_idle+0x124/0x140
 pm_runtime_work+0xa0/0xf8
 process_one_work+0x1dc/0x370
 worker_thread+0x48/0x468
 kthread+0xf0/0x120
 ret_from_fork+0x10/0x1c

oops2:
usb 2-1: USB disconnect, device number 2
xhci-hcd xhci-hcd.1.auto: remove, state 4
usb usb2: USB disconnect, device number 1
xhci-hcd xhci-hcd.1.auto: USB bus 2 deregistered
xhci-hcd xhci-hcd.1.auto: remove, state 4
usb usb1: USB disconnect, device number 1
Unable to handle kernel NULL pointer dereference at virtual address 0000000000000138
Mem abort info:
  ESR = 0x96000004
  EC = 0x25: DABT (current EL), IL = 32 bits
  SET = 0, FnV = 0
  EA = 0, S1PTW = 0
Data abort info:
  ISV = 0, ISS = 0x00000004
  CM = 0, WnR = 0
user pgtable: 4k pages, 48-bit VAs, pgdp=00000008b05e8000
[0000000000000138] pgd=0000000000000000, p4d=0000000000000000
Internal error: Oops: 96000004 [#1] PREEMPT SMP
Modules linked in:
CPU: 2 PID: 7 Comm: kworker/u8:0 Not tainted 5.6.0-rc4-next-20200304-03578-gd6235ff42e2b #101
Hardware name: Freescale i.MX8QXP MEK (DT)
Workqueue: 1-0050 tcpm_state_machine_work
pstate: 20000005 (nzCv daif -PAN -UAO)
pc : xhci_free_dev+0x214/0x270
lr : xhci_plat_runtime_resume+0x78/0x88
sp : ffff80001006b5b0
x29: ffff80001006b5b0 x28: 0000000000000002
x27: ffff00083b74fd48 x26: ffff00083a365580
x25: ffff800010141458 x24: 0000000000000000
x23: 0000000000000000 x22: ffff000837e58138
x21: 0000000000000004 x20: ffff000837e58000
x19: ffff000837e58250 x18: 0000000000000000
x17: 0000000000000000 x16: 0000000000000001
x15: 0000000000000004 x14: ffffffffffffffff
x13: 0000000000004ed8 x12: ffff8000123d1000
x11: ffff800012158000 x10: ffff8000123d1360
x9 : ffff800010c74b00 x8 : 0000000000000007
x7 : 00000000000012c2 x6 : ffff8000123d1000
x5 : 0000000000000001 x4 : 0000000000000000
x3 : 0000000000000000 x2 : 0000000000000138
x1 : 0000000000000000 x0 : 0000000000000138
Call trace:
 xhci_free_dev+0x214/0x270
 xhci_plat_runtime_resume+0x78/0x88
 pm_generic_runtime_resume+0x30/0x48
 __rpm_callback+0x90/0x148
 rpm_callback+0x28/0x88
 rpm_resume+0x568/0x758
 rpm_resume+0x260/0x758
 rpm_resume+0x260/0x758
 __pm_runtime_resume+0x40/0x88
 device_release_driver_internal+0xa0/0x1c8
 device_release_driver+0x1c/0x28
 bus_remove_device+0xd4/0x158
 device_del+0x15c/0x3a0
 usb_disable_device+0xb0/0x268
 usb_disconnect+0xcc/0x300
 usb_remove_hcd+0xf4/0x1dc
 xhci_plat_remove+0x78/0xe0
 platform_drv_remove+0x30/0x50
 device_release_driver_internal+0xfc/0x1c8
 device_release_driver+0x1c/0x28
 bus_remove_device+0xd4/0x158
 device_del+0x15c/0x3a0
 platform_device_del.part.0+0x20/0x90
 platform_device_unregister+0x28/0x40
 cdns3_host_exit+0x20/0x40
 cdns3_role_stop+0x60/0x90
 cdns3_role_set+0x64/0xd8
 usb_role_switch_set_role.part.0+0x3c/0x68
 usb_role_switch_set_role+0x20/0x30
 tcpm_mux_set+0x60/0xf8
 tcpm_reset_port+0xa4/0xf0
 tcpm_detach.part.0+0x28/0x50
 tcpm_state_machine_work+0x12ac/0x2360
 process_one_work+0x1c8/0x470
 worker_thread+0x50/0x428
 kthread+0xfc/0x128
 ret_from_fork+0x10/0x18
Code: c8037c02 35ffffa3 17ffe7c3 f9800011 (c85f7c01)
---[ end trace 45b1a173d2679e44 ]---

Cc: Baolin Wang <baolin.wang@xxxxxxxxxx>
Cc: Mathias Nyman <mathias.nyman@xxxxxxxxxxxxxxx>
Cc: <stable@xxxxxxxxxxxxxxx>
Fixes: b0c69b4bace3 ("usb: host: plat: Enable xHCI plat runtime PM")
Reviewed-by: Peter Chen <peter.chen@xxxxxxx>
Tested-by: Peter Chen <peter.chen@xxxxxxx>
Signed-off-by: Li Jun <jun.li@xxxxxxx>
---
changes for v2:
- Add pm_runtime_put_noidle() to balance pm_runtime_get_sync().
- Move pm_runtime_set_suspended() to be after pm_runtime_disable().

 drivers/usb/host/xhci-plat.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
index 1d4f6f8..ea460b9 100644
--- a/drivers/usb/host/xhci-plat.c
+++ b/drivers/usb/host/xhci-plat.c
@@ -362,6 +362,7 @@ static int xhci_plat_remove(struct platform_device *dev)
 	struct clk *reg_clk = xhci->reg_clk;
 	struct usb_hcd *shared_hcd = xhci->shared_hcd;
 
+	pm_runtime_get_sync(&dev->dev);
 	xhci->xhc_state |= XHCI_STATE_REMOVING;
 
 	usb_remove_hcd(shared_hcd);
@@ -375,8 +376,9 @@ static int xhci_plat_remove(struct platform_device *dev)
 	clk_disable_unprepare(reg_clk);
 	usb_put_hcd(hcd);
 
-	pm_runtime_set_suspended(&dev->dev);
 	pm_runtime_disable(&dev->dev);
+	pm_runtime_put_noidle(&dev->dev);
+	pm_runtime_set_suspended(&dev->dev);
 
 	return 0;
 }
-- 
2.7.4




[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux