|
@@ -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,18 @@ 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;
|
|
|
+ }
|
|
|
+
|
|
|
+ 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;
|
|
@@ -167,6 +179,11 @@ 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;
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(ahci_platform_enable_regulators);
|
|
@@ -175,7 +192,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 +204,11 @@ 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);
|
|
|
+ if (hpriv->phy_regulator)
|
|
|
+ regulator_disable(hpriv->phy_regulator);
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(ahci_platform_disable_regulators);
|
|
|
/**
|
|
@@ -303,8 +326,8 @@ static int ahci_platform_get_phy(struct ahci_host_priv *hpriv, u32 port,
|
|
|
/* No PHY support. Check if PHY is required. */
|
|
|
if (of_find_property(node, "phys", NULL)) {
|
|
|
dev_err(dev,
|
|
|
- "couldn't get PHY in node %s: ENOSYS\n",
|
|
|
- node->name);
|
|
|
+ "couldn't get PHY in node %pOFn: ENOSYS\n",
|
|
|
+ node);
|
|
|
break;
|
|
|
}
|
|
|
/* fall through */
|
|
@@ -316,8 +339,8 @@ static int ahci_platform_get_phy(struct ahci_host_priv *hpriv, u32 port,
|
|
|
|
|
|
default:
|
|
|
dev_err(dev,
|
|
|
- "couldn't get PHY in node %s: %d\n",
|
|
|
- node->name, rc);
|
|
|
+ "couldn't get PHY in node %pOFn: %d\n",
|
|
|
+ node, rc);
|
|
|
|
|
|
break;
|
|
|
}
|
|
@@ -351,6 +374,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 +432,24 @@ 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;
|
|
|
+ }
|
|
|
+
|
|
|
+ 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)) {
|