dio-driver.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. /*
  2. * DIO Driver Services
  3. *
  4. * Copyright (C) 2004 Jochen Friedrich
  5. *
  6. * Loosely based on drivers/pci/pci-driver.c and drivers/zorro/zorro-driver.c
  7. *
  8. * This file is subject to the terms and conditions of the GNU General Public
  9. * License. See the file COPYING in the main directory of this archive
  10. * for more details.
  11. */
  12. #include <linux/init.h>
  13. #include <linux/module.h>
  14. #include <linux/dio.h>
  15. /**
  16. * dio_match_device - Tell if a DIO device structure has a matching DIO device id structure
  17. * @ids: array of DIO device id structures to search in
  18. * @d: the DIO device structure to match against
  19. *
  20. * Used by a driver to check whether a DIO device present in the
  21. * system is in its list of supported devices. Returns the matching
  22. * dio_device_id structure or %NULL if there is no match.
  23. */
  24. static const struct dio_device_id *
  25. dio_match_device(const struct dio_device_id *ids,
  26. const struct dio_dev *d)
  27. {
  28. while (ids->id) {
  29. if (ids->id == DIO_WILDCARD)
  30. return ids;
  31. if (DIO_NEEDSSECID(ids->id & 0xff)) {
  32. if (ids->id == d->id)
  33. return ids;
  34. } else {
  35. if ((ids->id & 0xff) == (d->id & 0xff))
  36. return ids;
  37. }
  38. ids++;
  39. }
  40. return NULL;
  41. }
  42. static int dio_device_probe(struct device *dev)
  43. {
  44. int error = 0;
  45. struct dio_driver *drv = to_dio_driver(dev->driver);
  46. struct dio_dev *d = to_dio_dev(dev);
  47. if (!d->driver && drv->probe) {
  48. const struct dio_device_id *id;
  49. id = dio_match_device(drv->id_table, d);
  50. if (id)
  51. error = drv->probe(d, id);
  52. if (error >= 0) {
  53. d->driver = drv;
  54. error = 0;
  55. }
  56. }
  57. return error;
  58. }
  59. /**
  60. * dio_register_driver - register a new DIO driver
  61. * @drv: the driver structure to register
  62. *
  63. * Adds the driver structure to the list of registered drivers
  64. * Returns zero or a negative error value.
  65. */
  66. int dio_register_driver(struct dio_driver *drv)
  67. {
  68. /* initialize common driver fields */
  69. drv->driver.name = drv->name;
  70. drv->driver.bus = &dio_bus_type;
  71. /* register with core */
  72. return driver_register(&drv->driver);
  73. }
  74. /**
  75. * dio_unregister_driver - unregister a DIO driver
  76. * @drv: the driver structure to unregister
  77. *
  78. * Deletes the driver structure from the list of registered DIO drivers,
  79. * gives it a chance to clean up by calling its remove() function for
  80. * each device it was responsible for, and marks those devices as
  81. * driverless.
  82. */
  83. void dio_unregister_driver(struct dio_driver *drv)
  84. {
  85. driver_unregister(&drv->driver);
  86. }
  87. /**
  88. * dio_bus_match - Tell if a DIO device structure has a matching DIO device id structure
  89. * @dev: the DIO device structure to match against
  90. * @drv: the &device_driver that points to the array of DIO device id structures to search
  91. *
  92. * Used by the driver core to check whether a DIO device present in the
  93. * system is in a driver's list of supported devices. Returns 1 if supported,
  94. * and 0 if there is no match.
  95. */
  96. static int dio_bus_match(struct device *dev, struct device_driver *drv)
  97. {
  98. struct dio_dev *d = to_dio_dev(dev);
  99. struct dio_driver *dio_drv = to_dio_driver(drv);
  100. const struct dio_device_id *ids = dio_drv->id_table;
  101. if (!ids)
  102. return 0;
  103. return dio_match_device(ids, d) ? 1 : 0;
  104. }
  105. struct bus_type dio_bus_type = {
  106. .name = "dio",
  107. .match = dio_bus_match,
  108. .probe = dio_device_probe,
  109. };
  110. static int __init dio_driver_init(void)
  111. {
  112. return bus_register(&dio_bus_type);
  113. }
  114. postcore_initcall(dio_driver_init);
  115. EXPORT_SYMBOL(dio_register_driver);
  116. EXPORT_SYMBOL(dio_unregister_driver);
  117. EXPORT_SYMBOL(dio_bus_type);