diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2015-01-06 15:06:39 +0100 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2015-01-06 15:11:59 +0100 |
commit | b2568de82d62c18fd5dc8affb0e4dc050403c498 (patch) | |
tree | 16f3e9b4805e6c6f777c90a0865b8d5cc0eb781f /drivers | |
parent | fec4b794499a628e534a45a3da82d9c0ed94561c (diff) | |
download | barebox-b2568de82d62c18fd5dc8affb0e4dc050403c498.tar.gz barebox-b2568de82d62c18fd5dc8affb0e4dc050403c498.tar.xz |
net: cpsw: ignore error on slave setup
The CPSW has two slaves. When one of them fails to setup continue
anyway with the other one. This fixes a crash in the beaglebone black
which only has one slave connected. The code doesn't find a phy on
the second slave and bails out, but the error path is broken: It frees
the private data structures which contains used resources.
Reported-by: Philippe Leduc <ledphilippe@gmail.com>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/cpsw.c | 29 |
1 files changed, 14 insertions, 15 deletions
diff --git a/drivers/net/cpsw.c b/drivers/net/cpsw.c index b6618ad675..799fac89a2 100644 --- a/drivers/net/cpsw.c +++ b/drivers/net/cpsw.c @@ -910,6 +910,16 @@ static int cpsw_slave_setup(struct cpsw_slave *slave, int slave_num, struct eth_device *edev = &slave->edev; struct device_d *dev = &slave->dev; int ret; + struct phy_device *phy; + + phy = mdiobus_scan(&priv->miibus, priv->slaves[slave_num].phy_id); + if (IS_ERR(phy)) + return PTR_ERR(phy); + + phy->dev.device_node = priv->slaves[slave_num].dev.device_node; + ret = phy_register_device(phy); + if (ret) + return ret; sprintf(dev->name, "cpsw-slave"); dev->id = slave->slave_num; @@ -1199,22 +1209,11 @@ int cpsw_probe(struct device_d *dev) mdiobus_register(&priv->miibus); for (i = 0; i < priv->num_slaves; i++) { - struct phy_device *phy; - - phy = mdiobus_scan(&priv->miibus, priv->slaves[i].phy_id); - if (IS_ERR(phy)) { - ret = PTR_ERR(phy); - goto out; - } - - phy->dev.device_node = priv->slaves[i].dev.device_node; - ret = phy_register_device(phy); - if (ret) - goto out; - ret = cpsw_slave_setup(&priv->slaves[i], i, priv); - if (ret) - goto out; + if (ret) { + dev_err(dev, "Failed to setup slave %d: %s\n", i, strerror(-ret)); + continue; + } } return 0; |