Skip to content

Commit 7c47d87

Browse files
Selvarasu Ganesangregkh
authored andcommitted
usb: dwc3: core: Stop processing of pending events if controller is halted
[ Upstream commit 0d410e8 ] This commit addresses an issue where events were being processed when the controller was in a halted state. To fix this issue by stop processing the events as the event count was considered stale or invalid when the controller was halted. Fixes: fc8bb91 ("usb: dwc3: implement runtime PM") Cc: stable@kernel.org Signed-off-by: Selvarasu Ganesan <selvarasu.g@samsung.com> Suggested-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com> Acked-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com> Link: https://lore.kernel.org/r/20240916231813.206-1-selvarasu.g@samsung.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent a317705 commit 7c47d87

3 files changed

Lines changed: 19 additions & 18 deletions

File tree

drivers/usb/dwc3/core.c

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,7 @@ static int dwc3_alloc_event_buffers(struct dwc3 *dwc, unsigned length)
404404
int dwc3_event_buffers_setup(struct dwc3 *dwc)
405405
{
406406
struct dwc3_event_buffer *evt;
407+
u32 reg;
407408

408409
if (!dwc->ev_buf)
409410
return 0;
@@ -416,8 +417,10 @@ int dwc3_event_buffers_setup(struct dwc3 *dwc)
416417
upper_32_bits(evt->dma));
417418
dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0),
418419
DWC3_GEVNTSIZ_SIZE(evt->length));
419-
dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), 0);
420420

421+
/* Clear any stale event */
422+
reg = dwc3_readl(dwc->regs, DWC3_GEVNTCOUNT(0));
423+
dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), reg);
421424
return 0;
422425
}
423426

@@ -444,7 +447,10 @@ void dwc3_event_buffers_cleanup(struct dwc3 *dwc)
444447
dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(0), 0);
445448
dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0), DWC3_GEVNTSIZ_INTMASK
446449
| DWC3_GEVNTSIZ_SIZE(0));
447-
dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), 0);
450+
451+
/* Clear any stale event */
452+
reg = dwc3_readl(dwc->regs, DWC3_GEVNTCOUNT(0));
453+
dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), reg);
448454
}
449455

450456
static int dwc3_alloc_scratch_buffers(struct dwc3 *dwc)
@@ -1792,7 +1798,11 @@ static int dwc3_runtime_resume(struct device *dev)
17921798

17931799
switch (dwc->current_dr_role) {
17941800
case DWC3_GCTL_PRTCAP_DEVICE:
1795-
dwc3_gadget_process_pending_events(dwc);
1801+
if (dwc->pending_events) {
1802+
pm_runtime_put(dwc->dev);
1803+
dwc->pending_events = false;
1804+
enable_irq(dwc->irq_gadget);
1805+
}
17961806
break;
17971807
case DWC3_GCTL_PRTCAP_HOST:
17981808
default:
@@ -1879,6 +1889,12 @@ static void dwc3_complete(struct device *dev)
18791889
static const struct dev_pm_ops dwc3_dev_pm_ops = {
18801890
SET_SYSTEM_SLEEP_PM_OPS(dwc3_suspend, dwc3_resume)
18811891
.complete = dwc3_complete,
1892+
1893+
/*
1894+
* Runtime suspend halts the controller on disconnection. It relies on
1895+
* platforms with custom connection notification to start the controller
1896+
* again.
1897+
*/
18821898
SET_RUNTIME_PM_OPS(dwc3_runtime_suspend, dwc3_runtime_resume,
18831899
dwc3_runtime_idle)
18841900
};

drivers/usb/dwc3/core.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1430,7 +1430,6 @@ static inline void dwc3_otg_host_init(struct dwc3 *dwc)
14301430
#if !IS_ENABLED(CONFIG_USB_DWC3_HOST)
14311431
int dwc3_gadget_suspend(struct dwc3 *dwc);
14321432
int dwc3_gadget_resume(struct dwc3 *dwc);
1433-
void dwc3_gadget_process_pending_events(struct dwc3 *dwc);
14341433
#else
14351434
static inline int dwc3_gadget_suspend(struct dwc3 *dwc)
14361435
{
@@ -1442,9 +1441,6 @@ static inline int dwc3_gadget_resume(struct dwc3 *dwc)
14421441
return 0;
14431442
}
14441443

1445-
static inline void dwc3_gadget_process_pending_events(struct dwc3 *dwc)
1446-
{
1447-
}
14481444
#endif /* !IS_ENABLED(CONFIG_USB_DWC3_HOST) */
14491445

14501446
#if IS_ENABLED(CONFIG_USB_DWC3_ULPI)

drivers/usb/dwc3/gadget.c

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3474,14 +3474,3 @@ int dwc3_gadget_resume(struct dwc3 *dwc)
34743474
err0:
34753475
return ret;
34763476
}
3477-
3478-
void dwc3_gadget_process_pending_events(struct dwc3 *dwc)
3479-
{
3480-
if (dwc->pending_events) {
3481-
dwc3_interrupt(dwc->irq_gadget, dwc->ev_buf);
3482-
dwc3_thread_interrupt(dwc->irq_gadget, dwc->ev_buf);
3483-
pm_runtime_put(dwc->dev);
3484-
dwc->pending_events = false;
3485-
enable_irq(dwc->irq_gadget);
3486-
}
3487-
}

0 commit comments

Comments
 (0)