summaryrefslogtreecommitdiffstats
path: root/drivers/usb/host
diff options
context:
space:
mode:
authorThierry Reding <treding@nvidia.com>2019-12-06 15:06:50 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-12-10 11:36:28 +0100
commit17926924be44b21556043a2faccc3b449110bd00 (patch)
tree0deb33f0a93f1c2ad84cef7206740e458d841b60 /drivers/usb/host
parentusb: host: xhci-tegra: Reuse stored register base address (diff)
downloadlinux-17926924be44b21556043a2faccc3b449110bd00.tar.xz
linux-17926924be44b21556043a2faccc3b449110bd00.zip
usb: host: xhci-tegra: Enable runtime PM as late as possible
A number of things can currently go wrong after the XUSB controller has been enabled, which means that it might need to be disabled again before it has ever been used. Avoid this by delaying runtime PM enablement until it's really required right before registers are accessed for the first time. Signed-off-by: Thierry Reding <treding@nvidia.com> Link: https://lore.kernel.org/r/20191206140653.2085561-8-thierry.reding@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/host')
-rw-r--r--drivers/usb/host/xhci-tegra.c33
1 files changed, 17 insertions, 16 deletions
diff --git a/drivers/usb/host/xhci-tegra.c b/drivers/usb/host/xhci-tegra.c
index 31411f85e742..117e91b8ac6f 100644
--- a/drivers/usb/host/xhci-tegra.c
+++ b/drivers/usb/host/xhci-tegra.c
@@ -1242,19 +1242,6 @@ static int tegra_xusb_probe(struct platform_device *pdev)
goto put_hcd;
}
- pm_runtime_enable(&pdev->dev);
- if (pm_runtime_enabled(&pdev->dev))
- err = pm_runtime_get_sync(&pdev->dev);
- else
- err = tegra_xusb_runtime_resume(&pdev->dev);
-
- if (err < 0) {
- dev_err(&pdev->dev, "failed to enable device: %d\n", err);
- goto disable_phy;
- }
-
- tegra_xusb_config(tegra);
-
/*
* The XUSB Falcon microcontroller can only address 40 bits, so set
* the DMA mask accordingly.
@@ -1262,7 +1249,7 @@ static int tegra_xusb_probe(struct platform_device *pdev)
err = dma_set_mask_and_coherent(tegra->dev, DMA_BIT_MASK(40));
if (err < 0) {
dev_err(&pdev->dev, "failed to set DMA mask: %d\n", err);
- goto put_rpm;
+ goto disable_phy;
}
err = tegra_xusb_request_firmware(tegra);
@@ -1271,16 +1258,30 @@ static int tegra_xusb_probe(struct platform_device *pdev)
goto disable_phy;
}
+ pm_runtime_enable(&pdev->dev);
+
+ if (!pm_runtime_enabled(&pdev->dev))
+ err = tegra_xusb_runtime_resume(&pdev->dev);
+ else
+ err = pm_runtime_get_sync(&pdev->dev);
+
+ if (err < 0) {
+ dev_err(&pdev->dev, "failed to enable device: %d\n", err);
+ goto free_firmware;
+ }
+
+ tegra_xusb_config(tegra);
+
err = tegra_xusb_load_firmware(tegra);
if (err < 0) {
dev_err(&pdev->dev, "failed to load firmware: %d\n", err);
- goto free_firmware;
+ goto put_rpm;
}
err = usb_add_hcd(tegra->hcd, tegra->xhci_irq, IRQF_SHARED);
if (err < 0) {
dev_err(&pdev->dev, "failed to add USB HCD: %d\n", err);
- goto free_firmware;
+ goto put_rpm;
}
device_wakeup_enable(tegra->hcd->self.controller);