mdio_device.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. /* Framework for MDIO devices, other than PHYs.
  2. *
  3. * Copyright (c) 2016 Andrew Lunn <andrew@lunn.ch>
  4. *
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms of the GNU General Public License as published by the
  7. * Free Software Foundation; either version 2 of the License, or (at your
  8. * option) any later version.
  9. *
  10. */
  11. #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  12. #include <linux/errno.h>
  13. #include <linux/init.h>
  14. #include <linux/interrupt.h>
  15. #include <linux/kernel.h>
  16. #include <linux/mdio.h>
  17. #include <linux/mii.h>
  18. #include <linux/module.h>
  19. #include <linux/phy.h>
  20. #include <linux/slab.h>
  21. #include <linux/string.h>
  22. #include <linux/unistd.h>
  23. void mdio_device_free(struct mdio_device *mdiodev)
  24. {
  25. put_device(&mdiodev->dev);
  26. }
  27. EXPORT_SYMBOL(mdio_device_free);
  28. static void mdio_device_release(struct device *dev)
  29. {
  30. kfree(to_mdio_device(dev));
  31. }
  32. int mdio_device_bus_match(struct device *dev, struct device_driver *drv)
  33. {
  34. struct mdio_device *mdiodev = to_mdio_device(dev);
  35. struct mdio_driver *mdiodrv = to_mdio_driver(drv);
  36. if (mdiodrv->mdiodrv.flags & MDIO_DEVICE_IS_PHY)
  37. return 0;
  38. return strcmp(mdiodev->modalias, drv->name) == 0;
  39. }
  40. struct mdio_device *mdio_device_create(struct mii_bus *bus, int addr)
  41. {
  42. struct mdio_device *mdiodev;
  43. /* We allocate the device, and initialize the default values */
  44. mdiodev = kzalloc(sizeof(*mdiodev), GFP_KERNEL);
  45. if (!mdiodev)
  46. return ERR_PTR(-ENOMEM);
  47. mdiodev->dev.release = mdio_device_release;
  48. mdiodev->dev.parent = &bus->dev;
  49. mdiodev->dev.bus = &mdio_bus_type;
  50. mdiodev->device_free = mdio_device_free;
  51. mdiodev->device_remove = mdio_device_remove;
  52. mdiodev->bus = bus;
  53. mdiodev->addr = addr;
  54. dev_set_name(&mdiodev->dev, PHY_ID_FMT, bus->id, addr);
  55. device_initialize(&mdiodev->dev);
  56. return mdiodev;
  57. }
  58. EXPORT_SYMBOL(mdio_device_create);
  59. /**
  60. * mdio_device_register - Register the mdio device on the MDIO bus
  61. * @mdiodev: mdio_device structure to be added to the MDIO bus
  62. */
  63. int mdio_device_register(struct mdio_device *mdiodev)
  64. {
  65. int err;
  66. dev_dbg(&mdiodev->dev, "mdio_device_register\n");
  67. err = mdiobus_register_device(mdiodev);
  68. if (err)
  69. return err;
  70. err = device_add(&mdiodev->dev);
  71. if (err) {
  72. pr_err("MDIO %d failed to add\n", mdiodev->addr);
  73. goto out;
  74. }
  75. return 0;
  76. out:
  77. mdiobus_unregister_device(mdiodev);
  78. return err;
  79. }
  80. EXPORT_SYMBOL(mdio_device_register);
  81. /**
  82. * mdio_device_remove - Remove a previously registered mdio device from the
  83. * MDIO bus
  84. * @mdiodev: mdio_device structure to remove
  85. *
  86. * This doesn't free the mdio_device itself, it merely reverses the effects
  87. * of mdio_device_register(). Use mdio_device_free() to free the device
  88. * after calling this function.
  89. */
  90. void mdio_device_remove(struct mdio_device *mdiodev)
  91. {
  92. device_del(&mdiodev->dev);
  93. mdiobus_unregister_device(mdiodev);
  94. }
  95. EXPORT_SYMBOL(mdio_device_remove);
  96. /**
  97. * mdio_probe - probe an MDIO device
  98. * @dev: device to probe
  99. *
  100. * Description: Take care of setting up the mdio_device structure
  101. * and calling the driver to probe the device.
  102. */
  103. static int mdio_probe(struct device *dev)
  104. {
  105. struct mdio_device *mdiodev = to_mdio_device(dev);
  106. struct device_driver *drv = mdiodev->dev.driver;
  107. struct mdio_driver *mdiodrv = to_mdio_driver(drv);
  108. int err = 0;
  109. if (mdiodrv->probe)
  110. err = mdiodrv->probe(mdiodev);
  111. return err;
  112. }
  113. static int mdio_remove(struct device *dev)
  114. {
  115. struct mdio_device *mdiodev = to_mdio_device(dev);
  116. struct device_driver *drv = mdiodev->dev.driver;
  117. struct mdio_driver *mdiodrv = to_mdio_driver(drv);
  118. if (mdiodrv->remove)
  119. mdiodrv->remove(mdiodev);
  120. return 0;
  121. }
  122. /**
  123. * mdio_driver_register - register an mdio_driver with the MDIO layer
  124. * @new_driver: new mdio_driver to register
  125. */
  126. int mdio_driver_register(struct mdio_driver *drv)
  127. {
  128. struct mdio_driver_common *mdiodrv = &drv->mdiodrv;
  129. int retval;
  130. pr_debug("mdio_driver_register: %s\n", mdiodrv->driver.name);
  131. mdiodrv->driver.bus = &mdio_bus_type;
  132. mdiodrv->driver.probe = mdio_probe;
  133. mdiodrv->driver.remove = mdio_remove;
  134. retval = driver_register(&mdiodrv->driver);
  135. if (retval) {
  136. pr_err("%s: Error %d in registering driver\n",
  137. mdiodrv->driver.name, retval);
  138. return retval;
  139. }
  140. return 0;
  141. }
  142. EXPORT_SYMBOL(mdio_driver_register);
  143. void mdio_driver_unregister(struct mdio_driver *drv)
  144. {
  145. struct mdio_driver_common *mdiodrv = &drv->mdiodrv;
  146. driver_unregister(&mdiodrv->driver);
  147. }
  148. EXPORT_SYMBOL(mdio_driver_unregister);