Commit ab696fa7 authored by David S. Miller's avatar David S. Miller

Merge branch 'net-phy-relax-PHY-and-MDIO-reset-handling'

Bartosz Golaszewski says:

====================
net: phy: relax PHY and MDIO reset handling

Previously these patches were submitted as part of a larger series[1]
but since the approach in it will have to be reworked I'm resending
the ones that were non-controversial and have been reviewed for upstream.

Florian suggested a better solution for managing multiple resets. While
I will definitely try to implement something at the driver model's bus
level (together with regulator support), the 'resets' and 'reset-gpios'
DT property is a stable ABI defined in mdio.yaml so improving its support
is in order as we'll have to stick with it anyway. Current implementation
contains an unnecessary limitation where drivers without probe() can't
define resets.

Changes from the previous version:
- order forward declarations in patch 4 alphabetically
- collect review tags

[1] https://lkml.org/lkml/2020/6/22/253
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 61b5cc20 96e26359
...@@ -8,32 +8,32 @@ ...@@ -8,32 +8,32 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/unistd.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/errno.h>
#include <linux/etherdevice.h>
#include <linux/ethtool.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/gpio/consumer.h> #include <linux/gpio/consumer.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/mii.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/of_device.h> #include <linux/of_device.h>
#include <linux/of_mdio.h>
#include <linux/of_gpio.h> #include <linux/of_gpio.h>
#include <linux/netdevice.h> #include <linux/of_mdio.h>
#include <linux/etherdevice.h> #include <linux/phy.h>
#include <linux/reset.h> #include <linux/reset.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/slab.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/mm.h> #include <linux/string.h>
#include <linux/module.h>
#include <linux/mii.h>
#include <linux/ethtool.h>
#include <linux/phy.h>
#include <linux/io.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <linux/unistd.h>
#define CREATE_TRACE_POINTS #define CREATE_TRACE_POINTS
#include <trace/events/mdio.h> #include <trace/events/mdio.h>
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/delay.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/gpio/consumer.h> #include <linux/gpio/consumer.h>
...@@ -20,7 +21,6 @@ ...@@ -20,7 +21,6 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/unistd.h> #include <linux/unistd.h>
#include <linux/delay.h>
void mdio_device_free(struct mdio_device *mdiodev) void mdio_device_free(struct mdio_device *mdiodev)
{ {
...@@ -150,10 +150,10 @@ static int mdio_probe(struct device *dev) ...@@ -150,10 +150,10 @@ static int mdio_probe(struct device *dev)
struct mdio_driver *mdiodrv = to_mdio_driver(drv); struct mdio_driver *mdiodrv = to_mdio_driver(drv);
int err = 0; int err = 0;
if (mdiodrv->probe) { /* Deassert the reset signal */
/* Deassert the reset signal */ mdio_device_reset(mdiodev, 0);
mdio_device_reset(mdiodev, 0);
if (mdiodrv->probe) {
err = mdiodrv->probe(mdiodev); err = mdiodrv->probe(mdiodev);
if (err) { if (err) {
/* Assert the reset signal */ /* Assert the reset signal */
...@@ -170,12 +170,11 @@ static int mdio_remove(struct device *dev) ...@@ -170,12 +170,11 @@ static int mdio_remove(struct device *dev)
struct device_driver *drv = mdiodev->dev.driver; struct device_driver *drv = mdiodev->dev.driver;
struct mdio_driver *mdiodrv = to_mdio_driver(drv); struct mdio_driver *mdiodrv = to_mdio_driver(drv);
if (mdiodrv->remove) { if (mdiodrv->remove)
mdiodrv->remove(mdiodev); mdiodrv->remove(mdiodev);
/* Assert the reset signal */ /* Assert the reset signal */
mdio_device_reset(mdiodev, 1); mdio_device_reset(mdiodev, 1);
}
return 0; return 0;
} }
......
...@@ -9,29 +9,29 @@ ...@@ -9,29 +9,29 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/kernel.h> #include <linux/bitmap.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/unistd.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/netdevice.h> #include <linux/errno.h>
#include <linux/etherdevice.h> #include <linux/etherdevice.h>
#include <linux/skbuff.h> #include <linux/ethtool.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/mdio.h>
#include <linux/mii.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/mii.h> #include <linux/netdevice.h>
#include <linux/ethtool.h>
#include <linux/bitmap.h>
#include <linux/phy.h> #include <linux/phy.h>
#include <linux/phy_led_triggers.h> #include <linux/phy_led_triggers.h>
#include <linux/property.h>
#include <linux/sfp.h> #include <linux/sfp.h>
#include <linux/mdio.h> #include <linux/skbuff.h>
#include <linux/io.h> #include <linux/slab.h>
#include <linux/string.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <linux/property.h> #include <linux/unistd.h>
MODULE_DESCRIPTION("PHY library"); MODULE_DESCRIPTION("PHY library");
MODULE_AUTHOR("Andy Fleming"); MODULE_AUTHOR("Andy Fleming");
...@@ -2846,16 +2846,13 @@ static int phy_probe(struct device *dev) ...@@ -2846,16 +2846,13 @@ static int phy_probe(struct device *dev)
mutex_lock(&phydev->lock); mutex_lock(&phydev->lock);
if (phydev->drv->probe) { /* Deassert the reset signal */
/* Deassert the reset signal */ phy_device_reset(phydev, 0);
phy_device_reset(phydev, 0);
if (phydev->drv->probe) {
err = phydev->drv->probe(phydev); err = phydev->drv->probe(phydev);
if (err) { if (err)
/* Assert the reset signal */
phy_device_reset(phydev, 1);
goto out; goto out;
}
} }
/* Start out supporting everything. Eventually, /* Start out supporting everything. Eventually,
...@@ -2917,6 +2914,10 @@ static int phy_probe(struct device *dev) ...@@ -2917,6 +2914,10 @@ static int phy_probe(struct device *dev)
phydev->state = PHY_READY; phydev->state = PHY_READY;
out: out:
/* Assert the reset signal */
if (err)
phy_device_reset(phydev, 1);
mutex_unlock(&phydev->lock); mutex_unlock(&phydev->lock);
return err; return err;
...@@ -2935,12 +2936,12 @@ static int phy_remove(struct device *dev) ...@@ -2935,12 +2936,12 @@ static int phy_remove(struct device *dev)
sfp_bus_del_upstream(phydev->sfp_bus); sfp_bus_del_upstream(phydev->sfp_bus);
phydev->sfp_bus = NULL; phydev->sfp_bus = NULL;
if (phydev->drv && phydev->drv->remove) { if (phydev->drv && phydev->drv->remove)
phydev->drv->remove(phydev); phydev->drv->remove(phydev);
/* Assert the reset signal */ /* Assert the reset signal */
phy_device_reset(phydev, 1); phy_device_reset(phydev, 1);
}
phydev->drv = NULL; phydev->drv = NULL;
return 0; return 0;
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
struct gpio_desc; struct gpio_desc;
struct mii_bus; struct mii_bus;
struct reset_control;
/* Multiple levels of nesting are possible. However typically this is /* Multiple levels of nesting are possible. However typically this is
* limited to nested DSA like layer, a MUX layer, and the normal * limited to nested DSA like layer, a MUX layer, and the normal
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment