Skip to content

Commit 0d410e8

Browse files
Selvarasu Ganesangregkh
authored andcommitted
usb: dwc3: core: Stop processing of pending events if controller is halted
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: [email protected] Signed-off-by: Selvarasu Ganesan <[email protected]> Suggested-by: Thinh Nguyen <[email protected]> Acked-by: Thinh Nguyen <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 897e13a commit 0d410e8

File tree

3 files changed

+19
-18
lines changed

3 files changed

+19
-18
lines changed

drivers/usb/dwc3/core.c

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,7 @@ static int dwc3_alloc_event_buffers(struct dwc3 *dwc, unsigned int length)
544544
int dwc3_event_buffers_setup(struct dwc3 *dwc)
545545
{
546546
struct dwc3_event_buffer *evt;
547+
u32 reg;
547548

548549
if (!dwc->ev_buf)
549550
return 0;
@@ -556,8 +557,10 @@ int dwc3_event_buffers_setup(struct dwc3 *dwc)
556557
upper_32_bits(evt->dma));
557558
dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0),
558559
DWC3_GEVNTSIZ_SIZE(evt->length));
559-
dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), 0);
560560

561+
/* Clear any stale event */
562+
reg = dwc3_readl(dwc->regs, DWC3_GEVNTCOUNT(0));
563+
dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), reg);
561564
return 0;
562565
}
563566

@@ -584,7 +587,10 @@ void dwc3_event_buffers_cleanup(struct dwc3 *dwc)
584587
dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(0), 0);
585588
dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0), DWC3_GEVNTSIZ_INTMASK
586589
| DWC3_GEVNTSIZ_SIZE(0));
587-
dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), 0);
590+
591+
/* Clear any stale event */
592+
reg = dwc3_readl(dwc->regs, DWC3_GEVNTCOUNT(0));
593+
dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), reg);
588594
}
589595

590596
static void dwc3_core_num_eps(struct dwc3 *dwc)
@@ -2499,7 +2505,11 @@ static int dwc3_runtime_resume(struct device *dev)
24992505

25002506
switch (dwc->current_dr_role) {
25012507
case DWC3_GCTL_PRTCAP_DEVICE:
2502-
dwc3_gadget_process_pending_events(dwc);
2508+
if (dwc->pending_events) {
2509+
pm_runtime_put(dwc->dev);
2510+
dwc->pending_events = false;
2511+
enable_irq(dwc->irq_gadget);
2512+
}
25032513
break;
25042514
case DWC3_GCTL_PRTCAP_HOST:
25052515
default:
@@ -2587,6 +2597,12 @@ static void dwc3_complete(struct device *dev)
25872597
static const struct dev_pm_ops dwc3_dev_pm_ops = {
25882598
SET_SYSTEM_SLEEP_PM_OPS(dwc3_suspend, dwc3_resume)
25892599
.complete = dwc3_complete,
2600+
2601+
/*
2602+
* Runtime suspend halts the controller on disconnection. It relies on
2603+
* platforms with custom connection notification to start the controller
2604+
* again.
2605+
*/
25902606
SET_RUNTIME_PM_OPS(dwc3_runtime_suspend, dwc3_runtime_resume,
25912607
dwc3_runtime_idle)
25922608
};

drivers/usb/dwc3/core.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1675,7 +1675,6 @@ static inline void dwc3_otg_host_init(struct dwc3 *dwc)
16751675
#if !IS_ENABLED(CONFIG_USB_DWC3_HOST)
16761676
int dwc3_gadget_suspend(struct dwc3 *dwc);
16771677
int dwc3_gadget_resume(struct dwc3 *dwc);
1678-
void dwc3_gadget_process_pending_events(struct dwc3 *dwc);
16791678
#else
16801679
static inline int dwc3_gadget_suspend(struct dwc3 *dwc)
16811680
{
@@ -1687,9 +1686,6 @@ static inline int dwc3_gadget_resume(struct dwc3 *dwc)
16871686
return 0;
16881687
}
16891688

1690-
static inline void dwc3_gadget_process_pending_events(struct dwc3 *dwc)
1691-
{
1692-
}
16931689
#endif /* !IS_ENABLED(CONFIG_USB_DWC3_HOST) */
16941690

16951691
#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
@@ -4728,14 +4728,3 @@ int dwc3_gadget_resume(struct dwc3 *dwc)
47284728

47294729
return dwc3_gadget_soft_connect(dwc);
47304730
}
4731-
4732-
void dwc3_gadget_process_pending_events(struct dwc3 *dwc)
4733-
{
4734-
if (dwc->pending_events) {
4735-
dwc3_interrupt(dwc->irq_gadget, dwc->ev_buf);
4736-
dwc3_thread_interrupt(dwc->irq_gadget, dwc->ev_buf);
4737-
pm_runtime_put(dwc->dev);
4738-
dwc->pending_events = false;
4739-
enable_irq(dwc->irq_gadget);
4740-
}
4741-
}

0 commit comments

Comments
 (0)