All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/4] Teach phylib hard-resetting devices
@ 2017-10-20  8:14 Geert Uytterhoeven
  2017-10-20  8:14 ` [PATCH v3 1/4] phylib: Add device reset GPIO support Geert Uytterhoeven
                   ` (4 more replies)
  0 siblings, 5 replies; 15+ messages in thread
From: Geert Uytterhoeven @ 2017-10-20  8:14 UTC (permalink / raw)
  To: David S . Miller, Andrew Lunn, Florian Fainelli, Simon Horman,
	Magnus Damm
  Cc: Sergei Shtylyov, Rob Herring, Mark Rutland, Nicolas Ferre,
	netdev, devicetree, linux-renesas-soc, linux-kernel,
	Geert Uytterhoeven

	Hi David, Andrew, Florian, Simon, Magnus,

This patch series adds optional PHY reset support to phylib.

The first two patches are destined for David's net-next tree. They add
core PHY reset code, and update a driver that currently uses its own
reset code.  Note that these patches depend on "[PATCH v2] of_mdio: Fix
broken PHY IRQ in case of probe deferral"
(https://www.spinics.net/lists/linux-renesas-soc/msg19442.html), as v3
needs to propagate errors from of_mdiobus_register_phy() and
of_mdiobus_register_device() [1].

The last two patches are new (sort of, see [2]), and destined for
Simon's renesas tree.  They add properties to describe the EthernetAVB
PHY reset topology to the common Salvator-X/XS and ULCB DTS files, which
solves two issues:
  1. On Salvator-XS, the enable pin of the regulator providing PHY power
     is connected to PRESETn, and PSCI powers down the SoC during system
     suspend.  Hence a PHY reset is needed to restore network functionality
     after resume.
  2. Linux should not rely on the boot loader having reset the PHY, but
     should reset the PHY during driver probe.

Changes compared to v2, as sent by Sergei Shtylyov:
  - Fix fwnode_get_named_gpiod() call due to added parameters (which
    allowed to eliminate the gpiod_direction_output() call),
  - Rebased, refreshed, reworded,
  - Take over from Sergei,
  - Add Acked-by,
  - Remove unneeded gpiod check, as gpiod_set_value() handles NULL fine,
  - Handle fwnode_get_named_gpiod() errors correctly:
      - -ENOENT is ignored (the GPIO is optional), and turned into NULL,
	which allowed to remove all later !IS_ERR() checks,
      - Other errors (incl. -EPROBE_DEFER) are propagated [1],
  - Extract DTS patches from series "[PATCH 0/4] ravb: Add PHY reset
    support" (https://www.spinics.net/lists/netdev/msg457308.html), and
    incorporate in this series, after moving reset-gpios from the
    ethernet to the ethernet-phy node [2].

Thanks for your comments!

Geert Uytterhoeven (2):
  arm64: dts: renesas: salvator-common: Add EthernetAVB PHY reset
  arm64: dts: renesas: ulcb: Add EthernetAVB PHY reset

Sergei Shtylyov (2):
  phylib: Add device reset GPIO support
  macb: Kill PHY reset code

 Documentation/devicetree/bindings/net/phy.txt    |  2 ++
 arch/arm64/boot/dts/renesas/salvator-common.dtsi |  1 +
 arch/arm64/boot/dts/renesas/ulcb.dtsi            |  1 +
 drivers/net/ethernet/cadence/macb.h              |  1 -
 drivers/net/ethernet/cadence/macb_main.c         | 21 ---------------
 drivers/net/phy/at803x.c                         | 18 +++----------
 drivers/net/phy/mdio_bus.c                       |  4 +++
 drivers/net/phy/mdio_device.c                    | 26 +++++++++++++++++--
 drivers/net/phy/phy_device.c                     | 33 ++++++++++++++++++++++--
 drivers/of/of_mdio.c                             | 23 +++++++++++++++++
 include/linux/mdio.h                             |  3 +++
 include/linux/phy.h                              |  5 ++++
 12 files changed, 97 insertions(+), 41 deletions(-)

-- 
2.7.4

Gr{oetje,eeting}s,

						Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
							    -- Linus Torvalds

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

* [PATCH v3 1/4] phylib: Add device reset GPIO support
  2017-10-20  8:14 [PATCH v3 0/4] Teach phylib hard-resetting devices Geert Uytterhoeven
@ 2017-10-20  8:14 ` Geert Uytterhoeven
  2017-10-20 10:56   ` Sergei Shtylyov
  2017-10-20 18:11   ` Florian Fainelli
  2017-10-20  8:14 ` [PATCH v3 2/4] macb: Kill PHY reset code Geert Uytterhoeven
                   ` (3 subsequent siblings)
  4 siblings, 2 replies; 15+ messages in thread
From: Geert Uytterhoeven @ 2017-10-20  8:14 UTC (permalink / raw)
  To: David S . Miller, Andrew Lunn, Florian Fainelli, Simon Horman,
	Magnus Damm
  Cc: Sergei Shtylyov, Rob Herring, Mark Rutland, Nicolas Ferre,
	netdev, devicetree, linux-renesas-soc, linux-kernel,
	Geert Uytterhoeven

From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>

The PHY devices sometimes do have their reset signal (maybe even power
supply?) tied to some GPIO and sometimes it also does happen that a boot
loader does not leave it deasserted. So far this issue has been attacked
from (as I believe) a wrong angle: by teaching the MAC driver to manipulate
the GPIO in question; that solution, when applied to the device trees, led
to adding the PHY reset GPIO properties to the MAC device node, with one
exception: Cadence MACB driver which could handle the "reset-gpios" prop
in a PHY device subnode. I believe that the correct approach is to teach
the 'phylib' to get the MDIO device reset GPIO from the device tree node
corresponding to this device -- which this patch is doing...

Note that I had to modify the AT803x PHY driver as it would stop working
otherwise -- it made use of the reset GPIO for its own purposes...

Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
Acked-by: Rob Herring <robh@kernel.org>
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
[geert: Propagate actual errors from fwnode_get_named_gpiod()]
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
This has gained a dependency on "[PATCH v2] of_mdio: Fix broken PHY IRQ
in case of probe deferral"
(https://www.spinics.net/lists/linux-renesas-soc/msg19442.html), as v3
needs to propagate errors from of_mdiobus_register_phy() and
of_mdiobus_register_device() [*].

v3:
  - Fix fwnode_get_named_gpiod() call due to added parameters (which
    allowed to eliminate the gpiod_direction_output() call),
  - Undelete one blank line in the AT803x driver,
  - Resolve rejects, refresh patch,
  - Reword/reformat changelog,
  - Take over from Sergei,
  - Add Acked-by,
  - Remove unneeded gpiod check, as gpiod_set_value() handles NULL fine,
  - Handle fwnode_get_named_gpiod() errors correctly:
      - -ENOENT is ignored (the GPIO is optional), and turned into NULL,
	which allowed to remove all later !IS_ERR() checks,
      - Other errors (incl. -EPROBE_DEFER) are propagated [*],

v2:
  - Reformat changelog,
  - Resolve rejects, refresh patch.
---
 Documentation/devicetree/bindings/net/phy.txt |  2 ++
 drivers/net/phy/at803x.c                      | 18 +++------------
 drivers/net/phy/mdio_bus.c                    |  4 ++++
 drivers/net/phy/mdio_device.c                 | 26 +++++++++++++++++++--
 drivers/net/phy/phy_device.c                  | 33 +++++++++++++++++++++++++--
 drivers/of/of_mdio.c                          | 23 +++++++++++++++++++
 include/linux/mdio.h                          |  3 +++
 include/linux/phy.h                           |  5 ++++
 8 files changed, 95 insertions(+), 19 deletions(-)

diff --git a/Documentation/devicetree/bindings/net/phy.txt b/Documentation/devicetree/bindings/net/phy.txt
index 77d0b2a61ffa96fc..c05479f5ac7cc837 100644
--- a/Documentation/devicetree/bindings/net/phy.txt
+++ b/Documentation/devicetree/bindings/net/phy.txt
@@ -53,6 +53,8 @@ Optional Properties:
   to ensure the integrated PHY is used. The absence of this property indicates
   the muxers should be configured so that the external PHY is used.
 
+- reset-gpios: The GPIO phandle and specifier for the PHY reset signal.
+
 Example:
 
 ethernet-phy@0 {
diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c
index 5f93e6add56394f2..15b4560aeb5de759 100644
--- a/drivers/net/phy/at803x.c
+++ b/drivers/net/phy/at803x.c
@@ -71,7 +71,6 @@ MODULE_LICENSE("GPL");
 
 struct at803x_priv {
 	bool phy_reset:1;
-	struct gpio_desc *gpiod_reset;
 };
 
 struct at803x_context {
@@ -254,22 +253,11 @@ static int at803x_probe(struct phy_device *phydev)
 {
 	struct device *dev = &phydev->mdio.dev;
 	struct at803x_priv *priv;
-	struct gpio_desc *gpiod_reset;
 
 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 	if (!priv)
 		return -ENOMEM;
 
-	if (phydev->drv->phy_id != ATH8030_PHY_ID)
-		goto does_not_require_reset_workaround;
-
-	gpiod_reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
-	if (IS_ERR(gpiod_reset))
-		return PTR_ERR(gpiod_reset);
-
-	priv->gpiod_reset = gpiod_reset;
-
-does_not_require_reset_workaround:
 	phydev->priv = priv;
 
 	return 0;
@@ -343,14 +331,14 @@ static void at803x_link_change_notify(struct phy_device *phydev)
 	 * cannot recover from by software.
 	 */
 	if (phydev->state == PHY_NOLINK) {
-		if (priv->gpiod_reset && !priv->phy_reset) {
+		if (phydev->mdio.reset && !priv->phy_reset) {
 			struct at803x_context context;
 
 			at803x_context_save(phydev, &context);
 
-			gpiod_set_value(priv->gpiod_reset, 1);
+			phy_device_reset(phydev, 1);
 			msleep(1);
-			gpiod_set_value(priv->gpiod_reset, 0);
+			phy_device_reset(phydev, 0);
 			msleep(1);
 
 			at803x_context_restore(phydev, &context);
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index 2df7b62c1a36811e..da6e5366d641a416 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -38,6 +38,7 @@
 #include <linux/phy.h>
 #include <linux/io.h>
 #include <linux/uaccess.h>
+#include <linux/gpio/consumer.h>
 
 #include <asm/irq.h>
 
@@ -420,6 +421,9 @@ void mdiobus_unregister(struct mii_bus *bus)
 		if (!mdiodev)
 			continue;
 
+		if (mdiodev->reset)
+			gpiod_put(mdiodev->reset);
+
 		mdiodev->device_remove(mdiodev);
 		mdiodev->device_free(mdiodev);
 	}
diff --git a/drivers/net/phy/mdio_device.c b/drivers/net/phy/mdio_device.c
index e24f28924af8953d..6926db11ae888174 100644
--- a/drivers/net/phy/mdio_device.c
+++ b/drivers/net/phy/mdio_device.c
@@ -12,6 +12,8 @@
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/errno.h>
+#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
@@ -114,6 +116,12 @@ void mdio_device_remove(struct mdio_device *mdiodev)
 }
 EXPORT_SYMBOL(mdio_device_remove);
 
+void mdio_device_reset(struct mdio_device *mdiodev, int value)
+{
+	gpiod_set_value(mdiodev->reset, value);
+}
+EXPORT_SYMBOL(mdio_device_reset);
+
 /**
  * mdio_probe - probe an MDIO device
  * @dev: device to probe
@@ -128,9 +136,16 @@ static int mdio_probe(struct device *dev)
 	struct mdio_driver *mdiodrv = to_mdio_driver(drv);
 	int err = 0;
 
-	if (mdiodrv->probe)
+	if (mdiodrv->probe) {
+		/* Deassert the reset signal */
+		mdio_device_reset(mdiodev, 0);
+
 		err = mdiodrv->probe(mdiodev);
 
+		/* Assert the reset signal */
+		mdio_device_reset(mdiodev, 1);
+	}
+
 	return err;
 }
 
@@ -140,9 +155,16 @@ static int mdio_remove(struct device *dev)
 	struct device_driver *drv = mdiodev->dev.driver;
 	struct mdio_driver *mdiodrv = to_mdio_driver(drv);
 
-	if (mdiodrv->remove)
+	if (mdiodrv->remove) {
+		/* Deassert the reset signal */
+		mdio_device_reset(mdiodev, 0);
+
 		mdiodrv->remove(mdiodev);
 
+		/* Assert the reset signal */
+		mdio_device_reset(mdiodev, 1);
+	}
+
 	return 0;
 }
 
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 67f25ac29025c539..e694b0ecf780d096 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -632,6 +632,9 @@ int phy_device_register(struct phy_device *phydev)
 	if (err)
 		return err;
 
+	/* Deassert the reset signal */
+	phy_device_reset(phydev, 0);
+
 	/* Run all of the fixups for this PHY */
 	err = phy_scan_fixups(phydev);
 	if (err) {
@@ -647,9 +650,15 @@ int phy_device_register(struct phy_device *phydev)
 		goto out;
 	}
 
+	/* Assert the reset signal */
+	phy_device_reset(phydev, 1);
+
 	return 0;
 
  out:
+	/* Assert the reset signal */
+	phy_device_reset(phydev, 1);
+
 	mdiobus_unregister_device(&phydev->mdio);
 	return err;
 }
@@ -849,6 +858,9 @@ int phy_init_hw(struct phy_device *phydev)
 {
 	int ret = 0;
 
+	/* Deassert the reset signal */
+	phy_device_reset(phydev, 0);
+
 	if (!phydev->drv || !phydev->drv->config_init)
 		return 0;
 
@@ -1126,6 +1138,9 @@ void phy_detach(struct phy_device *phydev)
 	put_device(&phydev->mdio.dev);
 	if (ndev_owner != bus->owner)
 		module_put(bus->owner);
+
+	/* Assert the reset signal */
+	phy_device_reset(phydev, 1);
 }
 EXPORT_SYMBOL(phy_detach);
 
@@ -1811,9 +1826,16 @@ static int phy_probe(struct device *dev)
 	/* Set the state to READY by default */
 	phydev->state = PHY_READY;
 
-	if (phydev->drv->probe)
+	if (phydev->drv->probe) {
+		/* Deassert the reset signal */
+		phy_device_reset(phydev, 0);
+
 		err = phydev->drv->probe(phydev);
 
+		/* Assert the reset signal */
+		phy_device_reset(phydev, 1);
+	}
+
 	mutex_unlock(&phydev->lock);
 
 	return err;
@@ -1829,8 +1851,15 @@ static int phy_remove(struct device *dev)
 	phydev->state = PHY_DOWN;
 	mutex_unlock(&phydev->lock);
 
-	if (phydev->drv && phydev->drv->remove)
+	if (phydev->drv && phydev->drv->remove) {
+		/* Deassert the reset signal */
+		phy_device_reset(phydev, 0);
+
 		phydev->drv->remove(phydev);
+
+		/* Assert the reset signal */
+		phy_device_reset(phydev, 1);
+	}
 	phydev->drv = NULL;
 
 	return 0;
diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c
index 98258583abb0b405..3d044119c032d176 100644
--- a/drivers/of/of_mdio.c
+++ b/drivers/of/of_mdio.c
@@ -47,6 +47,7 @@ static int of_get_phy_id(struct device_node *device, u32 *phy_id)
 static int of_mdiobus_register_phy(struct mii_bus *mdio,
 				    struct device_node *child, u32 addr)
 {
+	struct gpio_desc *gpiod;
 	struct phy_device *phy;
 	bool is_c45;
 	int rc;
@@ -55,10 +56,22 @@ static int of_mdiobus_register_phy(struct mii_bus *mdio,
 	is_c45 = of_device_is_compatible(child,
 					 "ethernet-phy-ieee802.3-c45");
 
+	/* Deassert the optional reset signal */
+	gpiod = fwnode_get_named_gpiod(&child->fwnode, "reset-gpios", 0,
+				       GPIOD_OUT_LOW, "PHY reset");
+	if (PTR_ERR(gpiod) == -ENOENT)
+		gpiod = NULL;
+	else if (IS_ERR(gpiod))
+		return PTR_ERR(gpiod);
+
 	if (!is_c45 && !of_get_phy_id(child, &phy_id))
 		phy = phy_device_create(mdio, addr, phy_id, 0, NULL);
 	else
 		phy = get_phy_device(mdio, addr, is_c45);
+
+	/* Assert the reset signal again */
+	gpiod_set_value(gpiod, 1);
+
 	if (IS_ERR(phy))
 		return PTR_ERR(phy);
 
@@ -81,6 +94,7 @@ static int of_mdiobus_register_phy(struct mii_bus *mdio,
 	 * can be looked up later */
 	of_node_get(child);
 	phy->mdio.dev.of_node = child;
+	phy->mdio.reset = gpiod;
 
 	/* All data is now stored in the phy struct;
 	 * register it */
@@ -100,6 +114,7 @@ static int of_mdiobus_register_device(struct mii_bus *mdio,
 				      struct device_node *child, u32 addr)
 {
 	struct mdio_device *mdiodev;
+	struct gpio_desc *gpiod;
 	int rc;
 
 	mdiodev = mdio_device_create(mdio, addr);
@@ -112,6 +127,14 @@ static int of_mdiobus_register_device(struct mii_bus *mdio,
 	of_node_get(child);
 	mdiodev->dev.of_node = child;
 
+	gpiod = fwnode_get_named_gpiod(&child->fwnode, "reset-gpios", 0,
+				       GPIOD_ASIS, "PHY reset");
+	if (PTR_ERR(gpiod) == -ENOENT)
+		gpiod = NULL;
+	else if (IS_ERR(gpiod))
+		return PTR_ERR(gpiod);
+	mdiodev->reset = gpiod;
+
 	/* All data is now stored in the mdiodev struct; register it. */
 	rc = mdio_device_register(mdiodev);
 	if (rc) {
diff --git a/include/linux/mdio.h b/include/linux/mdio.h
index ca08ab16ecdc9b78..92d4e55ffe675637 100644
--- a/include/linux/mdio.h
+++ b/include/linux/mdio.h
@@ -12,6 +12,7 @@
 #include <uapi/linux/mdio.h>
 #include <linux/mod_devicetable.h>
 
+struct gpio_desc;
 struct mii_bus;
 
 /* Multiple levels of nesting are possible. However typically this is
@@ -39,6 +40,7 @@ struct mdio_device {
 	/* Bus address of the MDIO device (0-31) */
 	int addr;
 	int flags;
+	struct gpio_desc *reset;
 };
 #define to_mdio_device(d) container_of(d, struct mdio_device, dev)
 
@@ -71,6 +73,7 @@ void mdio_device_free(struct mdio_device *mdiodev);
 struct mdio_device *mdio_device_create(struct mii_bus *bus, int addr);
 int mdio_device_register(struct mdio_device *mdiodev);
 void mdio_device_remove(struct mdio_device *mdiodev);
+void mdio_device_reset(struct mdio_device *mdiodev, int value);
 int mdio_driver_register(struct mdio_driver *drv);
 void mdio_driver_unregister(struct mdio_driver *drv);
 int mdio_device_bus_match(struct device *dev, struct device_driver *drv);
diff --git a/include/linux/phy.h b/include/linux/phy.h
index d78cd01ea5131018..175f3a6a61abcf0f 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -847,6 +847,11 @@ static inline int phy_read_status(struct phy_device *phydev)
 	return phydev->drv->read_status(phydev);
 }
 
+static inline void phy_device_reset(struct phy_device *phydev, int value)
+{
+	mdio_device_reset(&phydev->mdio, value);
+}
+
 #define phydev_err(_phydev, format, args...)	\
 	dev_err(&_phydev->mdio.dev, format, ##args)
 
-- 
2.7.4

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

* [PATCH v3 2/4] macb: Kill PHY reset code
  2017-10-20  8:14 [PATCH v3 0/4] Teach phylib hard-resetting devices Geert Uytterhoeven
  2017-10-20  8:14 ` [PATCH v3 1/4] phylib: Add device reset GPIO support Geert Uytterhoeven
@ 2017-10-20  8:14 ` Geert Uytterhoeven
  2017-10-20 18:04     ` Florian Fainelli
  2017-10-20  8:14   ` Geert Uytterhoeven
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 15+ messages in thread
From: Geert Uytterhoeven @ 2017-10-20  8:14 UTC (permalink / raw)
  To: David S . Miller, Andrew Lunn, Florian Fainelli, Simon Horman,
	Magnus Damm
  Cc: Sergei Shtylyov, Rob Herring, Mark Rutland, Nicolas Ferre,
	netdev, devicetree, linux-renesas-soc, linux-kernel,
	Geert Uytterhoeven

From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>

With the phylib now being aware of the "reset-gpios" PHY node property,
there should be no need to frob the PHY reset in this driver anymore...

Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
Acked-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - Resolve rejects due to the file being renamed, refresh the patch,
  - Added code to reset PHY on probe error,
  - Edit patch description,
  - Take over from Sergei,
  - Add Acked-by,

v2:
  - No changes.
---
 drivers/net/ethernet/cadence/macb.h      |  1 -
 drivers/net/ethernet/cadence/macb_main.c | 21 ---------------------
 2 files changed, 22 deletions(-)

diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h
index c93f3a2dc6c1a318..146cb24ebf4461bf 100644
--- a/drivers/net/ethernet/cadence/macb.h
+++ b/drivers/net/ethernet/cadence/macb.h
@@ -1032,7 +1032,6 @@ struct macb {
 	unsigned int		dma_burst_length;
 
 	phy_interface_t		phy_interface;
-	struct gpio_desc	*reset_gpio;
 
 	/* AT91RM9200 transmit */
 	struct sk_buff *skb;			/* holds skb until xmit interrupt completes */
diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
index 6df2cad61647a6d7..fc11c04be6837ff2 100644
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -3393,7 +3393,6 @@ static int macb_probe(struct platform_device *pdev)
 					      = macb_config->clk_init;
 	int (*init)(struct platform_device *) = macb_config->init;
 	struct device_node *np = pdev->dev.of_node;
-	struct device_node *phy_node;
 	struct clk *pclk, *hclk = NULL, *tx_clk = NULL, *rx_clk = NULL;
 	unsigned int queue_mask, num_queues;
 	struct macb_platform_data *pdata;
@@ -3499,18 +3498,6 @@ static int macb_probe(struct platform_device *pdev)
 	else
 		macb_get_hwaddr(bp);
 
-	/* Power up the PHY if there is a GPIO reset */
-	phy_node =  of_get_next_available_child(np, NULL);
-	if (phy_node) {
-		int gpio = of_get_named_gpio(phy_node, "reset-gpios", 0);
-
-		if (gpio_is_valid(gpio)) {
-			bp->reset_gpio = gpio_to_desc(gpio);
-			gpiod_direction_output(bp->reset_gpio, 1);
-		}
-	}
-	of_node_put(phy_node);
-
 	err = of_get_phy_mode(np);
 	if (err < 0) {
 		pdata = dev_get_platdata(&pdev->dev);
@@ -3554,10 +3541,6 @@ static int macb_probe(struct platform_device *pdev)
 	mdiobus_unregister(bp->mii_bus);
 	mdiobus_free(bp->mii_bus);
 
-	/* Shutdown the PHY if there is a GPIO reset */
-	if (bp->reset_gpio)
-		gpiod_set_value(bp->reset_gpio, 0);
-
 err_out_free_netdev:
 	free_netdev(dev);
 
@@ -3585,10 +3568,6 @@ static int macb_remove(struct platform_device *pdev)
 		dev->phydev = NULL;
 		mdiobus_free(bp->mii_bus);
 
-		/* Shutdown the PHY if there is a GPIO reset */
-		if (bp->reset_gpio)
-			gpiod_set_value(bp->reset_gpio, 0);
-
 		unregister_netdev(dev);
 		clk_disable_unprepare(bp->tx_clk);
 		clk_disable_unprepare(bp->hclk);
-- 
2.7.4

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

* [PATCH v3 3/4] arm64: dts: renesas: salvator-common: Add EthernetAVB PHY reset
@ 2017-10-20  8:14   ` Geert Uytterhoeven
  0 siblings, 0 replies; 15+ messages in thread
From: Geert Uytterhoeven @ 2017-10-20  8:14 UTC (permalink / raw)
  To: David S . Miller, Andrew Lunn, Florian Fainelli, Simon Horman,
	Magnus Damm
  Cc: Sergei Shtylyov, Rob Herring, Mark Rutland, Nicolas Ferre,
	netdev, devicetree, linux-renesas-soc, linux-kernel,
	Geert Uytterhoeven

Describe the GPIO used to reset the Ethernet PHY for EthernetAVB.
This allows the driver to reset the PHY during probe and after system
resume.

This fixes Ethernet operation after resume from s2ram on Salvator-XS,
where the enable pin of the regulator providing PHY power is connected
to PRESETn, and PSCI powers down the SoC during system suspend.

On Salvator-X, the enable pin is always pulled high, but the driver may
still need to reset the PHY if this wasn't done by the bootloader
before.

Inspired by patches in the BSP for the individual Salvator-X/XS boards
by Kazuya Mizuguchi.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
For proper PHY reset operation during system resume, this depends on
"[PATCH v3 2/4] phylib: Add device reset GPIO support".
However, this patch can be applied independently.

v3:
  - Extract from series "[PATCH 0/4] ravb: Add PHY reset support", and
    incorporate in this series,
  - Move reset-gpios from the ethernet to the ethernet-phy node.
---
 arch/arm64/boot/dts/renesas/salvator-common.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/renesas/salvator-common.dtsi b/arch/arm64/boot/dts/renesas/salvator-common.dtsi
index a028cf577ae1d185..78dcb83f59c76333 100644
--- a/arch/arm64/boot/dts/renesas/salvator-common.dtsi
+++ b/arch/arm64/boot/dts/renesas/salvator-common.dtsi
@@ -313,6 +313,7 @@
 		reg = <0>;
 		interrupt-parent = <&gpio2>;
 		interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
+		reset-gpios = <&gpio2 10 GPIO_ACTIVE_LOW>;
 	};
 };
 
