On 2/19/24 9:03 PM, Roger Quadros wrote:
> Some platforms have bus level Reset controlled
> by a GPIO line. If available then handle bus reset
> via GPIO.
> 
> Signed-off-by: Roger Quadros <rog...@kernel.org>
> ---
>  include/phy.h     |  7 +++++++
>  net/mdio-uclass.c | 37 ++++++++++++++++++++++++++++++++++++-
>  2 files changed, 43 insertions(+), 1 deletion(-)
> 
> diff --git a/include/phy.h b/include/phy.h
> index e02cbdb58c..90a595cae4 100644
> --- a/include/phy.h
> +++ b/include/phy.h
> @@ -9,6 +9,7 @@
>  #ifndef _PHY_H
>  #define _PHY_H
>  
> +#include <asm/gpio.h>
>  #include <log.h>
>  #include <phy_interface.h>
>  #include <dm/ofnode.h>
> @@ -76,6 +77,12 @@ struct mii_dev {
>       int (*reset)(struct mii_dev *bus);
>       struct phy_device *phymap[PHY_MAX_ADDR];
>       u32 phy_mask;
> +     /** @reset_delay_us: Bus GPIO reset pulse width in microseconds */
> +     int reset_delay_us;
> +     /** @reset_post_delay_us: Bus GPIO reset deassert delay in microseconds 
> */
> +     int reset_post_delay_us;
> +     /** @reset_gpiod: Bus Reset GPIO descriptor pointer */
> +     struct gpio_desc reset_gpiod;
>  };
>  
>  /* struct phy_driver: a structure which defines PHY behavior
> diff --git a/net/mdio-uclass.c b/net/mdio-uclass.c
> index e758cc66d7..4500c50430 100644
> --- a/net/mdio-uclass.c
> +++ b/net/mdio-uclass.c
> @@ -14,6 +14,9 @@
>  #include <dm/of_extra.h>
>  #include <dm/uclass-internal.h>
>  #include <linux/compat.h>
> +#include <linux/delay.h>
> +
> +#define DEFAULT_GPIO_RESET_DELAY     10      /* in microseconds */
>  
>  void dm_mdio_probe_devices(void)
>  {
> @@ -80,6 +83,16 @@ int dm_mdio_write(struct udevice *mdio_dev, int addr, int 
> devad, int reg,
>  int dm_mdio_reset(struct udevice *mdio_dev)
>  {
>       struct mdio_ops *ops = mdio_get_ops(mdio_dev);
> +     struct mdio_perdev_priv *pdata = dev_get_uclass_priv(mdio_dev);
> +     struct mii_dev *mii_bus = pdata->mii_bus;
> +
> +     if (dm_gpio_is_valid(&mii_bus->reset_gpiod)) {
> +             dm_gpio_set_value(&mii_bus->reset_gpiod, 1);

undefined reference to `dm_gpio_set_value'
Build fails for configs that don't have CONFIG_DM_GPIO defined.

We can have this under "if (IS_ENABLED(CONFIG_DM_GPIO))"

> +             udelay(mii_bus->reset_delay_us);
> +             dm_gpio_set_value(&mii_bus->reset_gpiod, 0);
> +             if (mii_bus->reset_post_delay_us > 0)
> +                     udelay(mii_bus->reset_post_delay_us);
> +     }
>  
>       if (!ops->reset)
>               return 0;
> @@ -111,14 +124,36 @@ static int mdio_reset(struct mii_dev *mii_bus)
>  static int dm_mdio_post_probe(struct udevice *dev)
>  {
>       struct mdio_perdev_priv *pdata = dev_get_uclass_priv(dev);
> +     struct mii_dev *mii_bus;
> +     int ret;
>  
> -     pdata->mii_bus = mdio_alloc();
> +     mii_bus = mdio_alloc();
> +     if (!mii_bus) {
> +             dev_err(dev, "couldn't allocate mii_bus\n");
> +             return -ENOMEM;
> +     }
> +     pdata->mii_bus = mii_bus;
>       pdata->mii_bus->read = mdio_read;
>       pdata->mii_bus->write = mdio_write;
>       pdata->mii_bus->reset = mdio_reset;
>       pdata->mii_bus->priv = dev;
>       strlcpy(pdata->mii_bus->name, dev->name, MDIO_NAME_LEN);
>  
> +     if (IS_ENABLED(CONFIG_DM_GPIO)) {
> +             /* Get bus level PHY reset GPIO details */
> +             mii_bus->reset_delay_us = dev_read_u32_default(dev, 
> "reset-delay-us",
> +                                                            
> DEFAULT_GPIO_RESET_DELAY);
> +             mii_bus->reset_post_delay_us = dev_read_u32_default(dev,
> +                                                                 
> "reset-post-delay-us",
> +                                                                 0);
> +             ret = gpio_request_by_name(dev, "reset-gpios", 0, 
> &mii_bus->reset_gpiod,
> +                                        GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
> +             if (ret && ret != -ENOENT) {
> +                     dev_err(dev, "couldn't get reset-gpios: %d\n", ret);
> +                     return ret;
> +             }
> +     }
> +
>       return mdio_register(pdata->mii_bus);
>  }
>  
> 

-- 
Regards,
Ravi

Reply via email to