summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRussell King (Oracle) <rmk+kernel@armlinux.org.uk>2024-01-04 10:37:55 +0000
committerDavid S. Miller <davem@davemloft.net>2024-01-04 11:24:55 +0000
commit3b73a7b8ec3821928cfaf399da7876bc39a5cf78 (patch)
tree78653c7c78a8dd69394e82e0ac067e93ff06ebc3
parent0f2b21477988634ba7d813539f034d595f9501d7 (diff)
net: mdio_bus: add refcounting for fwnodes to mdiobus
Luiz Angelo Daros de Luca reports that the MDIO bus code maintains a reference to the DT node, but does not hold a refcount on the node. The simple solution to this is to add the necessary refcounting into the MDIO bus code for all users, ensuring that on registration, the refcount is incremented, and only dropped when the MDIO bus is released. Do this for fwnodes, so we not only fix this for DT, but also other types of firmware nodes as well. Reported-by: Luiz Angelo Daros de Luca <luizluca@gmail.com> Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/phy/mdio_bus.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index 6cf73c15635b..afbad1ad8683 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -193,6 +193,10 @@ static void mdiobus_release(struct device *d)
bus->state != MDIOBUS_ALLOCATED,
"%s: not in RELEASED or ALLOCATED state\n",
bus->id);
+
+ if (bus->state == MDIOBUS_RELEASED)
+ fwnode_handle_put(dev_fwnode(d));
+
kfree(bus);
}
@@ -684,6 +688,15 @@ int __mdiobus_register(struct mii_bus *bus, struct module *owner)
bus->dev.groups = NULL;
dev_set_name(&bus->dev, "%s", bus->id);
+ /* If the bus state is allocated, we're registering a fresh bus
+ * that may have a fwnode associated with it. Grab a reference
+ * to the fwnode. This will be dropped when the bus is released.
+ * If the bus was set to unregistered, it means that the bus was
+ * previously registered, and we've already grabbed a reference.
+ */
+ if (bus->state == MDIOBUS_ALLOCATED)
+ fwnode_handle_get(dev_fwnode(&bus->dev));
+
/* We need to set state to MDIOBUS_UNREGISTERED to correctly release
* the device in mdiobus_free()
*