aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLennert Buytenhek <buytenh@wantstofly.org>2008-08-26 07:08:46 -0400
committerLennert Buytenhek <buytenh@marvell.com>2008-09-18 23:13:54 -0400
commit4fd5f812c23c7deee6425f4a318e85c317cd1d6c (patch)
treec554d67d67921e66516d978afc58878286b02966
parent4ff3495a51c7226376d8013c5742d1d5e54876a7 (diff)
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>
-rw-r--r--drivers/net/phy/mdio_bus.c89
-rw-r--r--include/linux/phy.h2
2 files changed, 50 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)
60 bus->reset(bus); 60 bus->reset(bus);
61 61
62 for (i = 0; i < PHY_MAX_ADDR; i++) { 62 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;
64 66
65 if (bus->phy_mask & (1 << i)) { 67 phydev = mdiobus_scan(bus, i);
66 bus->phy_map[i] = NULL; 68 if (IS_ERR(phydev))
67 continue; 69 err = PTR_ERR(phydev);
68 } 70 }
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;
106 } 71 }
107 72
108 pr_info("%s: probed\n", bus->name); 73 pr_info("%s: probed\n", bus->name);
@@ -122,6 +87,48 @@ void mdiobus_unregister(struct mii_bus *bus)
122} 87}
123EXPORT_SYMBOL(mdiobus_unregister); 88EXPORT_SYMBOL(mdiobus_unregister);
124 89
90struct 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}
130EXPORT_SYMBOL(mdiobus_scan);
131
125/** 132/**
126 * mdio_bus_match - determine if given PHY driver supports the given PHY device 133 * mdio_bus_match - determine if given PHY driver supports the given PHY device
127 * @dev: target PHY device 134 * @dev: target PHY device
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 7224c4099a28..5f170f5b1a30 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -410,6 +410,8 @@ int phy_start_aneg(struct phy_device *phydev);
410 410
411int mdiobus_register(struct mii_bus *bus); 411int mdiobus_register(struct mii_bus *bus);
412void mdiobus_unregister(struct mii_bus *bus); 412void mdiobus_unregister(struct mii_bus *bus);
413struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr);
414
413void phy_sanitize_settings(struct phy_device *phydev); 415void phy_sanitize_settings(struct phy_device *phydev);
414int phy_stop_interrupts(struct phy_device *phydev); 416int phy_stop_interrupts(struct phy_device *phydev);
415int phy_enable_interrupts(struct phy_device *phydev); 417int phy_enable_interrupts(struct phy_device *phydev);