summaryrefslogtreecommitdiff
path: root/drivers/usb
diff options
context:
space:
mode:
authorDouglas Anderson <dianders@chromium.org>2015-11-20 09:06:27 -0800
committerFelipe Balbi <balbi@ti.com>2015-12-15 09:12:41 -0600
commit4a065c7bdbec9536f7b899241b125b9c3b5ba97a (patch)
tree36d4022995b2c1647664716c35daf44d44a19618 /drivers/usb
parent98bfb39466954c69d2a448e6ddcab6d91cd48e25 (diff)
usb: dwc2: host: Add missing spinlock in dwc2_hcd_reset_func()
The dwc2_hcd_reset_func() function is only ever called directly by a delayed work function. As such no locks are already held when the function is called. Doing a read-modify-write of CPU registers and setting fields in the main hsotg data structure is a bad idea without locks. Let's add locks. The bug was found by code inspection only. It turns out that the dwc2_hcd_reset_func() is only ever called today if the "host_support_fs_ls_low_power" parameter is enabled and no code in mainline enables that parameter. Thus no known issues in mainline are fixed by this patch, but it's still probably wise to fix the function. Signed-off-by: Douglas Anderson <dianders@chromium.org> Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/dwc2/hcd.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index cbfdcb804adb..880b549f737a 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -2358,13 +2358,19 @@ static void dwc2_hcd_reset_func(struct work_struct *work)
{
struct dwc2_hsotg *hsotg = container_of(work, struct dwc2_hsotg,
reset_work.work);
+ unsigned long flags;
u32 hprt0;
dev_dbg(hsotg->dev, "USB RESET function called\n");
+
+ spin_lock_irqsave(&hsotg->lock, flags);
+
hprt0 = dwc2_read_hprt0(hsotg);
hprt0 &= ~HPRT0_RST;
dwc2_writel(hprt0, hsotg->regs + HPRT0);
hsotg->flags.b.port_reset_change = 1;
+
+ spin_unlock_irqrestore(&hsotg->lock, flags);
}
/*