intel_gt_sysfs.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. // SPDX-License-Identifier: MIT
  2. /*
  3. * Copyright © 2022 Intel Corporation
  4. */
  5. #include <drm/drm_device.h>
  6. #include <linux/device.h>
  7. #include <linux/kobject.h>
  8. #include <linux/printk.h>
  9. #include <linux/sysfs.h>
  10. #include "i915_drv.h"
  11. #include "i915_sysfs.h"
  12. #include "intel_gt.h"
  13. #include "intel_gt_print.h"
  14. #include "intel_gt_sysfs.h"
  15. #include "intel_gt_sysfs_pm.h"
  16. #include "intel_gt_types.h"
  17. #include "intel_rc6.h"
  18. bool is_object_gt(struct kobject *kobj)
  19. {
  20. return !strncmp(kobj->name, "gt", 2);
  21. }
  22. struct intel_gt *intel_gt_sysfs_get_drvdata(struct kobject *kobj,
  23. const char *name)
  24. {
  25. /*
  26. * We are interested at knowing from where the interface
  27. * has been called, whether it's called from gt/ or from
  28. * the parent directory.
  29. * From the interface position it depends also the value of
  30. * the private data.
  31. * If the interface is called from gt/ then private data is
  32. * of the "struct intel_gt *" type, otherwise it's * a
  33. * "struct drm_i915_private *" type.
  34. */
  35. if (!is_object_gt(kobj)) {
  36. struct device *dev = kobj_to_dev(kobj);
  37. struct drm_i915_private *i915 = kdev_minor_to_i915(dev);
  38. return to_gt(i915);
  39. }
  40. return kobj_to_gt(kobj);
  41. }
  42. static struct kobject *gt_get_parent_obj(struct intel_gt *gt)
  43. {
  44. return &gt->i915->drm.primary->kdev->kobj;
  45. }
  46. static ssize_t id_show(struct kobject *kobj,
  47. struct kobj_attribute *attr,
  48. char *buf)
  49. {
  50. struct intel_gt *gt = intel_gt_sysfs_get_drvdata(kobj, attr->attr.name);
  51. return sysfs_emit(buf, "%u\n", gt->info.id);
  52. }
  53. static struct kobj_attribute attr_id = __ATTR_RO(id);
  54. static struct attribute *id_attrs[] = {
  55. &attr_id.attr,
  56. NULL,
  57. };
  58. ATTRIBUTE_GROUPS(id);
  59. /* A kobject needs a release() method even if it does nothing */
  60. static void kobj_gt_release(struct kobject *kobj)
  61. {
  62. }
  63. static const struct kobj_type kobj_gt_type = {
  64. .release = kobj_gt_release,
  65. .sysfs_ops = &kobj_sysfs_ops,
  66. .default_groups = id_groups,
  67. };
  68. void intel_gt_sysfs_register(struct intel_gt *gt)
  69. {
  70. /*
  71. * We need to make things right with the
  72. * ABI compatibility. The files were originally
  73. * generated under the parent directory.
  74. *
  75. * We generate the files only for gt 0
  76. * to avoid duplicates.
  77. */
  78. if (gt_is_root(gt))
  79. intel_gt_sysfs_pm_init(gt, gt_get_parent_obj(gt));
  80. /* init and xfer ownership to sysfs tree */
  81. if (kobject_init_and_add(&gt->sysfs_gt, &kobj_gt_type,
  82. gt->i915->sysfs_gt, "gt%d", gt->info.id))
  83. goto exit_fail;
  84. gt->sysfs_defaults = kobject_create_and_add(".defaults", &gt->sysfs_gt);
  85. if (!gt->sysfs_defaults)
  86. goto exit_fail;
  87. intel_gt_sysfs_pm_init(gt, &gt->sysfs_gt);
  88. return;
  89. exit_fail:
  90. kobject_put(&gt->sysfs_gt);
  91. gt_warn(gt, "failed to initialize sysfs root\n");
  92. }
  93. void intel_gt_sysfs_unregister(struct intel_gt *gt)
  94. {
  95. kobject_put(gt->sysfs_defaults);
  96. kobject_put(&gt->sysfs_gt);
  97. }