Skip to content
This repository was archived by the owner on Oct 31, 2024. It is now read-only.

Commit 38aef06

Browse files
Selvarasu Ganesangregkh
Selvarasu Ganesan
authored andcommitted
usb: dwc3: core: Stop processing of pending events if controller is halted
commit 0d410e8 upstream. 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>
1 parent 936564b commit 38aef06

File tree

3 files changed

+19
-18
lines changed

3 files changed

+19
-18
lines changed

drivers/usb/dwc3/core.c

+19-3
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,7 @@ static int dwc3_alloc_event_buffers(struct dwc3 *dwc, unsigned int length)
533533
int dwc3_event_buffers_setup(struct dwc3 *dwc)
534534
{
535535
struct dwc3_event_buffer *evt;
536+
u32 reg;
536537

537538
if (!dwc->ev_buf)
538539
return 0;
@@ -545,8 +546,10 @@ int dwc3_event_buffers_setup(struct dwc3 *dwc)
545546
upper_32_bits(evt->dma));
546547
dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0),
547548
DWC3_GEVNTSIZ_SIZE(evt->length));
548-
dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), 0);
549549

550+
/* Clear any stale event */
551+
reg = dwc3_readl(dwc->regs, DWC3_GEVNTCOUNT(0));
552+
dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), reg);
550553
return 0;
551554
}
552555

@@ -573,7 +576,10 @@ void dwc3_event_buffers_cleanup(struct dwc3 *dwc)
573576
dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(0), 0);
574577
dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0), DWC3_GEVNTSIZ_INTMASK
575578
| DWC3_GEVNTSIZ_SIZE(0));
576-
dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), 0);
579+
580+
/* Clear any stale event */
581+
reg = dwc3_readl(dwc->regs, DWC3_GEVNTCOUNT(0));
582+
dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), reg);
577583
}
578584

579585
static void dwc3_core_num_eps(struct dwc3 *dwc)
@@ -2254,7 +2260,11 @@ static int dwc3_runtime_resume(struct device *dev)
22542260

22552261
switch (dwc->current_dr_role) {
22562262
case DWC3_GCTL_PRTCAP_DEVICE:
2257-
dwc3_gadget_process_pending_events(dwc);
2263+
if (dwc->pending_events) {
2264+
pm_runtime_put(dwc->dev);
2265+
dwc->pending_events = false;
2266+
enable_irq(dwc->irq_gadget);
2267+
}
22582268
break;
22592269
case DWC3_GCTL_PRTCAP_HOST:
22602270
default:
@@ -2341,6 +2351,12 @@ static void dwc3_complete(struct device *dev)
23412351
static const struct dev_pm_ops dwc3_dev_pm_ops = {
23422352
SET_SYSTEM_SLEEP_PM_OPS(dwc3_suspend, dwc3_resume)
23432353
.complete = dwc3_complete,
2354+
2355+
/*
2356+
* Runtime suspend halts the controller on disconnection. It relies on
2357+
* platforms with custom connection notification to start the controller
2358+
* again.
2359+
*/
23442360
SET_RUNTIME_PM_OPS(dwc3_runtime_suspend, dwc3_runtime_resume,
23452361
dwc3_runtime_idle)
23462362
};

drivers/usb/dwc3/core.h

-4
Original file line numberDiff line numberDiff line change
@@ -1643,7 +1643,6 @@ static inline void dwc3_otg_host_init(struct dwc3 *dwc)
16431643
#if !IS_ENABLED(CONFIG_USB_DWC3_HOST)
16441644
int dwc3_gadget_suspend(struct dwc3 *dwc);
16451645
int dwc3_gadget_resume(struct dwc3 *dwc);
1646-
void dwc3_gadget_process_pending_events(struct dwc3 *dwc);
16471646
#else
16481647
static inline int dwc3_gadget_suspend(struct dwc3 *dwc)
16491648
{
@@ -1655,9 +1654,6 @@ static inline int dwc3_gadget_resume(struct dwc3 *dwc)
16551654
return 0;
16561655
}
16571656

1658-
static inline void dwc3_gadget_process_pending_events(struct dwc3 *dwc)
1659-
{
1660-
}
16611657
#endif /* !IS_ENABLED(CONFIG_USB_DWC3_HOST) */
16621658

16631659
#if IS_ENABLED(CONFIG_USB_DWC3_ULPI)

drivers/usb/dwc3/gadget.c

-11
Original file line numberDiff line numberDiff line change
@@ -4741,14 +4741,3 @@ int dwc3_gadget_resume(struct dwc3 *dwc)
47414741

47424742
return dwc3_gadget_soft_connect(dwc);
47434743
}
4744-
4745-
void dwc3_gadget_process_pending_events(struct dwc3 *dwc)
4746-
{
4747-
if (dwc->pending_events) {
4748-
dwc3_interrupt(dwc->irq_gadget, dwc->ev_buf);
4749-
dwc3_thread_interrupt(dwc->irq_gadget, dwc->ev_buf);
4750-
pm_runtime_put(dwc->dev);
4751-
dwc->pending_events = false;
4752-
enable_irq(dwc->irq_gadget);
4753-
}
4754-
}

0 commit comments

Comments
 (0)