mdio-boardinfo.c 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. /*
  2. * mdio-boardinfo - Collect pre-declarations for MDIO devices
  3. *
  4. * This program is free software; you can redistribute it and/or modify it
  5. * under the terms of the GNU General Public License as published by the
  6. * Free Software Foundation; either version 2 of the License, or (at your
  7. * option) any later version.
  8. */
  9. #include <linux/kernel.h>
  10. #include <linux/slab.h>
  11. #include <linux/export.h>
  12. #include <linux/mutex.h>
  13. #include <linux/list.h>
  14. #include "mdio-boardinfo.h"
  15. static LIST_HEAD(mdio_board_list);
  16. static DEFINE_MUTEX(mdio_board_lock);
  17. /**
  18. * mdiobus_setup_mdiodev_from_board_info - create and setup MDIO devices
  19. * from pre-collected board specific MDIO information
  20. * @mdiodev: MDIO device pointer
  21. * Context: can sleep
  22. */
  23. void mdiobus_setup_mdiodev_from_board_info(struct mii_bus *bus)
  24. {
  25. struct mdio_board_entry *be;
  26. struct mdio_device *mdiodev;
  27. struct mdio_board_info *bi;
  28. int ret;
  29. mutex_lock(&mdio_board_lock);
  30. list_for_each_entry(be, &mdio_board_list, list) {
  31. bi = &be->board_info;
  32. if (strcmp(bus->id, bi->bus_id))
  33. continue;
  34. mdiodev = mdio_device_create(bus, bi->mdio_addr);
  35. if (IS_ERR(mdiodev))
  36. continue;
  37. strncpy(mdiodev->modalias, bi->modalias,
  38. sizeof(mdiodev->modalias));
  39. mdiodev->bus_match = mdio_device_bus_match;
  40. mdiodev->dev.platform_data = (void *)bi->platform_data;
  41. ret = mdio_device_register(mdiodev);
  42. if (ret) {
  43. mdio_device_free(mdiodev);
  44. continue;
  45. }
  46. }
  47. mutex_unlock(&mdio_board_lock);
  48. }
  49. /**
  50. * mdio_register_board_info - register MDIO devices for a given board
  51. * @info: array of devices descriptors
  52. * @n: number of descriptors provided
  53. * Context: can sleep
  54. *
  55. * The board info passed can be marked with __initdata but be pointers
  56. * such as platform_data etc. are copied as-is
  57. */
  58. int mdiobus_register_board_info(const struct mdio_board_info *info,
  59. unsigned int n)
  60. {
  61. struct mdio_board_entry *be;
  62. unsigned int i;
  63. be = kcalloc(n, sizeof(*be), GFP_KERNEL);
  64. if (!be)
  65. return -ENOMEM;
  66. for (i = 0; i < n; i++, be++, info++) {
  67. memcpy(&be->board_info, info, sizeof(*info));
  68. mutex_lock(&mdio_board_lock);
  69. list_add_tail(&be->list, &mdio_board_list);
  70. mutex_unlock(&mdio_board_lock);
  71. }
  72. return 0;
  73. }