Skip to content

Commit 4fd5f81

Browse files
buytenhLennert Buytenhek
authored andcommitted
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 <[email protected]> Acked-by: Andy Fleming <[email protected]>
1 parent 4ff3495 commit 4fd5f81

File tree

2 files changed

+50
-41
lines changed

2 files changed

+50
-41
lines changed

drivers/net/phy/mdio_bus.c

Lines changed: 48 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -60,49 +60,14 @@ int mdiobus_register(struct mii_bus *bus)
6060
bus->reset(bus);
6161

6262
for (i = 0; i < PHY_MAX_ADDR; i++) {
63-
struct phy_device *phydev;
63+
bus->phy_map[i] = NULL;
64+
if ((bus->phy_mask & (1 << i)) == 0) {
65+
struct phy_device *phydev;
6466

65-
if (bus->phy_mask & (1 << i)) {
66-
bus->phy_map[i] = NULL;
67-
continue;
67+
phydev = mdiobus_scan(bus, i);
68+
if (IS_ERR(phydev))
69+
err = PTR_ERR(phydev);
6870
}
69-
70-
phydev = get_phy_device(bus, i);
71-
72-
if (IS_ERR(phydev))
73-
return PTR_ERR(phydev);
74-
75-
/* There's a PHY at this address
76-
* We need to set:
77-
* 1) IRQ
78-
* 2) bus_id
79-
* 3) parent
80-
* 4) bus
81-
* 5) mii_bus
82-
* And, we need to register it */
83-
if (phydev) {
84-
phydev->irq = bus->irq[i];
85-
86-
phydev->dev.parent = bus->dev;
87-
phydev->dev.bus = &mdio_bus_type;
88-
snprintf(phydev->dev.bus_id, BUS_ID_SIZE, PHY_ID_FMT, bus->id, i);
89-
90-
phydev->bus = bus;
91-
92-
/* Run all of the fixups for this PHY */
93-
phy_scan_fixups(phydev);
94-
95-
err = device_register(&phydev->dev);
96-
97-
if (err) {
98-
printk(KERN_ERR "phy %d failed to register\n",
99-
i);
100-
phy_device_free(phydev);
101-
phydev = NULL;
102-
}
103-
}
104-
105-
bus->phy_map[i] = phydev;
10671
}
10772

10873
pr_info("%s: probed\n", bus->name);
@@ -122,6 +87,48 @@ void mdiobus_unregister(struct mii_bus *bus)
12287
}
12388
EXPORT_SYMBOL(mdiobus_unregister);
12489

90+
struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr)
91+
{
92+
struct phy_device *phydev;
93+
int err;
94+
95+
phydev = get_phy_device(bus, addr);
96+
if (IS_ERR(phydev) || phydev == NULL)
97+
return phydev;
98+
99+
/* There's a PHY at this address
100+
* We need to set:
101+
* 1) IRQ
102+
* 2) bus_id
103+
* 3) parent
104+
* 4) bus
105+
* 5) mii_bus
106+
* And, we need to register it */
107+
108+
phydev->irq = bus->irq != NULL ? bus->irq[addr] : PHY_POLL;
109+
110+
phydev->dev.parent = bus->dev;
111+
phydev->dev.bus = &mdio_bus_type;
112+
snprintf(phydev->dev.bus_id, BUS_ID_SIZE, PHY_ID_FMT, bus->id, addr);
113+
114+
phydev->bus = bus;
115+
116+
/* Run all of the fixups for this PHY */
117+
phy_scan_fixups(phydev);
118+
119+
err = device_register(&phydev->dev);
120+
if (err) {
121+
printk(KERN_ERR "phy %d failed to register\n", addr);
122+
phy_device_free(phydev);
123+
phydev = NULL;
124+
}
125+
126+
bus->phy_map[addr] = phydev;
127+
128+
return phydev;
129+
}
130+
EXPORT_SYMBOL(mdiobus_scan);
131+
125132
/**
126133
* mdio_bus_match - determine if given PHY driver supports the given PHY device
127134
* @dev: target PHY device

include/linux/phy.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,8 @@ int phy_start_aneg(struct phy_device *phydev);
410410

411411
int mdiobus_register(struct mii_bus *bus);
412412
void mdiobus_unregister(struct mii_bus *bus);
413+
struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr);
414+
413415
void phy_sanitize_settings(struct phy_device *phydev);
414416
int phy_stop_interrupts(struct phy_device *phydev);
415417
int phy_enable_interrupts(struct phy_device *phydev);

0 commit comments

Comments
 (0)