i915_debugfs_params.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. // SPDX-License-Identifier: MIT
  2. /*
  3. * Copyright © 2019 Intel Corporation
  4. */
  5. #include <linux/kernel.h>
  6. #include <linux/debugfs.h>
  7. #include "i915_debugfs_params.h"
  8. #include "gt/intel_gt.h"
  9. #include "gt/uc/intel_guc.h"
  10. #include "i915_drv.h"
  11. #include "i915_params.h"
  12. #define MATCH_DEBUGFS_NODE_NAME(_file, _name) \
  13. (strcmp((_file)->f_path.dentry->d_name.name, (_name)) == 0)
  14. #define GET_I915(i915, name, ptr) \
  15. do { \
  16. struct i915_params *params; \
  17. params = container_of(((void *)(ptr)), typeof(*params), name); \
  18. (i915) = container_of(params, typeof(*(i915)), params); \
  19. } while (0)
  20. /* int param */
  21. static int i915_param_int_show(struct seq_file *m, void *data)
  22. {
  23. int *value = m->private;
  24. seq_printf(m, "%d\n", *value);
  25. return 0;
  26. }
  27. static int i915_param_int_open(struct inode *inode, struct file *file)
  28. {
  29. return single_open(file, i915_param_int_show, inode->i_private);
  30. }
  31. static int notify_guc(struct drm_i915_private *i915)
  32. {
  33. struct intel_gt *gt;
  34. int i, ret = 0;
  35. for_each_gt(gt, i915, i) {
  36. if (intel_uc_uses_guc_submission(&gt->uc))
  37. ret = intel_guc_global_policies_update(&gt->uc.guc);
  38. }
  39. return ret;
  40. }
  41. static ssize_t i915_param_int_write(struct file *file,
  42. const char __user *ubuf, size_t len,
  43. loff_t *offp)
  44. {
  45. struct seq_file *m = file->private_data;
  46. int *value = m->private;
  47. int ret;
  48. ret = kstrtoint_from_user(ubuf, len, 0, value);
  49. if (ret) {
  50. /* support boolean values too */
  51. bool b;
  52. ret = kstrtobool_from_user(ubuf, len, &b);
  53. if (!ret)
  54. *value = b;
  55. }
  56. return ret ?: len;
  57. }
  58. static const struct file_operations i915_param_int_fops = {
  59. .owner = THIS_MODULE,
  60. .open = i915_param_int_open,
  61. .read = seq_read,
  62. .write = i915_param_int_write,
  63. .llseek = default_llseek,
  64. .release = single_release,
  65. };
  66. static const struct file_operations i915_param_int_fops_ro = {
  67. .owner = THIS_MODULE,
  68. .open = i915_param_int_open,
  69. .read = seq_read,
  70. .llseek = default_llseek,
  71. .release = single_release,
  72. };
  73. /* unsigned int param */
  74. static int i915_param_uint_show(struct seq_file *m, void *data)
  75. {
  76. unsigned int *value = m->private;
  77. seq_printf(m, "%u\n", *value);
  78. return 0;
  79. }
  80. static int i915_param_uint_open(struct inode *inode, struct file *file)
  81. {
  82. return single_open(file, i915_param_uint_show, inode->i_private);
  83. }
  84. static ssize_t i915_param_uint_write(struct file *file,
  85. const char __user *ubuf, size_t len,
  86. loff_t *offp)
  87. {
  88. struct drm_i915_private *i915;
  89. struct seq_file *m = file->private_data;
  90. unsigned int *value = m->private;
  91. unsigned int old = *value;
  92. int ret;
  93. ret = kstrtouint_from_user(ubuf, len, 0, value);
  94. if (ret) {
  95. /* support boolean values too */
  96. bool b;
  97. ret = kstrtobool_from_user(ubuf, len, &b);
  98. if (!ret)
  99. *value = b;
  100. }
  101. if (!ret && MATCH_DEBUGFS_NODE_NAME(file, "reset")) {
  102. GET_I915(i915, reset, value);
  103. ret = notify_guc(i915);
  104. if (ret)
  105. *value = old;
  106. }
  107. return ret ?: len;
  108. }
  109. static const struct file_operations i915_param_uint_fops = {
  110. .owner = THIS_MODULE,
  111. .open = i915_param_uint_open,
  112. .read = seq_read,
  113. .write = i915_param_uint_write,
  114. .llseek = default_llseek,
  115. .release = single_release,
  116. };
  117. static const struct file_operations i915_param_uint_fops_ro = {
  118. .owner = THIS_MODULE,
  119. .open = i915_param_uint_open,
  120. .read = seq_read,
  121. .llseek = default_llseek,
  122. .release = single_release,
  123. };
  124. /* char * param */
  125. static int i915_param_charp_show(struct seq_file *m, void *data)
  126. {
  127. const char **s = m->private;
  128. seq_printf(m, "%s\n", *s);
  129. return 0;
  130. }
  131. static int i915_param_charp_open(struct inode *inode, struct file *file)
  132. {
  133. return single_open(file, i915_param_charp_show, inode->i_private);
  134. }
  135. static ssize_t i915_param_charp_write(struct file *file,
  136. const char __user *ubuf, size_t len,
  137. loff_t *offp)
  138. {
  139. struct seq_file *m = file->private_data;
  140. char **s = m->private;
  141. char *new, *old;
  142. old = *s;
  143. new = strndup_user(ubuf, PAGE_SIZE);
  144. if (IS_ERR(new)) {
  145. len = PTR_ERR(new);
  146. goto out;
  147. }
  148. *s = new;
  149. kfree(old);
  150. out:
  151. return len;
  152. }
  153. static const struct file_operations i915_param_charp_fops = {
  154. .owner = THIS_MODULE,
  155. .open = i915_param_charp_open,
  156. .read = seq_read,
  157. .write = i915_param_charp_write,
  158. .llseek = default_llseek,
  159. .release = single_release,
  160. };
  161. static const struct file_operations i915_param_charp_fops_ro = {
  162. .owner = THIS_MODULE,
  163. .open = i915_param_charp_open,
  164. .read = seq_read,
  165. .llseek = default_llseek,
  166. .release = single_release,
  167. };
  168. #define RO(mode) (((mode) & 0222) == 0)
  169. static struct dentry *
  170. i915_debugfs_create_int(const char *name, umode_t mode,
  171. struct dentry *parent, int *value)
  172. {
  173. return debugfs_create_file_unsafe(name, mode, parent, value,
  174. RO(mode) ? &i915_param_int_fops_ro :
  175. &i915_param_int_fops);
  176. }
  177. static struct dentry *
  178. i915_debugfs_create_uint(const char *name, umode_t mode,
  179. struct dentry *parent, unsigned int *value)
  180. {
  181. return debugfs_create_file_unsafe(name, mode, parent, value,
  182. RO(mode) ? &i915_param_uint_fops_ro :
  183. &i915_param_uint_fops);
  184. }
  185. static struct dentry *
  186. i915_debugfs_create_charp(const char *name, umode_t mode,
  187. struct dentry *parent, char **value)
  188. {
  189. return debugfs_create_file(name, mode, parent, value,
  190. RO(mode) ? &i915_param_charp_fops_ro :
  191. &i915_param_charp_fops);
  192. }
  193. #define _i915_param_create_file(parent, name, mode, valp) \
  194. do { \
  195. if (mode) \
  196. _Generic(valp, \
  197. bool *: debugfs_create_bool, \
  198. int *: i915_debugfs_create_int, \
  199. unsigned int *: i915_debugfs_create_uint, \
  200. unsigned long *: debugfs_create_ulong, \
  201. char **: i915_debugfs_create_charp)(name, mode, parent, valp); \
  202. } while(0)
  203. /* add a subdirectory with files for each i915 param */
  204. struct dentry *i915_debugfs_params(struct drm_i915_private *i915)
  205. {
  206. struct drm_minor *minor = i915->drm.primary;
  207. struct i915_params *params = &i915->params;
  208. struct dentry *dir;
  209. dir = debugfs_create_dir("i915_params", minor->debugfs_root);
  210. if (IS_ERR(dir))
  211. return dir;
  212. /*
  213. * Note: We could create files for params needing special handling
  214. * here. Set mode in params to 0 to skip the generic create file, or
  215. * just let the generic create file fail silently with -EEXIST.
  216. */
  217. #define REGISTER(T, x, unused, mode, ...) _i915_param_create_file(dir, #x, mode, &params->x);
  218. I915_PARAMS_FOR_EACH(REGISTER);
  219. #undef REGISTER
  220. return dir;
  221. }