[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