From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from smtp1.osuosl.org (smtp1.osuosl.org [140.211.166.138]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id C8EFEC5DF81 for ; Mon, 24 Aug 2026 16:46:55 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id 9473D81000; Mon, 24 Aug 2026 16:46:55 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id vuFK44cDQJUz; Mon, 24 Aug 2026 16:46:52 +0000 (UTC) X-Comment: SPF check N/A for local connections - client-ip=140.211.166.142; helo=lists1.osuosl.org; envelope-from=u-boot-bounces@lists.u-boot-project.org; receiver= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=lists.u-boot-project.org; s=default; t=1787589924; bh=Joolsl9I0RM147Yq5P0/o2a5p9AUCYnMyf5z3iKQ+lc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=RUC4c78ZuKZyGKcgXwVsjJcKjcF6CAM25bByhfJmMFY6RR9SDOcS0zIVnurHH/AF4 0cHRtRb635CtCloQ+R8Yyr1flCW8N8qMkjs3senRHOpW0X0EvUr4o2PdOmYitGvfsA Q+thWe8AkkCoyx2MeNiMpuTLVYv382vhNm1OtJA+WLYAXw+E/dQ669x0nMQODlcHIb bTh7w/TP4A5o2ePuYwWD8Up7PcYT7oSbvV8SKi13CN2q2WW+j07CA0Go2mCQdoNFLI v05XoEnXCvO/q5Cvr6TLA7MLoICt5noKUBp1wh6XbTKQPjL/aGs5g8E/WRISzaixGr NKohDqgWmmLsA== Received: from lists1.osuosl.org (lists1.osuosl.org [140.211.166.142]) by smtp1.osuosl.org (Postfix) with ESMTP id 6B09580F01; Mon, 24 Aug 2026 16:45:24 +0000 (UTC) Received: from smtp3.osuosl.org (smtp3.osuosl.org [IPv6:2605:bc80:3010::136]) by lists1.osuosl.org (Postfix) with ESMTP id C32F329B for ; Mon, 24 Aug 2026 15:32:47 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id A98726062C for ; Mon, 24 Aug 2026 15:32:47 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp3.osuosl.org ([127.0.0.1]) by localhost (smtp3.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id Tm83ikggBrnz for ; Mon, 24 Aug 2026 15:32:46 +0000 (UTC) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=2a00:1450:4864:20::62d; helo=mail-ej1-x62d.google.com; envelope-from=anders.roxell@linaro.org; receiver= Authentication-Results: smtp3.osuosl.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: smtp3.osuosl.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=R/tAXwnX Received: from mail-ej1-x62d.google.com (mail-ej1-x62d.google.com [IPv6:2a00:1450:4864:20::62d]) by smtp3.osuosl.org (Postfix) with ESMTPS id 0E509605EC for ; Mon, 24 Aug 2026 15:32:45 +0000 (UTC) Received: by mail-ej1-x62d.google.com with SMTP id a640c23a62f3a-c16111a9b8dso34930066b.1 for ; Mon, 24 Aug 2026 08:32:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1787585564; x=1788190364; darn=lists.u-boot-project.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=Joolsl9I0RM147Yq5P0/o2a5p9AUCYnMyf5z3iKQ+lc=; b=R/tAXwnXxt1iXaifHkKH4tfUhWGGTx2QpCU7eCMjIEP0QA9EU9CfVBPiUdTJhUeeSz N9mzKsjfptTYY4SqTmczVKQDCH66RIkXKbb8xa5j5+5b5Jx8vVWNL2M5der/vKuVwdOy MSB1fhVduzL/Cthuyskq93vIP8eG9BgQy4FRFVY/5WuKeobRe6leNu8ipBbLcAcLCObI G49k1l4fd3F0MPw770MBLsIMXwBV3fmrsXFAouPiAuvq9/+LjV7pl+LzeVTE2mOC4SpJ 8dSNeX87KAtz3OEZ06kVCh5nHQO+w5wTVIpljz2QsAzwm4MvclahOlDRKp1IecmBwg8N 4eJg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787585564; x=1788190364; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=Joolsl9I0RM147Yq5P0/o2a5p9AUCYnMyf5z3iKQ+lc=; b=IF3XBklsuG/LxbSAs8dqEePQsTGclQItsarJtJG3zmeAKwUgyklJQm8X0kogbd59cx Mq8Z1aMo0OGr64fTv0CUrNfz3R4KBV4R0trUUy1CFg2+8llgbePmnLZKTJoe9dwQA9JI hbdqo68h7J06+VZW0avOfbYNVXqyubwB59lZ+xH34u8S7lDKphq5dCQJmcGCEyLvq0fp EBIB2yDERp+PxgG7ETIaCx2irszxRs3gFG07ldHjwMSeGsTmrJ14V+C7hWfSlBeufwkX p3RshnXD0xXvBsfunpF12W0HiE+3isfjQCsjJ0+4WdI7AUME3t+Kxo4SwqTpsiCCN4KN etzA== X-Gm-Message-State: AFuF++kwJIV4oSGpzmjzBYM3LsVyloYgJQcRNZ27vmmRVNvGVFN8KCx1 Q6JDCiHTo2g0BGgRYKlUj5ImbE9JaudUXp6UDEMQkbRgTZhna8cqgQvo/i1evbg8VvaYhS9YSwg XIYHh X-Gm-Gg: AR+sD10eWEIJwDliWlHIEISNYXW3WYx9G5OvY6d028Mxr0DpQuV3xK+MKqXkyQb/J3/ eCzGu+bDSz2uT3x0SmbssBkr/5dt12sJzP4BVsS7y63zspZlVrfs2JKmlv6LE0AbbEquLW7Qsi5 QhFUE16qAbu4ZufmC4ioarQ8t3cCqIaZKgVdY6WvXN+HrVUNPNcNldgKBACW7cFTsZgAaJomArJ B8m2sGUGByjx1WYxGwPgxjpA8ygqHDApXEtfSGOZkJksRZdMbKI4YD0MblAcmJFCK8FNsVSeHc/ /uTyfymD122/O7b8nPPy6FgJODvjxv7TSz/RqWoAwoLYM4/Z6bkIjJ2pBGmbp4dRIWLJKm7OREs HVHSrvQiHWjCVLD99TaZ5ZJiqg6DnZR4LDSmB8OMaBTUffEu4my2UpHfnx5f4cHfC6Ko6dY74Ot TbIOST+lcqR+LNp8Epat79LwlOsG/alYlJfzsRz2ToVk8RSy6QoZ1Spz2dyFORbSiUVhUoe2gQU MtsZZCkfxHRyQSOQdTHew== X-Received: by 2002:a17:907:c19:b0:c21:6f8c:231f with SMTP id a640c23a62f3a-c246a2e942emr1716582566b.1.1787585563789; Mon, 24 Aug 2026 08:32:43 -0700 (PDT) Received: from monster (c-85-229-7-191.bbcust.telenor.se. [85.229.7.191]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-c2496295627sm1267430166b.15.2026.08.24.08.32.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 24 Aug 2026 08:32:43 -0700 (PDT) From: Anders Roxell To: u-boot@lists.u-boot-project.org Cc: marek.vasut@mailbox.org, trini@konsulko.com, ilias.apalodimas@linaro.org, michal.simek@amd.com, lukma@denx.de, alchark@flipper.net, jerome.forissier@arm.com, Jens Wiklander , Anders Roxell , Mattijs Korpershoek Subject: [PATCH v7 61/63] usb: dwc3: import from kernel v6.16 Date: Mon, 24 Aug 2026 17:27:32 +0200 Message-ID: <20260824152734.159794-62-anders.roxell@linaro.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260824152734.159794-1-anders.roxell@linaro.org> References: <20260824152734.159794-1-anders.roxell@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Mailman-Approved-At: Mon, 24 Aug 2026 16:43:55 +0000 X-BeenThere: u-boot@lists.u-boot-project.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.u-boot-project.org From: Jens Wiklander Sync Linux kernel dwc3 changes from v6.15 to v6.16. The following files are preserved across the import: Makefile Kconfig dwc3-meson-g12a.c dwc3-meson-gxl.c dwc3-omap.c dwc3-uniphier.c dwc3-generic.h dwc3-generic.c dwc3-generic-sti.c dwc3-layerscape.c ti_usb_phy.c Skipping unused files: debugfs.c drd.c dwc3-exynos.c dwc3-haps.c dwc3-imx8mp.c dwc3-keystone.c dwc3-octeon.c dwc3-of-simple.c dwc3-pci.c dwc3-qcom.c dwc3-qcom-legacy.c dwc3-rtk.c dwc3-st.c dwc3-xilinx.c host.c trace.c trace.h ulpi.c Note that this is a raw import and doesn't build. A fixup commit at the end of the series fixes that. List of commits: git log --oneline v6.15..v6.16 Commits imported: 80e083943775 usb: dwc3: gadget: Fix TRB reclaim logic for short transfers and ZLPs 630a1dec3b0e usb: dwc3: Abort suspend on soft disconnect failure 170940f7e685 usb: dwc3: core: Don't touch resets and clocks 613a2e655d4d usb: dwc3: core: Expose core driver as library 850e634006f4 usb: dwc3: core: Avoid redundant system suspend/resume callbacks 8da7644493b4 usb: dwc3: Specify maximum number of XHCI interrupters Signed-off-by: Jens Wiklander Signed-off-by: Anders Roxell Reviewed-by: Mattijs Korpershoek --- drivers/usb/dwc3/core.c | 206 ++++++++++++++++++++++++++++---------- drivers/usb/dwc3/core.h | 2 + drivers/usb/dwc3/gadget.c | 24 ++--- drivers/usb/dwc3/glue.h | 36 +++++++ 4 files changed, 199 insertions(+), 69 deletions(-) create mode 100644 drivers/usb/dwc3/glue.h diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 66a08b527165..8002c23a5a02 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -36,6 +37,7 @@ #include "core.h" #include "gadget.h" +#include "glue.h" #include "io.h" #include "debug.h" @@ -1699,6 +1701,7 @@ static void dwc3_get_properties(struct dwc3 *dwc) u8 tx_thr_num_pkt_prd = 0; u8 tx_max_burst_prd = 0; u8 tx_fifo_resize_max_num; + u16 num_hc_interrupters; /* default to highest possible threshold */ lpm_nyet_threshold = 0xf; @@ -1719,6 +1722,9 @@ static void dwc3_get_properties(struct dwc3 *dwc) */ tx_fifo_resize_max_num = 6; + /* default to a single XHCI interrupter */ + num_hc_interrupters = 1; + dwc->maximum_speed = usb_get_maximum_speed(dev); dwc->max_ssp_rate = usb_get_maximum_ssp_rate(dev); dwc->dr_mode = usb_get_dr_mode(dev); @@ -1765,6 +1771,12 @@ static void dwc3_get_properties(struct dwc3 *dwc) &tx_thr_num_pkt_prd); device_property_read_u8(dev, "snps,tx-max-burst-prd", &tx_max_burst_prd); + device_property_read_u16(dev, "num-hc-interrupters", + &num_hc_interrupters); + /* DWC3 core allowed to have a max of 8 interrupters */ + if (num_hc_interrupters > 8) + num_hc_interrupters = 8; + dwc->do_fifo_resize = device_property_read_bool(dev, "tx-fifo-resize"); if (dwc->do_fifo_resize) @@ -1851,6 +1863,8 @@ static void dwc3_get_properties(struct dwc3 *dwc) dwc->tx_max_burst_prd = tx_max_burst_prd; dwc->tx_fifo_resize_max_num = tx_fifo_resize_max_num; + + dwc->num_hc_interrupters = num_hc_interrupters; } /* check whether the core supports IMOD */ @@ -2148,27 +2162,16 @@ static struct power_supply *dwc3_get_usb_power_supply(struct dwc3 *dwc) return usb_psy; } -static int dwc3_probe(struct platform_device *pdev) +int dwc3_core_probe(const struct dwc3_probe_data *data) { - struct device *dev = &pdev->dev; - struct resource *res, dwc_res; + struct dwc3 *dwc = data->dwc; + struct device *dev = dwc->dev; + struct resource dwc_res; unsigned int hw_mode; void __iomem *regs; - struct dwc3 *dwc; + struct resource *res = data->res; int ret; - dwc = devm_kzalloc(dev, sizeof(*dwc), GFP_KERNEL); - if (!dwc) - return -ENOMEM; - - dwc->dev = dev; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(dev, "missing memory resource\n"); - return -ENODEV; - } - dwc->xhci_resources[0].start = res->start; dwc->xhci_resources[0].end = dwc->xhci_resources[0].start + DWC3_XHCI_REGS_END; @@ -2208,15 +2211,17 @@ static int dwc3_probe(struct platform_device *pdev) if (IS_ERR(dwc->usb_psy)) return dev_err_probe(dev, PTR_ERR(dwc->usb_psy), "couldn't get usb power supply\n"); - dwc->reset = devm_reset_control_array_get_optional_shared(dev); - if (IS_ERR(dwc->reset)) { - ret = PTR_ERR(dwc->reset); - goto err_put_psy; - } + if (!data->ignore_clocks_and_resets) { + dwc->reset = devm_reset_control_array_get_optional_shared(dev); + if (IS_ERR(dwc->reset)) { + ret = PTR_ERR(dwc->reset); + goto err_put_psy; + } - ret = dwc3_get_clocks(dwc); - if (ret) - goto err_put_psy; + ret = dwc3_get_clocks(dwc); + if (ret) + goto err_put_psy; + } ret = reset_control_deassert(dwc->reset); if (ret) @@ -2232,7 +2237,7 @@ static int dwc3_probe(struct platform_device *pdev) goto err_disable_clks; } - platform_set_drvdata(pdev, dwc); + dev_set_drvdata(dev, dwc); dwc3_cache_hwparams(dwc); if (!dwc->sysdev_is_parent && @@ -2327,12 +2332,35 @@ err_put_psy: return ret; } +EXPORT_SYMBOL_GPL(dwc3_core_probe); -static void dwc3_remove(struct platform_device *pdev) +static int dwc3_probe(struct platform_device *pdev) { - struct dwc3 *dwc = platform_get_drvdata(pdev); + struct dwc3_probe_data probe_data = {}; + struct resource *res; + struct dwc3 *dwc; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "missing memory resource\n"); + return -ENODEV; + } + + dwc = devm_kzalloc(&pdev->dev, sizeof(*dwc), GFP_KERNEL); + if (!dwc) + return -ENOMEM; - pm_runtime_get_sync(&pdev->dev); + dwc->dev = &pdev->dev; + + probe_data.dwc = dwc; + probe_data.res = res; + + return dwc3_core_probe(&probe_data); +} + +void dwc3_core_remove(struct dwc3 *dwc) +{ + pm_runtime_get_sync(dwc->dev); dwc3_core_exit_mode(dwc); dwc3_debugfs_exit(dwc); @@ -2340,22 +2368,28 @@ static void dwc3_remove(struct platform_device *pdev) dwc3_core_exit(dwc); dwc3_ulpi_exit(dwc); - pm_runtime_allow(&pdev->dev); - pm_runtime_disable(&pdev->dev); - pm_runtime_dont_use_autosuspend(&pdev->dev); - pm_runtime_put_noidle(&pdev->dev); + pm_runtime_allow(dwc->dev); + pm_runtime_disable(dwc->dev); + pm_runtime_dont_use_autosuspend(dwc->dev); + pm_runtime_put_noidle(dwc->dev); /* * HACK: Clear the driver data, which is currently accessed by parent * glue drivers, before allowing the parent to suspend. */ - platform_set_drvdata(pdev, NULL); - pm_runtime_set_suspended(&pdev->dev); + dev_set_drvdata(dwc->dev, NULL); + pm_runtime_set_suspended(dwc->dev); dwc3_free_event_buffers(dwc); if (dwc->usb_psy) power_supply_put(dwc->usb_psy); } +EXPORT_SYMBOL_GPL(dwc3_core_remove); + +static void dwc3_remove(struct platform_device *pdev) +{ + dwc3_core_remove(platform_get_drvdata(pdev)); +} #ifdef CONFIG_PM static int dwc3_core_init_for_resume(struct dwc3 *dwc) @@ -2388,6 +2422,7 @@ static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg) { u32 reg; int i; + int ret; if (!pm_runtime_suspended(dwc->dev) && !PMSG_IS_AUTO(msg)) { dwc->susphy_state = (dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)) & @@ -2406,7 +2441,9 @@ static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg) case DWC3_GCTL_PRTCAP_DEVICE: if (pm_runtime_suspended(dwc->dev)) break; - dwc3_gadget_suspend(dwc); + ret = dwc3_gadget_suspend(dwc); + if (ret) + return ret; synchronize_irq(dwc->irq_gadget); dwc3_core_exit(dwc); break; @@ -2441,7 +2478,9 @@ static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg) break; if (dwc->current_otg_role == DWC3_OTG_ROLE_DEVICE) { - dwc3_gadget_suspend(dwc); + ret = dwc3_gadget_suspend(dwc); + if (ret) + return ret; synchronize_irq(dwc->irq_gadget); } @@ -2544,9 +2583,8 @@ static int dwc3_runtime_checks(struct dwc3 *dwc) return 0; } -static int dwc3_runtime_suspend(struct device *dev) +int dwc3_runtime_suspend(struct dwc3 *dwc) { - struct dwc3 *dwc = dev_get_drvdata(dev); int ret; if (dwc3_runtime_checks(dwc)) @@ -2558,10 +2596,11 @@ static int dwc3_runtime_suspend(struct device *dev) return 0; } +EXPORT_SYMBOL_GPL(dwc3_runtime_suspend); -static int dwc3_runtime_resume(struct device *dev) +int dwc3_runtime_resume(struct dwc3 *dwc) { - struct dwc3 *dwc = dev_get_drvdata(dev); + struct device *dev = dwc->dev; int ret; ret = dwc3_resume_common(dwc, PMSG_AUTO_RESUME); @@ -2571,7 +2610,7 @@ static int dwc3_runtime_resume(struct device *dev) switch (dwc->current_dr_role) { case DWC3_GCTL_PRTCAP_DEVICE: if (dwc->pending_events) { - pm_runtime_put(dwc->dev); + pm_runtime_put(dev); dwc->pending_events = false; enable_irq(dwc->irq_gadget); } @@ -2586,10 +2625,11 @@ static int dwc3_runtime_resume(struct device *dev) return 0; } +EXPORT_SYMBOL_GPL(dwc3_runtime_resume); -static int dwc3_runtime_idle(struct device *dev) +int dwc3_runtime_idle(struct dwc3 *dwc) { - struct dwc3 *dwc = dev_get_drvdata(dev); + struct device *dev = dwc->dev; switch (dwc->current_dr_role) { case DWC3_GCTL_PRTCAP_DEVICE: @@ -2607,12 +2647,28 @@ static int dwc3_runtime_idle(struct device *dev) return 0; } +EXPORT_SYMBOL_GPL(dwc3_runtime_idle); + +static int dwc3_plat_runtime_suspend(struct device *dev) +{ + return dwc3_runtime_suspend(dev_get_drvdata(dev)); +} + +static int dwc3_plat_runtime_resume(struct device *dev) +{ + return dwc3_runtime_resume(dev_get_drvdata(dev)); +} + +static int dwc3_plat_runtime_idle(struct device *dev) +{ + return dwc3_runtime_idle(dev_get_drvdata(dev)); +} #endif /* CONFIG_PM */ #ifdef CONFIG_PM_SLEEP -static int dwc3_suspend(struct device *dev) +int dwc3_pm_suspend(struct dwc3 *dwc) { - struct dwc3 *dwc = dev_get_drvdata(dev); + struct device *dev = dwc->dev; int ret; ret = dwc3_suspend_common(dwc, PMSG_SUSPEND); @@ -2623,10 +2679,11 @@ static int dwc3_suspend(struct device *dev) return 0; } +EXPORT_SYMBOL_GPL(dwc3_pm_suspend); -static int dwc3_resume(struct device *dev) +int dwc3_pm_resume(struct dwc3 *dwc) { - struct dwc3 *dwc = dev_get_drvdata(dev); + struct device *dev = dwc->dev; int ret = 0; pinctrl_pm_select_default_state(dev); @@ -2645,10 +2702,10 @@ out: return ret; } +EXPORT_SYMBOL_GPL(dwc3_pm_resume); -static void dwc3_complete(struct device *dev) +void dwc3_pm_complete(struct dwc3 *dwc) { - struct dwc3 *dwc = dev_get_drvdata(dev); u32 reg; if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_HOST && @@ -2658,21 +2715,60 @@ static void dwc3_complete(struct device *dev) dwc3_writel(dwc->regs, DWC3_GUCTL3, reg); } } +EXPORT_SYMBOL_GPL(dwc3_pm_complete); + +int dwc3_pm_prepare(struct dwc3 *dwc) +{ + struct device *dev = dwc->dev; + + /* + * Indicate to the PM core that it may safely leave the device in + * runtime suspend if runtime-suspended already in device mode. + */ + if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_DEVICE && + pm_runtime_suspended(dev) && + !dev_pinctrl(dev)) + return 1; + + return 0; +} +EXPORT_SYMBOL_GPL(dwc3_pm_prepare); + +static int dwc3_plat_suspend(struct device *dev) +{ + return dwc3_pm_suspend(dev_get_drvdata(dev)); +} + +static int dwc3_plat_resume(struct device *dev) +{ + return dwc3_pm_resume(dev_get_drvdata(dev)); +} + +static void dwc3_plat_complete(struct device *dev) +{ + dwc3_pm_complete(dev_get_drvdata(dev)); +} + +static int dwc3_plat_prepare(struct device *dev) +{ + return dwc3_pm_prepare(dev_get_drvdata(dev)); +} #else -#define dwc3_complete NULL +#define dwc3_plat_complete NULL +#define dwc3_plat_prepare NULL #endif /* CONFIG_PM_SLEEP */ static const struct dev_pm_ops dwc3_dev_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(dwc3_suspend, dwc3_resume) - .complete = dwc3_complete, - + SET_SYSTEM_SLEEP_PM_OPS(dwc3_plat_suspend, dwc3_plat_resume) + .complete = dwc3_plat_complete, + .prepare = dwc3_plat_prepare, /* * 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) + SET_RUNTIME_PM_OPS(dwc3_plat_runtime_suspend, dwc3_plat_runtime_resume, + dwc3_plat_runtime_idle) }; #ifdef CONFIG_OF diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 27eae4cf223d..d5b985fa12f4 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -1083,6 +1083,7 @@ struct dwc3_scratchpad_array { * @tx_max_burst_prd: max periodic ESS transmit burst size * @tx_fifo_resize_max_num: max number of fifos allocated during txfifo resize * @clear_stall_protocol: endpoint number that requires a delayed status phase + * @num_hc_interrupters: number of host controller interrupters * @hsphy_interface: "utmi" or "ulpi" * @connected: true when we're connected to a host, false otherwise * @softconnect: true when gadget connect is called, false when disconnect runs @@ -1333,6 +1334,7 @@ struct dwc3 { u8 tx_max_burst_prd; u8 tx_fifo_resize_max_num; u8 clear_stall_protocol; + u16 num_hc_interrupters; const char *hsphy_interface; diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 321361288935..74968f93d4a3 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -3516,7 +3516,7 @@ static int dwc3_gadget_ep_reclaim_completed_trb(struct dwc3_ep *dep, * We're going to do that here to avoid problems of HW trying * to use bogus TRBs for transfers. */ - if (chain && (trb->ctrl & DWC3_TRB_CTRL_HWO)) + if (trb->ctrl & DWC3_TRB_CTRL_HWO) trb->ctrl &= ~DWC3_TRB_CTRL_HWO; /* @@ -4821,26 +4821,22 @@ int dwc3_gadget_suspend(struct dwc3 *dwc) int ret; ret = dwc3_gadget_soft_disconnect(dwc); - if (ret) - goto err; - - spin_lock_irqsave(&dwc->lock, flags); - if (dwc->gadget_driver) - dwc3_disconnect_gadget(dwc); - spin_unlock_irqrestore(&dwc->lock, flags); - - return 0; - -err: /* * Attempt to reset the controller's state. Likely no * communication can be established until the host * performs a port reset. */ - if (dwc->softconnect) + if (ret && dwc->softconnect) { dwc3_gadget_soft_connect(dwc); + return -EAGAIN; + } - return ret; + spin_lock_irqsave(&dwc->lock, flags); + if (dwc->gadget_driver) + dwc3_disconnect_gadget(dwc); + spin_unlock_irqrestore(&dwc->lock, flags); + + return 0; } int dwc3_gadget_resume(struct dwc3 *dwc) diff --git a/drivers/usb/dwc3/glue.h b/drivers/usb/dwc3/glue.h new file mode 100644 index 000000000000..2efd00e763be --- /dev/null +++ b/drivers/usb/dwc3/glue.h @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * glue.h - DesignWare USB3 DRD glue header + */ + +#ifndef __DRIVERS_USB_DWC3_GLUE_H +#define __DRIVERS_USB_DWC3_GLUE_H + +#include +#include "core.h" + +/** + * dwc3_probe_data: Initialization parameters passed to dwc3_core_probe() + * @dwc: Reference to dwc3 context structure + * @res: resource for the DWC3 core mmio region + * @ignore_clocks_and_resets: clocks and resets defined for the device should + * be ignored by the DWC3 core, as they are managed by the glue + */ +struct dwc3_probe_data { + struct dwc3 *dwc; + struct resource *res; + bool ignore_clocks_and_resets; +}; + +int dwc3_core_probe(const struct dwc3_probe_data *data); +void dwc3_core_remove(struct dwc3 *dwc); + +int dwc3_runtime_suspend(struct dwc3 *dwc); +int dwc3_runtime_resume(struct dwc3 *dwc); +int dwc3_runtime_idle(struct dwc3 *dwc); +int dwc3_pm_suspend(struct dwc3 *dwc); +int dwc3_pm_resume(struct dwc3 *dwc); +void dwc3_pm_complete(struct dwc3 *dwc); +int dwc3_pm_prepare(struct dwc3 *dwc); + +#endif -- 2.53.0