diff options
author | 2014-02-22 16:53:32 +0100 | |
---|---|---|
committer | 2014-02-22 15:35:42 -0500 | |
commit | 4b3e603a298db26c6c37e8b08adcce24d014df13 (patch) | |
tree | ee83e07b60a9fc55e3882c826ee9804223ebaf3a /drivers/ata/ahci_platform.c | |
parent | ahci-platform: Add support for devices with more then 1 clock (diff) | |
download | linux-4b3e603a298db26c6c37e8b08adcce24d014df13.tar.gz linux-4b3e603a298db26c6c37e8b08adcce24d014df13.tar.bz2 linux-4b3e603a298db26c6c37e8b08adcce24d014df13.zip |
ahci-platform: Add support for an optional regulator for sata-target power
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'drivers/ata/ahci_platform.c')
-rw-r--r-- | drivers/ata/ahci_platform.c | 36 |
1 files changed, 34 insertions, 2 deletions
diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c index 8d5a9a7ce958..4befd78133ad 100644 --- a/drivers/ata/ahci_platform.c +++ b/drivers/ata/ahci_platform.c @@ -185,6 +185,14 @@ static int ahci_probe(struct platform_device *pdev) return -ENOMEM; } + hpriv->target_pwr = devm_regulator_get_optional(dev, "target"); + if (IS_ERR(hpriv->target_pwr)) { + rc = PTR_ERR(hpriv->target_pwr); + if (rc == -EPROBE_DEFER) + return -EPROBE_DEFER; + hpriv->target_pwr = NULL; + } + for (i = 0; i < AHCI_MAX_CLKS; i++) { /* * For now we must use clk_get(dev, NULL) for the first clock, @@ -206,9 +214,15 @@ static int ahci_probe(struct platform_device *pdev) hpriv->clks[i] = clk; } + if (hpriv->target_pwr) { + rc = regulator_enable(hpriv->target_pwr); + if (rc) + goto free_clk; + } + rc = ahci_enable_clks(dev, hpriv); if (rc) - goto free_clk; + goto disable_regulator; /* * Some platforms might need to prepare for mmio region access, @@ -291,6 +305,9 @@ pdata_exit: pdata->exit(dev); disable_unprepare_clk: ahci_disable_clks(hpriv); +disable_regulator: + if (hpriv->target_pwr) + regulator_disable(hpriv->target_pwr); free_clk: ahci_put_clks(hpriv); return rc; @@ -307,6 +324,9 @@ static void ahci_host_stop(struct ata_host *host) ahci_disable_clks(hpriv); ahci_put_clks(hpriv); + + if (hpriv->target_pwr) + regulator_disable(hpriv->target_pwr); } #ifdef CONFIG_PM_SLEEP @@ -343,6 +363,9 @@ static int ahci_suspend(struct device *dev) ahci_disable_clks(hpriv); + if (hpriv->target_pwr) + regulator_disable(hpriv->target_pwr); + return 0; } @@ -353,9 +376,15 @@ static int ahci_resume(struct device *dev) struct ahci_host_priv *hpriv = host->private_data; int rc; + if (hpriv->target_pwr) { + rc = regulator_enable(hpriv->target_pwr); + if (rc) + return rc; + } + rc = ahci_enable_clks(dev, hpriv); if (rc) - return rc; + goto disable_regulator; if (pdata && pdata->resume) { rc = pdata->resume(dev); @@ -377,6 +406,9 @@ static int ahci_resume(struct device *dev) disable_unprepare_clk: ahci_disable_clks(hpriv); +disable_regulator: + if (hpriv->target_pwr) + regulator_disable(hpriv->target_pwr); return rc; } |