-- 
2.7.4

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

* [PATCH v3 3/4] arm64: dts: renesas: salvator-common: Add EthernetAVB PHY reset
@ 2017-10-20  8:14   ` Geert Uytterhoeven
  0 siblings, 0 replies; 15+ messages in thread
From: Geert Uytterhoeven @ 2017-10-20  8:14 UTC (permalink / raw)
  To: David S . Miller, Andrew Lunn, Florian Fainelli, Simon Horman,
	Magnus Damm
  Cc: Sergei Shtylyov, Rob Herring, Mark Rutland, Nicolas Ferre,
	netdev-u79uwXL29TY76Z2rM5mHXA, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-renesas-soc-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Geert Uytterhoeven

Describe the GPIO used to reset the Ethernet PHY for EthernetAVB.
This allows the driver to reset the PHY during probe and after system
resume.

This fixes Ethernet operation after resume from s2ram on Salvator-XS,
where the enable pin of the regulator providing PHY power is connected
to PRESETn, and PSCI powers down the SoC during system suspend.

On Salvator-X, the enable pin is always pulled high, but the driver may
still need to reset the PHY if this wasn't done by the bootloader
before.

Inspired by patches in the BSP for the individual Salvator-X/XS boards
by Kazuya Mizuguchi.

Signed-off-by: Geert Uytterhoeven <geert+renesas-gXvu3+zWzMSzQB+pC5nmwQ@public.gmane.org>
---
For proper PHY reset operation during system resume, this depends on
"[PATCH v3 2/4] phylib: Add device reset GPIO support".
However, this patch can be applied independently.

v3:
  - Extract from series "[PATCH 0/4] ravb: Add PHY reset support", and
    incorporate in this series,
  - Move reset-gpios from the ethernet to the ethernet-phy node.
---
 arch/arm64/boot/dts/renesas/salvator-common.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/renesas/salvator-common.dtsi b/arch/arm64/boot/dts/renesas/salvator-common.dtsi
index a028cf577ae1d185..78dcb83f59c76333 100644
--- a/arch/arm64/boot/dts/renesas/salvator-common.dtsi
+++ b/arch/arm64/boot/dts/renesas/salvator-common.dtsi
@@ -313,6 +313,7 @@
 		reg = <0>;
 		interrupt-parent = <&gpio2>;
 		interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
+		reset-gpios = <&gpio2 10 GPIO_ACTIVE_LOW>;
 	};
 };
 
-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v3 4/4] arm64: dts: renesas: ulcb: Add EthernetAVB PHY reset
  2017-10-20  8:14 [PATCH v3 0/4] Teach phylib hard-resetting devices Geert Uytterhoeven
                   ` (2 preceding siblings ...)
  2017-10-20  8:14   ` Geert Uytterhoeven
@ 2017-10-20  8:14 ` Geert Uytterhoeven
  2017-10-20  9:05   ` Simon Horman
  4 siblings, 0 replies; 15+ messages in thread
From: Geert Uytterhoeven @ 2017-10-20  8:14 UTC (permalink / raw)
  To: David S . Miller, Andrew Lunn, Florian Fainelli, Simon Horman,
	Magnus Damm
  Cc: Sergei Shtylyov, Rob Herring, Mark Rutland, Nicolas Ferre,
	netdev, devicetree, linux-renesas-soc, linux-kernel,
	Geert Uytterhoeven

Describe the GPIO used to reset the Ethernet PHY for EthernetAVB.
This allows the driver to reset the PHY during probe and after system
resume.

On ULCB, the enable pin of the regulator providing PHY power is always
pulled high, but the driver may still need to reset the PHY if this
wasn't done by the bootloader before.

Inspired by patches in the BSP for the individual Salvator-X/XS boards
by Kazuya Mizuguchi.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
Compile-tested only.

v3:
  - Extract from series "[PATCH 0/4] ravb: Add PHY reset support", and
    incorporate in this series,
  - Move reset-gpios from the ethernet to the ethernet-phy node.
---
 arch/arm64/boot/dts/renesas/ulcb.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/renesas/ulcb.dtsi b/arch/arm64/boot/dts/renesas/ulcb.dtsi
index 0d85b315ce711c8f..be91016e0b48f196 100644
--- a/arch/arm64/boot/dts/renesas/ulcb.dtsi
+++ b/arch/arm64/boot/dts/renesas/ulcb.dtsi
@@ -154,6 +154,7 @@
 		reg = <0>;
 		interrupt-parent = <&gpio2>;
 		interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
+		reset-gpios = <&gpio2 10 GPIO_ACTIVE_LOW>;
 	};
 };
 
-- 
2.7.4

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

* Re: [PATCH v3 0/4] Teach phylib hard-resetting devices
@ 2017-10-20  9:05   ` Simon Horman
  0 siblings, 0 replies; 15+ messages in thread
