summaryrefslogtreecommitdiffstats
path: root/drivers/net/phy/mdio_bus.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/phy/mdio_bus.c')
-rw-r--r--drivers/net/phy/mdio_bus.c39
1 files changed, 27 insertions, 12 deletions
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index 536bda1..11adf6e 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -63,7 +63,9 @@ EXPORT_SYMBOL(mdiobus_alloc);
static void mdiobus_release(struct device *d)
{
struct mii_bus *bus = to_mii_bus(d);
- BUG_ON(bus->state != MDIOBUS_RELEASED);
+ BUG_ON(bus->state != MDIOBUS_RELEASED &&
+ /* for compatibility with error handling in drivers */
+ bus->state != MDIOBUS_ALLOCATED);
kfree(bus);
}
@@ -83,8 +85,7 @@ static struct class mdio_bus_class = {
*/
int mdiobus_register(struct mii_bus *bus)
{
- int i;
- int err = 0;
+ int i, err;
if (NULL == bus || NULL == bus->name ||
NULL == bus->read ||
@@ -97,7 +98,7 @@ int mdiobus_register(struct mii_bus *bus)
bus->dev.parent = bus->parent;
bus->dev.class = &mdio_bus_class;
bus->dev.groups = NULL;
- memcpy(bus->dev.bus_id, bus->id, MII_BUS_ID_SIZE);
+ dev_set_name(&bus->dev, bus->id);
err = device_register(&bus->dev);
if (err) {
@@ -105,8 +106,6 @@ int mdiobus_register(struct mii_bus *bus)
return -EINVAL;
}
- bus->state = MDIOBUS_REGISTERED;
-
mutex_init(&bus->mdio_lock);
if (bus->reset)
@@ -118,13 +117,23 @@ int mdiobus_register(struct mii_bus *bus)
struct phy_device *phydev;
phydev = mdiobus_scan(bus, i);
- if (IS_ERR(phydev))
+ if (IS_ERR(phydev)) {
err = PTR_ERR(phydev);
+ goto error;
+ }
}
}
+ bus->state = MDIOBUS_REGISTERED;
pr_info("%s: probed\n", bus->name);
+ return 0;
+error:
+ while (--i >= 0) {
+ if (bus->phy_map[i])
+ device_unregister(&bus->phy_map[i]->dev);
+ }
+ device_del(&bus->dev);
return err;
}
EXPORT_SYMBOL(mdiobus_register);
@@ -191,7 +200,7 @@ struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr)
phydev->dev.parent = bus->parent;
phydev->dev.bus = &mdio_bus_type;
- snprintf(phydev->dev.bus_id, BUS_ID_SIZE, PHY_ID_FMT, bus->id, addr);
+ dev_set_name(&phydev->dev, PHY_ID_FMT, bus->id, addr);
phydev->bus = bus;
@@ -284,9 +293,12 @@ static int mdio_bus_suspend(struct device * dev, pm_message_t state)
{
int ret = 0;
struct device_driver *drv = dev->driver;
+ struct phy_driver *phydrv = to_phy_driver(drv);
+ struct phy_device *phydev = to_phy_device(dev);
- if (drv && drv->suspend)
- ret = drv->suspend(dev, state);
+ if ((!device_may_wakeup(phydev->dev.parent)) &&
+ (phydrv && phydrv->suspend))
+ ret = phydrv->suspend(phydev);
return ret;
}
@@ -295,9 +307,12 @@ static int mdio_bus_resume(struct device * dev)
{
int ret = 0;
struct device_driver *drv = dev->driver;
+ struct phy_driver *phydrv = to_phy_driver(drv);
+ struct phy_device *phydev = to_phy_device(dev);
- if (drv && drv->resume)
- ret = drv->resume(dev);
+ if ((!device_may_wakeup(phydev->dev.parent)) &&
+ (phydrv && phydrv->resume))
+ ret = phydrv->resume(phydev);
return ret;
}
OpenPOWER on IntegriCloud