ata: ahci_platform: add support for AHCI controller regulator
The SoC R40 AHCI controller need a regulator to work. So this patch add a way to add an optional regulator on AHCI controller. 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>
This commit is contained in:
parent
15fd6ec97d
commit
a37da9180f
|
@ -352,6 +352,7 @@ struct ahci_host_priv {
|
|||
struct clk *clks[AHCI_MAX_CLKS]; /* Optional */
|
||||
struct reset_control *rsts; /* Optional */
|
||||
struct regulator **target_pwrs; /* Optional */
|
||||
struct regulator *ahci_regulator;/* Optional */
|
||||
/*
|
||||
* If platform uses PHYs. There is a 1:1 relation between the port number and
|
||||
* the PHY position in this array.
|
||||
|
|
|
@ -139,7 +139,7 @@ EXPORT_SYMBOL_GPL(ahci_platform_disable_clks);
|
|||
* ahci_platform_enable_regulators - Enable regulators
|
||||
* @hpriv: host private area to store config values
|
||||
*
|
||||
* This function enables all the regulators found in
|
||||
* This function enables all the regulators found in controller and
|
||||
* hpriv->target_pwrs, if any. If a regulator fails to be enabled, it
|
||||
* disables all the regulators already enabled in reverse order and
|
||||
* returns an error.
|
||||
|
@ -151,6 +151,12 @@ int ahci_platform_enable_regulators(struct ahci_host_priv *hpriv)
|
|||
{
|
||||
int rc, i;
|
||||
|
||||
if (hpriv->ahci_regulator) {
|
||||
rc = regulator_enable(hpriv->ahci_regulator);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
for (i = 0; i < hpriv->nports; i++) {
|
||||
if (!hpriv->target_pwrs[i])
|
||||
continue;
|
||||
|
@ -167,6 +173,8 @@ disable_target_pwrs:
|
|||
if (hpriv->target_pwrs[i])
|
||||
regulator_disable(hpriv->target_pwrs[i]);
|
||||
|
||||
if (hpriv->ahci_regulator)
|
||||
regulator_disable(hpriv->ahci_regulator);
|
||||
return rc;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ahci_platform_enable_regulators);
|
||||
|
@ -175,7 +183,8 @@ EXPORT_SYMBOL_GPL(ahci_platform_enable_regulators);
|
|||
* ahci_platform_disable_regulators - Disable regulators
|
||||
* @hpriv: host private area to store config values
|
||||
*
|
||||
* This function disables all regulators found in hpriv->target_pwrs.
|
||||
* This function disables all regulators found in hpriv->target_pwrs and
|
||||
* AHCI controller.
|
||||
*/
|
||||
void ahci_platform_disable_regulators(struct ahci_host_priv *hpriv)
|
||||
{
|
||||
|
@ -186,6 +195,9 @@ void ahci_platform_disable_regulators(struct ahci_host_priv *hpriv)
|
|||
continue;
|
||||
regulator_disable(hpriv->target_pwrs[i]);
|
||||
}
|
||||
|
||||
if (hpriv->ahci_regulator)
|
||||
regulator_disable(hpriv->ahci_regulator);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ahci_platform_disable_regulators);
|
||||
/**
|
||||
|
@ -351,6 +363,7 @@ static int ahci_platform_get_regulator(struct ahci_host_priv *hpriv, u32 port,
|
|||
*
|
||||
* 1) mmio registers (IORESOURCE_MEM 0, mandatory)
|
||||
* 2) regulator for controlling the targets power (optional)
|
||||
* regulator for controlling the AHCI controller (optional)
|
||||
* 3) 0 - AHCI_MAX_CLKS clocks, as specified in the devs devicetree node,
|
||||
* or for non devicetree enabled platforms a single clock
|
||||
* 4) resets, if flags has AHCI_PLATFORM_GET_RESETS (optional)
|
||||
|
@ -408,6 +421,15 @@ struct ahci_host_priv *ahci_platform_get_resources(struct platform_device *pdev,
|
|||
hpriv->clks[i] = clk;
|
||||
}
|
||||
|
||||
hpriv->ahci_regulator = devm_regulator_get_optional(dev, "ahci");
|
||||
if (IS_ERR(hpriv->ahci_regulator)) {
|
||||
rc = PTR_ERR(hpriv->ahci_regulator);
|
||||
if (rc == -EPROBE_DEFER)
|
||||
goto err_out;
|
||||
rc = 0;
|
||||
hpriv->ahci_regulator = NULL;
|
||||
}
|
||||
|
||||
if (flags & AHCI_PLATFORM_GET_RESETS) {
|
||||
hpriv->rsts = devm_reset_control_array_get_optional_shared(dev);
|
||||
if (IS_ERR(hpriv->rsts)) {
|
||||
|
|
Loading…
Reference in New Issue