aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGrant Likely <grant.likely@secretlab.ca>2009-04-25 08:52:51 -0400
committerDavid S. Miller <davem@davemloft.net>2009-04-27 05:53:46 -0400
commitfa94f6d93c5382810ff41f010f12ca8698fc775e (patch)
tree177e38a91f53221e0b15f8b5ed6b0ae66f6ffc52
parent4dea547fef1ba23f9d23f5e7f5218187a7dcf1b3 (diff)
phylib: add *_direct() variants of phy_connect and phy_attach functions
Add phy_connect_direct() and phy_attach_direct() functions so that drivers can use a pointer to the phy_device instead of trying to determine the phy's bus_id string. This patch is useful for OF device tree descriptions of phy devices where the driver doesn't need or know what the bus_id value in order to get a phy_device pointer. Signed-off-by: Grant Likely <grant.likely@secretlab.ca> Acked-by: Andy Fleming <afleming@freescale.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/phy/phy_device.c118
-rw-r--r--include/linux/phy.h5
2 files changed, 90 insertions, 33 deletions
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 9352ca8fa2cc..a2ece89622d6 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -292,6 +292,33 @@ void phy_prepare_link(struct phy_device *phydev,
292} 292}
293 293
294/** 294/**
295 * phy_connect_direct - connect an ethernet device to a specific phy_device
296 * @dev: the network device to connect
297 * @phydev: the pointer to the phy device
298 * @handler: callback function for state change notifications
299 * @flags: PHY device's dev_flags
300 * @interface: PHY device's interface
301 */
302int phy_connect_direct(struct net_device *dev, struct phy_device *phydev,
303 void (*handler)(struct net_device *), u32 flags,
304 phy_interface_t interface)
305{
306 int rc;
307
308 rc = phy_attach_direct(dev, phydev, flags, interface);
309 if (rc)
310 return rc;
311
312 phy_prepare_link(phydev, handler);
313 phy_start_machine(phydev, NULL);
314 if (phydev->irq > 0)
315 phy_start_interrupts(phydev);
316
317 return 0;
318}
319EXPORT_SYMBOL(phy_connect_direct);
320
321/**
295 * phy_connect - connect an ethernet device to a PHY device 322 * phy_connect - connect an ethernet device to a PHY device
296 * @dev: the network device to connect 323 * @dev: the network device to connect
297 * @bus_id: the id string of the PHY device to connect 324 * @bus_id: the id string of the PHY device to connect
@@ -312,18 +339,21 @@ struct phy_device * phy_connect(struct net_device *dev, const char *bus_id,
312 phy_interface_t interface) 339 phy_interface_t interface)
313{ 340{
314 struct phy_device *phydev; 341 struct phy_device *phydev;
342 struct device *d;
343 int rc;
315 344
316 phydev = phy_attach(dev, bus_id, flags, interface); 345 /* Search the list of PHY devices on the mdio bus for the
317 346 * PHY with the requested name */
318 if (IS_ERR(phydev)) 347 d = bus_find_device_by_name(&mdio_bus_type, NULL, bus_id);
319 return phydev; 348 if (!d) {
320 349 pr_err("PHY %s not found\n", bus_id);
321 phy_prepare_link(phydev, handler); 350 return ERR_PTR(-ENODEV);
322 351 }
323 phy_start_machine(phydev, NULL); 352 phydev = to_phy_device(d);
324 353
325 if (phydev->irq > 0) 354 rc = phy_connect_direct(dev, phydev, handler, flags, interface);
326 phy_start_interrupts(phydev); 355 if (rc)
356 return ERR_PTR(rc);
327 357
328 return phydev; 358 return phydev;
329} 359}
@@ -347,9 +377,9 @@ void phy_disconnect(struct phy_device *phydev)
347EXPORT_SYMBOL(phy_disconnect); 377EXPORT_SYMBOL(phy_disconnect);
348 378
349/** 379/**
350 * phy_attach - attach a network device to a particular PHY device 380 * phy_attach_direct - attach a network device to a given PHY device pointer
351 * @dev: network device to attach 381 * @dev: network device to attach
352 * @bus_id: PHY device to attach 382 * @phydev: Pointer to phy_device to attach
353 * @flags: PHY device's dev_flags 383 * @flags: PHY device's dev_flags
354 * @interface: PHY device's interface 384 * @interface: PHY device's interface
355 * 385 *
@@ -360,22 +390,10 @@ EXPORT_SYMBOL(phy_disconnect);
360 * the attaching device, and given a callback for link status 390 * the attaching device, and given a callback for link status
361 * change. The phy_device is returned to the attaching driver. 391 * change. The phy_device is returned to the attaching driver.
362 */ 392 */
363struct phy_device *phy_attach(struct net_device *dev, 393int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
364 const char *bus_id, u32 flags, phy_interface_t interface) 394 u32 flags, phy_interface_t interface)
365{ 395{
366 struct bus_type *bus = &mdio_bus_type; 396 struct device *d = &phydev->dev;
367 struct phy_device *phydev;
368 struct device *d;
369
370 /* Search the list of PHY devices on the mdio bus for the
371 * PHY with the requested name */
372 d = bus_find_device_by_name(bus, NULL, bus_id);
373 if (d) {
374 phydev = to_phy_device(d);
375 } else {
376 printk(KERN_ERR "%s not found\n", bus_id);
377 return ERR_PTR(-ENODEV);
378 }
379 397
380 /* Assume that if there is no driver, that it doesn't 398 /* Assume that if there is no driver, that it doesn't
381 * exist, and we should use the genphy driver. */ 399 * exist, and we should use the genphy driver. */
@@ -388,13 +406,12 @@ struct phy_device *phy_attach(struct net_device *dev,
388 err = device_bind_driver(d); 406 err = device_bind_driver(d);
389 407
390 if (err) 408 if (err)
391 return ERR_PTR(err); 409 return err;
392 } 410 }
393 411
394 if (phydev->attached_dev) { 412 if (phydev->attached_dev) {
395 printk(KERN_ERR "%s: %s already attached\n", 413 dev_err(&dev->dev, "PHY already attached\n");
396 dev->name, bus_id); 414 return -EBUSY;
397 return ERR_PTR(-EBUSY);
398 } 415 }
399 416
400 phydev->attached_dev = dev; 417 phydev->attached_dev = dev;
@@ -412,13 +429,48 @@ struct phy_device *phy_attach(struct net_device *dev,
412 err = phy_scan_fixups(phydev); 429 err = phy_scan_fixups(phydev);
413 430
414 if (err < 0) 431 if (err < 0)
415 return ERR_PTR(err); 432 return err;
416 433
417 err = phydev->drv->config_init(phydev); 434 err = phydev->drv->config_init(phydev);
418 435
419 if (err < 0) 436 if (err < 0)
420 return ERR_PTR(err); 437 return err;
438 }
439
440 return 0;
441}
442EXPORT_SYMBOL(phy_attach_direct);
443
444/**
445 * phy_attach - attach a network device to a particular PHY device
446 * @dev: network device to attach
447 * @bus_id: Bus ID of PHY device to attach
448 * @flags: PHY device's dev_flags
449 * @interface: PHY device's interface
450 *
451 * Description: Same as phy_attach_direct() except that a PHY bus_id
452 * string is passed instead of a pointer to a struct phy_device.
453 */
454struct phy_device *phy_attach(struct net_device *dev,
455 const char *bus_id, u32 flags, phy_interface_t interface)
456{
457 struct bus_type *bus = &mdio_bus_type;
458 struct phy_device *phydev;
459 struct device *d;
460 int rc;
461
462 /* Search the list of PHY devices on the mdio bus for the
463 * PHY with the requested name */
464 d = bus_find_device_by_name(bus, NULL, bus_id);
465 if (!d) {
466 pr_err("PHY %s not found\n", bus_id);
467 return ERR_PTR(-ENODEV);
421 } 468 }
469 phydev = to_phy_device(d);
470
471 rc = phy_attach_direct(dev, phydev, flags, interface);
472 if (rc)
473 return ERR_PTR(rc);
422 474
423 return phydev; 475 return phydev;
424} 476}
diff --git a/include/linux/phy.h b/include/linux/phy.h
index bf0b5f112dc7..c216e4e503b3 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -447,8 +447,13 @@ struct phy_device* get_phy_device(struct mii_bus *bus, int addr);
447int phy_device_register(struct phy_device *phy); 447int phy_device_register(struct phy_device *phy);
448int phy_clear_interrupt(struct phy_device *phydev); 448int phy_clear_interrupt(struct phy_device *phydev);
449int phy_config_interrupt(struct phy_device *phydev, u32 interrupts); 449int phy_config_interrupt(struct phy_device *phydev, u32 interrupts);
450int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
451 u32 flags, phy_interface_t interface);
450struct phy_device * phy_attach(struct net_device *dev, 452struct phy_device * phy_attach(struct net_device *dev,
451 const char *bus_id, u32 flags, phy_interface_t interface); 453 const char *bus_id, u32 flags, phy_interface_t interface);
454int phy_connect_direct(struct net_device *dev, struct phy_device *phydev,
455 void (*handler)(struct net_device *), u32 flags,
456 phy_interface_t interface);
452struct phy_device * phy_connect(struct net_device *dev, const char *bus_id, 457struct phy_device * phy_connect(struct net_device *dev, const char *bus_id,
453 void (*handler)(struct net_device *), u32 flags, 458 void (*handler)(struct net_device *), u32 flags,
454 phy_interface_t interface); 459 phy_interface_t interface);