| From 1d2b3bb8de45136c89d02e7030d4f5dce7f4061d Mon Sep 17 00:00:00 2001 |
| From: Nagarjuna Kristam <nkristam@nvidia.com> |
| Date: Mon, 4 Nov 2019 14:54:30 +0530 |
| Subject: [PATCH] usb: host: xhci-tegra: Correct phy enable sequence |
| |
| commit 6351653febbb784d86fdf83afe41f7523a61b392 upstream. |
| |
| XUSB phy needs to be enabled before un-powergating the power partitions. |
| However in the current sequence, it happens opposite. Correct the phy |
| enable and powergating partition sequence to avoid any boot hangs. |
| |
| Signed-off-by: Nagarjuna Kristam <nkristam@nvidia.com> |
| Cc: stable <stable@vger.kernel.org> |
| Signed-off-by: Jui Chang Kuo <jckuo@nvidia.com> |
| Tested-by: Jon Hunter <jonathanh@nvidia.com> |
| Acked-by: Thierry Reding <treding@nvidia.com> |
| Link: https://lore.kernel.org/r/1572859470-7823-1-git-send-email-nkristam@nvidia.com |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/usb/host/xhci-tegra.c b/drivers/usb/host/xhci-tegra.c |
| index 77142f9bf26a..ef3023eaf1ef 100644 |
| --- a/drivers/usb/host/xhci-tegra.c |
| +++ b/drivers/usb/host/xhci-tegra.c |
| @@ -778,7 +778,6 @@ static int tegra_xusb_runtime_suspend(struct device *dev) |
| { |
| struct tegra_xusb *tegra = dev_get_drvdata(dev); |
| |
| - tegra_xusb_phy_disable(tegra); |
| regulator_bulk_disable(tegra->soc->num_supplies, tegra->supplies); |
| tegra_xusb_clk_disable(tegra); |
| |
| @@ -802,16 +801,8 @@ static int tegra_xusb_runtime_resume(struct device *dev) |
| goto disable_clk; |
| } |
| |
| - err = tegra_xusb_phy_enable(tegra); |
| - if (err < 0) { |
| - dev_err(dev, "failed to enable PHYs: %d\n", err); |
| - goto disable_regulator; |
| - } |
| - |
| return 0; |
| |
| -disable_regulator: |
| - regulator_bulk_disable(tegra->soc->num_supplies, tegra->supplies); |
| disable_clk: |
| tegra_xusb_clk_disable(tegra); |
| return err; |
| @@ -1204,6 +1195,12 @@ static int tegra_xusb_probe(struct platform_device *pdev) |
| */ |
| platform_set_drvdata(pdev, tegra); |
| |
| + err = tegra_xusb_phy_enable(tegra); |
| + if (err < 0) { |
| + dev_err(&pdev->dev, "failed to enable PHYs: %d\n", err); |
| + goto put_hcd; |
| + } |
| + |
| pm_runtime_enable(&pdev->dev); |
| if (pm_runtime_enabled(&pdev->dev)) |
| err = pm_runtime_get_sync(&pdev->dev); |
| @@ -1212,7 +1209,7 @@ static int tegra_xusb_probe(struct platform_device *pdev) |
| |
| if (err < 0) { |
| dev_err(&pdev->dev, "failed to enable device: %d\n", err); |
| - goto disable_rpm; |
| + goto disable_phy; |
| } |
| |
| tegra_xusb_config(tegra, regs); |
| @@ -1298,9 +1295,11 @@ static int tegra_xusb_probe(struct platform_device *pdev) |
| put_rpm: |
| if (!pm_runtime_status_suspended(&pdev->dev)) |
| tegra_xusb_runtime_suspend(&pdev->dev); |
| -disable_rpm: |
| - pm_runtime_disable(&pdev->dev); |
| +put_hcd: |
| usb_put_hcd(tegra->hcd); |
| +disable_phy: |
| + tegra_xusb_phy_disable(tegra); |
| + pm_runtime_disable(&pdev->dev); |
| put_powerdomains: |
| if (!of_property_read_bool(pdev->dev.of_node, "power-domains")) { |
| tegra_powergate_power_off(TEGRA_POWERGATE_XUSBC); |
| @@ -1337,6 +1336,8 @@ static int tegra_xusb_remove(struct platform_device *pdev) |
| tegra_xusb_powerdomain_remove(&pdev->dev, tegra); |
| } |
| |
| + tegra_xusb_phy_disable(tegra); |
| + |
| tegra_xusb_padctl_put(tegra->padctl); |
| |
| return 0; |
| -- |
| 2.7.4 |
| |