]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
net: mdio: introduce a shutdown method to mdio device drivers
authorVladimir Oltean <vladimir.oltean@nxp.com>
Fri, 17 Sep 2021 13:34:32 +0000 (16:34 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 9 Oct 2021 12:11:03 +0000 (14:11 +0200)
[ Upstream commit cf9579976f724ad517cc15b7caadea728c7e245c ]

MDIO-attached devices might have interrupts and other things that might
need quiesced when we kexec into a new kernel. Things are even more
creepy when those interrupt lines are shared, and in that case it is
absolutely mandatory to disable all interrupt sources.

Moreover, MDIO devices might be DSA switches, and DSA needs its own
shutdown method to unlink from the DSA master, which is a new
requirement that appeared after commit 2f1e8ea726e9 ("net: dsa: link
interfaces with the DSA master to get rid of lockdep warnings").

So introduce a ->shutdown method in the MDIO device driver structure.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/net/phy/mdio_device.c
include/linux/mdio.h

index c924700cf37b5f4d5c31f48aa48a1cf185a8078e..922f0f8973b65f8657d7bb9e0d401494b7ce6b48 100644 (file)
@@ -176,6 +176,16 @@ static int mdio_remove(struct device *dev)
        return 0;
 }
 
+static void mdio_shutdown(struct device *dev)
+{
+       struct mdio_device *mdiodev = to_mdio_device(dev);
+       struct device_driver *drv = mdiodev->dev.driver;
+       struct mdio_driver *mdiodrv = to_mdio_driver(drv);
+
+       if (mdiodrv->shutdown)
+               mdiodrv->shutdown(mdiodev);
+}
+
 /**
  * mdio_driver_register - register an mdio_driver with the MDIO layer
  * @new_driver: new mdio_driver to register
@@ -190,6 +200,7 @@ int mdio_driver_register(struct mdio_driver *drv)
        mdiodrv->driver.bus = &mdio_bus_type;
        mdiodrv->driver.probe = mdio_probe;
        mdiodrv->driver.remove = mdio_remove;
+       mdiodrv->driver.shutdown = mdio_shutdown;
 
        retval = driver_register(&mdiodrv->driver);
        if (retval) {
index bfa7114167d71f897b0c25807a38d8f373aee3b9..85325e110a796824350ffe19f886cedd91bfd999 100644 (file)
@@ -66,6 +66,9 @@ struct mdio_driver {
 
        /* Clears up any memory if needed */
        void (*remove)(struct mdio_device *mdiodev);
+
+       /* Quiesces the device on system shutdown, turns off interrupts etc */
+       void (*shutdown)(struct mdio_device *mdiodev);
 };
 #define to_mdio_driver(d)                                              \
        container_of(to_mdio_common_driver(d), struct mdio_driver, mdiodrv)