summaryrefslogtreecommitdiffstats
path: root/drivers/usb/dwc3
diff options
context:
space:
mode:
authorLi Jun <jun.li@nxp.com>2020-07-26 11:17:39 +0800
committerFelipe Balbi <balbi@kernel.org>2020-10-02 09:43:36 +0300
commitdc336b19e82d0454ea60270cd18fbb4749e162f6 (patch)
tree90fc0840f4adb9898e89cde5199cefeab779c1ff /drivers/usb/dwc3
parente8d5f92b8d30bb4ade76494490c3c065e12411b1 (diff)
downloadlinux-dc336b19e82d0454ea60270cd18fbb4749e162f6.tar.bz2
usb: dwc3: core: do not queue work if dr_mode is not USB_DR_MODE_OTG
Do not try to queue a drd work if dr_mode is not USB_DR_MODE_OTG because the work is not inited, this may be triggered by user try to change mode file of debugfs on a single role port, which will cause below kernel dump: [ 60.115529] ------------[ cut here ]------------ [ 60.120166] WARNING: CPU: 1 PID: 627 at kernel/workqueue.c:1473 __queue_work+0x46c/0x520 [ 60.128254] Modules linked in: [ 60.131313] CPU: 1 PID: 627 Comm: sh Not tainted 5.7.0-rc4-00022-g914a586-dirty #135 [ 60.139054] Hardware name: NXP i.MX8MQ EVK (DT) [ 60.143585] pstate: a0000085 (NzCv daIf -PAN -UAO) [ 60.148376] pc : __queue_work+0x46c/0x520 [ 60.152385] lr : __queue_work+0x314/0x520 [ 60.156393] sp : ffff8000124ebc40 [ 60.159705] x29: ffff8000124ebc40 x28: ffff800011808018 [ 60.165018] x27: ffff800011819ef8 x26: ffff800011d39980 [ 60.170331] x25: ffff800011808018 x24: 0000000000000100 [ 60.175643] x23: 0000000000000013 x22: 0000000000000001 [ 60.180955] x21: ffff0000b7c08e00 x20: ffff0000b6c31080 [ 60.186267] x19: ffff0000bb99bc00 x18: 0000000000000000 [ 60.191579] x17: 0000000000000000 x16: 0000000000000000 [ 60.196891] x15: 0000000000000000 x14: 0000000000000000 [ 60.202202] x13: 0000000000000000 x12: 0000000000000000 [ 60.207515] x11: 0000000000000000 x10: 0000000000000040 [ 60.212827] x9 : ffff800011d55460 x8 : ffff800011d55458 [ 60.218138] x7 : ffff0000b7800028 x6 : 0000000000000000 [ 60.223450] x5 : ffff0000b7800000 x4 : 0000000000000000 [ 60.228762] x3 : ffff0000bb997cc0 x2 : 0000000000000001 [ 60.234074] x1 : 0000000000000000 x0 : ffff0000b6c31088 [ 60.239386] Call trace: [ 60.241834] __queue_work+0x46c/0x520 [ 60.245496] queue_work_on+0x6c/0x90 [ 60.249075] dwc3_set_mode+0x48/0x58 [ 60.252651] dwc3_mode_write+0xf8/0x150 [ 60.256489] full_proxy_write+0x5c/0xa8 [ 60.260327] __vfs_write+0x18/0x40 [ 60.263729] vfs_write+0xdc/0x1c8 [ 60.267045] ksys_write+0x68/0xf0 [ 60.270360] __arm64_sys_write+0x18/0x20 [ 60.274286] el0_svc_common.constprop.0+0x68/0x160 [ 60.279077] do_el0_svc+0x20/0x80 [ 60.282394] el0_sync_handler+0x10c/0x178 [ 60.286403] el0_sync+0x140/0x180 [ 60.289716] ---[ end trace 70b155582e2b7988 ]--- Signed-off-by: Li Jun <jun.li@nxp.com> Signed-off-by: Felipe Balbi <balbi@kernel.org>
Diffstat (limited to 'drivers/usb/dwc3')
-rw-r--r--drivers/usb/dwc3/core.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index f3093b4e5307..9b49a6ce0132 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -120,9 +120,6 @@ static void __dwc3_set_mode(struct work_struct *work)
unsigned long flags;
int ret;
- if (dwc->dr_mode != USB_DR_MODE_OTG)
- return;
-
pm_runtime_get_sync(dwc->dev);
if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_OTG)
@@ -203,6 +200,9 @@ void dwc3_set_mode(struct dwc3 *dwc, u32 mode)
{
unsigned long flags;
+ if (dwc->dr_mode != USB_DR_MODE_OTG)
+ return;
+
spin_lock_irqsave(&dwc->lock, flags);
dwc->desired_dr_role = mode;
spin_unlock_irqrestore(&dwc->lock, flags);