[PATCH v4 3/5] phy: add support for phy-supply
Jonas Karlman
jonas at kwiboo.se
Wed Apr 12 08:53:47 CEST 2023
Hi Eugen,
On 2023-04-04 16:11, 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.
Thanks for looking at this, I have now had some time to test this and it
turned out there was some minor issues.
First, the regulator is enabled in power_on and disabled in exit. It
should probably be disabled after power_off ops has been called.
Second, the return value is ignored, this will change the meson code to
continue with the call to the power_on ops, before it would have stopped
and returned early with an error from the power_on ops.
Third, there seem to be a possibility that the counts in regulator core
can end up uneven when any of init/exit/power_on/power_off ops is NULL.
I created "fixup! phy: add support for phy-supply" and "phy: Keep
balance of counts when ops is missing" at [1] during my testing,
please feel free to fixup/squash/rework any code :-)
Tested with USB (multiple usb start/reset/stop cycles) and PCIe
(multiple pci enum) on RK3568 together with your "regulator: implement
basic reference counter".
[1] https://github.com/Kwiboo/u-boot-rockchip/commits/rk3568-usb-v1
Regards,
Jonas
>
> Signed-off-by: Eugen Hristev <eugen.hristev at collabora.com>
> ---
> drivers/phy/phy-uclass.c | 22 ++++++++++++++++++++++
> 1 file changed, 22 insertions(+)
>
> diff --git a/drivers/phy/phy-uclass.c b/drivers/phy/phy-uclass.c
> index 3fef5135a9cb..475ac285df05 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)
> @@ -224,6 +227,12 @@ int generic_phy_init(struct phy *phy)
> return 0;
> }
>
> +#if CONFIG_IS_ENABLED(DM_REGULATOR)
> + device_get_supply_regulator(phy->dev, "phy-supply", &counts->supply);
> + if (IS_ERR(counts->supply))
> + dev_dbg(phy->dev, "no phy-supply property found\n");
> +#endif
> +
> ret = ops->init(phy);
> if (ret)
> dev_err(phy->dev, "PHY: Failed to init %s: %d.\n",
> @@ -272,6 +281,12 @@ int generic_phy_exit(struct phy *phy)
> return 0;
> }
>
> +#if CONFIG_IS_ENABLED(DM_REGULATOR)
> + if (!IS_ERR_OR_NULL(counts->supply)) {
> + ret = regulator_set_enable(counts->supply, false);
> + dev_dbg(phy->dev, "supply disable status: %d\n", ret);
> + }
> +#endif
> ret = ops->exit(phy);
> if (ret)
> dev_err(phy->dev, "PHY: Failed to exit %s: %d.\n",
> @@ -300,6 +315,13 @@ int generic_phy_power_on(struct phy *phy)
> return 0;
> }
>
> +#if CONFIG_IS_ENABLED(DM_REGULATOR)
> + if (!IS_ERR_OR_NULL(counts->supply)) {
> + ret = regulator_set_enable(counts->supply, true);
> + dev_dbg(phy->dev, "supply enable status: %d\n", ret);
> + }
> +#endif
> +
> ret = ops->power_on(phy);
> if (ret)
> dev_err(phy->dev, "PHY: Failed to power on %s: %d.\n",
More information about the U-Boot
mailing list