diff options
author | Marek Vasut <marek.vasut+renesas@mailbox.org> | 2024-03-18 15:57:01 +0100 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2024-03-26 19:58:26 -0400 |
commit | e99a6efa80eaf69aa07d5845f6d2bb362a81c0dd (patch) | |
tree | db6bb5520f2527aa5ccf43f83147ab2276b894e2 /drivers/net/phy/phy.c | |
parent | 85d44e424a32b49f2c9ddf002a684e43bb7828c1 (diff) |
net: phy: Factor out PHY GPIO reset code
Pull the PHY GPIO reset code into separate function, since
this is and will be reused multiple times. Set up default
reset assert and deassert timing to generous 20ms and 1ms
for maximum compatibility in case those DT properties are
missing.
Reviewed-by: Ramon Fried <rfried.dev@gmail.com>
Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
Diffstat (limited to 'drivers/net/phy/phy.c')
-rw-r--r-- | drivers/net/phy/phy.c | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 9cec04a0c94..270176cfe62 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -18,6 +18,8 @@ #include <phy.h> #include <errno.h> #include <asm/global_data.h> +#include <asm-generic/gpio.h> +#include <dm/device_compat.h> #include <dm/of_extra.h> #include <linux/bitops.h> #include <linux/delay.h> @@ -769,6 +771,59 @@ int miiphy_reset(const char *devname, unsigned char addr) return phy_reset(phydev); } +#if CONFIG_IS_ENABLED(DM_GPIO) && CONFIG_IS_ENABLED(OF_REAL) && \ + !IS_ENABLED(CONFIG_DM_ETH_PHY) +int phy_gpio_reset(struct udevice *dev) +{ + struct ofnode_phandle_args phandle_args; + struct gpio_desc gpio; + u32 assert, deassert; + ofnode node; + int ret; + + ret = dev_read_phandle_with_args(dev, "phy-handle", NULL, 0, 0, + &phandle_args); + /* No PHY handle is OK */ + if (ret) + return 0; + + node = phandle_args.node; + if (!ofnode_valid(node)) + return -EINVAL; + + ret = gpio_request_by_name_nodev(node, "reset-gpios", 0, &gpio, + GPIOD_IS_OUT | GPIOD_ACTIVE_LOW); + /* No PHY reset GPIO is OK */ + if (ret) + return 0; + + assert = ofnode_read_u32_default(node, "reset-assert-us", 20000); + deassert = ofnode_read_u32_default(node, "reset-deassert-us", 1000); + ret = dm_gpio_set_value(&gpio, 1); + if (ret) { + dev_err(dev, "Failed assert gpio, err: %d\n", ret); + return ret; + } + + udelay(assert); + + ret = dm_gpio_set_value(&gpio, 0); + if (ret) { + dev_err(dev, "Failed deassert gpio, err: %d\n", ret); + return ret; + } + + udelay(deassert); + + return 0; +} +#else +int phy_gpio_reset(struct udevice *dev) +{ + return 0; +} +#endif + struct phy_device *phy_find_by_mask(struct mii_dev *bus, uint phy_mask) { /* Reset the bus */ |