bus.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (C) 2021 ARM Ltd.
  4. */
  5. #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  6. #include <linux/arm_ffa.h>
  7. #include <linux/device.h>
  8. #include <linux/fs.h>
  9. #include <linux/kernel.h>
  10. #include <linux/module.h>
  11. #include <linux/slab.h>
  12. #include <linux/types.h>
  13. #include "common.h"
  14. static DEFINE_IDA(ffa_bus_id);
  15. static int ffa_device_match(struct device *dev, struct device_driver *drv)
  16. {
  17. const struct ffa_device_id *id_table;
  18. struct ffa_device *ffa_dev;
  19. id_table = to_ffa_driver(drv)->id_table;
  20. ffa_dev = to_ffa_dev(dev);
  21. while (!uuid_is_null(&id_table->uuid)) {
  22. /*
  23. * FF-A v1.0 doesn't provide discovery of UUIDs, just the
  24. * partition IDs, so fetch the partitions IDs for this
  25. * id_table UUID and assign the UUID to the device if the
  26. * partition ID matches
  27. */
  28. if (uuid_is_null(&ffa_dev->uuid))
  29. ffa_device_match_uuid(ffa_dev, &id_table->uuid);
  30. if (uuid_equal(&ffa_dev->uuid, &id_table->uuid))
  31. return 1;
  32. id_table++;
  33. }
  34. return 0;
  35. }
  36. static int ffa_device_probe(struct device *dev)
  37. {
  38. struct ffa_driver *ffa_drv = to_ffa_driver(dev->driver);
  39. struct ffa_device *ffa_dev = to_ffa_dev(dev);
  40. return ffa_drv->probe(ffa_dev);
  41. }
  42. static void ffa_device_remove(struct device *dev)
  43. {
  44. struct ffa_driver *ffa_drv = to_ffa_driver(dev->driver);
  45. if (ffa_drv->remove)
  46. ffa_drv->remove(to_ffa_dev(dev));
  47. }
  48. static int ffa_device_uevent(struct device *dev, struct kobj_uevent_env *env)
  49. {
  50. struct ffa_device *ffa_dev = to_ffa_dev(dev);
  51. return add_uevent_var(env, "MODALIAS=arm_ffa:%04x:%pUb",
  52. ffa_dev->vm_id, &ffa_dev->uuid);
  53. }
  54. static ssize_t partition_id_show(struct device *dev,
  55. struct device_attribute *attr, char *buf)
  56. {
  57. struct ffa_device *ffa_dev = to_ffa_dev(dev);
  58. return sprintf(buf, "0x%04x\n", ffa_dev->vm_id);
  59. }
  60. static DEVICE_ATTR_RO(partition_id);
  61. static ssize_t uuid_show(struct device *dev, struct device_attribute *attr,
  62. char *buf)
  63. {
  64. struct ffa_device *ffa_dev = to_ffa_dev(dev);
  65. return sprintf(buf, "%pUb\n", &ffa_dev->uuid);
  66. }
  67. static DEVICE_ATTR_RO(uuid);
  68. static struct attribute *ffa_device_attributes_attrs[] = {
  69. &dev_attr_partition_id.attr,
  70. &dev_attr_uuid.attr,
  71. NULL,
  72. };
  73. ATTRIBUTE_GROUPS(ffa_device_attributes);
  74. struct bus_type ffa_bus_type = {
  75. .name = "arm_ffa",
  76. .match = ffa_device_match,
  77. .probe = ffa_device_probe,
  78. .remove = ffa_device_remove,
  79. .uevent = ffa_device_uevent,
  80. .dev_groups = ffa_device_attributes_groups,
  81. };
  82. EXPORT_SYMBOL_GPL(ffa_bus_type);
  83. int ffa_driver_register(struct ffa_driver *driver, struct module *owner,
  84. const char *mod_name)
  85. {
  86. int ret;
  87. if (!driver->probe)
  88. return -EINVAL;
  89. driver->driver.bus = &ffa_bus_type;
  90. driver->driver.name = driver->name;
  91. driver->driver.owner = owner;
  92. driver->driver.mod_name = mod_name;
  93. ret = driver_register(&driver->driver);
  94. if (!ret)
  95. pr_debug("registered new ffa driver %s\n", driver->name);
  96. return ret;
  97. }
  98. EXPORT_SYMBOL_GPL(ffa_driver_register);
  99. void ffa_driver_unregister(struct ffa_driver *driver)
  100. {
  101. driver_unregister(&driver->driver);
  102. }
  103. EXPORT_SYMBOL_GPL(ffa_driver_unregister);
  104. static void ffa_release_device(struct device *dev)
  105. {
  106. struct ffa_device *ffa_dev = to_ffa_dev(dev);
  107. ida_free(&ffa_bus_id, ffa_dev->id);
  108. kfree(ffa_dev);
  109. }
  110. static int __ffa_devices_unregister(struct device *dev, void *data)
  111. {
  112. device_unregister(dev);
  113. return 0;
  114. }
  115. static void ffa_devices_unregister(void)
  116. {
  117. bus_for_each_dev(&ffa_bus_type, NULL, NULL,
  118. __ffa_devices_unregister);
  119. }
  120. bool ffa_device_is_valid(struct ffa_device *ffa_dev)
  121. {
  122. bool valid = false;
  123. struct device *dev = NULL;
  124. struct ffa_device *tmp_dev;
  125. do {
  126. dev = bus_find_next_device(&ffa_bus_type, dev);
  127. tmp_dev = to_ffa_dev(dev);
  128. if (tmp_dev == ffa_dev) {
  129. valid = true;
  130. break;
  131. }
  132. put_device(dev);
  133. } while (dev);
  134. put_device(dev);
  135. return valid;
  136. }
  137. struct ffa_device *ffa_device_register(const uuid_t *uuid, int vm_id,
  138. const struct ffa_ops *ops)
  139. {
  140. int id, ret;
  141. struct device *dev;
  142. struct ffa_device *ffa_dev;
  143. id = ida_alloc_min(&ffa_bus_id, 1, GFP_KERNEL);
  144. if (id < 0)
  145. return NULL;
  146. ffa_dev = kzalloc(sizeof(*ffa_dev), GFP_KERNEL);
  147. if (!ffa_dev) {
  148. ida_free(&ffa_bus_id, id);
  149. return NULL;
  150. }
  151. dev = &ffa_dev->dev;
  152. dev->bus = &ffa_bus_type;
  153. dev->release = ffa_release_device;
  154. dev_set_name(&ffa_dev->dev, "arm-ffa-%d", id);
  155. ffa_dev->id = id;
  156. ffa_dev->vm_id = vm_id;
  157. ffa_dev->ops = ops;
  158. uuid_copy(&ffa_dev->uuid, uuid);
  159. ret = device_register(&ffa_dev->dev);
  160. if (ret) {
  161. dev_err(dev, "unable to register device %s err=%d\n",
  162. dev_name(dev), ret);
  163. put_device(dev);
  164. return NULL;
  165. }
  166. return ffa_dev;
  167. }
  168. EXPORT_SYMBOL_GPL(ffa_device_register);
  169. void ffa_device_unregister(struct ffa_device *ffa_dev)
  170. {
  171. if (!ffa_dev)
  172. return;
  173. device_unregister(&ffa_dev->dev);
  174. }
  175. EXPORT_SYMBOL_GPL(ffa_device_unregister);
  176. int arm_ffa_bus_init(void)
  177. {
  178. return bus_register(&ffa_bus_type);
  179. }
  180. void arm_ffa_bus_exit(void)
  181. {
  182. ffa_devices_unregister();
  183. bus_unregister(&ffa_bus_type);
  184. ida_destroy(&ffa_bus_id);
  185. }