diff options
| author | Praneeth Bajjuri <praneeth@ti.com> | 2024-12-03 10:05:41 -0600 |
|---|---|---|
| committer | Praneeth Bajjuri <praneeth@ti.com> | 2024-12-03 10:05:41 -0600 |
| commit | 3b2bb5514e8497634b034b053a89d7f6b6208571 (patch) | |
| tree | 297cba09f7dd64b0365fcafdd71c262b010016bc /drivers/usb/dwc3 | |
| parent | 7d47730ef310533af2a933ae466724f71dad879a (diff) | |
| parent | e4d90d63d385228b1e0bcf31cc15539bbbc28f7f (diff) | |
Merge branch 'linux-6.1.y' of git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux into ti-linux-6.1.y-cicd
* 'linux-6.1.y' of git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux: (1362 commits)
Linux 6.1.119
net: Make copy_safe_from_sockptr() match documentation
char: xillybus: Fix trivial bug with mutex
parisc: fix a possible DMA corruption
null_blk: Fix return value of nullb_device_power_store()
null_blk: fix null-ptr-dereference while configuring 'power' and 'submit_queues'
null_blk: Remove usage of the deprecated ida_simple_xx() API
char: xillybus: Prevent use-after-free due to race condition
drm/amd: check num of link levels when update pcie param
mm: resolve faulty mmap_region() error path behaviour
mm: refactor arch_calc_vm_flag_bits() and arm64 MTE handling
mm: unconditionally close VMAs on error
mm: avoid unsafe VMA hook invocation when error arises on mmap hook
mm: revert "mm: shmem: fix data-race in shmem_getattr()"
net: fec: remove .ndo_poll_controller to avoid deadlocks
net/sched: taprio: extend minimum interval restriction to entire cycle too
ipvs: properly dereference pe in ip_vs_add_service
fs/9p: fix uninitialized values during inode evict
nfc: llcp: fix nfc_llcp_setsockopt() unsafe copies
net: add copy_safe_from_sockptr() helper
...
Signed-off-by: Praneeth Bajjuri <praneeth@ti.com>
Diffstat (limited to 'drivers/usb/dwc3')
| -rw-r--r-- | drivers/usb/dwc3/core.c | 40 | ||||
| -rw-r--r-- | drivers/usb/dwc3/core.h | 7 | ||||
| -rw-r--r-- | drivers/usb/dwc3/gadget.c | 21 |
3 files changed, 46 insertions, 22 deletions
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 21bfc6e06366..9a192efa1531 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -533,6 +533,7 @@ static int dwc3_alloc_event_buffers(struct dwc3 *dwc, unsigned int length) int dwc3_event_buffers_setup(struct dwc3 *dwc) { struct dwc3_event_buffer *evt; + u32 reg; if (!dwc->ev_buf) return 0; @@ -545,8 +546,10 @@ int dwc3_event_buffers_setup(struct dwc3 *dwc) upper_32_bits(evt->dma)); dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0), DWC3_GEVNTSIZ_SIZE(evt->length)); - dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), 0); + /* Clear any stale event */ + reg = dwc3_readl(dwc->regs, DWC3_GEVNTCOUNT(0)); + dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), reg); return 0; } @@ -573,7 +576,10 @@ void dwc3_event_buffers_cleanup(struct dwc3 *dwc) dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(0), 0); dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0), DWC3_GEVNTSIZ_INTMASK | DWC3_GEVNTSIZ_SIZE(0)); - dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), 0); + + /* Clear any stale event */ + reg = dwc3_readl(dwc->regs, DWC3_GEVNTCOUNT(0)); + dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), reg); } static int dwc3_alloc_scratch_buffers(struct dwc3 *dwc) @@ -2132,6 +2138,19 @@ static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg) { u32 reg; + if (!pm_runtime_suspended(dwc->dev) && !PMSG_IS_AUTO(msg)) { + dwc->susphy_state = (dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)) & + DWC3_GUSB2PHYCFG_SUSPHY) || + (dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0)) & + DWC3_GUSB3PIPECTL_SUSPHY); + /* + * TI AM62 platform requires SUSPHY to be + * enabled for system suspend to work. + */ + if (!dwc->susphy_state) + dwc3_enable_susphy(dwc, true); + } + switch (dwc->current_dr_role) { case DWC3_GCTL_PRTCAP_DEVICE: if (pm_runtime_suspended(dwc->dev)) @@ -2241,6 +2260,11 @@ static int dwc3_resume_common(struct dwc3 *dwc, pm_message_t msg) break; } + if (!PMSG_IS_AUTO(msg)) { + /* restore SUSPHY state to that before system suspend. */ + dwc3_enable_susphy(dwc, dwc->susphy_state); + } + return 0; } @@ -2286,7 +2310,11 @@ static int dwc3_runtime_resume(struct device *dev) switch (dwc->current_dr_role) { case DWC3_GCTL_PRTCAP_DEVICE: - dwc3_gadget_process_pending_events(dwc); + if (dwc->pending_events) { + pm_runtime_put(dwc->dev); + dwc->pending_events = false; + enable_irq(dwc->irq_gadget); + } break; case DWC3_GCTL_PRTCAP_HOST: default: @@ -2373,6 +2401,12 @@ static void dwc3_complete(struct device *dev) static const struct dev_pm_ops dwc3_dev_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(dwc3_suspend, dwc3_resume) .complete = dwc3_complete, + + /* + * Runtime suspend halts the controller on disconnection. It relies on + * platforms with custom connection notification to start the controller + * again. + */ SET_RUNTIME_PM_OPS(dwc3_runtime_suspend, dwc3_runtime_resume, dwc3_runtime_idle) }; diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 251bc438bf40..1b496c8e7b80 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -1118,6 +1118,8 @@ struct dwc3_scratchpad_array { * @dis_metastability_quirk: set to disable metastability quirk. * @dis_split_quirk: set to disable split boundary. * @suspended: set to track suspend event due to U3/L2. + * @susphy_state: state of DWC3_GUSB2PHYCFG_SUSPHY + DWC3_GUSB3PIPECTL_SUSPHY + * before PM suspend. * @imod_interval: set the interrupt moderation interval in 250ns * increments or 0 to disable. * @max_cfg_eps: current max number of IN eps used across all USB configs. @@ -1341,6 +1343,7 @@ struct dwc3 { unsigned dis_split_quirk:1; unsigned async_callbacks:1; unsigned suspended:1; + unsigned susphy_state:1; u16 imod_interval; @@ -1633,7 +1636,6 @@ static inline void dwc3_otg_host_init(struct dwc3 *dwc) #if !IS_ENABLED(CONFIG_USB_DWC3_HOST) int dwc3_gadget_suspend(struct dwc3 *dwc); int dwc3_gadget_resume(struct dwc3 *dwc); -void dwc3_gadget_process_pending_events(struct dwc3 *dwc); #else static inline int dwc3_gadget_suspend(struct dwc3 *dwc) { @@ -1645,9 +1647,6 @@ static inline int dwc3_gadget_resume(struct dwc3 *dwc) return 0; } -static inline void dwc3_gadget_process_pending_events(struct dwc3 *dwc) -{ -} #endif /* !IS_ENABLED(CONFIG_USB_DWC3_HOST) */ #if IS_ENABLED(CONFIG_USB_DWC3_ULPI) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index c72c6f8ec2c8..0373239d44c2 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -445,6 +445,10 @@ skip_status: dwc3_gadget_ep_get_transfer_index(dep); } + if (DWC3_DEPCMD_CMD(cmd) == DWC3_DEPCMD_ENDTRANSFER && + !(cmd & DWC3_DEPCMD_CMDIOC)) + mdelay(1); + if (saved_config) { reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); reg |= saved_config; @@ -1731,12 +1735,10 @@ static int __dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force, bool int WARN_ON_ONCE(ret); dep->resource_index = 0; - if (!interrupt) { - mdelay(1); + if (!interrupt) dep->flags &= ~DWC3_EP_TRANSFER_STARTED; - } else if (!ret) { + else if (!ret) dep->flags |= DWC3_EP_END_TRANSFER_PENDING; - } dep->flags &= ~DWC3_EP_DELAY_STOP; return ret; @@ -4618,14 +4620,3 @@ int dwc3_gadget_resume(struct dwc3 *dwc) return dwc3_gadget_soft_connect(dwc); } - -void dwc3_gadget_process_pending_events(struct dwc3 *dwc) -{ - if (dwc->pending_events) { - dwc3_interrupt(dwc->irq_gadget, dwc->ev_buf); - dwc3_thread_interrupt(dwc->irq_gadget, dwc->ev_buf); - pm_runtime_put(dwc->dev); - dwc->pending_events = false; - enable_irq(dwc->irq_gadget); - } -} |
