aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/phy/mdio_bus.c29
-rw-r--r--drivers/net/phy/phy_device.c45
-rw-r--r--include/linux/phy.h1
3 files changed, 45 insertions, 30 deletions
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index b754020cbe75..bd4e8d72dc08 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -113,7 +113,6 @@ int mdiobus_register(struct mii_bus *bus)
113 bus->reset(bus); 113 bus->reset(bus);
114 114
115 for (i = 0; i < PHY_MAX_ADDR; i++) { 115 for (i = 0; i < PHY_MAX_ADDR; i++) {
116 bus->phy_map[i] = NULL;
117 if ((bus->phy_mask & (1 << i)) == 0) { 116 if ((bus->phy_mask & (1 << i)) == 0) {
118 struct phy_device *phydev; 117 struct phy_device *phydev;
119 118
@@ -150,6 +149,7 @@ void mdiobus_unregister(struct mii_bus *bus)
150 for (i = 0; i < PHY_MAX_ADDR; i++) { 149 for (i = 0; i < PHY_MAX_ADDR; i++) {
151 if (bus->phy_map[i]) 150 if (bus->phy_map[i])
152 device_unregister(&bus->phy_map[i]->dev); 151 device_unregister(&bus->phy_map[i]->dev);
152 bus->phy_map[i] = NULL;
153 } 153 }
154} 154}
155EXPORT_SYMBOL(mdiobus_unregister); 155EXPORT_SYMBOL(mdiobus_unregister);
@@ -188,35 +188,12 @@ struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr)
188 if (IS_ERR(phydev) || phydev == NULL) 188 if (IS_ERR(phydev) || phydev == NULL)
189 return phydev; 189 return phydev;
190 190
191 /* There's a PHY at this address 191 err = phy_device_register(phydev);
192 * We need to set:
193 * 1) IRQ
194 * 2) bus_id
195 * 3) parent
196 * 4) bus
197 * 5) mii_bus
198 * And, we need to register it */
199
200 phydev->irq = bus->irq != NULL ? bus->irq[addr] : PHY_POLL;
201
202 phydev->dev.parent = bus->parent;
203 phydev->dev.bus = &mdio_bus_type;
204 dev_set_name(&phydev->dev, PHY_ID_FMT, bus->id, addr);
205
206 phydev->bus = bus;
207
208 /* Run all of the fixups for this PHY */
209 phy_scan_fixups(phydev);
210
211 err = device_register(&phydev->dev);
212 if (err) { 192 if (err) {
213 printk(KERN_ERR "phy %d failed to register\n", addr);
214 phy_device_free(phydev); 193 phy_device_free(phydev);
215 phydev = NULL; 194 return NULL;
216 } 195 }
217 196
218 bus->phy_map[addr] = phydev;
219
220 return phydev; 197 return phydev;
221} 198}
222EXPORT_SYMBOL(mdiobus_scan); 199EXPORT_SYMBOL(mdiobus_scan);
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 0a06e4fd37d9..9352ca8fa2cc 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -39,20 +39,21 @@ MODULE_DESCRIPTION("PHY library");
39MODULE_AUTHOR("Andy Fleming"); 39MODULE_AUTHOR("Andy Fleming");
40MODULE_LICENSE("GPL"); 40MODULE_LICENSE("GPL");
41 41
42static struct phy_driver genphy_driver;
43extern int mdio_bus_init(void);
44extern void mdio_bus_exit(void);
45
46void phy_device_free(struct phy_device *phydev) 42void phy_device_free(struct phy_device *phydev)
47{ 43{
48 kfree(phydev); 44 kfree(phydev);
49} 45}
46EXPORT_SYMBOL(phy_device_free);
50 47
51static void phy_device_release(struct device *dev) 48static void phy_device_release(struct device *dev)
52{ 49{
53 phy_device_free(to_phy_device(dev)); 50 phy_device_free(to_phy_device(dev));
54} 51}
55 52
53static struct phy_driver genphy_driver;
54extern int mdio_bus_init(void);
55extern void mdio_bus_exit(void);
56
56static LIST_HEAD(phy_fixup_list); 57static LIST_HEAD(phy_fixup_list);
57static DEFINE_MUTEX(phy_fixup_lock); 58static DEFINE_MUTEX(phy_fixup_lock);
58 59
@@ -166,6 +167,10 @@ struct phy_device* phy_device_create(struct mii_bus *bus, int addr, int phy_id)
166 dev->addr = addr; 167 dev->addr = addr;
167 dev->phy_id = phy_id; 168 dev->phy_id = phy_id;
168 dev->bus = bus; 169 dev->bus = bus;
170 dev->dev.parent = bus->parent;
171 dev->dev.bus = &mdio_bus_type;
172 dev->irq = bus->irq != NULL ? bus->irq[addr] : PHY_POLL;
173 dev_set_name(&dev->dev, PHY_ID_FMT, bus->id, addr);
169 174
170 dev->state = PHY_DOWN; 175 dev->state = PHY_DOWN;
171 176
@@ -235,6 +240,38 @@ struct phy_device * get_phy_device(struct mii_bus *bus, int addr)
235 240
236 return dev; 241 return dev;
237} 242}
243EXPORT_SYMBOL(get_phy_device);
244
245/**
246 * phy_device_register - Register the phy device on the MDIO bus
247 * @phy_device: phy_device structure to be added to the MDIO bus
248 */
249int phy_device_register(struct phy_device *phydev)
250{
251 int err;
252
253 /* Don't register a phy if one is already registered at this
254 * address */
255 if (phydev->bus->phy_map[phydev->addr])
256 return -EINVAL;
257 phydev->bus->phy_map[phydev->addr] = phydev;
258
259 /* Run all of the fixups for this PHY */
260 phy_scan_fixups(phydev);
261
262 err = device_register(&phydev->dev);
263 if (err) {
264 pr_err("phy %d failed to register\n", phydev->addr);
265 goto out;
266 }
267
268 return 0;
269
270 out:
271 phydev->bus->phy_map[phydev->addr] = NULL;
272 return err;
273}
274EXPORT_SYMBOL(phy_device_register);
238 275
239/** 276/**
240 * phy_prepare_link - prepares the PHY layer to monitor link status 277 * phy_prepare_link - prepares the PHY layer to monitor link status
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 97e40cb6b588..bf0b5f112dc7 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -444,6 +444,7 @@ static inline int phy_write(struct phy_device *phydev, u16 regnum, u16 val)
444 444
445int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id); 445int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id);
446struct phy_device* get_phy_device(struct mii_bus *bus, int addr); 446struct phy_device* get_phy_device(struct mii_bus *bus, int addr);
447int phy_device_register(struct phy_device *phy);
447int phy_clear_interrupt(struct phy_device *phydev); 448int phy_clear_interrupt(struct phy_device *phydev);
448int phy_config_interrupt(struct phy_device *phydev, u32 interrupts); 449int phy_config_interrupt(struct phy_device *phydev, u32 interrupts);
449struct phy_device * phy_attach(struct net_device *dev, 450struct phy_device * phy_attach(struct net_device *dev,