Commit 97712f8f authored by David S. Miller's avatar David S. Miller

Merge branch 'mdio-fixes'

Saravana Kannan says:

====================
Clean up and fix error handling in mdio_mux_init()

This patch series was started due to -EPROBE_DEFER not being handled
correctly in mdio_mux_init() and causing issues [1]. While at it, I also
did some more error handling fixes and clean ups. The -EPROBE_DEFER fix is
the last patch.

Ideally, in the last patch we'd treat any error similar to -EPROBE_DEFER
but I'm not sure if it'll break any board/platforms where some child
mdiobus never successfully registers. If we treated all errors similar to
-EPROBE_DEFER, then none of the child mdiobus will work and that might be a
regression. If people are sure this is not a real case, then I can fix up
the last patch to always fail the entire mdio-mux init if any of the child
mdiobus registration fails.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents ed5d2937 7bd0cef5
...@@ -82,6 +82,17 @@ static int mdio_mux_write(struct mii_bus *bus, int phy_id, ...@@ -82,6 +82,17 @@ static int mdio_mux_write(struct mii_bus *bus, int phy_id,
static int parent_count; static int parent_count;
static void mdio_mux_uninit_children(struct mdio_mux_parent_bus *pb)
{
struct mdio_mux_child_bus *cb = pb->children;
while (cb) {
mdiobus_unregister(cb->mii_bus);
mdiobus_free(cb->mii_bus);
cb = cb->next;
}
}
int mdio_mux_init(struct device *dev, int mdio_mux_init(struct device *dev,
struct device_node *mux_node, struct device_node *mux_node,
int (*switch_fn)(int cur, int desired, void *data), int (*switch_fn)(int cur, int desired, void *data),
...@@ -144,7 +155,7 @@ int mdio_mux_init(struct device *dev, ...@@ -144,7 +155,7 @@ int mdio_mux_init(struct device *dev,
cb = devm_kzalloc(dev, sizeof(*cb), GFP_KERNEL); cb = devm_kzalloc(dev, sizeof(*cb), GFP_KERNEL);
if (!cb) { if (!cb) {
ret_val = -ENOMEM; ret_val = -ENOMEM;
continue; goto err_loop;
} }
cb->bus_number = v; cb->bus_number = v;
cb->parent = pb; cb->parent = pb;
...@@ -152,8 +163,7 @@ int mdio_mux_init(struct device *dev, ...@@ -152,8 +163,7 @@ int mdio_mux_init(struct device *dev,
cb->mii_bus = mdiobus_alloc(); cb->mii_bus = mdiobus_alloc();
if (!cb->mii_bus) { if (!cb->mii_bus) {
ret_val = -ENOMEM; ret_val = -ENOMEM;
devm_kfree(dev, cb); goto err_loop;
continue;
} }
cb->mii_bus->priv = cb; cb->mii_bus->priv = cb;
...@@ -165,11 +175,15 @@ int mdio_mux_init(struct device *dev, ...@@ -165,11 +175,15 @@ int mdio_mux_init(struct device *dev,
cb->mii_bus->write = mdio_mux_write; cb->mii_bus->write = mdio_mux_write;
r = of_mdiobus_register(cb->mii_bus, child_bus_node); r = of_mdiobus_register(cb->mii_bus, child_bus_node);
if (r) { if (r) {
mdiobus_free(cb->mii_bus);
if (r == -EPROBE_DEFER) {
ret_val = r;
goto err_loop;
}
devm_kfree(dev, cb);
dev_err(dev, dev_err(dev,
"Error: Failed to register MDIO bus for child %pOF\n", "Error: Failed to register MDIO bus for child %pOF\n",
child_bus_node); child_bus_node);
mdiobus_free(cb->mii_bus);
devm_kfree(dev, cb);
} else { } else {
cb->next = pb->children; cb->next = pb->children;
pb->children = cb; pb->children = cb;
...@@ -181,7 +195,10 @@ int mdio_mux_init(struct device *dev, ...@@ -181,7 +195,10 @@ int mdio_mux_init(struct device *dev,
} }
dev_err(dev, "Error: No acceptable child buses found\n"); dev_err(dev, "Error: No acceptable child buses found\n");
devm_kfree(dev, pb);
err_loop:
mdio_mux_uninit_children(pb);
of_node_put(child_bus_node);
err_pb_kz: err_pb_kz:
put_device(&parent_bus->dev); put_device(&parent_bus->dev);
err_parent_bus: err_parent_bus:
...@@ -193,14 +210,8 @@ EXPORT_SYMBOL_GPL(mdio_mux_init); ...@@ -193,14 +210,8 @@ EXPORT_SYMBOL_GPL(mdio_mux_init);
void mdio_mux_uninit(void *mux_handle) void mdio_mux_uninit(void *mux_handle)
{ {
struct mdio_mux_parent_bus *pb = mux_handle; struct mdio_mux_parent_bus *pb = mux_handle;
struct mdio_mux_child_bus *cb = pb->children;
while (cb) {
mdiobus_unregister(cb->mii_bus);
mdiobus_free(cb->mii_bus);
cb = cb->next;
}
mdio_mux_uninit_children(pb);
put_device(&pb->mii_bus->dev); put_device(&pb->mii_bus->dev);
} }
EXPORT_SYMBOL_GPL(mdio_mux_uninit); EXPORT_SYMBOL_GPL(mdio_mux_uninit);
......
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