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: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller 2020-06-26 13:40:18 -07:00
commit ab696fa70f
4 changed files with 54 additions and 53 deletions

View File

@ -8,32 +8,32 @@
#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/device.h>
#include <linux/errno.h>
#include <linux/etherdevice.h>
#include <linux/ethtool.h>
#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/of_device.h>
#include <linux/of_mdio.h>
#include <linux/of_gpio.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/reset.h>
#include <linux/skbuff.h>
#include <linux/spinlock.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/mii.h>
#include <linux/ethtool.h>
#include <linux/netdevice.h>
#include <linux/of_device.h>
#include <linux/of_gpio.h>
#include <linux/of_mdio.h>
#include <linux/phy.h>
#include <linux/io.h>
#include <linux/reset.h>
#include <linux/skbuff.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/string.h>
#include <linux/uaccess.h>
#include <linux/unistd.h>
#define CREATE_TRACE_POINTS
#include <trace/events/mdio.h>

View File

@ -6,6 +6,7 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
@ -20,7 +21,6 @@
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/unistd.h>
#include <linux/delay.h>
void mdio_device_free(struct mdio_device *mdiodev)
{
@ -150,10 +150,10 @@ static int mdio_probe(struct device *dev)
struct mdio_driver *mdiodrv = to_mdio_driver(drv);
int err = 0;
if (mdiodrv->probe) {
/* Deassert the reset signal */
mdio_device_reset(mdiodev, 0);
/* Deassert the reset signal */
mdio_device_reset(mdiodev, 0);
if (mdiodrv->probe) {
err = mdiodrv->probe(mdiodev);
if (err) {
/* Assert the reset signal */
@ -170,12 +170,11 @@ 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)
mdiodrv->remove(mdiodev);
/* Assert the reset signal */
mdio_device_reset(mdiodev, 1);
}
/* Assert the reset signal */
mdio_device_reset(mdiodev, 1);
return 0;
}

View File

@ -9,29 +9,29 @@
#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/bitmap.h>
#include <linux/delay.h>
#include <linux/netdevice.h>
#include <linux/errno.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/module.h>
#include <linux/mii.h>
#include <linux/ethtool.h>
#include <linux/bitmap.h>
#include <linux/netdevice.h>
#include <linux/phy.h>
#include <linux/phy_led_triggers.h>
#include <linux/sfp.h>
#include <linux/mdio.h>
#include <linux/io.h>
#include <linux/uaccess.h>
#include <linux/property.h>
#include <linux/sfp.h>
#include <linux/skbuff.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/uaccess.h>
#include <linux/unistd.h>
MODULE_DESCRIPTION("PHY library");
MODULE_AUTHOR("Andy Fleming");
@ -2846,16 +2846,13 @@ static int phy_probe(struct device *dev)
mutex_lock(&phydev->lock);
if (phydev->drv->probe) {
/* Deassert the reset signal */
phy_device_reset(phydev, 0);
/* Deassert the reset signal */
phy_device_reset(phydev, 0);
if (phydev->drv->probe) {
err = phydev->drv->probe(phydev);
if (err) {
/* Assert the reset signal */
phy_device_reset(phydev, 1);
if (err)
goto out;
}
}
/* Start out supporting everything. Eventually,
@ -2917,6 +2914,10 @@ static int phy_probe(struct device *dev)
phydev->state = PHY_READY;
out:
/* Assert the reset signal */
if (err)
phy_device_reset(phydev, 1);
mutex_unlock(&phydev->lock);
return err;
@ -2935,12 +2936,12 @@ static int phy_remove(struct device *dev)
sfp_bus_del_upstream(phydev->sfp_bus);
phydev->sfp_bus = NULL;
if (phydev->drv && phydev->drv->remove) {
if (phydev->drv && phydev->drv->remove)
phydev->drv->remove(phydev);
/* Assert the reset signal */
phy_device_reset(phydev, 1);
}
/* Assert the reset signal */
phy_device_reset(phydev, 1);
phydev->drv = NULL;
return 0;

View File

@ -18,6 +18,7 @@
struct gpio_desc;
struct mii_bus;
struct reset_control;
/* Multiple levels of nesting are possible. However typically this is
* limited to nested DSA like layer, a MUX layer, and the normal