|
@@ -22,6 +22,7 @@
|
|
|
#include <linux/regulator/consumer.h>
|
|
|
#include <linux/reset.h>
|
|
|
#include <linux/slab.h>
|
|
|
+#include <soc/tegra/pmc.h>
|
|
|
|
|
|
#include "xhci.h"
|
|
|
|
|
@@ -974,20 +975,6 @@ static int tegra_xusb_probe(struct platform_device *pdev)
|
|
|
if (IS_ERR(tegra->padctl))
|
|
|
return PTR_ERR(tegra->padctl);
|
|
|
|
|
|
- tegra->host_rst = devm_reset_control_get(&pdev->dev, "xusb_host");
|
|
|
- if (IS_ERR(tegra->host_rst)) {
|
|
|
- err = PTR_ERR(tegra->host_rst);
|
|
|
- dev_err(&pdev->dev, "failed to get xusb_host reset: %d\n", err);
|
|
|
- goto put_padctl;
|
|
|
- }
|
|
|
-
|
|
|
- tegra->ss_rst = devm_reset_control_get(&pdev->dev, "xusb_ss");
|
|
|
- if (IS_ERR(tegra->ss_rst)) {
|
|
|
- err = PTR_ERR(tegra->ss_rst);
|
|
|
- dev_err(&pdev->dev, "failed to get xusb_ss reset: %d\n", err);
|
|
|
- goto put_padctl;
|
|
|
- }
|
|
|
-
|
|
|
tegra->host_clk = devm_clk_get(&pdev->dev, "xusb_host");
|
|
|
if (IS_ERR(tegra->host_clk)) {
|
|
|
err = PTR_ERR(tegra->host_clk);
|
|
@@ -1051,11 +1038,48 @@ static int tegra_xusb_probe(struct platform_device *pdev)
|
|
|
goto put_padctl;
|
|
|
}
|
|
|
|
|
|
+ if (!pdev->dev.pm_domain) {
|
|
|
+ tegra->host_rst = devm_reset_control_get(&pdev->dev,
|
|
|
+ "xusb_host");
|
|
|
+ if (IS_ERR(tegra->host_rst)) {
|
|
|
+ err = PTR_ERR(tegra->host_rst);
|
|
|
+ dev_err(&pdev->dev,
|
|
|
+ "failed to get xusb_host reset: %d\n", err);
|
|
|
+ goto put_padctl;
|
|
|
+ }
|
|
|
+
|
|
|
+ tegra->ss_rst = devm_reset_control_get(&pdev->dev, "xusb_ss");
|
|
|
+ if (IS_ERR(tegra->ss_rst)) {
|
|
|
+ err = PTR_ERR(tegra->ss_rst);
|
|
|
+ dev_err(&pdev->dev, "failed to get xusb_ss reset: %d\n",
|
|
|
+ err);
|
|
|
+ goto put_padctl;
|
|
|
+ }
|
|
|
+
|
|
|
+ err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_XUSBA,
|
|
|
+ tegra->ss_clk,
|
|
|
+ tegra->ss_rst);
|
|
|
+ if (err) {
|
|
|
+ dev_err(&pdev->dev,
|
|
|
+ "failed to enable XUSBA domain: %d\n", err);
|
|
|
+ goto put_padctl;
|
|
|
+ }
|
|
|
+
|
|
|
+ err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_XUSBC,
|
|
|
+ tegra->host_clk,
|
|
|
+ tegra->host_rst);
|
|
|
+ if (err) {
|
|
|
+ dev_err(&pdev->dev,
|
|
|
+ "failed to enable XUSBC domain: %d\n", err);
|
|
|
+ goto disable_xusba;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
tegra->supplies = devm_kcalloc(&pdev->dev, tegra->soc->num_supplies,
|
|
|
sizeof(*tegra->supplies), GFP_KERNEL);
|
|
|
if (!tegra->supplies) {
|
|
|
err = -ENOMEM;
|
|
|
- goto put_padctl;
|
|
|
+ goto disable_xusbc;
|
|
|
}
|
|
|
|
|
|
for (i = 0; i < tegra->soc->num_supplies; i++)
|
|
@@ -1065,7 +1089,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 put_padctl;
|
|
|
+ goto disable_xusbc;
|
|
|
}
|
|
|
|
|
|
for (i = 0; i < tegra->soc->num_types; i++)
|
|
@@ -1075,7 +1099,7 @@ static int tegra_xusb_probe(struct platform_device *pdev)
|
|
|
sizeof(*tegra->phys), GFP_KERNEL);
|
|
|
if (!tegra->phys) {
|
|
|
err = -ENOMEM;
|
|
|
- goto put_padctl;
|
|
|
+ goto disable_xusbc;
|
|
|
}
|
|
|
|
|
|
for (i = 0, k = 0; i < tegra->soc->num_types; i++) {
|
|
@@ -1091,7 +1115,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 put_padctl;
|
|
|
+ goto disable_xusbc;
|
|
|
}
|
|
|
|
|
|
tegra->phys[k++] = phy;
|
|
@@ -1102,7 +1126,7 @@ static int tegra_xusb_probe(struct platform_device *pdev)
|
|
|
dev_name(&pdev->dev));
|
|
|
if (!tegra->hcd) {
|
|
|
err = -ENOMEM;
|
|
|
- goto put_padctl;
|
|
|
+ goto disable_xusbc;
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -1198,6 +1222,12 @@ put_rpm:
|
|
|
disable_rpm:
|
|
|
pm_runtime_disable(&pdev->dev);
|
|
|
usb_put_hcd(tegra->hcd);
|
|
|
+disable_xusbc:
|
|
|
+ if (!&pdev->dev.pm_domain)
|
|
|
+ tegra_powergate_power_off(TEGRA_POWERGATE_XUSBC);
|
|
|
+disable_xusba:
|
|
|
+ if (!&pdev->dev.pm_domain)
|
|
|
+ tegra_powergate_power_off(TEGRA_POWERGATE_XUSBA);
|
|
|
put_padctl:
|
|
|
tegra_xusb_padctl_put(tegra->padctl);
|
|
|
return err;
|