Received: by 2002:a05:6a10:1287:0:0:0:0 with SMTP id d7csp198192pxv; Thu, 15 Jul 2021 02:11:01 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwFd7OLCzxHqYwiTnwDgCe2pUE/sMWMJihhRHbdV3lM22v0jzyJLPxGwBAoMTmKkHScaKjk X-Received: by 2002:a6b:7905:: with SMTP id i5mr2463899iop.175.1626340261640; Thu, 15 Jul 2021 02:11:01 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1626340261; cv=none; d=google.com; s=arc-20160816; b=S7ULGoH9qNZ0qGCMmkZynHEAxvMY+IUwK40chGX+rPfYYRXAL0yDjrswMJMDMdUFWE R2FxJce/QiTd3mcTDNKbrPylNlvHy1Gjm7pJgF+1am05w1hVJrACMDM/Gqm6eCbEd+a0 LPL83AKLU81peVkcttFPdTek0zsdJT6225w9CUscxfzI3sq8DfmSdHS/jdXu/ectjiQI MyAFc31P1X5dZGqGPo0kHSo0Nf6ifmXekxwc49OPtZUz3A7r78Y0qbLdI444eHrVINby itRZTNPAs6RF+0DKRlLwjDFqvYARdIYJxS0Bz3cAo3i1bEp9PTrYmNBaRT43aHPxWOgp Lq6g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:mime-version:references:in-reply-to:message-id :date:subject:cc:to:from; bh=JKyUHoxJQIEbpuUKL6yozy4cy6NQrqsi1aTEz2JcX9k=; b=Sdej7I4692czMPRmUzMpm3iaAMTaPoLCuOiKT1dnnDqKmFAzoDQ5g1X7MFXWCj8SI8 UzTmcGejATWjyDyiF/anCrhLmn2m+1MDDmvHM+ZRHM6QFpaHgCI6DWY1Kdx45yfS5A9z mXyQ7j1i+rERe7+kXnRsrZ+DHN4iVN+Gr9gk6l9FcHqrANL+zpefcIp/IlVaBsPIA28L MK2w7DDZETD6kFnw+9JD32FT9w89HtsLJjOGZpnCkRoDWmPFsp2WKqeOcQXROqkCGZt0 VzYlnOOo1n0nZm5HYahUB7SXbXxw3SnUC60gLhso5MRXtxGHGD58O7ehxH2iJzw6uoZ5 vZyA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=mediatek.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id q41si6050623jav.74.2021.07.15.02.10.50; Thu, 15 Jul 2021 02:11:01 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=mediatek.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240975AbhGOJLb (ORCPT + 99 others); Thu, 15 Jul 2021 05:11:31 -0400 Received: from mailgw02.mediatek.com ([210.61.82.184]:39846 "EHLO mailgw02.mediatek.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S240856AbhGOJLR (ORCPT ); Thu, 15 Jul 2021 05:11:17 -0400 X-UUID: 845cffa5f8a8465a8c2e11b2c5f6bde7-20210715 X-UUID: 845cffa5f8a8465a8c2e11b2c5f6bde7-20210715 Received: from mtkmbs10n1.mediatek.inc [(172.21.101.34)] by mailgw02.mediatek.com (envelope-from ) (Generic MTA with TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 256/256) with ESMTP id 324683270; Thu, 15 Jul 2021 17:08:22 +0800 Received: from MTKCAS06.mediatek.inc (172.21.101.30) by mtkmbs05n2.mediatek.inc (172.21.101.140) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Thu, 15 Jul 2021 17:08:20 +0800 Received: from localhost.localdomain (10.17.3.153) by MTKCAS06.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Thu, 15 Jul 2021 17:08:20 +0800 From: Chunfeng Yun To: Greg Kroah-Hartman , Rob Herring , Felipe Balbi CC: Chunfeng Yun , Matthias Brugger , Thinh Nguyen , , , , , , Yuwen Ng , Eddie Hung Subject: [PATCH v3 10/13] usb: mtu3: support runtime PM for host mode Date: Thu, 15 Jul 2021 17:07:55 +0800 Message-ID: <1626340078-29111-11-git-send-email-chunfeng.yun@mediatek.com> X-Mailer: git-send-email 1.8.1.1.dirty In-Reply-To: <1626340078-29111-1-git-send-email-chunfeng.yun@mediatek.com> References: <1626340078-29111-1-git-send-email-chunfeng.yun@mediatek.com> MIME-Version: 1.0 Content-Type: text/plain X-MTK: N Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Use a dedicated wakeup irq for runtime suspend/resume, and interrupts names are provided if using wakeup irq, this patch only support host mode. Signed-off-by: Chunfeng Yun --- v3: fix free-after-use issue v2: no changes --- drivers/usb/mtu3/mtu3.h | 1 + drivers/usb/mtu3/mtu3_core.c | 13 ++++++-- drivers/usb/mtu3/mtu3_plat.c | 64 ++++++++++++++++++++++++++++++++---- 3 files changed, 69 insertions(+), 9 deletions(-) diff --git a/drivers/usb/mtu3/mtu3.h b/drivers/usb/mtu3/mtu3.h index 0ae9b33b50ea..171e5b383063 100644 --- a/drivers/usb/mtu3/mtu3.h +++ b/drivers/usb/mtu3/mtu3.h @@ -246,6 +246,7 @@ struct ssusb_mtk { void __iomem *ippc_base; struct phy **phys; int num_phys; + int wakeup_irq; /* common power & clock */ struct regulator *vusb33; struct clk_bulk_data clks[BULK_CLKS_CNT]; diff --git a/drivers/usb/mtu3/mtu3_core.c b/drivers/usb/mtu3/mtu3_core.c index 562f4357831e..6d23acb4fffc 100644 --- a/drivers/usb/mtu3/mtu3_core.c +++ b/drivers/usb/mtu3/mtu3_core.c @@ -888,9 +888,16 @@ int ssusb_gadget_init(struct ssusb_mtk *ssusb) if (mtu == NULL) return -ENOMEM; - mtu->irq = platform_get_irq(pdev, 0); - if (mtu->irq < 0) - return mtu->irq; + mtu->irq = platform_get_irq_byname_optional(pdev, "device"); + if (mtu->irq < 0) { + if (mtu->irq == -EPROBE_DEFER) + return mtu->irq; + + /* for backward compatibility */ + mtu->irq = platform_get_irq(pdev, 0); + if (mtu->irq < 0) + return mtu->irq; + } dev_info(dev, "irq %d\n", mtu->irq); mtu->mac_base = devm_platform_ioremap_resource_byname(pdev, "mac"); diff --git a/drivers/usb/mtu3/mtu3_plat.c b/drivers/usb/mtu3/mtu3_plat.c index a906b24723e6..2be890f84c94 100644 --- a/drivers/usb/mtu3/mtu3_plat.c +++ b/drivers/usb/mtu3/mtu3_plat.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "mtu3.h" #include "mtu3_dr.h" @@ -208,6 +209,10 @@ static int get_ssusb_rscs(struct platform_device *pdev, struct ssusb_mtk *ssusb) if (IS_ERR(ssusb->ippc_base)) return PTR_ERR(ssusb->ippc_base); + ssusb->wakeup_irq = platform_get_irq_byname_optional(pdev, "wakeup"); + if (ssusb->wakeup_irq == -EPROBE_DEFER) + return ssusb->wakeup_irq; + ssusb->dr_mode = usb_get_dr_mode(dev); if (ssusb->dr_mode == USB_DR_MODE_UNKNOWN) ssusb->dr_mode = USB_DR_MODE_OTG; @@ -295,14 +300,25 @@ static int mtu3_probe(struct platform_device *pdev) ssusb_debugfs_create_root(ssusb); /* enable power domain */ + pm_runtime_set_active(dev); + pm_runtime_use_autosuspend(dev); + pm_runtime_set_autosuspend_delay(dev, 4000); pm_runtime_enable(dev); pm_runtime_get_sync(dev); - device_enable_async_suspend(dev); ret = ssusb_rscs_init(ssusb); if (ret) goto comm_init_err; + if (ssusb->wakeup_irq > 0) { + ret = dev_pm_set_dedicated_wake_irq(dev, ssusb->wakeup_irq); + if (ret) { + dev_err(dev, "failed to set wakeup irq %d\n", ssusb->wakeup_irq); + goto comm_exit; + } + dev_info(dev, "wakeup irq %d\n", ssusb->wakeup_irq); + } + ssusb_ip_sw_reset(ssusb); if (IS_ENABLED(CONFIG_USB_MTU3_HOST)) @@ -353,6 +369,11 @@ static int mtu3_probe(struct platform_device *pdev) goto comm_exit; } + device_enable_async_suspend(dev); + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); + pm_runtime_forbid(dev); + return 0; host_exit: @@ -362,7 +383,7 @@ static int mtu3_probe(struct platform_device *pdev) comm_exit: ssusb_rscs_exit(ssusb); comm_init_err: - pm_runtime_put_sync(dev); + pm_runtime_put_noidle(dev); pm_runtime_disable(dev); ssusb_debugfs_remove_root(ssusb); @@ -373,6 +394,8 @@ static int mtu3_remove(struct platform_device *pdev) { struct ssusb_mtk *ssusb = platform_get_drvdata(pdev); + pm_runtime_get_sync(&pdev->dev); + switch (ssusb->dr_mode) { case USB_DR_MODE_PERIPHERAL: ssusb_gadget_exit(ssusb); @@ -390,9 +413,10 @@ static int mtu3_remove(struct platform_device *pdev) } ssusb_rscs_exit(ssusb); - pm_runtime_put_sync(&pdev->dev); - pm_runtime_disable(&pdev->dev); ssusb_debugfs_remove_root(ssusb); + pm_runtime_disable(&pdev->dev); + pm_runtime_put_noidle(&pdev->dev); + pm_runtime_set_suspended(&pdev->dev); return 0; } @@ -401,7 +425,7 @@ static int mtu3_remove(struct platform_device *pdev) * when support dual-role mode, we reject suspend when * it works as device mode; */ -static int __maybe_unused mtu3_suspend(struct device *dev) +static int mtu3_suspend_common(struct device *dev, pm_message_t msg) { struct ssusb_mtk *ssusb = dev_get_drvdata(dev); @@ -419,7 +443,7 @@ static int __maybe_unused mtu3_suspend(struct device *dev) return 0; } -static int __maybe_unused mtu3_resume(struct device *dev) +static int mtu3_resume_common(struct device *dev, pm_message_t msg) { struct ssusb_mtk *ssusb = dev_get_drvdata(dev); int ret; @@ -448,8 +472,36 @@ static int __maybe_unused mtu3_resume(struct device *dev) return ret; } +static int __maybe_unused mtu3_suspend(struct device *dev) +{ + return mtu3_suspend_common(dev, PMSG_SUSPEND); +} + +static int __maybe_unused mtu3_resume(struct device *dev) +{ + return mtu3_resume_common(dev, PMSG_SUSPEND); +} + +static int __maybe_unused mtu3_runtime_suspend(struct device *dev) +{ + if (!device_may_wakeup(dev)) + return 0; + + return mtu3_suspend_common(dev, PMSG_AUTO_SUSPEND); +} + +static int __maybe_unused mtu3_runtime_resume(struct device *dev) +{ + if (!device_may_wakeup(dev)) + return 0; + + return mtu3_resume_common(dev, PMSG_AUTO_SUSPEND); +} + static const struct dev_pm_ops mtu3_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(mtu3_suspend, mtu3_resume) + SET_RUNTIME_PM_OPS(mtu3_runtime_suspend, + mtu3_runtime_resume, NULL) }; #define DEV_PM_OPS (IS_ENABLED(CONFIG_PM) ? &mtu3_pm_ops : NULL) -- 2.18.0