diff options
author | Corentin Labbe <clabbe.montjoie@gmail.com> | 2018-09-03 12:01:56 +0200 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2018-09-03 08:17:13 -0600 |
commit | f20fb266e77a8af8a6e42eecfb5981178cc4d8a1 (patch) | |
tree | 5cd13dc53c3ed624c68bc91337759c5c96294d65 /drivers/ata | |
parent | d4fbe64bc6ed4a08f01bfd3a224c5a3ff083ec85 (diff) |
ata: ahci_platform: add support for PHY controller regulator
The SoC R40 AHCI controller need a PHY regulator to work.
But since the PHY is embedded in the controller, we cannot do a DT node for it,
since phy-supply works only in node with a PHY compatible.
So this patch adds a way to add an optional phy-supply regulator on AHCI controller node.
Acked-by: Maxime Ripard <maxime.ripard@bootlin.com>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Corentin Labbe <clabbe.montjoie@gmail.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'drivers/ata')
-rw-r--r-- | drivers/ata/ahci.h | 1 | ||||
-rw-r--r-- | drivers/ata/libahci_platform.c | 20 |
2 files changed, 21 insertions, 0 deletions
diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h index 1415f1012de5..ef356e70e6de 100644 --- a/drivers/ata/ahci.h +++ b/drivers/ata/ahci.h @@ -353,6 +353,7 @@ struct ahci_host_priv { struct reset_control *rsts; /* Optional */ struct regulator **target_pwrs; /* Optional */ struct regulator *ahci_regulator;/* Optional */ + struct regulator *phy_regulator;/* Optional */ /* * If platform uses PHYs. There is a 1:1 relation between the port number and * the PHY position in this array. diff --git a/drivers/ata/libahci_platform.c b/drivers/ata/libahci_platform.c index e56f3a9fc7d4..4b900fc659f7 100644 --- a/drivers/ata/libahci_platform.c +++ b/drivers/ata/libahci_platform.c @@ -157,6 +157,12 @@ int ahci_platform_enable_regulators(struct ahci_host_priv *hpriv) return rc; } + if (hpriv->phy_regulator) { + rc = regulator_enable(hpriv->phy_regulator); + if (rc) + goto disable_ahci_pwrs; + } + for (i = 0; i < hpriv->nports; i++) { if (!hpriv->target_pwrs[i]) continue; @@ -173,6 +179,9 @@ disable_target_pwrs: if (hpriv->target_pwrs[i]) regulator_disable(hpriv->target_pwrs[i]); + if (hpriv->phy_regulator) + regulator_disable(hpriv->phy_regulator); +disable_ahci_pwrs: if (hpriv->ahci_regulator) regulator_disable(hpriv->ahci_regulator); return rc; @@ -198,6 +207,8 @@ void ahci_platform_disable_regulators(struct ahci_host_priv *hpriv) if (hpriv->ahci_regulator) regulator_disable(hpriv->ahci_regulator); + if (hpriv->phy_regulator) + regulator_disable(hpriv->phy_regulator); } EXPORT_SYMBOL_GPL(ahci_platform_disable_regulators); /** @@ -430,6 +441,15 @@ struct ahci_host_priv *ahci_platform_get_resources(struct platform_device *pdev, hpriv->ahci_regulator = NULL; } + hpriv->phy_regulator = devm_regulator_get_optional(dev, "phy"); + if (IS_ERR(hpriv->phy_regulator)) { + rc = PTR_ERR(hpriv->phy_regulator); + if (rc == -EPROBE_DEFER) + goto err_out; + rc = 0; + hpriv->phy_regulator = NULL; + } + if (flags & AHCI_PLATFORM_GET_RESETS) { hpriv->rsts = devm_reset_control_array_get_optional_shared(dev); if (IS_ERR(hpriv->rsts)) { |