Commit a37da918 authored by Corentin Labbe's avatar Corentin Labbe Committed by Jens Axboe
Browse files

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: default avatarMaxime Ripard <maxime.ripard@bootlin.com>
Reviewed-by: default avatarHans de Goede <hdegoede@redhat.com>
Signed-off-by: default avatarCorentin Labbe <clabbe.montjoie@gmail.com>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 15fd6ec9
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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.
+24 −2
Original line number Diff line number Diff line
@@ -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)) {