[PATCH v5 3/6] phy: add support for phy-supply

Kever Yang kever.yang at rock-chips.com
Sat May 6 11:34:25 CEST 2023


On 2023/4/19 21:40, Eugen Hristev wrote:
> Some phys require a phy-supply property that is a phandle to a regulator
> that needs to be enabled for phy operations.
> Implement basic supply lookup, enable and disabling, if DM_REGULATOR is
> available.
>
> [jonas at kwiboo.se:
> use regulator_set_enable_if_allowed and disable if power_on ops fails]
> Signed-off-by: Jonas Karlman <jonas at kwiboo.se>
> Signed-off-by: Eugen Hristev <eugen.hristev at collabora.com>
Reviewed-by: Kever Yang <kever.yang at rock-chips.com>

Thanks,
- Kever
> ---
> Changes in v5:
> - add changes done by Jonas
>
>   drivers/phy/phy-uclass.c | 51 +++++++++++++++++++++++++++++++---------
>   1 file changed, 40 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/phy/phy-uclass.c b/drivers/phy/phy-uclass.c
> index 3fef5135a9cb..45ec1471d0ae 100644
> --- a/drivers/phy/phy-uclass.c
> +++ b/drivers/phy/phy-uclass.c
> @@ -12,6 +12,7 @@
>   #include <dm/devres.h>
>   #include <generic-phy.h>
>   #include <linux/list.h>
> +#include <power/regulator.h>
>   
>   /**
>    * struct phy_counts - Init and power-on counts of a single PHY port
> @@ -29,12 +30,14 @@
>    *              without a matching generic_phy_exit() afterwards
>    * @list: Handle for a linked list of these structures corresponding to
>    *        ports of the same PHY provider
> + * @supply: Handle to a phy-supply device
>    */
>   struct phy_counts {
>   	unsigned long id;
>   	int power_on_count;
>   	int init_count;
>   	struct list_head list;
> +	struct udevice *supply;
>   };
>   
>   static inline struct phy_ops *phy_dev_ops(struct udevice *dev)
> @@ -58,7 +61,7 @@ static struct phy_counts *phy_get_counts(struct phy *phy)
>   	return NULL;
>   }
>   
> -static int phy_alloc_counts(struct phy *phy)
> +static int phy_alloc_counts(struct phy *phy, struct udevice *supply)
>   {
>   	struct list_head *uc_priv;
>   	struct phy_counts *counts;
> @@ -76,6 +79,7 @@ static int phy_alloc_counts(struct phy *phy)
>   	counts->id = phy->id;
>   	counts->power_on_count = 0;
>   	counts->init_count = 0;
> +	counts->supply = supply;
>   	list_add(&counts->list, uc_priv);
>   
>   	return 0;
> @@ -123,7 +127,7 @@ int generic_phy_get_by_index_nodev(ofnode node, int index, struct phy *phy)
>   {
>   	struct ofnode_phandle_args args;
>   	struct phy_ops *ops;
> -	struct udevice *phydev;
> +	struct udevice *phydev, *supply = NULL;
>   	int i, ret;
>   
>   	debug("%s(node=%s, index=%d, phy=%p)\n",
> @@ -172,7 +176,17 @@ int generic_phy_get_by_index_nodev(ofnode node, int index, struct phy *phy)
>   		goto err;
>   	}
>   
> -	ret = phy_alloc_counts(phy);
> +	if (CONFIG_IS_ENABLED(DM_REGULATOR)) {
> +		ret = device_get_supply_regulator(phydev, "phy-supply",
> +						  &supply);
> +		if (ret && ret != -ENOENT) {
> +			debug("%s: device_get_supply_regulator failed: %d\n",
> +			      __func__, ret);
> +			goto err;
> +		}
> +	}
> +
> +	ret = phy_alloc_counts(phy, supply);
>   	if (ret) {
>   		debug("phy_alloc_counts() failed: %d\n", ret);
>   		goto err;
> @@ -300,14 +314,23 @@ int generic_phy_power_on(struct phy *phy)
>   		return 0;
>   	}
>   
> +	ret = regulator_set_enable_if_allowed(counts->supply, true);
> +	if (ret && ret != -ENOSYS) {
> +		dev_err(phy->dev, "PHY: Failed to enable regulator %s: %d.\n",
> +			counts->supply->name, ret);
> +		return ret;
> +	}
> +
>   	ret = ops->power_on(phy);
> -	if (ret)
> +	if (ret) {
>   		dev_err(phy->dev, "PHY: Failed to power on %s: %d.\n",
>   			phy->dev->name, ret);
> -	else
> -		counts->power_on_count = 1;
> +		regulator_set_enable_if_allowed(counts->supply, false);
> +		return ret;
> +	}
> +	counts->power_on_count = 1;
>   
> -	return ret;
> +	return 0;
>   }
>   
>   int generic_phy_power_off(struct phy *phy)
> @@ -331,13 +354,19 @@ int generic_phy_power_off(struct phy *phy)
>   	}
>   
>   	ret = ops->power_off(phy);
> -	if (ret)
> +	if (ret) {
>   		dev_err(phy->dev, "PHY: Failed to power off %s: %d.\n",
>   			phy->dev->name, ret);
> -	else
> -		counts->power_on_count = 0;
> +		return ret;
> +	}
> +	counts->power_on_count = 0;
>   
> -	return ret;
> +	ret = regulator_set_enable_if_allowed(counts->supply, false);
> +	if (ret && ret != -ENOSYS)
> +		dev_err(phy->dev, "PHY: Failed to disable regulator %s: %d.\n",
> +			counts->supply->name, ret);
> +
> +	return 0;
>   }
>   
>   int generic_phy_configure(struct phy *phy, void *params)


More information about the U-Boot mailing list