summaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2015-05-28 08:27:02 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2015-05-28 08:27:02 +0200
commitf13f1c269ebffca25697deb420cce64b099d66b5 (patch)
tree7303f16dd2c4d3fb1b19a43231a9d00dade2f78e /drivers/net
parente8f4eaceddbdf7347584871f310dd6c785be9d1b (diff)
parent0706fd366faab8274d96662265ac8c14baf0762c (diff)
downloadbarebox-f13f1c269ebffca25697deb420cce64b099d66b5.tar.gz
barebox-f13f1c269ebffca25697deb420cce64b099d66b5.tar.xz
Merge branch 'pu/am335x'
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/cpsw.c44
-rw-r--r--drivers/net/phy/phy.c11
2 files changed, 50 insertions, 5 deletions
diff --git a/drivers/net/cpsw.c b/drivers/net/cpsw.c
index 76872546fd..c0db96bb53 100644
--- a/drivers/net/cpsw.c
+++ b/drivers/net/cpsw.c
@@ -916,20 +916,22 @@ static int cpsw_slave_setup(struct cpsw_slave *slave, int slave_num,
struct phy_device *phy;
phy = mdiobus_scan(&priv->miibus, priv->slaves[slave_num].phy_id);
- if (IS_ERR(phy))
- return PTR_ERR(phy);
+ if (IS_ERR(phy)) {
+ ret = PTR_ERR(phy);
+ goto err_out;
+ }
phy->dev.device_node = priv->slaves[slave_num].dev.device_node;
ret = phy_register_device(phy);
if (ret)
- return ret;
+ goto err_out;
sprintf(dev->name, "cpsw-slave");
dev->id = slave->slave_num;
dev->parent = priv->dev;
ret = register_device(dev);
if (ret)
- return ret;
+ goto err_register_dev;
dev_dbg(&slave->dev, "* %s\n", __func__);
@@ -948,7 +950,20 @@ static int cpsw_slave_setup(struct cpsw_slave *slave, int slave_num,
edev->set_ethaddr = cpsw_set_hwaddr;
edev->parent = dev;
- return eth_register(edev);
+ ret = eth_register(edev);
+ if (ret)
+ goto err_register_edev;
+
+ return 0;
+
+err_register_dev:
+ phy_unregister_device(phy);
+err_register_edev:
+ unregister_device(dev);
+err_out:
+ slave->slave_num = -1;
+
+ return ret;
}
struct cpsw_data {
@@ -1219,6 +1234,8 @@ int cpsw_probe(struct device_d *dev)
}
}
+ dev->priv = priv;
+
return 0;
out:
free(priv->slaves);
@@ -1227,6 +1244,22 @@ out:
return ret;
}
+static void cpsw_remove(struct device_d *dev)
+{
+ struct cpsw_priv *priv = dev->priv;
+ int i;
+
+ for (i = 0; i < priv->num_slaves; i++) {
+ struct cpsw_slave *slave = &priv->slaves[i];
+ if (slave->slave_num < 0)
+ continue;
+
+ eth_unregister(&slave->edev);
+ }
+
+ mdiobus_unregister(&priv->miibus);
+}
+
static __maybe_unused struct of_device_id cpsw_dt_ids[] = {
{
.compatible = "ti,cpsw",
@@ -1238,6 +1271,7 @@ static __maybe_unused struct of_device_id cpsw_dt_ids[] = {
static struct driver_d cpsw_driver = {
.name = "cpsw",
.probe = cpsw_probe,
+ .remove = cpsw_remove,
.of_compatible = DRV_OF_COMPAT(cpsw_dt_ids),
};
device_platform_driver(cpsw_driver);
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index f3dffca46e..edf5d03d94 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -272,6 +272,17 @@ int phy_register_device(struct phy_device *phydev)
return ret;
}
+void phy_unregister_device(struct phy_device *phydev)
+{
+ if (!phydev->registered)
+ return;
+
+ phydev->bus->phy_map[phydev->addr] = NULL;
+
+ unregister_device(&phydev->dev);
+ phydev->registered = 0;
+}
+
static struct phy_device *of_mdio_find_phy(struct eth_device *edev)
{
struct device_d *dev;