From: Simon Horman @ 2017-10-20  9:05 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: David S . Miller, Andrew Lunn, Florian Fainelli, Magnus Damm,
	Sergei Shtylyov, Rob Herring, Mark Rutland, Nicolas Ferre,
	netdev, devicetree, linux-renesas-soc, linux-kernel

On Fri, Oct 20, 2017 at 10:14:17AM +0200, Geert Uytterhoeven wrote:
> 	Hi David, Andrew, Florian, Simon, Magnus,
> 
> This patch series adds optional PHY reset support to phylib.
> 
> The first two patches are destined for David's net-next tree. They add
> core PHY reset code, and update a driver that currently uses its own
> reset code.  Note that these patches depend on "[PATCH v2] of_mdio: Fix
> broken PHY IRQ in case of probe deferral"
> (https://www.spinics.net/lists/linux-renesas-soc/msg19442.html), as v3
> needs to propagate errors from of_mdiobus_register_phy() and
> of_mdiobus_register_device() [1].
> 
> The last two patches are new (sort of, see [2]), and destined for
> Simon's renesas tree.  They add properties to describe the EthernetAVB
> PHY reset topology to the common Salvator-X/XS and ULCB DTS files, which
> solves two issues:
>   1. On Salvator-XS, the enable pin of the regulator providing PHY power
>      is connected to PRESETn, and PSCI powers down the SoC during system
>      suspend.  Hence a PHY reset is needed to restore network functionality
>      after resume.
>   2. Linux should not rely on the boot loader having reset the PHY, but
>      should reset the PHY during driver probe.
> 
> Changes compared to v2, as sent by Sergei Shtylyov:
>   - Fix fwnode_get_named_gpiod() call due to added parameters (which
>     allowed to eliminate the gpiod_direction_output() call),
>   - Rebased, refreshed, reworded,
>   - Take over from Sergei,
>   - Add Acked-by,
>   - Remove unneeded gpiod check, as gpiod_set_value() handles NULL fine,
>   - Handle fwnode_get_named_gpiod() errors correctly:
>       - -ENOENT is ignored (the GPIO is optional), and turned into NULL,
> 	which allowed to remove all later !IS_ERR() checks,
>       - Other errors (incl. -EPROBE_DEFER) are propagated [1],
>   - Extract DTS patches from series "[PATCH 0/4] ravb: Add PHY reset
>     support" (https://www.spinics.net/lists/netdev/msg457308.html), and
>     incorporate in this series, after moving reset-gpios from the
>     ethernet to the ethernet-phy node [2].
> 
> Thanks for your comments!
> 
> Geert Uytterhoeven (2):
>   arm64: dts: renesas: salvator-common: Add EthernetAVB PHY reset
>   arm64: dts: renesas: ulcb: Add EthernetAVB PHY reset

I have marked the above patches as deferred pending acceptance of
the other patches in this series. Please repost or otherwise ping
me once that has happened.

> 
> Sergei Shtylyov (2):
>   phylib: Add device reset GPIO support
>   macb: Kill PHY reset code
> 
>  Documentation/devicetree/bindings/net/phy.txt    |  2 ++
>  arch/arm64/boot/dts/renesas/salvator-common.dtsi |  1 +
>  arch/arm64/boot/dts/renesas/ulcb.dtsi            |  1 +
>  drivers/net/ethernet/cadence/macb.h              |  1 -
>  drivers/net/ethernet/cadence/macb_main.c         | 21 ---------------
>  drivers/net/phy/at803x.c                         | 18 +++----------
>  drivers/net/phy/mdio_bus.c                       |  4 +++
>  drivers/net/phy/mdio_device.c                    | 26 +++++++++++++++++--
>  drivers/net/phy/phy_device.c                     | 33 ++++++++++++++++++++++--
>  drivers/of/of_mdio.c                             | 23 +++++++++++++++++
>  include/linux/mdio.h                             |  3 +++
>  include/linux/phy.h                              |  5 ++++
>  12 files changed, 97 insertions(+), 41 deletions(-)
> 
> -- 
> 2.7.4
> 
> Gr{oetje,eeting}s,
> 
> 						Geert
> 
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
> 
> In personal conversations with technical people, I call myself a hacker. But
> when I'm talking to journalists I just say "programmer" or something like that.
> 							    -- Linus Torvalds
> 

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

* Re: [PATCH v3 0/4] Teach phylib hard-resetting devices
@ 2017-10-20  9:05   ` Simon Horman
  0 siblings, 0 replies; 15+ messages in thread
From: Simon Horman @ 2017-10-20  9:05 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: David S . Miller, Andrew Lunn, Florian Fainelli, Magnus Damm,
	Sergei Shtylyov, Rob Herring, Mark Rutland, Nicolas Ferre,
	netdev-u79uwXL29TY76Z2rM5mHXA, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-renesas-soc-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On Fri, Oct 20, 2017 at 10:14:17AM +0200, Geert Uytterhoeven wrote:
> 	Hi David, Andrew, Florian, Simon, Magnus,
> 
> This patch series adds optional PHY reset support to phylib.
> 
> The first two patches are destined for David's net-next tree. They add
> core PHY reset code, and update a driver that currently uses its own
> reset code.  Note that these patches depend on "[PATCH v2] of_mdio: Fix
> broken PHY IRQ in case of probe deferral"
> (https://www.spinics.net/lists/linux-renesas-soc/msg19442.html), as v3
> needs to propagate errors from of_mdiobus_register_phy() and
> of_mdiobus_register_device() [1].
> 
> The last two patches are new (sort of, see [2]), and destined for
> Simon's renesas tree.  They add properties to describe the EthernetAVB
> PHY reset topology to the common Salvator-X/XS and ULCB DTS files, which
> solves two issues:
>   1. On Salvator-XS, the enable pin of the regulator providing PHY power
>      is connected to PRESETn, and PSCI powers down the SoC during system
>      suspend.  Hence a PHY reset is needed to restore network functionality
>      after resume.
>   2. Linux should not rely on the boot loader having reset the PHY, but
>      should reset the PHY during driver probe.
> 
> Changes compared to v2, as sent by Sergei Shtylyov:
>   - Fix fwnode_get_named_gpiod() call due to added parameters (which
>     allowed to eliminate the gpiod_direction_output() call),
>   - Rebased, refreshed, reworded,
>   - Take over from Sergei,
>   - Add Acked-by,
>   - Remove unneeded gpiod check, as gpiod_set_value() handles NULL fine,
>   - Handle fwnode_get_named_gpiod() errors correctly:
>       - -ENOENT is ignored (the GPIO is optional), and turned into NULL,
> 	which allowed to remove all later !IS_ERR() checks,
>       - Other errors (incl. -EPROBE_DEFER) are propagated [1],
>   - Extract DTS patches from series "[PATCH 0/4] ravb: Add PHY reset
>     support" (https://www.spinics.net/lists/netdev/msg457308.html), and
>     incorporate in this series, after moving reset-gpios from the
>     ethernet to the ethernet-phy node [2].
> 
> Thanks for your comments!
> 
> Geert Uytterhoeven (2):
>   arm64: dts: renesas: salvator-common: Add EthernetAVB PHY reset
>   arm64: dts: renesas: ulcb: Add EthernetAVB PHY reset

I have marked the above patches as deferred pending acceptance of
the other patches in this series. Please repost or otherwise ping
me once that has happened.

> 
> Sergei Shtylyov (2):
>   phylib: Add device reset GPIO support
>   macb: Kill PHY reset code
> 
>  Documentation/devicetree/bindings/net/phy.txt    |  2 ++
>  arch/arm64/boot/dts/renesas/salvator-common.dtsi |  1 +
>  arch/arm64/boot/dts/renesas/ulcb.dtsi            |  1 +
>  drivers/net/ethernet/cadence/macb.h              |  1 -
>  drivers/net/ethernet/cadence/macb_main.c         | 21 ---------------
>  drivers/net/phy/at803x.c                         | 18 +++----------
>  drivers/net/phy/mdio_bus.c                       |  4 +++
>  drivers/net/phy/mdio_device.c                    | 26 +++++++++++++++++--
>  drivers/net/phy/phy_device.c                     | 33 ++++++++++++++++++++++--
>  drivers/of/of_mdio.c                             | 23 +++++++++++++++++
>  include/linux/mdio.h                             |  3 +++
>  include/linux/phy.h                              |  5 ++++
>  12 files changed, 97 insertions(+), 41 deletions(-)
> 
> -- 
> 2.7.4
> 
> Gr{oetje,eeting}s,
> 
> 						Geert
> 
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org
> 
> In personal conversations with technical people, I call myself a hacker. But
> when I'm talking to journalists I just say "programmer" or something like that.
> 							    -- Linus Torvalds
> 
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH v3 1/4] phylib: Add device reset GPIO support
  2017-10-20  8:14 ` [PATCH v3 1/4] phylib: Add device reset GPIO support Geert Uytterhoeven
@ 2017-10-20 10:56   ` Sergei Shtylyov
  2017-10-20 18:11   ` Florian Fainelli
  1 sibling, 0 replies; 15+ messages in thread
From: Sergei Shtylyov @ 2017-10-20 10:56 UTC (permalink / raw)
  To: Geert Uytterhoeven, David S . Miller, Andrew Lunn,
	Florian Fainelli, Simon Horman, Magnus Damm
  Cc: Rob Herring, Mark Rutland, Nicolas Ferre, netdev, devicetree,
	linux-renesas-soc, linux-kernel

Hello!

On 10/20/2017 11:14 AM, Geert Uytterhoeven wrote:

> From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
> 
> The PHY devices sometimes do have their reset signal (maybe even power
> supply?) tied to some GPIO and sometimes it also does happen that a boot
> loader does not leave it deasserted. So far this issue has been attacked
> from (as I believe) a wrong angle: by teaching the MAC driver to manipulate
> the GPIO in question; that solution, when applied to the device trees, led
> to adding the PHY reset GPIO properties to the MAC device node, with one
> exception: Cadence MACB driver which could handle the "reset-gpios" prop
> in a PHY device subnode. I believe that the correct approach is to teach
> the 'phylib' to get the MDIO device reset GPIO from the device tree node
> corresponding to this device -- which this patch is doing...
> 
> Note that I had to modify the AT803x PHY driver as it would stop working
> otherwise -- it made use of the reset GPIO for its own purposes...
> 
> Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
> Acked-by: Rob Herring <robh@kernel.org>
> Acked-by: Florian Fainelli <f.fainelli@gmail.com>
> [geert: Propagate actual errors from fwnode_get_named_gpiod()]
> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
[...]
> diff --git a/drivers/net/phy/mdio_device.c b/drivers/net/phy/mdio_device.c
> index e24f28924af8953d..6926db11ae888174 100644
> --- a/drivers/net/phy/mdio_device.c
> +++ b/drivers/net/phy/mdio_device.c
[...]
> @@ -128,9 +136,16 @@ static int mdio_probe(struct device *dev)
>   	struct mdio_driver *mdiodrv = to_mdio_driver(drv);
>   	int err = 0;
>   
> -	if (mdiodrv->probe)
> +	if (mdiodrv->probe) {
> +		/* Deassert the reset signal */
> +		mdio_device_reset(mdiodev, 0);
> +
>   		err = mdiodrv->probe(mdiodev);

    If the probe() method performs some register setup...

> +		/* Assert the reset signal */
> +		mdio_device_reset(mdiodev, 1);

    ... this reset would kill that setup. Hence we shouldn't drive the reset 
signal at least when the probe() method succeeds.

> +	}
> +
>   	return err;
>   }
>   
[...]
> diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
> index 67f25ac29025c539..e694b0ecf780d096 100644
> --- a/drivers/net/phy/phy_device.c
> +++ b/drivers/net/phy/phy_device.c
[...]
> @@ -1811,9 +1826,16 @@ static int phy_probe(struct device *dev)
>   	/* Set the state to READY by default */
>   	phydev->state = PHY_READY;
>   
> -	if (phydev->drv->probe)
> +	if (phydev->drv->probe) {
> +		/* Deassert the reset signal */
> +		phy_device_reset(phydev, 0);
> +
>   		err = phydev->drv->probe(phydev);

    If the probe() method performs some register setup (as does the LXT PHY 
driver!)...

> +		/* Assert the reset signal */
> +		phy_device_reset(phydev, 1);

    ... this reset would kill that setup. Hence we shouldn't drive the reset 
signal at least when the probe() method succeeds.

> +	}
> +
>   	mutex_unlock(&phydev->lock);
>   
>   	return err;
[...]

