summaryrefslogtreecommitdiff
path: root/drivers/net/phy/mdio_bus.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-12-28 12:49:40 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2008-12-28 12:49:40 -0800
commit0191b625ca5a46206d2fb862bb08f36f2fcb3b31 (patch)
tree454d1842b1833d976da62abcbd5c47521ebe9bd7 /drivers/net/phy/mdio_bus.c
parent54a696bd07c14d3b1192d03ce7269bc59b45209a (diff)
parenteb56092fc168bf5af199d47af50c0d84a96db898 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1429 commits) net: Allow dependancies of FDDI & Tokenring to be modular. igb: Fix build warning when DCA is disabled. net: Fix warning fallout from recent NAPI interface changes. gro: Fix potential use after free sfc: If AN is enabled, always read speed/duplex from the AN advertising bits sfc: When disabling the NIC, close the device rather than unregistering it sfc: SFT9001: Add cable diagnostics sfc: Add support for multiple PHY self-tests sfc: Merge top-level functions for self-tests sfc: Clean up PHY mode management in loopback self-test sfc: Fix unreliable link detection in some loopback modes sfc: Generate unique names for per-NIC workqueues 802.3ad: use standard ethhdr instead of ad_header 802.3ad: generalize out mac address initializer 802.3ad: initialize ports LACPDU from const initializer 802.3ad: remove typedef around ad_system 802.3ad: turn ports is_individual into a bool 802.3ad: turn ports is_enabled into a bool 802.3ad: make ntt bool ixgbe: Fix set_ringparam in ixgbe to use the same memory pools. ... Fixed trivial IPv4/6 address printing conflicts in fs/cifs/connect.c due to the conversion to %pI (in this networking merge) and the addition of doing IPv6 addresses (from the earlier merge of CIFS).
Diffstat (limited to 'drivers/net/phy/mdio_bus.c')
-rw-r--r--drivers/net/phy/mdio_bus.c40
1 files changed, 27 insertions, 13 deletions
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index 289fc267edf3..11adf6ed4628 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) {
@@ -116,16 +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;
+ }
}
}
- if (!err)
- bus->state = MDIOBUS_REGISTERED;
-
+ 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);
@@ -192,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;
@@ -285,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;
}
@@ -296,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;
}