Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+54 -53
+18 -18
drivers/net/phy/mdio_bus.c
··· 8 8 9 9 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 10 10 11 - #include <linux/kernel.h> 12 - #include <linux/string.h> 13 - #include <linux/errno.h> 14 - #include <linux/unistd.h> 15 - #include <linux/slab.h> 16 - #include <linux/interrupt.h> 17 - #include <linux/init.h> 18 11 #include <linux/delay.h> 19 12 #include <linux/device.h> 13 + #include <linux/errno.h> 14 + #include <linux/etherdevice.h> 15 + #include <linux/ethtool.h> 20 16 #include <linux/gpio.h> 21 17 #include <linux/gpio/consumer.h> 22 - #include <linux/of_device.h> 23 - #include <linux/of_mdio.h> 24 - #include <linux/of_gpio.h> 25 - #include <linux/netdevice.h> 26 - #include <linux/etherdevice.h> 27 - #include <linux/reset.h> 28 - #include <linux/skbuff.h> 29 - #include <linux/spinlock.h> 18 + #include <linux/init.h> 19 + #include <linux/interrupt.h> 20 + #include <linux/io.h> 21 + #include <linux/kernel.h> 22 + #include <linux/mii.h> 30 23 #include <linux/mm.h> 31 24 #include <linux/module.h> 32 - #include <linux/mii.h> 33 - #include <linux/ethtool.h> 25 + #include <linux/netdevice.h> 26 + #include <linux/of_device.h> 27 + #include <linux/of_gpio.h> 28 + #include <linux/of_mdio.h> 34 29 #include <linux/phy.h> 35 - #include <linux/io.h> 30 + #include <linux/reset.h> 31 + #include <linux/skbuff.h> 32 + #include <linux/slab.h> 33 + #include <linux/spinlock.h> 34 + #include <linux/string.h> 36 35 #include <linux/uaccess.h> 36 + #include <linux/unistd.h> 37 37 38 38 #define CREATE_TRACE_POINTS 39 39 #include <trace/events/mdio.h>
+7 -8
drivers/net/phy/mdio_device.c
··· 6 6 7 7 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 8 8 9 + #include <linux/delay.h> 9 10 #include <linux/errno.h> 10 11 #include <linux/gpio.h> 11 12 #include <linux/gpio/consumer.h> ··· 21 20 #include <linux/slab.h> 22 21 #include <linux/string.h> 23 22 #include <linux/unistd.h> 24 - #include <linux/delay.h> 25 23 26 24 void mdio_device_free(struct mdio_device *mdiodev) 27 25 { ··· 150 150 struct mdio_driver *mdiodrv = to_mdio_driver(drv); 151 151 int err = 0; 152 152 153 - if (mdiodrv->probe) { 154 - /* Deassert the reset signal */ 155 - mdio_device_reset(mdiodev, 0); 153 + /* Deassert the reset signal */ 154 + mdio_device_reset(mdiodev, 0); 156 155 156 + if (mdiodrv->probe) { 157 157 err = mdiodrv->probe(mdiodev); 158 158 if (err) { 159 159 /* Assert the reset signal */ ··· 170 170 struct device_driver *drv = mdiodev->dev.driver; 171 171 struct mdio_driver *mdiodrv = to_mdio_driver(drv); 172 172 173 - if (mdiodrv->remove) { 173 + if (mdiodrv->remove) 174 174 mdiodrv->remove(mdiodev); 175 175 176 - /* Assert the reset signal */ 177 - mdio_device_reset(mdiodev, 1); 178 - } 176 + /* Assert the reset signal */ 177 + mdio_device_reset(mdiodev, 1); 179 178 180 179 return 0; 181 180 }
+28 -27
drivers/net/phy/phy_device.c
··· 9 9 10 10 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 11 11 12 - #include <linux/kernel.h> 13 - #include <linux/string.h> 14 - #include <linux/errno.h> 15 - #include <linux/unistd.h> 16 - #include <linux/slab.h> 17 - #include <linux/interrupt.h> 18 - #include <linux/init.h> 12 + #include <linux/bitmap.h> 19 13 #include <linux/delay.h> 20 - #include <linux/netdevice.h> 14 + #include <linux/errno.h> 21 15 #include <linux/etherdevice.h> 22 - #include <linux/skbuff.h> 16 + #include <linux/ethtool.h> 17 + #include <linux/init.h> 18 + #include <linux/interrupt.h> 19 + #include <linux/io.h> 20 + #include <linux/kernel.h> 21 + #include <linux/mdio.h> 22 + #include <linux/mii.h> 23 23 #include <linux/mm.h> 24 24 #include <linux/module.h> 25 - #include <linux/mii.h> 26 - #include <linux/ethtool.h> 27 - #include <linux/bitmap.h> 25 + #include <linux/netdevice.h> 28 26 #include <linux/phy.h> 29 27 #include <linux/phy_led_triggers.h> 30 - #include <linux/sfp.h> 31 - #include <linux/mdio.h> 32 - #include <linux/io.h> 33 - #include <linux/uaccess.h> 34 28 #include <linux/property.h> 29 + #include <linux/sfp.h> 30 + #include <linux/skbuff.h> 31 + #include <linux/slab.h> 32 + #include <linux/string.h> 33 + #include <linux/uaccess.h> 34 + #include <linux/unistd.h> 35 35 36 36 MODULE_DESCRIPTION("PHY library"); 37 37 MODULE_AUTHOR("Andy Fleming"); ··· 2846 2846 2847 2847 mutex_lock(&phydev->lock); 2848 2848 2849 - if (phydev->drv->probe) { 2850 - /* Deassert the reset signal */ 2851 - phy_device_reset(phydev, 0); 2849 + /* Deassert the reset signal */ 2850 + phy_device_reset(phydev, 0); 2852 2851 2852 + if (phydev->drv->probe) { 2853 2853 err = phydev->drv->probe(phydev); 2854 - if (err) { 2855 - /* Assert the reset signal */ 2856 - phy_device_reset(phydev, 1); 2854 + if (err) 2857 2855 goto out; 2858 - } 2859 2856 } 2860 2857 2861 2858 /* Start out supporting everything. Eventually, ··· 2914 2917 phydev->state = PHY_READY; 2915 2918 2916 2919 out: 2920 + /* Assert the reset signal */ 2921 + if (err) 2922 + phy_device_reset(phydev, 1); 2923 + 2917 2924 mutex_unlock(&phydev->lock); 2918 2925 2919 2926 return err; ··· 2936 2935 sfp_bus_del_upstream(phydev->sfp_bus); 2937 2936 phydev->sfp_bus = NULL; 2938 2937 2939 - if (phydev->drv && phydev->drv->remove) { 2938 + if (phydev->drv && phydev->drv->remove) 2940 2939 phydev->drv->remove(phydev); 2941 2940 2942 - /* Assert the reset signal */ 2943 - phy_device_reset(phydev, 1); 2944 - } 2941 + /* Assert the reset signal */ 2942 + phy_device_reset(phydev, 1); 2943 + 2945 2944 phydev->drv = NULL; 2946 2945 2947 2946 return 0;
+1
include/linux/mdio.h
··· 18 18 19 19 struct gpio_desc; 20 20 struct mii_bus; 21 + struct reset_control; 21 22 22 23 /* Multiple levels of nesting are possible. However typically this is 23 24 * limited to nested DSA like layer, a MUX layer, and the normal