umc-bus.c 5.4 KB

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