MBR, Sergei

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

* Re: [PATCH v3 2/4] macb: Kill PHY reset code
@ 2017-10-20 18:04     ` Florian Fainelli
  0 siblings, 0 replies; 15+ messages in thread
From: Florian Fainelli @ 2017-10-20 18:04 UTC (permalink / raw)
  To: Geert Uytterhoeven, David S . Miller, Andrew Lunn, Simon Horman,
	Magnus Damm
  Cc: Sergei Shtylyov, Rob Herring, Mark Rutland, Nicolas Ferre,
	netdev, devicetree, linux-renesas-soc, linux-kernel

On 10/20/2017 01:14 AM, Geert Uytterhoeven wrote:
> From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
> 
> With the phylib now being aware of the "reset-gpios" PHY node property,
> there should be no need to frob the PHY reset in this driver anymore...
> 
> Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
> Acked-by: Nicolas Ferre <nicolas.ferre@atmel.com>
> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>

Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-- 
Florian

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

* Re: [PATCH v3 2/4] macb: Kill PHY reset code
@ 2017-10-20 18:04     ` Florian Fainelli
  0 siblings, 0 replies; 15+ messages in thread
From: Florian Fainelli @ 2017-10-20 18:04 UTC (permalink / raw)
  To: Geert Uytterhoeven, David S . Miller, Andrew Lunn, Simon Horman,
	Magnus Damm
  Cc: Sergei Shtylyov, Rob Herring, Mark Rutland, Nicolas Ferre,
	netdev-u79uwXL29TY76Z2rM5mHXA, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-renesas-soc-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On 10/20/2017 01:14 AM, Geert Uytterhoeven wrote:
