bus_type.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. // SPDX-License-Identifier: GPL-2.0
  2. // Copyright(c) 2015-17 Intel Corporation.
  3. #include <linux/module.h>
  4. #include <linux/mod_devicetable.h>
  5. #include <linux/pm_domain.h>
  6. #include <linux/soundwire/sdw.h>
  7. #include <linux/soundwire/sdw_type.h>
  8. #include "bus.h"
  9. #include "sysfs_local.h"
  10. /**
  11. * sdw_get_device_id - find the matching SoundWire device id
  12. * @slave: SoundWire Slave Device
  13. * @drv: SoundWire Slave Driver
  14. *
  15. * The match is done by comparing the mfg_id and part_id from the
  16. * struct sdw_device_id.
  17. */
  18. static const struct sdw_device_id *
  19. sdw_get_device_id(struct sdw_slave *slave, struct sdw_driver *drv)
  20. {
  21. const struct sdw_device_id *id;
  22. for (id = drv->id_table; id && id->mfg_id; id++)
  23. if (slave->id.mfg_id == id->mfg_id &&
  24. slave->id.part_id == id->part_id &&
  25. (!id->sdw_version ||
  26. slave->id.sdw_version == id->sdw_version) &&
  27. (!id->class_id ||
  28. slave->id.class_id == id->class_id))
  29. return id;
  30. return NULL;
  31. }
  32. static int sdw_bus_match(struct device *dev, struct device_driver *ddrv)
  33. {
  34. struct sdw_slave *slave;
  35. struct sdw_driver *drv;
  36. int ret = 0;
  37. if (is_sdw_slave(dev)) {
  38. slave = dev_to_sdw_dev(dev);
  39. drv = drv_to_sdw_driver(ddrv);
  40. ret = !!sdw_get_device_id(slave, drv);
  41. }
  42. return ret;
  43. }
  44. int sdw_slave_modalias(const struct sdw_slave *slave, char *buf, size_t size)
  45. {
  46. /* modalias is sdw:m<mfg_id>p<part_id>v<version>c<class_id> */
  47. return snprintf(buf, size, "sdw:m%04Xp%04Xv%02Xc%02X\n",
  48. slave->id.mfg_id, slave->id.part_id,
  49. slave->id.sdw_version, slave->id.class_id);
  50. }
  51. int sdw_slave_uevent(struct device *dev, struct kobj_uevent_env *env)
  52. {
  53. struct sdw_slave *slave = dev_to_sdw_dev(dev);
  54. char modalias[32];
  55. sdw_slave_modalias(slave, modalias, sizeof(modalias));
  56. if (add_uevent_var(env, "MODALIAS=%s", modalias))
  57. return -ENOMEM;
  58. return 0;
  59. }
  60. struct bus_type sdw_bus_type = {
  61. .name = "soundwire",
  62. .match = sdw_bus_match,
  63. };
  64. EXPORT_SYMBOL_GPL(sdw_bus_type);
  65. static int sdw_drv_probe(struct device *dev)
  66. {
  67. struct sdw_slave *slave = dev_to_sdw_dev(dev);
  68. struct sdw_driver *drv = drv_to_sdw_driver(dev->driver);
  69. const struct sdw_device_id *id;
  70. int ret;
  71. /*
  72. * fw description is mandatory to bind
  73. */
  74. if (!dev->fwnode)
  75. return -ENODEV;
  76. if (!IS_ENABLED(CONFIG_ACPI) && !dev->of_node)
  77. return -ENODEV;
  78. id = sdw_get_device_id(slave, drv);
  79. if (!id)
  80. return -ENODEV;
  81. slave->ops = drv->ops;
  82. /*
  83. * attach to power domain but don't turn on (last arg)
  84. */
  85. ret = dev_pm_domain_attach(dev, false);
  86. if (ret)
  87. return ret;
  88. ret = drv->probe(slave, id);
  89. if (ret) {
  90. dev_err(dev, "Probe of %s failed: %d\n", drv->name, ret);
  91. dev_pm_domain_detach(dev, false);
  92. return ret;
  93. }
  94. /* device is probed so let's read the properties now */
  95. if (slave->ops && slave->ops->read_prop)
  96. slave->ops->read_prop(slave);
  97. /* init the sysfs as we have properties now */
  98. ret = sdw_slave_sysfs_init(slave);
  99. if (ret < 0)
  100. dev_warn(dev, "Slave sysfs init failed:%d\n", ret);
  101. /*
  102. * Check for valid clk_stop_timeout, use DisCo worst case value of
  103. * 300ms
  104. *
  105. * TODO: check the timeouts and driver removal case
  106. */
  107. if (slave->prop.clk_stop_timeout == 0)
  108. slave->prop.clk_stop_timeout = 300;
  109. slave->bus->clk_stop_timeout = max_t(u32, slave->bus->clk_stop_timeout,
  110. slave->prop.clk_stop_timeout);
  111. slave->probed = true;
  112. complete(&slave->probe_complete);
  113. dev_dbg(dev, "probe complete\n");
  114. return 0;
  115. }
  116. static int sdw_drv_remove(struct device *dev)
  117. {
  118. struct sdw_slave *slave = dev_to_sdw_dev(dev);
  119. struct sdw_driver *drv = drv_to_sdw_driver(dev->driver);
  120. int ret = 0;
  121. if (drv->remove)
  122. ret = drv->remove(slave);
  123. dev_pm_domain_detach(dev, false);
  124. return ret;
  125. }
  126. static void sdw_drv_shutdown(struct device *dev)
  127. {
  128. struct sdw_slave *slave = dev_to_sdw_dev(dev);
  129. struct sdw_driver *drv = drv_to_sdw_driver(dev->driver);
  130. if (drv->shutdown)
  131. drv->shutdown(slave);
  132. }
  133. /**
  134. * __sdw_register_driver() - register a SoundWire Slave driver
  135. * @drv: driver to register
  136. * @owner: owning module/driver
  137. *
  138. * Return: zero on success, else a negative error code.
  139. */
  140. int __sdw_register_driver(struct sdw_driver *drv, struct module *owner)
  141. {
  142. drv->driver.bus = &sdw_bus_type;
  143. if (!drv->probe) {
  144. pr_err("driver %s didn't provide SDW probe routine\n",
  145. drv->name);
  146. return -EINVAL;
  147. }
  148. drv->driver.owner = owner;
  149. drv->driver.probe = sdw_drv_probe;
  150. if (drv->remove)
  151. drv->driver.remove = sdw_drv_remove;
  152. if (drv->shutdown)
  153. drv->driver.shutdown = sdw_drv_shutdown;
  154. return driver_register(&drv->driver);
  155. }
  156. EXPORT_SYMBOL_GPL(__sdw_register_driver);
  157. /**
  158. * sdw_unregister_driver() - unregisters the SoundWire Slave driver
  159. * @drv: driver to unregister
  160. */
  161. void sdw_unregister_driver(struct sdw_driver *drv)
  162. {
  163. driver_unregister(&drv->driver);
  164. }
  165. EXPORT_SYMBOL_GPL(sdw_unregister_driver);
  166. static int __init sdw_bus_init(void)
  167. {
  168. sdw_debugfs_init();
  169. return bus_register(&sdw_bus_type);
  170. }
  171. static void __exit sdw_bus_exit(void)
  172. {
  173. sdw_debugfs_exit();
  174. bus_unregister(&sdw_bus_type);
  175. }
  176. postcore_initcall(sdw_bus_init);
  177. module_exit(sdw_bus_exit);
  178. MODULE_DESCRIPTION("SoundWire bus");
  179. MODULE_LICENSE("GPL v2");