From patchwork Tue Oct 16 11:22:42 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mathias Nyman X-Patchwork-Id: 10643451 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5F52F1057 for ; Tue, 16 Oct 2018 11:19:29 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4C6F429447 for ; Tue, 16 Oct 2018 11:19:29 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3EF322944E; Tue, 16 Oct 2018 11:19:29 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CE79A29447 for ; Tue, 16 Oct 2018 11:19:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726718AbeJPTJZ (ORCPT ); Tue, 16 Oct 2018 15:09:25 -0400 Received: from mga14.intel.com ([192.55.52.115]:18954 "EHLO mga14.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726595AbeJPTJZ (ORCPT ); Tue, 16 Oct 2018 15:09:25 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 16 Oct 2018 04:19:25 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.54,388,1534834800"; d="scan'208";a="99853055" Received: from mattu-haswell.fi.intel.com ([10.237.72.164]) by orsmga001.jf.intel.com with ESMTP; 16 Oct 2018 04:19:22 -0700 From: Mathias Nyman To: Cc: , thierry.reding@gmail.com, mark.rutland@arm.com, robh+dt@kernel.org, ulf.hansson@linaro.org, jonathanh@nvidia.com, Mathias Nyman Subject: [PATCH 1/2] usb: xhci: tegra: Power-off power-domains on removal Date: Tue, 16 Oct 2018 14:22:42 +0300 Message-Id: <1539688963-12564-2-git-send-email-mathias.nyman@linux.intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1539688963-12564-1-git-send-email-mathias.nyman@linux.intel.com> References: <1539688963-12564-1-git-send-email-mathias.nyman@linux.intel.com> Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Jon Hunter Currently the XUSB power domains used by the Tegra xHCI controller are never powered off on the removal of the driver, however, they will be powered off on probe failure. Update the removal code to be consistent with the probe failure path to power off the XUSB power domains. Signed-off-by: Jon Hunter Acked-by: Thierry Reding Signed-off-by: Mathias Nyman --- drivers/usb/host/xhci-tegra.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/usb/host/xhci-tegra.c b/drivers/usb/host/xhci-tegra.c index 4ee510a..920a50a 100644 --- a/drivers/usb/host/xhci-tegra.c +++ b/drivers/usb/host/xhci-tegra.c @@ -1249,6 +1249,11 @@ static int tegra_xusb_remove(struct platform_device *pdev) pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); + if (!pdev->dev.pm_domain) { + tegra_powergate_power_off(TEGRA_POWERGATE_XUSBC); + tegra_powergate_power_off(TEGRA_POWERGATE_XUSBA); + } + tegra_xusb_padctl_put(tegra->padctl); return 0; From patchwork Tue Oct 16 11:22:43 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mathias Nyman X-Patchwork-Id: 10643453 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D72061057 for ; Tue, 16 Oct 2018 11:19:34 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C50BC29447 for ; Tue, 16 Oct 2018 11:19:34 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B92732944E; Tue, 16 Oct 2018 11:19:34 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3D40E29447 for ; Tue, 16 Oct 2018 11:19:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726778AbeJPTJ0 (ORCPT ); Tue, 16 Oct 2018 15:09:26 -0400 Received: from mga14.intel.com ([192.55.52.115]:18954 "EHLO mga14.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726595AbeJPTJ0 (ORCPT ); Tue, 16 Oct 2018 15:09:26 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 16 Oct 2018 04:19:28 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.54,388,1534834800"; d="scan'208";a="99853063" Received: from mattu-haswell.fi.intel.com ([10.237.72.164]) by orsmga001.jf.intel.com with ESMTP; 16 Oct 2018 04:19:25 -0700 From: Mathias Nyman To: Cc: , thierry.reding@gmail.com, mark.rutland@arm.com, robh+dt@kernel.org, ulf.hansson@linaro.org, jonathanh@nvidia.com, Mathias Nyman Subject: [PATCH 2/2] usb: xhci: tegra: Add genpd support Date: Tue, 16 Oct 2018 14:22:43 +0300 Message-Id: <1539688963-12564-3-git-send-email-mathias.nyman@linux.intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1539688963-12564-1-git-send-email-mathias.nyman@linux.intel.com> References: <1539688963-12564-1-git-send-email-mathias.nyman@linux.intel.com> Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Jon Hunter The generic power-domain framework has been updated to allow devices that require more than one power-domain to create a new device for each power-domain required and then link these new power-domain devices to the consumer device. Update the Tegra xHCI driver to use the new APIs provided by the generic power-domain framework so we can use the generic power-domain framework for managing the xHCI controllers power-domains. Please note that to maintain backward compatibility with older device-tree blobs these new generic power-domain APIs are only used if the 'power-domains' property is present and otherwise we fall back to using the legacy Tegra APIs for managing the power-domains. Signed-off-by: Jon Hunter Acked-by: Thierry Reding Reviewed-by: Ulf Hansson Signed-off-by: Mathias Nyman --- drivers/usb/host/xhci-tegra.c | 89 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 77 insertions(+), 12 deletions(-) diff --git a/drivers/usb/host/xhci-tegra.c b/drivers/usb/host/xhci-tegra.c index 920a50a..6b5db34 100644 --- a/drivers/usb/host/xhci-tegra.c +++ b/drivers/usb/host/xhci-tegra.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -194,6 +195,11 @@ struct tegra_xusb { struct reset_control *host_rst; struct reset_control *ss_rst; + struct device *genpd_dev_host; + struct device *genpd_dev_ss; + struct device_link *genpd_dl_host; + struct device_link *genpd_dl_ss; + struct phy **phys; unsigned int num_phys; @@ -928,6 +934,57 @@ static int tegra_xusb_load_firmware(struct tegra_xusb *tegra) return 0; } +static void tegra_xusb_powerdomain_remove(struct device *dev, + struct tegra_xusb *tegra) +{ + if (tegra->genpd_dl_ss) + device_link_del(tegra->genpd_dl_ss); + if (tegra->genpd_dl_host) + device_link_del(tegra->genpd_dl_host); + if (tegra->genpd_dev_ss) + dev_pm_domain_detach(tegra->genpd_dev_ss, true); + if (tegra->genpd_dev_host) + dev_pm_domain_detach(tegra->genpd_dev_host, true); +} + +static int tegra_xusb_powerdomain_init(struct device *dev, + struct tegra_xusb *tegra) +{ + int err; + + tegra->genpd_dev_host = dev_pm_domain_attach_by_name(dev, "xusb_host"); + if (IS_ERR(tegra->genpd_dev_host)) { + err = PTR_ERR(tegra->genpd_dev_host); + dev_err(dev, "failed to get host pm-domain: %d\n", err); + return err; + } + + tegra->genpd_dev_ss = dev_pm_domain_attach_by_name(dev, "xusb_ss"); + if (IS_ERR(tegra->genpd_dev_ss)) { + err = PTR_ERR(tegra->genpd_dev_ss); + dev_err(dev, "failed to get superspeed pm-domain: %d\n", err); + return err; + } + + tegra->genpd_dl_host = device_link_add(dev, tegra->genpd_dev_host, + DL_FLAG_PM_RUNTIME | + DL_FLAG_STATELESS); + if (!tegra->genpd_dl_host) { + dev_err(dev, "adding host device link failed!\n"); + return -ENODEV; + } + + tegra->genpd_dl_ss = device_link_add(dev, tegra->genpd_dev_ss, + DL_FLAG_PM_RUNTIME | + DL_FLAG_STATELESS); + if (!tegra->genpd_dl_ss) { + dev_err(dev, "adding superspeed device link failed!\n"); + return -ENODEV; + } + + return 0; +} + static int tegra_xusb_probe(struct platform_device *pdev) { struct tegra_xusb_mbox_msg msg; @@ -1038,7 +1095,7 @@ static int tegra_xusb_probe(struct platform_device *pdev) goto put_padctl; } - if (!pdev->dev.pm_domain) { + if (!of_property_read_bool(pdev->dev.of_node, "power-domains")) { tegra->host_rst = devm_reset_control_get(&pdev->dev, "xusb_host"); if (IS_ERR(tegra->host_rst)) { @@ -1069,17 +1126,22 @@ static int tegra_xusb_probe(struct platform_device *pdev) tegra->host_clk, tegra->host_rst); if (err) { + tegra_powergate_power_off(TEGRA_POWERGATE_XUSBA); dev_err(&pdev->dev, "failed to enable XUSBC domain: %d\n", err); - goto disable_xusba; + goto put_padctl; } + } else { + err = tegra_xusb_powerdomain_init(&pdev->dev, tegra); + if (err) + goto put_powerdomains; } tegra->supplies = devm_kcalloc(&pdev->dev, tegra->soc->num_supplies, sizeof(*tegra->supplies), GFP_KERNEL); if (!tegra->supplies) { err = -ENOMEM; - goto disable_xusbc; + goto put_powerdomains; } for (i = 0; i < tegra->soc->num_supplies; i++) @@ -1089,7 +1151,7 @@ static int tegra_xusb_probe(struct platform_device *pdev) tegra->supplies); if (err) { dev_err(&pdev->dev, "failed to get regulators: %d\n", err); - goto disable_xusbc; + goto put_powerdomains; } for (i = 0; i < tegra->soc->num_types; i++) @@ -1099,7 +1161,7 @@ static int tegra_xusb_probe(struct platform_device *pdev) sizeof(*tegra->phys), GFP_KERNEL); if (!tegra->phys) { err = -ENOMEM; - goto disable_xusbc; + goto put_powerdomains; } for (i = 0, k = 0; i < tegra->soc->num_types; i++) { @@ -1115,7 +1177,7 @@ static int tegra_xusb_probe(struct platform_device *pdev) "failed to get PHY %s: %ld\n", prop, PTR_ERR(phy)); err = PTR_ERR(phy); - goto disable_xusbc; + goto put_powerdomains; } tegra->phys[k++] = phy; @@ -1126,7 +1188,7 @@ static int tegra_xusb_probe(struct platform_device *pdev) dev_name(&pdev->dev)); if (!tegra->hcd) { err = -ENOMEM; - goto disable_xusbc; + goto put_powerdomains; } /* @@ -1222,12 +1284,13 @@ static int tegra_xusb_probe(struct platform_device *pdev) disable_rpm: pm_runtime_disable(&pdev->dev); usb_put_hcd(tegra->hcd); -disable_xusbc: - if (!pdev->dev.pm_domain) +put_powerdomains: + if (!of_property_read_bool(pdev->dev.of_node, "power-domains")) { tegra_powergate_power_off(TEGRA_POWERGATE_XUSBC); -disable_xusba: - if (!pdev->dev.pm_domain) tegra_powergate_power_off(TEGRA_POWERGATE_XUSBA); + } else { + tegra_xusb_powerdomain_remove(&pdev->dev, tegra); + } put_padctl: tegra_xusb_padctl_put(tegra->padctl); return err; @@ -1249,9 +1312,11 @@ static int tegra_xusb_remove(struct platform_device *pdev) pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); - if (!pdev->dev.pm_domain) { + if (!of_property_read_bool(pdev->dev.of_node, "power-domains")) { tegra_powergate_power_off(TEGRA_POWERGATE_XUSBC); tegra_powergate_power_off(TEGRA_POWERGATE_XUSBA); + } else { + tegra_xusb_powerdomain_remove(&pdev->dev, tegra); } tegra_xusb_padctl_put(tegra->padctl);