> From: Sergei Shtylyov <sergei.shtylyov-M4DtvfQ/ZS1MRgGoP+s0PdBPR1lH4CV8@public.gmane.org>
> 
> With the phylib now being aware of the "reset-gpios" PHY node property,
> there should be no need to frob the PHY reset in this driver anymore...
> 
> Signed-off-by: Sergei Shtylyov <sergei.shtylyov-M4DtvfQ/ZS1MRgGoP+s0PdBPR1lH4CV8@public.gmane.org>
> Acked-by: Nicolas Ferre <nicolas.ferre-AIFe0yeh4nAAvxtiuMwx3w@public.gmane.org>
> Signed-off-by: Geert Uytterhoeven <geert+renesas-gXvu3+zWzMSzQB+pC5nmwQ@public.gmane.org>

Reviewed-by: Florian Fainelli <f.fainelli-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
-- 
Florian
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH v3 1/4] phylib: Add device reset GPIO support
  2017-10-20  8:14 ` [PATCH v3 1/4] phylib: Add device reset GPIO support Geert Uytterhoeven
  2017-10-20 10:56   ` Sergei Shtylyov
@ 2017-10-20 18:11   ` Florian Fainelli
  2017-10-21 10:03     ` Sergei Shtylyov
  1 sibling, 1 reply; 15+ messages in thread
From: Florian Fainelli @ 2017-10-20 18:11 UTC (permalink / raw)
  To: Geert Uytterhoeven, David S . Miller, Andrew Lunn, Simon Horman,
	Magnus Damm
  Cc: Sergei Shtylyov, Rob Herring, Mark Rutland, Nicolas Ferre,
	netdev, devicetree, linux-renesas-soc, linux-kernel

