summaryrefslogtreecommitdiffstats
path: root/drivers/net/phy
diff options
context:
space:
mode:
authorLennert Buytenhek <buytenh@wantstofly.org>2008-08-26 13:08:46 +0200
committerLennert Buytenhek <buytenh@marvell.com>2008-09-19 05:13:54 +0200
commit4fd5f812c23c7deee6425f4a318e85c317cd1d6c (patch)
treec554d67d67921e66516d978afc58878286b02966 /drivers/net/phy
parentmv643xx_eth: enforce frequent hardware statistics polling (diff)
downloadlinux-4fd5f812c23c7deee6425f4a318e85c317cd1d6c.tar.xz
linux-4fd5f812c23c7deee6425f4a318e85c317cd1d6c.zip
phylib: allow incremental scanning of an mii bus
This patch splits the bus scanning code in mdiobus_register() off into a separate function, and makes this function available for calling from external code. This allows incrementally scanning an mii bus, e.g. as information about which addresses are 'safe' to scan becomes available. Signed-off-by: Lennert Buytenhek <buytenh@marvell.com> Acked-by: Andy Fleming <afleming@freescale.com>
Diffstat (limited to 'drivers/net/phy')
-rw-r--r--drivers/net/phy/mdio_bus.c89
1 files changed, 48 insertions, 41 deletions
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index 94e0b7ed76f1..e7508c10887c 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -60,49 +60,14 @@ int mdiobus_register(struct mii_bus *bus)
bus->reset(bus);
for (i = 0; i < PHY_MAX_ADDR; i++) {
- struct phy_device *phydev;
+ bus->phy_map[i] = NULL;
+ if ((bus->phy_mask & (1 << i)) == 0) {
+ struct phy_device *phydev;
- if (bus->phy_mask & (1 << i)) {
- bus->phy_map[i] = NULL;
- continue;
+ phydev = mdiobus_scan(bus, i);
+ if (IS_ERR(phydev))
+ err = PTR_ERR(phydev);
}
-
- phydev = get_phy_device(bus, i);
-
- if (IS_ERR(phydev))
- return PTR_ERR(phydev);
-
- /* There's a PHY at this address
- * We need to set:
- * 1) IRQ
- * 2) bus_id
- * 3) parent
- * 4) bus
- * 5) mii_bus
- * And, we need to register it */
- if (phydev) {
- phydev->irq = bus->irq[i];
-
- phydev->dev.parent = bus->dev;
- phydev->dev.bus = &mdio_bus_type;
- snprintf(phydev->dev.bus_id, BUS_ID_SIZE, PHY_ID_FMT, bus->id, i);
-
- phydev->bus = bus;
-
- /* Run all of the fixups for this PHY */
- phy_scan_fixups(phydev);
-
- err = device_register(&phydev->dev);
-
- if (err) {
- printk(KERN_ERR "phy %d failed to register\n",
- i);
- phy_device_free(phydev);
- phydev = NULL;
- }
- }
-
- bus->phy_map[i] = phydev;
}
pr_info("%s: probed\n", bus->name);
@@ -122,6 +87,48 @@ void mdiobus_unregister(struct mii_bus *bus)
}
EXPORT_SYMBOL(mdiobus_unregister);
+struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr)
+{
+ struct phy_device *phydev;
+ int err;
+
+ phydev = get_phy_device(bus, addr);
+ if (IS_ERR(phydev) || phydev == NULL)
+ return phydev;
+
+ /* There's a PHY at this address
+ * We need to set:
+ * 1) IRQ
+ * 2) bus_id
+ * 3) parent
+ * 4) bus
+ * 5) mii_bus
+ * And, we need to register it */
+
+ phydev->irq = bus->irq != NULL ? bus->irq[addr] : PHY_POLL;
+
+ phydev->dev.parent = bus->dev;
+ phydev->dev.bus = &mdio_bus_type;
+ snprintf(phydev->dev.bus_id, BUS_ID_SIZE, PHY_ID_FMT, bus->id, addr);
+
+ phydev->bus = bus;
+
+ /* Run all of the fixups for this PHY */
+ phy_scan_fixups(phydev);
+
+ err = device_register(&phydev->dev);
+ if (err) {
+ printk(KERN_ERR "phy %d failed to register\n", addr);
+ phy_device_free(phydev);
+ phydev = NULL;
+ }
+
+ bus->phy_map[addr] = phydev;
+
+ return phydev;
+}
+EXPORT_SYMBOL(mdiobus_scan);
+
/**
* mdio_bus_match - determine if given PHY driver supports the given PHY device
* @dev: target PHY device