netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2] net: mdio: force deassert MDIO reset signal
@ 2023-01-15 21:37 Pierluigi Passaro
  2023-01-16 11:10 ` Simon Horman
  0 siblings, 1 reply; 5+ messages in thread
From: Pierluigi Passaro @ 2023-01-15 21:37 UTC (permalink / raw)
  To: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni, netdev,
	linux-kernel
  Cc: eran.m, nate.d, francesco.f, pierluigi.p, pierluigi.passaro

When the reset gpio is defined within the node of the device tree
describing the PHY, the reset is initialized and managed only after
calling the fwnode_mdiobus_phy_device_register function.
However, before calling it, the MDIO communication is checked by the
get_phy_device function.
When this happen and the reset GPIO was somehow previously set down,
the get_phy_device function fails, preventing the PHY detection.
These changes force the deassert of the MDIO reset signal before
checking the MDIO channel.
The PHY may require a minimum deassert time before being responsive:
use a reasonable sleep time after forcing the deassert of the MDIO
reset signal.
Once done, free the gpio descriptor to allow managing it later.

Signed-off-by: Pierluigi Passaro <pierluigi.p@variscite.com>
Signed-off-by: FrancescoFerraro <francesco.f@variscite.com>
---
 drivers/net/mdio/fwnode_mdio.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/drivers/net/mdio/fwnode_mdio.c b/drivers/net/mdio/fwnode_mdio.c
index b782c35c4ac1..1f4b8c4c1f60 100644
--- a/drivers/net/mdio/fwnode_mdio.c
+++ b/drivers/net/mdio/fwnode_mdio.c
@@ -8,6 +8,8 @@
 
 #include <linux/acpi.h>
 #include <linux/fwnode_mdio.h>
+#include <linux/gpio/consumer.h>
+#include <linux/gpio/driver.h>
 #include <linux/of.h>
 #include <linux/phy.h>
 #include <linux/pse-pd/pse.h>
@@ -118,6 +120,8 @@ int fwnode_mdiobus_register_phy(struct mii_bus *bus,
 	bool is_c45 = false;
 	u32 phy_id;
 	int rc;
+	int reset_deassert_delay = 0;
+	struct gpio_desc *reset_gpio;
 
 	psec = fwnode_find_pse_control(child);
 	if (IS_ERR(psec))
@@ -134,10 +138,31 @@ int fwnode_mdiobus_register_phy(struct mii_bus *bus,
 	if (rc >= 0)
 		is_c45 = true;
 
+	reset_gpio = fwnode_gpiod_get_index(child, "reset", 0, GPIOD_OUT_LOW, "PHY reset");
+	if (reset_gpio == ERR_PTR(-EPROBE_DEFER)) {
+		dev_dbg(&bus->dev, "reset signal for PHY@%u not ready\n", addr);
+		return -EPROBE_DEFER;
+	} else if (IS_ERR(reset_gpio)) {
+		if (reset_gpio == ERR_PTR(-ENOENT))
+			dev_dbg(&bus->dev, "reset signal for PHY@%u not defined\n", addr);
+		else
+			dev_dbg(&bus->dev, "failed to request reset for PHY@%u, error %ld\n", addr, PTR_ERR(reset_gpio));
+		reset_gpio = NULL;
+	} else {
+		dev_dbg(&bus->dev, "deassert reset signal for PHY@%u\n", addr);
+		fwnode_property_read_u32(child, "reset-deassert-us",
+					 &reset_deassert_delay);
+		if (reset_deassert_delay)
+			fsleep(reset_deassert_delay);
+	}
+
 	if (is_c45 || fwnode_get_phy_id(child, &phy_id))
 		phy = get_phy_device(bus, addr, is_c45);
 	else
 		phy = phy_device_create(bus, addr, phy_id, 0, NULL);
+
+	gpiochip_free_own_desc(reset_gpio);
+
 	if (IS_ERR(phy)) {
 		rc = PTR_ERR(phy);
 		goto clean_mii_ts;
-- 
2.37.2


^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2023-01-16 13:56 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-01-15 21:37 [PATCH v2] net: mdio: force deassert MDIO reset signal Pierluigi Passaro
2023-01-16 11:10 ` Simon Horman
2023-01-16 13:13   ` Pierluigi Passaro
2023-01-16 13:36     ` Russell King (Oracle)
2023-01-16 13:52       ` Simon Horman

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).