On 10/20/2017 01:14 AM, Geert Uytterhoeven wrote:
> From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
> 
> The PHY devices sometimes do have their reset signal (maybe even power
> supply?) tied to some GPIO and sometimes it also does happen that a boot
> loader does not leave it deasserted. So far this issue has been attacked
> from (as I believe) a wrong angle: by teaching the MAC driver to manipulate
> the GPIO in question; that solution, when applied to the device trees, led
> to adding the PHY reset GPIO properties to the MAC device node, with one
> exception: Cadence MACB driver which could handle the "reset-gpios" prop
> in a PHY device subnode. I believe that the correct approach is to teach
> the 'phylib' to get the MDIO device reset GPIO from the device tree node
> corresponding to this device -- which this patch is doing...
> 
> Note that I had to modify the AT803x PHY driver as it would stop working
> otherwise -- it made use of the reset GPIO for its own purposes...
> 
> Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
> Acked-by: Rob Herring <robh@kernel.org>
> Acked-by: Florian Fainelli <f.fainelli@gmail.com>

This is a new patch as far as PHYLIB is concerned, so not quite accurate
anymore. Thanks for picking that up, this looks good, with a few minor
things here and there.

> [geert: Propagate actual errors from fwnode_get_named_gpiod()]
> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
> ---
> This has gained a dependency on "[PATCH v2] of_mdio: Fix broken PHY IRQ
> in case of probe deferral"
> (https://www.spinics.net/lists/linux-renesas-soc/msg19442.html), as v3
> needs to propagate errors from of_mdiobus_register_phy() and
> of_mdiobus_register_device() [*].
> 
> v3:
>   - Fix fwnode_get_named_gpiod() call due to added parameters (which
>     allowed to eliminate the gpiod_direction_output() call),
>   - Undelete one blank line in the AT803x driver,
>   - Resolve rejects, refresh patch,
>   - Reword/reformat changelog,
>   - Take over from Sergei,
>   - Add Acked-by,
>   - Remove unneeded gpiod check, as gpiod_set_value() handles NULL fine,
>   - Handle fwnode_get_named_gpiod() errors correctly:
>       - -ENOENT is ignored (the GPIO is optional), and turned into NULL,
> 	which allowed to remove all later !IS_ERR() checks,
>       - Other errors (incl. -EPROBE_DEFER) are propagated [*],
> 
> v2:
>   - Reformat changelog,
>   - Resolve rejects, refresh patch.
> ---
>  Documentation/devicetree/bindings/net/phy.txt |  2 ++
>  drivers/net/phy/at803x.c                      | 18 +++------------
>  drivers/net/phy/mdio_bus.c                    |  4 ++++
>  drivers/net/phy/mdio_device.c                 | 26 +++++++++++++++++++--
>  drivers/net/phy/phy_device.c                  | 33 +++++++++++++++++++++++++--
>  drivers/of/of_mdio.c                          | 23 +++++++++++++++++++
>  include/linux/mdio.h                          |  3 +++
>  include/linux/phy.h                           |  5 ++++
>  8 files changed, 95 insertions(+), 19 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/net/phy.txt b/Documentation/devicetree/bindings/net/phy.txt
> index 77d0b2a61ffa96fc..c05479f5ac7cc837 100644
> --- a/Documentation/devicetree/bindings/net/phy.txt
> +++ b/Documentation/devicetree/bindings/net/phy.txt
> @@ -53,6 +53,8 @@ Optional Properties:
>    to ensure the integrated PHY is used. The absence of this property indicates
>    the muxers should be configured so that the external PHY is used.
>  
> +- reset-gpios: The GPIO phandle and specifier for the PHY reset signal.
> +
>  Example:
>  
>  ethernet-phy@0 {
> diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c
> index 5f93e6add56394f2..15b4560aeb5de759 100644
> --- a/drivers/net/phy/at803x.c
> +++ b/drivers/net/phy/at803x.c

You most certainly want to make the conversion of the at803x.c driver as
a separate patch, there is no reason why it should be folded within the
patch teaching PHYLIB about PHY reset through GPIOs. More on that below.

> @@ -71,7 +71,6 @@ MODULE_LICENSE("GPL");
>  
>  struct at803x_priv {
>  	bool phy_reset:1;
> -	struct gpio_desc *gpiod_reset;
>  };
>  
>  struct at803x_context {
> @@ -254,22 +253,11 @@ static int at803x_probe(struct phy_device *phydev)
>  {
>  	struct device *dev = &phydev->mdio.dev;
>  	struct at803x_priv *priv;
> -	struct gpio_desc *gpiod_reset;
>  
>  	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
>  	if (!priv)
>  		return -ENOMEM;
>  
> -	if (phydev->drv->phy_id != ATH8030_PHY_ID)
> -		goto does_not_require_reset_workaround;

We have lost that bit now, see below.

> -
> -	gpiod_reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
> -	if (IS_ERR(gpiod_reset))
> -		return PTR_ERR(gpiod_reset);
> -
> -	priv->gpiod_reset = gpiod_reset;
> -
> -does_not_require_reset_workaround:
>  	phydev->priv = priv;
>  
>  	return 0;
> @@ -343,14 +331,14 @@ static void at803x_link_change_notify(struct phy_device *phydev)
>  	 * cannot recover from by software.
>  	 */
>  	if (phydev->state == PHY_NOLINK) {
> -		if (priv->gpiod_reset && !priv->phy_reset) {
> +		if (phydev->mdio.reset && !priv->phy_reset) {

and phydev->drv->phy_id == ATH8030_PHY_ID, the workaround is not
applicable to all PHY devices.

>  			struct at803x_context context;
>  
>  			at803x_context_save(phydev, &context);
>  
> -			gpiod_set_value(priv->gpiod_reset, 1);
> +			phy_device_reset(phydev, 1);
>  			msleep(1);
> -			gpiod_set_value(priv->gpiod_reset, 0);
> +			phy_device_reset(phydev, 0);
>  			msleep(1);
>  
>  			at803x_context_restore(phydev, &context);
> diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
> index 2df7b62c1a36811e..da6e5366d641a416 100644
> --- a/drivers/net/phy/mdio_bus.c
> +++ b/drivers/net/phy/mdio_bus.c
> @@ -38,6 +38,7 @@
>  #include <linux/phy.h>
>  #include <linux/io.h>
>  #include <linux/uaccess.h>
> +#include <linux/gpio/consumer.h>
>  
>  #include <asm/irq.h>
>  
> @@ -420,6 +421,9 @@ void mdiobus_unregister(struct mii_bus *bus)
>  		if (!mdiodev)
>  			continue;
>  
> +		if (mdiodev->reset)
> +			gpiod_put(mdiodev->reset);
> +
>  		mdiodev->device_remove(mdiodev);
>  		mdiodev->device_free(mdiodev);
>  	}
> diff --git a/drivers/net/phy/mdio_device.c b/drivers/net/phy/mdio_device.c
> index e24f28924af8953d..6926db11ae888174 100644
> --- a/drivers/net/phy/mdio_device.c
> +++ b/drivers/net/phy/mdio_device.c
> @@ -12,6 +12,8 @@
>  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
>  
>  #include <linux/errno.h>
> +#include <linux/gpio.h>
> +#include <linux/gpio/consumer.h>
>  #include <linux/init.h>
>  #include <linux/interrupt.h>
>  #include <linux/kernel.h>
> @@ -114,6 +116,12 @@ void mdio_device_remove(struct mdio_device *mdiodev)
>  }
>  EXPORT_SYMBOL(mdio_device_remove);
>  
> +void mdio_device_reset(struct mdio_device *mdiodev, int value)
> +{
> +	gpiod_set_value(mdiodev->reset, value);
> +}
> +EXPORT_SYMBOL(mdio_device_reset);
> +
>  /**
>   * mdio_probe - probe an MDIO device
>   * @dev: device to probe
> @@ -128,9 +136,16 @@ static int mdio_probe(struct device *dev)
>  	struct mdio_driver *mdiodrv = to_mdio_driver(drv);
>  	int err = 0;
>  
> -	if (mdiodrv->probe)
> +	if (mdiodrv->probe) {
> +		/* Deassert the reset signal */
> +		mdio_device_reset(mdiodev, 0);
> +
>  		err = mdiodrv->probe(mdiodev);
>  
> +		/* Assert the reset signal */
> +		mdio_device_reset(mdiodev, 1);

Really? Don't you want to do that only if err is non zero?

> +	}
> +
>  	return err;
>  }
>  
> @@ -140,9 +155,16 @@ static int mdio_remove(struct device *dev)
>  	struct device_driver *drv = mdiodev->dev.driver;
>  	struct mdio_driver *mdiodrv = to_mdio_driver(drv);
>  
> -	if (mdiodrv->remove)
> +	if (mdiodrv->remove) {
> +		/* Deassert the reset signal */
> +		mdio_device_reset(mdiodev, 0);
> +

Why would that be necessary here? If we remove the driver, we probed it,
so we should already be de-asserted, no?

>  		mdiodrv->remove(mdiodev);
>  
> +		/* Assert the reset signal */
> +		mdio_device_reset(mdiodev, 1);
> +	}
> +
>  	return 0;
>  }
>  
> diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
> index 67f25ac29025c539..e694b0ecf780d096 100644
> --- a/drivers/net/phy/phy_device.c
> +++ b/drivers/net/phy/phy_device.c
> @@ -632,6 +632,9 @@ int phy_device_register(struct phy_device *phydev)
>  	if (err)
>  		return err;
>  
> +	/* Deassert the reset signal */
> +	phy_device_reset(phydev, 0);
> +
>  	/* Run all of the fixups for this PHY */
>  	err = phy_scan_fixups(phydev);
>  	if (err) {
> @@ -647,9 +650,15 @@ int phy_device_register(struct phy_device *phydev)
>  		goto out;
>  	}
>  
> +	/* Assert the reset signal */
> +	phy_device_reset(phydev, 1);

Same here, I don't think you can safely assert the PHY reset signal here
and have no side effects. I see the intent now, you want to keep it in
reset for as long as possible, possibly to minimize power consumption?
Depending on how the reset signal is wired and how the PHY HW is
designed, this may cause the PHY to lose all of the programming done,
probably not a good idea.

> +
>  	return 0;
>  
>   out:
> +	/* Assert the reset signal */
> +	phy_device_reset(phydev, 1);
> +
>  	mdiobus_unregister_device(&phydev->mdio);
>  	return err;
>  }
> @@ -849,6 +858,9 @@ int phy_init_hw(struct phy_device *phydev)
>  {
>  	int ret = 0;
>  
> +	/* Deassert the reset signal */
> +	phy_device_reset(phydev, 0);
> +
>  	if (!phydev->drv || !phydev->drv->config_init)
>  		return 0;
>  
> @@ -1126,6 +1138,9 @@ void phy_detach(struct phy_device *phydev)
>  	put_device(&phydev->mdio.dev);
>  	if (ndev_owner != bus->owner)
>  		module_put(bus->owner);
> +
> +	/* Assert the reset signal */
> +	phy_device_reset(phydev, 1);
>  }
>  EXPORT_SYMBOL(phy_detach);
>  
> @@ -1811,9 +1826,16 @@ static int phy_probe(struct device *dev)
>  	/* Set the state to READY by default */
>  	phydev->state = PHY_READY;
>  
> -	if (phydev->drv->probe)
> +	if (phydev->drv->probe) {
> +		/* Deassert the reset signal */
> +		phy_device_reset(phydev, 0);
> +
>  		err = phydev->drv->probe(phydev);
>  
> +		/* Assert the reset signal */
> +		phy_device_reset(phydev, 1);

Same as for the MDIO device probe, we can't do that unless we return non
zero from probe.

> +	}
> +
>  	mutex_unlock(&phydev->lock);
>  
>  	return err;
> @@ -1829,8 +1851,15 @@ static int phy_remove(struct device *dev)
>  	phydev->state = PHY_DOWN;
>  	mutex_unlock(&phydev->lock);
>  
> -	if (phydev->drv && phydev->drv->remove)
> +	if (phydev->drv && phydev->drv->remove) {
> +		/* Deassert the reset signal */
> +		phy_device_reset(phydev, 0);
> +
>  		phydev->drv->remove(phydev);
> +
> +		/* Assert the reset signal */
> +		phy_device_reset(phydev, 1);
> +	}
>  	phydev->drv = NULL;
>  
>  	return 0;
> diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c
> index 98258583abb0b405..3d044119c032d176 100644
> --- a/drivers/of/of_mdio.c
> +++ b/drivers/of/of_mdio.c
> @@ -47,6 +47,7 @@ static int of_get_phy_id(struct device_node *device, u32 *phy_id)
>  static int of_mdiobus_register_phy(struct mii_bus *mdio,
>  				    struct device_node *child, u32 addr)
>  {
> +	struct gpio_desc *gpiod;
>  	struct phy_device *phy;
>  	bool is_c45;
>  	int rc;
> @@ -55,10 +56,22 @@ static int of_mdiobus_register_phy(struct mii_bus *mdio,
>  	is_c45 = of_device_is_compatible(child,
>  					 "ethernet-phy-ieee802.3-c45");
>  
> +	/* Deassert the optional reset signal */
> +	gpiod = fwnode_get_named_gpiod(&child->fwnode, "reset-gpios", 0,
> +				       GPIOD_OUT_LOW, "PHY reset");
> +	if (PTR_ERR(gpiod) == -ENOENT)
> +		gpiod = NULL;
> +	else if (IS_ERR(gpiod))
> +		return PTR_ERR(gpiod);
> +
>  	if (!is_c45 && !of_get_phy_id(child, &phy_id))
>  		phy = phy_device_create(mdio, addr, phy_id, 0, NULL);
>  	else
>  		phy = get_phy_device(mdio, addr, is_c45);
> +
> +	/* Assert the reset signal again */
> +	gpiod_set_value(gpiod, 1);

You have a phy_device reference now, so why not call phy_device_reset()
directly here?

> +
>  	if (IS_ERR(phy))
>  		return PTR_ERR(phy);
>  
> @@ -81,6 +94,7 @@ static int of_mdiobus_register_phy(struct mii_bus *mdio,
>  	 * can be looked up later */
>  	of_node_get(child);
>  	phy->mdio.dev.of_node = child;
> +	phy->mdio.reset = gpiod;
>  
>  	/* All data is now stored in the phy struct;
>  	 * register it */
> @@ -100,6 +114,7 @@ static int of_mdiobus_register_device(struct mii_bus *mdio,
>  				      struct device_node *child, u32 addr)
>  {
>  	struct mdio_device *mdiodev;
> +	struct gpio_desc *gpiod;
>  	int rc;
>  
>  	mdiodev = mdio_device_create(mdio, addr);
> @@ -112,6 +127,14 @@ static int of_mdiobus_register_device(struct mii_bus *mdio,
>  	of_node_get(child);
>  	mdiodev->dev.of_node = child;
>  
> +	gpiod = fwnode_get_named_gpiod(&child->fwnode, "reset-gpios", 0,
> +				       GPIOD_ASIS, "PHY reset");
> +	if (PTR_ERR(gpiod) == -ENOENT)
> +		gpiod = NULL;
> +	else if (IS_ERR(gpiod))
> +		return PTR_ERR(gpiod);
> +	mdiodev->reset = gpiod;

There is some obvious and non desireable duplication of code between
"pure" mdio_device and phy_device paths here, can you factor this such
that there is a common function storing gpiod into a mdio_device's reset
member in both cases?

Also, there is some asymetry being exposed here, the GPIO descriptor is
acquired from OF specific code, but is released in the generic MDIO
device layer, can we find a way to make that symmetrical?
-- 
Florian

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

* Re: [PATCH v3 1/4] phylib: Add device reset GPIO support
  2017-10-20 18:11   ` Florian Fainelli
@ 2017-10-21 10:03     ` Sergei Shtylyov
  2017-10-21 10:08         ` Geert Uytterhoeven
  0 siblings, 1 reply; 15+ messages in thread
From: Sergei Shtylyov @ 2017-10-21 10:03 UTC (permalink / raw)
  To: Florian Fainelli, Geert Uytterhoeven, David S . Miller,
	Andrew Lunn, Simon Horman, Magnus Damm
  Cc: Rob Herring, Mark Rutland, Nicolas Ferre, netdev, devicetree,
	linux-renesas-soc, linux-kernel

Hello!

On 10/20/2017 9:11 PM, Florian Fainelli wrote:

>> From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
>>
>> The PHY devices sometimes do have their reset signal (maybe even power
>> supply?) tied to some GPIO and sometimes it also does happen that a boot
>> loader does not leave it deasserted. So far this issue has been attacked
>> from (as I believe) a wrong angle: by teaching the MAC driver to manipulate
>> the GPIO in question; that solution, when applied to the device trees, led
>> to adding the PHY reset GPIO properties to the MAC device node, with one
>> exception: Cadence MACB driver which could handle the "reset-gpios" prop
>> in a PHY device subnode. I believe that the correct approach is to teach
>> the 'phylib' to get the MDIO device reset GPIO from the device tree node
>> corresponding to this device -- which this patch is doing...
>>
>> Note that I had to modify the AT803x PHY driver as it would stop working
>> otherwise -- it made use of the reset GPIO for its own purposes...
>>
>> Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
>> Acked-by: Rob Herring <robh@kernel.org>
>> Acked-by: Florian Fainelli <f.fainelli@gmail.com>
> 
> This is a new patch as far as PHYLIB is concerned, so not quite accurate

    No, it is not new. No changes in logic since v2.

> anymore. Thanks for picking that up, this looks good, with a few minor
> things here and there.

>> [geert: Propagate actual errors from fwnode_get_named_gpiod()]
>> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
[...]
>> diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c
>> index 5f93e6add56394f2..15b4560aeb5de759 100644
>> --- a/drivers/net/phy/at803x.c
>> +++ b/drivers/net/phy/at803x.c
> 
> You most certainly want to make the conversion of the at803x.c driver as
> a separate patch, there is no reason why it should be folded within the

    No, it can't be a separate patch, otherwise I would have posted it 
separately. We cannot request the same GPIO 2 times.

> patch teaching PHYLIB about PHY reset through GPIOs. More on that below.
> 
[...]
>> @@ -254,22 +253,11 @@ static int at803x_probe(struct phy_device *phydev)
>>   {
>>   	struct device *dev = &phydev->mdio.dev;
>>   	struct at803x_priv *priv;
>> -	struct gpio_desc *gpiod_reset;
>>   
>>   	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
>>   	if (!priv)
>>   		return -ENOMEM;
>>   
>> -	if (phydev->drv->phy_id != ATH8030_PHY_ID)
>> -		goto does_not_require_reset_workaround;
> 
> We have lost that bit now, see below.

    Hm... I'm still seeing this in net-next.

>> -
>> -	gpiod_reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
>> -	if (IS_ERR(gpiod_reset))
>> -		return PTR_ERR(gpiod_reset);
>> -
>> -	priv->gpiod_reset = gpiod_reset;
>> -
>> -does_not_require_reset_workaround:
>>   	phydev->priv = priv;
>>   
>>   	return 0;
>> @@ -343,14 +331,14 @@ static void at803x_link_change_notify(struct phy_device *phydev)
>>   	 * cannot recover from by software.
>>   	 */
>>   	if (phydev->state == PHY_NOLINK) {
>> -		if (priv->gpiod_reset && !priv->phy_reset) {
>> +		if (phydev->mdio.reset && !priv->phy_reset) {
> 
> and phydev->drv->phy_id == ATH8030_PHY_ID, the workaround is not
> applicable to all PHY devices.

    You are clearly looking at an outdated tree -- this check was removed,
This method is populated only for 8030 instead.

[...]
>> diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c
>> index 98258583abb0b405..3d044119c032d176 100644
>> --- a/drivers/of/of_mdio.c
>> +++ b/drivers/of/of_mdio.c
[...]
>> @@ -55,10 +56,22 @@ static int of_mdiobus_register_phy(struct mii_bus *mdio,
>>   	is_c45 = of_device_is_compatible(child,
>>   					 "ethernet-phy-ieee802.3-c45");
>>   
>> +	/* Deassert the optional reset signal */
>> +	gpiod = fwnode_get_named_gpiod(&child->fwnode, "reset-gpios", 0,
>> +				       GPIOD_OUT_LOW, "PHY reset");
>> +	if (PTR_ERR(gpiod) == -ENOENT)
>> +		gpiod = NULL;
>> +	else if (IS_ERR(gpiod))
>> +		return PTR_ERR(gpiod);
>> +
>>   	if (!is_c45 && !of_get_phy_id(child, &phy_id))
>>   		phy = phy_device_create(mdio, addr, phy_id, 0, NULL);
>>   	else
>>   		phy = get_phy_device(mdio, addr, is_c45);
>> +
>> +	/* Assert the reset signal again */
>> +	gpiod_set_value(gpiod, 1);
> 
> You have a phy_device reference now, so why not call phy_device_reset()
> directly here?

    Symmetry, perhaps? (There was a gpiod_set_value(gpiod, 0) call above it...

[...]
>> @@ -112,6 +127,14 @@ static int of_mdiobus_register_device(struct mii_bus *mdio,
>>   	of_node_get(child);
>>   	mdiodev->dev.of_node = child;
>>   
>> +	gpiod = fwnode_get_named_gpiod(&child->fwnode, "reset-gpios", 0,
>> +				       GPIOD_ASIS, "PHY reset");
>> +	if (PTR_ERR(gpiod) == -ENOENT)
>> +		gpiod = NULL;
>> +	else if (IS_ERR(gpiod))
>> +		return PTR_ERR(gpiod);
>> +	mdiodev->reset = gpiod;
> 
> There is some obvious and non desireable duplication of code between
> "pure" mdio_device and phy_device paths here, can you factor this such
> that there is a common function storing gpiod into a mdio_device's reset
> member in both cases?
> 
> Also, there is some asymetry being exposed here, the GPIO descriptor is
> acquired from OF specific code, but is released in the generic MDIO
> device layer, can we find a way to make that symmetrical?

    Finally move of_mdio.c into drivers/net/phy/? ;-)

MBR, Sergei

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

* Re: [PATCH v3 1/4] phylib: Add device reset GPIO support
@ 2017-10-21 10:08         ` Geert Uytterhoeven
  0 siblings, 0 replies; 15+ messages in thread
From: Geert Uytterhoeven @ 2017-10-21 10:08 UTC (permalink / raw)
  To: Sergei Shtylyov
  Cc: Florian Fainelli, Geert Uytterhoeven, David S . Miller,
	Andrew Lunn, Simon Horman, Magnus Damm, Rob Herring,
	Mark Rutland, Nicolas Ferre, netdev, devicetree, Linux-Renesas,
	linux-kernel

On Sat, Oct 21, 2017 at 12:03 PM, Sergei Shtylyov
<sergei.shtylyov@cogentembedded.com> wrote:
> On 10/20/2017 9:11 PM, Florian Fainelli wrote:
>>> From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
>>> --- a/drivers/of/of_mdio.c
>>> +++ b/drivers/of/of_mdio.c
>
> [...]
>>>
>>> @@ -55,10 +56,22 @@ static int of_mdiobus_register_phy(struct mii_bus
>>> *mdio,
>>>         is_c45 = of_device_is_compatible(child,
>>>                                          "ethernet-phy-ieee802.3-c45");
>>>   +     /* Deassert the optional reset signal */
>>> +       gpiod = fwnode_get_named_gpiod(&child->fwnode, "reset-gpios", 0,
>>> +                                      GPIOD_OUT_LOW, "PHY reset");
>>> +       if (PTR_ERR(gpiod) == -ENOENT)
>>> +               gpiod = NULL;
>>> +       else if (IS_ERR(gpiod))
>>> +               return PTR_ERR(gpiod);
>>> +
>>>         if (!is_c45 && !of_get_phy_id(child, &phy_id))
>>>                 phy = phy_device_create(mdio, addr, phy_id, 0, NULL);
>>>         else
>>>                 phy = get_phy_device(mdio, addr, is_c45);
>>> +
>>> +       /* Assert the reset signal again */
>>> +       gpiod_set_value(gpiod, 1);
>>
>> You have a phy_device reference now, so why not call phy_device_reset()
>> directly here?
>
>    Symmetry, perhaps? (There was a gpiod_set_value(gpiod, 0) call above
> it...

Not only because of symmetry: the validity of the phy object hasn't been
checked yet (that's done immediately below), and phy->mdio.reset hasn't been
filled in yet.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

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

* Re: [PATCH v3 1/4] phylib: Add device reset GPIO support
@ 2017-10-21 10:08         ` Geert Uytterhoeven
  0 siblings, 0 replies; 15+ messages in thread
From: Geert Uytterhoeven @ 2017-10-21 10:08 UTC (permalink / raw)
  To: Sergei Shtylyov
  Cc: Florian Fainelli, Geert Uytterhoeven, David S . Miller,
	Andrew Lunn, Simon Horman, Magnus Damm, Rob Herring,
	Mark Rutland, Nicolas Ferre, netdev-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Linux-Renesas,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On Sat, Oct 21, 2017 at 12:03 PM, Sergei Shtylyov
<sergei.shtylyov-M4DtvfQ/ZS1MRgGoP+s0PdBPR1lH4CV8@public.gmane.org> wrote:
> On 10/20/2017 9:11 PM, Florian Fainelli wrote:
>>> From: Sergei Shtylyov <sergei.shtylyov-M4DtvfQ/ZS1MRgGoP+s0PdBPR1lH4CV8@public.gmane.org>
>>> --- a/drivers/of/of_mdio.c
>>> +++ b/drivers/of/of_mdio.c
>
> [...]
>>>
>>> @@ -55,10 +56,22 @@ static int of_mdiobus_register_phy(struct mii_bus
>>> *mdio,
>>>         is_c45 = of_device_is_compatible(child,
>>>                                          "ethernet-phy-ieee802.3-c45");
>>>   +     /* Deassert the optional reset signal */
>>> +       gpiod = fwnode_get_named_gpiod(&child->fwnode, "reset-gpios", 0,
>>> +                                      GPIOD_OUT_LOW, "PHY reset");
>>> +       if (PTR_ERR(gpiod) == -ENOENT)
>>> +               gpiod = NULL;
>>> +       else if (IS_ERR(gpiod))
>>> +               return PTR_ERR(gpiod);
>>> +
>>>         if (!is_c45 && !of_get_phy_id(child, &phy_id))
>>>                 phy = phy_device_create(mdio, addr, phy_id, 0, NULL);
>>>         else
>>>                 phy = get_phy_device(mdio, addr, is_c45);
>>> +
>>> +       /* Assert the reset signal again */
>>> +       gpiod_set_value(gpiod, 1);
>>
>> You have a phy_device reference now, so why not call phy_device_reset()
>> directly here?
>
>    Symmetry, perhaps? (There was a gpiod_set_value(gpiod, 0) call above
> it...

Not only because of symmetry: the validity of the phy object hasn't been
checked yet (that's done immediately below), and phy->mdio.reset hasn't been
filled in yet.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

end of thread, other threads:[~2017-10-21 10:08 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-10-20  8:14 [PATCH v3 0/4] Teach phylib hard-resetting devices Geert Uytterhoeven
2017-10-20  8:14 ` [PATCH v3 1/4] phylib: Add device reset GPIO support Geert Uytterhoeven
2017-10-20 10:56   ` Sergei Shtylyov
2017-10-20 18:11   ` Florian Fainelli
2017-10-21 10:03     ` Sergei Shtylyov
2017-10-21 10:08       ` Geert Uytterhoeven
2017-10-21 10:08         ` Geert Uytterhoeven
2017-10-20  8:14 ` [PATCH v3 2/4] macb: Kill PHY reset code Geert Uytterhoeven
2017-10-20 18:04   ` Florian Fainelli
2017-10-20 18:04     ` Florian Fainelli
2017-10-20  8:14 ` [PATCH v3 3/4] arm64: dts: renesas: salvator-common: Add EthernetAVB PHY reset Geert Uytterhoeven
2017-10-20  8:14   ` Geert Uytterhoeven
2017-10-20  8:14 ` [PATCH v3 4/4] arm64: dts: renesas: ulcb: " Geert Uytterhoeven
2017-10-20  9:05 ` [PATCH v3 0/4] Teach phylib hard-resetting devices Simon Horman
2017-10-20  9:05   ` Simon Horman

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.