Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 21b5faee authored by Roger Quadros's avatar Roger Quadros Committed by Tejun Heo
Browse files

ata: ahci_platform: Manage SATA PHY



Some platforms have a PHY hooked up to the SATA controller. The PHY
needs to be initialized and powered up for SATA to work. We do that
using the PHY framework.

tj: Minor comment formatting updates.

CC: Balaji T K <balajitk@ti.com>
Signed-off-by: default avatarRoger Quadros <rogerq@ti.com>
Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
Signed-off-by: default avatarTejun <Heo&lt;tj@kernel.org>
parent 42a7f53b
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@

#include <linux/clk.h>
#include <linux/libata.h>
#include <linux/phy/phy.h>
#include <linux/regulator/consumer.h>

/* Enclosure Management Control */
@@ -325,6 +326,7 @@ struct ahci_host_priv {
	u32			em_msg_type;	/* EM message type */
	struct clk		*clks[AHCI_MAX_CLKS]; /* Optional */
	struct regulator	*target_pwr;	/* Optional */
	struct phy		*phy;		/* If platform uses phy */
	void			*plat_data;	/* Other platform data */
	/*
	 * Optional ahci_start_engine override, if not set this gets set to the
+45 −2
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include <linux/platform_device.h>
#include <linux/libata.h>
#include <linux/ahci_platform.h>
#include <linux/phy/phy.h>
#include "ahci.h"

static void ahci_host_stop(struct ata_host *host);
@@ -140,6 +141,7 @@ EXPORT_SYMBOL_GPL(ahci_platform_disable_clks);
 * following order:
 * 1) Regulator
 * 2) Clocks (through ahci_platform_enable_clks)
 * 3) Phy
 *
 * If resource enabling fails at any point the previous enabled resources
 * are disabled in reverse order.
@@ -161,8 +163,23 @@ int ahci_platform_enable_resources(struct ahci_host_priv *hpriv)
	if (rc)
		goto disable_regulator;

	if (hpriv->phy) {
		rc = phy_init(hpriv->phy);
		if (rc)
			goto disable_clks;

		rc = phy_power_on(hpriv->phy);
		if (rc) {
			phy_exit(hpriv->phy);
			goto disable_clks;
		}
	}

	return 0;

disable_clks:
	ahci_platform_disable_clks(hpriv);

disable_regulator:
	if (hpriv->target_pwr)
		regulator_disable(hpriv->target_pwr);
@@ -176,11 +193,17 @@ EXPORT_SYMBOL_GPL(ahci_platform_enable_resources);
 *
 * This function disables all ahci_platform managed resources in the
 * following order:
 * 1) Clocks (through ahci_platform_disable_clks)
 * 2) Regulator
 * 1) Phy
 * 2) Clocks (through ahci_platform_disable_clks)
 * 3) Regulator
 */
void ahci_platform_disable_resources(struct ahci_host_priv *hpriv)
{
	if (hpriv->phy) {
		phy_power_off(hpriv->phy);
		phy_exit(hpriv->phy);
	}

	ahci_platform_disable_clks(hpriv);

	if (hpriv->target_pwr)
@@ -208,6 +231,7 @@ static void ahci_platform_put_resources(struct device *dev, void *res)
 * 2) regulator for controlling the targets power (optional)
 * 3) 0 - AHCI_MAX_CLKS clocks, as specified in the devs devicetree node,
 *    or for non devicetree enabled platforms a single clock
 *	4) phy (optional)
 *
 * RETURNS:
 * The allocated ahci_host_priv on success, otherwise an ERR_PTR value
@@ -266,6 +290,25 @@ struct ahci_host_priv *ahci_platform_get_resources(
		hpriv->clks[i] = clk;
	}

	hpriv->phy = devm_phy_get(dev, "sata-phy");
	if (IS_ERR(hpriv->phy)) {
		rc = PTR_ERR(hpriv->phy);
		switch (rc) {
		case -ENODEV:
		case -ENOSYS:
			/* continue normally */
			hpriv->phy = NULL;
			break;

		case -EPROBE_DEFER:
			goto err_out;

		default:
			dev_err(dev, "couldn't get sata-phy\n");
			goto err_out;
		}
	}

	devres_remove_group(dev, NULL);
	return hpriv;