umc-bus.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. /*
  2. * Bus for UWB Multi-interface Controller capabilities.
  3. *
  4. * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
  5. *
  6. * This file is released under the GNU GPL v2.
  7. */
  8. #include <linux/kernel.h>
  9. #include <linux/sysfs.h>
  10. #include <linux/workqueue.h>
  11. #include <linux/module.h>
  12. #include <linux/uwb/umc.h>
  13. #include <linux/pci.h>
  14. static int umc_bus_pre_reset_helper(struct device *dev, void *data)
  15. {
  16. int ret = 0;
  17. if (dev->driver) {
  18. struct umc_dev *umc = to_umc_dev(dev);
  19. struct umc_driver *umc_drv = to_umc_driver(dev->driver);
  20. if (umc_drv->pre_reset)
  21. ret = umc_drv->pre_reset(umc);
  22. else
  23. device_release_driver(dev);
  24. }
  25. return ret;
  26. }
  27. static int umc_bus_post_reset_helper(struct device *dev, void *data)
  28. {
  29. int ret = 0;
  30. if (dev->driver) {
  31. struct umc_dev *umc = to_umc_dev(dev);
  32. struct umc_driver *umc_drv = to_umc_driver(dev->driver);
  33. if (umc_drv->post_reset)
  34. ret = umc_drv->post_reset(umc);
  35. } else
  36. ret = device_attach(dev);
  37. return ret;
  38. }
  39. /**
  40. * umc_controller_reset - reset the whole UMC controller
  41. * @umc: the UMC device for the radio controller.
  42. *
  43. * Drivers or all capabilities of the controller will have their
  44. * pre_reset methods called or be unbound from their device. Then all
  45. * post_reset methods will be called or the drivers will be rebound.
  46. *
  47. * Radio controllers must provide pre_reset and post_reset methods and
  48. * reset the hardware in their start method.
  49. *
  50. * If this is called while a probe() or remove() is in progress it
  51. * will return -EAGAIN and not perform the reset.
  52. */
  53. int umc_controller_reset(struct umc_dev *umc)
  54. {
  55. struct device *parent = umc->dev.parent;
  56. int ret = 0;
  57. if (!device_trylock(parent))
  58. return -EAGAIN;
  59. ret = device_for_each_child(parent, parent, umc_bus_pre_reset_helper);
  60. if (ret >= 0)
  61. ret = device_for_each_child(parent, parent, umc_bus_post_reset_helper);
  62. device_unlock(parent);
  63. return ret;
  64. }
  65. EXPORT_SYMBOL_GPL(umc_controller_reset);
  66. /**
  67. * umc_match_pci_id - match a UMC driver to a UMC device's parent PCI device.
  68. * @umc_drv: umc driver with match_data pointing to a zero-terminated
  69. * table of pci_device_id's.
  70. * @umc: umc device whose parent is to be matched.
  71. */
  72. int umc_match_pci_id(struct umc_driver *umc_drv, struct umc_dev *umc)
  73. {
  74. const struct pci_device_id *id_table = umc_drv->match_data;
  75. struct pci_dev *pci;
  76. if (!dev_is_pci(umc->dev.parent))
  77. return 0;
  78. pci = to_pci_dev(umc->dev.parent);
  79. return pci_match_id(id_table, pci) != NULL;
  80. }
  81. EXPORT_SYMBOL_GPL(umc_match_pci_id);
  82. static int umc_bus_rescan_helper(struct device *dev, void *data)
  83. {
  84. int ret = 0;
  85. if (!dev->driver)
  86. ret = device_attach(dev);
  87. return ret;
  88. }
  89. static void umc_bus_rescan(struct device *parent)
  90. {
  91. int err;
  92. /*
  93. * We can't use bus_rescan_devices() here as it deadlocks when
  94. * it tries to retake the dev->parent semaphore.
  95. */
  96. err = device_for_each_child(parent, NULL, umc_bus_rescan_helper);
  97. if (err < 0)
  98. printk(KERN_WARNING "%s: rescan of bus failed: %d\n",
  99. KBUILD_MODNAME, err);
  100. }
  101. static int umc_bus_match(struct device *dev, struct device_driver *drv)
  102. {
  103. struct umc_dev *umc = to_umc_dev(dev);
  104. struct umc_driver *umc_driver = to_umc_driver(drv);
  105. if (umc->cap_id == umc_driver->cap_id) {
  106. if (umc_driver->match)
  107. return umc_driver->match(umc_driver, umc);
  108. else
  109. return 1;
  110. }
  111. return 0;
  112. }
  113. static int umc_device_probe(struct device *dev)
  114. {
  115. struct umc_dev *umc;
  116. struct umc_driver *umc_driver;
  117. int err;
  118. umc_driver = to_umc_driver(dev->driver);
  119. umc = to_umc_dev(dev);
  120. get_device(dev);
  121. err = umc_driver->probe(umc);
  122. if (err)
  123. put_device(dev);
  124. else
  125. umc_bus_rescan(dev->parent);
  126. return err;
  127. }
  128. static int umc_device_remove(struct device *dev)
  129. {
  130. struct umc_dev *umc;
  131. struct umc_driver *umc_driver;
  132. umc_driver = to_umc_driver(dev->driver);
  133. umc = to_umc_dev(dev);
  134. umc_driver->remove(umc);
  135. put_device(dev);
  136. return 0;
  137. }
  138. static ssize_t capability_id_show(struct device *dev, struct device_attribute *attr, char *buf)
  139. {
  140. struct umc_dev *umc = to_umc_dev(dev);
  141. return sprintf(buf, "0x%02x\n", umc->cap_id);
  142. }
  143. static DEVICE_ATTR_RO(capability_id);
  144. static ssize_t version_show(struct device *dev, struct device_attribute *attr, char *buf)
  145. {
  146. struct umc_dev *umc = to_umc_dev(dev);
  147. return sprintf(buf, "0x%04x\n", umc->version);
  148. }
  149. static DEVICE_ATTR_RO(version);
  150. static struct attribute *umc_dev_attrs[] = {
  151. &dev_attr_capability_id.attr,
  152. &dev_attr_version.attr,
  153. NULL,
  154. };
  155. ATTRIBUTE_GROUPS(umc_dev);
  156. struct bus_type umc_bus_type = {
  157. .name = "umc",
  158. .match = umc_bus_match,
  159. .probe = umc_device_probe,
  160. .remove = umc_device_remove,
  161. .dev_groups = umc_dev_groups,
  162. };
  163. EXPORT_SYMBOL_GPL(umc_bus_type);
  164. static int __init umc_bus_init(void)
  165. {
  166. return bus_register(&umc_bus_type);
  167. }
  168. module_init(umc_bus_init);
  169. static void __exit umc_bus_exit(void)
  170. {
  171. bus_unregister(&umc_bus_type);
  172. }
  173. module_exit(umc_bus_exit);
  174. MODULE_DESCRIPTION("UWB Multi-interface Controller capability bus");
  175. MODULE_AUTHOR("Cambridge Silicon Radio Ltd.");
  176. MODULE_LICENSE("GPL");