Commit 4a065c7b authored by Douglas Anderson's avatar Douglas Anderson Committed by Felipe Balbi

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: default avatarDouglas Anderson <dianders@chromium.org>
Signed-off-by: default avatarFelipe Balbi <balbi@ti.com>
parent 98bfb394
...@@ -2358,13 +2358,19 @@ static void dwc2_hcd_reset_func(struct work_struct *work) ...@@ -2358,13 +2358,19 @@ static void dwc2_hcd_reset_func(struct work_struct *work)
{ {
struct dwc2_hsotg *hsotg = container_of(work, struct dwc2_hsotg, struct dwc2_hsotg *hsotg = container_of(work, struct dwc2_hsotg,
reset_work.work); reset_work.work);
unsigned long flags;
u32 hprt0; u32 hprt0;
dev_dbg(hsotg->dev, "USB RESET function called\n"); dev_dbg(hsotg->dev, "USB RESET function called\n");
spin_lock_irqsave(&hsotg->lock, flags);
hprt0 = dwc2_read_hprt0(hsotg); hprt0 = dwc2_read_hprt0(hsotg);
hprt0 &= ~HPRT0_RST; hprt0 &= ~HPRT0_RST;
dwc2_writel(hprt0, hsotg->regs + HPRT0); dwc2_writel(hprt0, hsotg->regs + HPRT0);
hsotg->flags.b.port_reset_change = 1; hsotg->flags.b.port_reset_change = 1;
spin_unlock_irqrestore(&hsotg->lock, flags);
} }
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment