iommu-sysfs.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * IOMMU sysfs class support
  4. *
  5. * Copyright (C) 2014 Red Hat, Inc. All rights reserved.
  6. * Author: Alex Williamson <alex.williamson@redhat.com>
  7. */
  8. #include <linux/device.h>
  9. #include <linux/iommu.h>
  10. #include <linux/init.h>
  11. #include <linux/slab.h>
  12. /*
  13. * We provide a common class "devices" group which initially has no attributes.
  14. * As devices are added to the IOMMU, we'll add links to the group.
  15. */
  16. static struct attribute *devices_attr[] = {
  17. NULL,
  18. };
  19. static const struct attribute_group devices_attr_group = {
  20. .name = "devices",
  21. .attrs = devices_attr,
  22. };
  23. static const struct attribute_group *dev_groups[] = {
  24. &devices_attr_group,
  25. NULL,
  26. };
  27. static void release_device(struct device *dev)
  28. {
  29. kfree(dev);
  30. }
  31. static struct class iommu_class = {
  32. .name = "iommu",
  33. .dev_release = release_device,
  34. .dev_groups = dev_groups,
  35. };
  36. static int __init iommu_dev_init(void)
  37. {
  38. return class_register(&iommu_class);
  39. }
  40. postcore_initcall(iommu_dev_init);
  41. /*
  42. * Init the struct device for the IOMMU. IOMMU specific attributes can
  43. * be provided as an attribute group, allowing a unique namespace per
  44. * IOMMU type.
  45. */
  46. int iommu_device_sysfs_add(struct iommu_device *iommu,
  47. struct device *parent,
  48. const struct attribute_group **groups,
  49. const char *fmt, ...)
  50. {
  51. va_list vargs;
  52. int ret;
  53. iommu->dev = kzalloc(sizeof(*iommu->dev), GFP_KERNEL);
  54. if (!iommu->dev)
  55. return -ENOMEM;
  56. device_initialize(iommu->dev);
  57. iommu->dev->class = &iommu_class;
  58. iommu->dev->parent = parent;
  59. iommu->dev->groups = groups;
  60. va_start(vargs, fmt);
  61. ret = kobject_set_name_vargs(&iommu->dev->kobj, fmt, vargs);
  62. va_end(vargs);
  63. if (ret)
  64. goto error;
  65. ret = device_add(iommu->dev);
  66. if (ret)
  67. goto error;
  68. dev_set_drvdata(iommu->dev, iommu);
  69. return 0;
  70. error:
  71. put_device(iommu->dev);
  72. return ret;
  73. }
  74. EXPORT_SYMBOL_GPL(iommu_device_sysfs_add);
  75. void iommu_device_sysfs_remove(struct iommu_device *iommu)
  76. {
  77. dev_set_drvdata(iommu->dev, NULL);
  78. device_unregister(iommu->dev);
  79. iommu->dev = NULL;
  80. }
  81. EXPORT_SYMBOL_GPL(iommu_device_sysfs_remove);
  82. /*
  83. * IOMMU drivers can indicate a device is managed by a given IOMMU using
  84. * this interface. A link to the device will be created in the "devices"
  85. * directory of the IOMMU device in sysfs and an "iommu" link will be
  86. * created under the linked device, pointing back at the IOMMU device.
  87. */
  88. int iommu_device_link(struct iommu_device *iommu, struct device *link)
  89. {
  90. int ret;
  91. if (!iommu || IS_ERR(iommu))
  92. return -ENODEV;
  93. ret = sysfs_add_link_to_group(&iommu->dev->kobj, "devices",
  94. &link->kobj, dev_name(link));
  95. if (ret)
  96. return ret;
  97. ret = sysfs_create_link_nowarn(&link->kobj, &iommu->dev->kobj, "iommu");
  98. if (ret)
  99. sysfs_remove_link_from_group(&iommu->dev->kobj, "devices",
  100. dev_name(link));
  101. return ret;
  102. }
  103. EXPORT_SYMBOL_GPL(iommu_device_link);
  104. void iommu_device_unlink(struct iommu_device *iommu, struct device *link)
  105. {
  106. if (!iommu || IS_ERR(iommu))
  107. return;
  108. sysfs_remove_link(&link->kobj, "iommu");
  109. sysfs_remove_link_from_group(&iommu->dev->kobj, "devices", dev_name(link));
  110. }
  111. EXPORT_SYMBOL_GPL(iommu_device_unlink);