1 // SPDX-License-Identifier: MIT
3 * Copyright © 2019 Intel Corporation
6 #include <linux/kernel.h>
7 #include <linux/debugfs.h>
9 #include "i915_debugfs_params.h"
10 #include "gt/intel_gt.h"
11 #include "gt/uc/intel_guc.h"
13 #include "i915_params.h"
15 #define MATCH_DEBUGFS_NODE_NAME(_file, _name) \
16 (strcmp((_file)->f_path.dentry->d_name.name, (_name)) == 0)
18 #define GET_I915(i915, name, ptr) \
20 struct i915_params *params; \
21 params = container_of(((void *)(ptr)), typeof(*params), name); \
22 (i915) = container_of(params, typeof(*(i915)), params); \
26 static int i915_param_int_show(struct seq_file *m, void *data)
28 int *value = m->private;
30 seq_printf(m, "%d\n", *value);
35 static int i915_param_int_open(struct inode *inode, struct file *file)
37 return single_open(file, i915_param_int_show, inode->i_private);
40 static int notify_guc(struct drm_i915_private *i915)
45 for_each_gt(gt, i915, i) {
46 if (intel_uc_uses_guc_submission(>->uc))
47 ret = intel_guc_global_policies_update(>->uc.guc);
53 static ssize_t i915_param_int_write(struct file *file,
54 const char __user *ubuf, size_t len,
57 struct seq_file *m = file->private_data;
58 int *value = m->private;
61 ret = kstrtoint_from_user(ubuf, len, 0, value);
63 /* support boolean values too */
66 ret = kstrtobool_from_user(ubuf, len, &b);
74 static const struct file_operations i915_param_int_fops = {
76 .open = i915_param_int_open,
78 .write = i915_param_int_write,
79 .llseek = default_llseek,
80 .release = single_release,
83 static const struct file_operations i915_param_int_fops_ro = {
85 .open = i915_param_int_open,
87 .llseek = default_llseek,
88 .release = single_release,
91 /* unsigned int param */
92 static int i915_param_uint_show(struct seq_file *m, void *data)
94 unsigned int *value = m->private;
96 seq_printf(m, "%u\n", *value);
101 static int i915_param_uint_open(struct inode *inode, struct file *file)
103 return single_open(file, i915_param_uint_show, inode->i_private);
106 static ssize_t i915_param_uint_write(struct file *file,
107 const char __user *ubuf, size_t len,
110 struct drm_i915_private *i915;
111 struct seq_file *m = file->private_data;
112 unsigned int *value = m->private;
113 unsigned int old = *value;
116 ret = kstrtouint_from_user(ubuf, len, 0, value);
118 /* support boolean values too */
121 ret = kstrtobool_from_user(ubuf, len, &b);
126 if (!ret && MATCH_DEBUGFS_NODE_NAME(file, "reset")) {
127 GET_I915(i915, reset, value);
129 ret = notify_guc(i915);
137 static const struct file_operations i915_param_uint_fops = {
138 .owner = THIS_MODULE,
139 .open = i915_param_uint_open,
141 .write = i915_param_uint_write,
142 .llseek = default_llseek,
143 .release = single_release,
146 static const struct file_operations i915_param_uint_fops_ro = {
147 .owner = THIS_MODULE,
148 .open = i915_param_uint_open,
150 .llseek = default_llseek,
151 .release = single_release,
155 static int i915_param_charp_show(struct seq_file *m, void *data)
157 const char **s = m->private;
159 seq_printf(m, "%s\n", *s);
164 static int i915_param_charp_open(struct inode *inode, struct file *file)
166 return single_open(file, i915_param_charp_show, inode->i_private);
169 static ssize_t i915_param_charp_write(struct file *file,
170 const char __user *ubuf, size_t len,
173 struct seq_file *m = file->private_data;
174 char **s = m->private;
178 new = strndup_user(ubuf, PAGE_SIZE);
191 static const struct file_operations i915_param_charp_fops = {
192 .owner = THIS_MODULE,
193 .open = i915_param_charp_open,
195 .write = i915_param_charp_write,
196 .llseek = default_llseek,
197 .release = single_release,
200 static const struct file_operations i915_param_charp_fops_ro = {
201 .owner = THIS_MODULE,
202 .open = i915_param_charp_open,
204 .llseek = default_llseek,
205 .release = single_release,
208 #define RO(mode) (((mode) & 0222) == 0)
210 static struct dentry *
211 i915_debugfs_create_int(const char *name, umode_t mode,
212 struct dentry *parent, int *value)
214 return debugfs_create_file_unsafe(name, mode, parent, value,
215 RO(mode) ? &i915_param_int_fops_ro :
216 &i915_param_int_fops);
219 static struct dentry *
220 i915_debugfs_create_uint(const char *name, umode_t mode,
221 struct dentry *parent, unsigned int *value)
223 return debugfs_create_file_unsafe(name, mode, parent, value,
224 RO(mode) ? &i915_param_uint_fops_ro :
225 &i915_param_uint_fops);
228 static struct dentry *
229 i915_debugfs_create_charp(const char *name, umode_t mode,
230 struct dentry *parent, char **value)
232 return debugfs_create_file(name, mode, parent, value,
233 RO(mode) ? &i915_param_charp_fops_ro :
234 &i915_param_charp_fops);
237 #define _i915_param_create_file(parent, name, mode, valp) \
241 bool *: debugfs_create_bool, \
242 int *: i915_debugfs_create_int, \
243 unsigned int *: i915_debugfs_create_uint, \
244 unsigned long *: debugfs_create_ulong, \
245 char **: i915_debugfs_create_charp)(name, mode, parent, valp); \
248 /* add a subdirectory with files for each i915 param */
249 struct dentry *i915_debugfs_params(struct drm_i915_private *i915)
251 struct drm_minor *minor = i915->drm.primary;
252 struct i915_params *params = &i915->params;
255 dir = debugfs_create_dir("i915_params", minor->debugfs_root);
260 * Note: We could create files for params needing special handling
261 * here. Set mode in params to 0 to skip the generic create file, or
262 * just let the generic create file fail silently with -EEXIST.
265 #define REGISTER(T, x, unused, mode, ...) _i915_param_create_file(dir, #x, mode, ¶ms->x);
266 I915_PARAMS_FOR_EACH(REGISTER);