]> Git Repo - linux.git/blob - drivers/gpu/drm/i915/i915_debugfs_params.c
Merge tag 'irq-urgent-2025-02-08' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux.git] / drivers / gpu / drm / i915 / i915_debugfs_params.c
1 // SPDX-License-Identifier: MIT
2 /*
3  * Copyright © 2019 Intel Corporation
4  */
5
6 #include <linux/kernel.h>
7 #include <linux/debugfs.h>
8
9 #include "i915_debugfs_params.h"
10 #include "gt/intel_gt.h"
11 #include "gt/uc/intel_guc.h"
12 #include "i915_drv.h"
13 #include "i915_params.h"
14
15 #define MATCH_DEBUGFS_NODE_NAME(_file, _name) \
16         (strcmp((_file)->f_path.dentry->d_name.name, (_name)) == 0)
17
18 #define GET_I915(i915, name, ptr)       \
19         do {    \
20                 struct i915_params *params;     \
21                 params = container_of(((void *)(ptr)), typeof(*params), name);  \
22                 (i915) = container_of(params, typeof(*(i915)), params); \
23         } while (0)
24
25 /* int param */
26 static int i915_param_int_show(struct seq_file *m, void *data)
27 {
28         int *value = m->private;
29
30         seq_printf(m, "%d\n", *value);
31
32         return 0;
33 }
34
35 static int i915_param_int_open(struct inode *inode, struct file *file)
36 {
37         return single_open(file, i915_param_int_show, inode->i_private);
38 }
39
40 static int notify_guc(struct drm_i915_private *i915)
41 {
42         struct intel_gt *gt;
43         int i, ret = 0;
44
45         for_each_gt(gt, i915, i) {
46                 if (intel_uc_uses_guc_submission(&gt->uc))
47                         ret = intel_guc_global_policies_update(&gt->uc.guc);
48         }
49
50         return ret;
51 }
52
53 static ssize_t i915_param_int_write(struct file *file,
54                                     const char __user *ubuf, size_t len,
55                                     loff_t *offp)
56 {
57         struct seq_file *m = file->private_data;
58         int *value = m->private;
59         int ret;
60
61         ret = kstrtoint_from_user(ubuf, len, 0, value);
62         if (ret) {
63                 /* support boolean values too */
64                 bool b;
65
66                 ret = kstrtobool_from_user(ubuf, len, &b);
67                 if (!ret)
68                         *value = b;
69         }
70
71         return ret ?: len;
72 }
73
74 static const struct file_operations i915_param_int_fops = {
75         .owner = THIS_MODULE,
76         .open = i915_param_int_open,
77         .read = seq_read,
78         .write = i915_param_int_write,
79         .llseek = default_llseek,
80         .release = single_release,
81 };
82
83 static const struct file_operations i915_param_int_fops_ro = {
84         .owner = THIS_MODULE,
85         .open = i915_param_int_open,
86         .read = seq_read,
87         .llseek = default_llseek,
88         .release = single_release,
89 };
90
91 /* unsigned int param */
92 static int i915_param_uint_show(struct seq_file *m, void *data)
93 {
94         unsigned int *value = m->private;
95
96         seq_printf(m, "%u\n", *value);
97
98         return 0;
99 }
100
101 static int i915_param_uint_open(struct inode *inode, struct file *file)
102 {
103         return single_open(file, i915_param_uint_show, inode->i_private);
104 }
105
106 static ssize_t i915_param_uint_write(struct file *file,
107                                      const char __user *ubuf, size_t len,
108                                      loff_t *offp)
109 {
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;
114         int ret;
115
116         ret = kstrtouint_from_user(ubuf, len, 0, value);
117         if (ret) {
118                 /* support boolean values too */
119                 bool b;
120
121                 ret = kstrtobool_from_user(ubuf, len, &b);
122                 if (!ret)
123                         *value = b;
124         }
125
126         if (!ret && MATCH_DEBUGFS_NODE_NAME(file, "reset")) {
127                 GET_I915(i915, reset, value);
128
129                 ret = notify_guc(i915);
130                 if (ret)
131                         *value = old;
132         }
133
134         return ret ?: len;
135 }
136
137 static const struct file_operations i915_param_uint_fops = {
138         .owner = THIS_MODULE,
139         .open = i915_param_uint_open,
140         .read = seq_read,
141         .write = i915_param_uint_write,
142         .llseek = default_llseek,
143         .release = single_release,
144 };
145
146 static const struct file_operations i915_param_uint_fops_ro = {
147         .owner = THIS_MODULE,
148         .open = i915_param_uint_open,
149         .read = seq_read,
150         .llseek = default_llseek,
151         .release = single_release,
152 };
153
154 /* char * param */
155 static int i915_param_charp_show(struct seq_file *m, void *data)
156 {
157         const char **s = m->private;
158
159         seq_printf(m, "%s\n", *s);
160
161         return 0;
162 }
163
164 static int i915_param_charp_open(struct inode *inode, struct file *file)
165 {
166         return single_open(file, i915_param_charp_show, inode->i_private);
167 }
168
169 static ssize_t i915_param_charp_write(struct file *file,
170                                       const char __user *ubuf, size_t len,
171                                       loff_t *offp)
172 {
173         struct seq_file *m = file->private_data;
174         char **s = m->private;
175         char *new, *old;
176
177         old = *s;
178         new = strndup_user(ubuf, PAGE_SIZE);
179         if (IS_ERR(new)) {
180                 len = PTR_ERR(new);
181                 goto out;
182         }
183
184         *s = new;
185
186         kfree(old);
187 out:
188         return len;
189 }
190
191 static const struct file_operations i915_param_charp_fops = {
192         .owner = THIS_MODULE,
193         .open = i915_param_charp_open,
194         .read = seq_read,
195         .write = i915_param_charp_write,
196         .llseek = default_llseek,
197         .release = single_release,
198 };
199
200 static const struct file_operations i915_param_charp_fops_ro = {
201         .owner = THIS_MODULE,
202         .open = i915_param_charp_open,
203         .read = seq_read,
204         .llseek = default_llseek,
205         .release = single_release,
206 };
207
208 #define RO(mode) (((mode) & 0222) == 0)
209
210 static struct dentry *
211 i915_debugfs_create_int(const char *name, umode_t mode,
212                         struct dentry *parent, int *value)
213 {
214         return debugfs_create_file_unsafe(name, mode, parent, value,
215                                           RO(mode) ? &i915_param_int_fops_ro :
216                                           &i915_param_int_fops);
217 }
218
219 static struct dentry *
220 i915_debugfs_create_uint(const char *name, umode_t mode,
221                          struct dentry *parent, unsigned int *value)
222 {
223         return debugfs_create_file_unsafe(name, mode, parent, value,
224                                           RO(mode) ? &i915_param_uint_fops_ro :
225                                           &i915_param_uint_fops);
226 }
227
228 static struct dentry *
229 i915_debugfs_create_charp(const char *name, umode_t mode,
230                           struct dentry *parent, char **value)
231 {
232         return debugfs_create_file(name, mode, parent, value,
233                                    RO(mode) ? &i915_param_charp_fops_ro :
234                                    &i915_param_charp_fops);
235 }
236
237 #define _i915_param_create_file(parent, name, mode, valp)               \
238         do {                                                            \
239                 if (mode)                                               \
240                         _Generic(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); \
246         } while(0)
247
248 /* add a subdirectory with files for each i915 param */
249 struct dentry *i915_debugfs_params(struct drm_i915_private *i915)
250 {
251         struct drm_minor *minor = i915->drm.primary;
252         struct i915_params *params = &i915->params;
253         struct dentry *dir;
254
255         dir = debugfs_create_dir("i915_params", minor->debugfs_root);
256         if (IS_ERR(dir))
257                 return dir;
258
259         /*
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.
263          */
264
265 #define REGISTER(T, x, unused, mode, ...) _i915_param_create_file(dir, #x, mode, &params->x);
266         I915_PARAMS_FOR_EACH(REGISTER);
267 #undef REGISTER
268
269         return dir;
270 }
This page took 0.044105 seconds and 4 git commands to generate.