mirror of
https://github.com/torvalds/linux.git
synced 2024-12-29 14:21:47 +00:00
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: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
97712f8f91
@ -82,6 +82,17 @@ out:
|
||||
|
||||
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,
|
||||
struct device_node *mux_node,
|
||||
int (*switch_fn)(int cur, int desired, void *data),
|
||||
@ -144,7 +155,7 @@ int mdio_mux_init(struct device *dev,
|
||||
cb = devm_kzalloc(dev, sizeof(*cb), GFP_KERNEL);
|
||||
if (!cb) {
|
||||
ret_val = -ENOMEM;
|
||||
continue;
|
||||
goto err_loop;
|
||||
}
|
||||
cb->bus_number = v;
|
||||
cb->parent = pb;
|
||||
@ -152,8 +163,7 @@ int mdio_mux_init(struct device *dev,
|
||||
cb->mii_bus = mdiobus_alloc();
|
||||
if (!cb->mii_bus) {
|
||||
ret_val = -ENOMEM;
|
||||
devm_kfree(dev, cb);
|
||||
continue;
|
||||
goto err_loop;
|
||||
}
|
||||
cb->mii_bus->priv = cb;
|
||||
|
||||
@ -165,11 +175,15 @@ int mdio_mux_init(struct device *dev,
|
||||
cb->mii_bus->write = mdio_mux_write;
|
||||
r = of_mdiobus_register(cb->mii_bus, child_bus_node);
|
||||
if (r) {
|
||||
mdiobus_free(cb->mii_bus);
|
||||
if (r == -EPROBE_DEFER) {
|
||||
ret_val = r;
|
||||
goto err_loop;
|
||||
}
|
||||
devm_kfree(dev, cb);
|
||||
dev_err(dev,
|
||||
"Error: Failed to register MDIO bus for child %pOF\n",
|
||||
child_bus_node);
|
||||
mdiobus_free(cb->mii_bus);
|
||||
devm_kfree(dev, cb);
|
||||
} else {
|
||||
cb->next = pb->children;
|
||||
pb->children = cb;
|
||||
@ -181,7 +195,10 @@ int mdio_mux_init(struct device *dev,
|
||||
}
|
||||
|
||||
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:
|
||||
put_device(&parent_bus->dev);
|
||||
err_parent_bus:
|
||||
@ -193,14 +210,8 @@ EXPORT_SYMBOL_GPL(mdio_mux_init);
|
||||
void mdio_mux_uninit(void *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);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mdio_mux_uninit);
|
||||
|
Loading…
Reference in New Issue
Block a user