0001
0002
0003
0004
0005
0006 #include <linux/kernel.h>
0007
0008 #include "i915_debugfs_params.h"
0009 #include "gt/intel_gt.h"
0010 #include "gt/uc/intel_guc.h"
0011 #include "i915_drv.h"
0012 #include "i915_params.h"
0013
0014 #define MATCH_DEBUGFS_NODE_NAME(_file, _name) \
0015 (strcmp((_file)->f_path.dentry->d_name.name, (_name)) == 0)
0016
0017 #define GET_I915(i915, name, ptr) \
0018 do { \
0019 struct i915_params *params; \
0020 params = container_of(((void *)(ptr)), typeof(*params), name); \
0021 (i915) = container_of(params, typeof(*(i915)), params); \
0022 } while (0)
0023
0024
0025 static int i915_param_int_show(struct seq_file *m, void *data)
0026 {
0027 int *value = m->private;
0028
0029 seq_printf(m, "%d\n", *value);
0030
0031 return 0;
0032 }
0033
0034 static int i915_param_int_open(struct inode *inode, struct file *file)
0035 {
0036 return single_open(file, i915_param_int_show, inode->i_private);
0037 }
0038
0039 static int notify_guc(struct drm_i915_private *i915)
0040 {
0041 int ret = 0;
0042
0043 if (intel_uc_uses_guc_submission(&to_gt(i915)->uc))
0044 ret = intel_guc_global_policies_update(&to_gt(i915)->uc.guc);
0045
0046 return ret;
0047 }
0048
0049 static ssize_t i915_param_int_write(struct file *file,
0050 const char __user *ubuf, size_t len,
0051 loff_t *offp)
0052 {
0053 struct seq_file *m = file->private_data;
0054 int *value = m->private;
0055 int ret;
0056
0057 ret = kstrtoint_from_user(ubuf, len, 0, value);
0058 if (ret) {
0059
0060 bool b;
0061
0062 ret = kstrtobool_from_user(ubuf, len, &b);
0063 if (!ret)
0064 *value = b;
0065 }
0066
0067 return ret ?: len;
0068 }
0069
0070 static const struct file_operations i915_param_int_fops = {
0071 .owner = THIS_MODULE,
0072 .open = i915_param_int_open,
0073 .read = seq_read,
0074 .write = i915_param_int_write,
0075 .llseek = default_llseek,
0076 .release = single_release,
0077 };
0078
0079 static const struct file_operations i915_param_int_fops_ro = {
0080 .owner = THIS_MODULE,
0081 .open = i915_param_int_open,
0082 .read = seq_read,
0083 .llseek = default_llseek,
0084 .release = single_release,
0085 };
0086
0087
0088 static int i915_param_uint_show(struct seq_file *m, void *data)
0089 {
0090 unsigned int *value = m->private;
0091
0092 seq_printf(m, "%u\n", *value);
0093
0094 return 0;
0095 }
0096
0097 static int i915_param_uint_open(struct inode *inode, struct file *file)
0098 {
0099 return single_open(file, i915_param_uint_show, inode->i_private);
0100 }
0101
0102 static ssize_t i915_param_uint_write(struct file *file,
0103 const char __user *ubuf, size_t len,
0104 loff_t *offp)
0105 {
0106 struct drm_i915_private *i915;
0107 struct seq_file *m = file->private_data;
0108 unsigned int *value = m->private;
0109 unsigned int old = *value;
0110 int ret;
0111
0112 ret = kstrtouint_from_user(ubuf, len, 0, value);
0113 if (ret) {
0114
0115 bool b;
0116
0117 ret = kstrtobool_from_user(ubuf, len, &b);
0118 if (!ret)
0119 *value = b;
0120 }
0121
0122 if (!ret && MATCH_DEBUGFS_NODE_NAME(file, "reset")) {
0123 GET_I915(i915, reset, value);
0124
0125 ret = notify_guc(i915);
0126 if (ret)
0127 *value = old;
0128 }
0129
0130 return ret ?: len;
0131 }
0132
0133 static const struct file_operations i915_param_uint_fops = {
0134 .owner = THIS_MODULE,
0135 .open = i915_param_uint_open,
0136 .read = seq_read,
0137 .write = i915_param_uint_write,
0138 .llseek = default_llseek,
0139 .release = single_release,
0140 };
0141
0142 static const struct file_operations i915_param_uint_fops_ro = {
0143 .owner = THIS_MODULE,
0144 .open = i915_param_uint_open,
0145 .read = seq_read,
0146 .llseek = default_llseek,
0147 .release = single_release,
0148 };
0149
0150
0151 static int i915_param_charp_show(struct seq_file *m, void *data)
0152 {
0153 const char **s = m->private;
0154
0155 seq_printf(m, "%s\n", *s);
0156
0157 return 0;
0158 }
0159
0160 static int i915_param_charp_open(struct inode *inode, struct file *file)
0161 {
0162 return single_open(file, i915_param_charp_show, inode->i_private);
0163 }
0164
0165 static ssize_t i915_param_charp_write(struct file *file,
0166 const char __user *ubuf, size_t len,
0167 loff_t *offp)
0168 {
0169 struct seq_file *m = file->private_data;
0170 char **s = m->private;
0171 char *new, *old;
0172
0173 old = *s;
0174 new = strndup_user(ubuf, PAGE_SIZE);
0175 if (IS_ERR(new)) {
0176 len = PTR_ERR(new);
0177 goto out;
0178 }
0179
0180 *s = new;
0181
0182 kfree(old);
0183 out:
0184 return len;
0185 }
0186
0187 static const struct file_operations i915_param_charp_fops = {
0188 .owner = THIS_MODULE,
0189 .open = i915_param_charp_open,
0190 .read = seq_read,
0191 .write = i915_param_charp_write,
0192 .llseek = default_llseek,
0193 .release = single_release,
0194 };
0195
0196 static const struct file_operations i915_param_charp_fops_ro = {
0197 .owner = THIS_MODULE,
0198 .open = i915_param_charp_open,
0199 .read = seq_read,
0200 .llseek = default_llseek,
0201 .release = single_release,
0202 };
0203
0204 #define RO(mode) (((mode) & 0222) == 0)
0205
0206 static struct dentry *
0207 i915_debugfs_create_int(const char *name, umode_t mode,
0208 struct dentry *parent, int *value)
0209 {
0210 return debugfs_create_file_unsafe(name, mode, parent, value,
0211 RO(mode) ? &i915_param_int_fops_ro :
0212 &i915_param_int_fops);
0213 }
0214
0215 static struct dentry *
0216 i915_debugfs_create_uint(const char *name, umode_t mode,
0217 struct dentry *parent, unsigned int *value)
0218 {
0219 return debugfs_create_file_unsafe(name, mode, parent, value,
0220 RO(mode) ? &i915_param_uint_fops_ro :
0221 &i915_param_uint_fops);
0222 }
0223
0224 static struct dentry *
0225 i915_debugfs_create_charp(const char *name, umode_t mode,
0226 struct dentry *parent, char **value)
0227 {
0228 return debugfs_create_file(name, mode, parent, value,
0229 RO(mode) ? &i915_param_charp_fops_ro :
0230 &i915_param_charp_fops);
0231 }
0232
0233 static __always_inline void
0234 _i915_param_create_file(struct dentry *parent, const char *name,
0235 const char *type, int mode, void *value)
0236 {
0237 if (!mode)
0238 return;
0239
0240 if (!__builtin_strcmp(type, "bool"))
0241 debugfs_create_bool(name, mode, parent, value);
0242 else if (!__builtin_strcmp(type, "int"))
0243 i915_debugfs_create_int(name, mode, parent, value);
0244 else if (!__builtin_strcmp(type, "unsigned int"))
0245 i915_debugfs_create_uint(name, mode, parent, value);
0246 else if (!__builtin_strcmp(type, "unsigned long"))
0247 debugfs_create_ulong(name, mode, parent, value);
0248 else if (!__builtin_strcmp(type, "char *"))
0249 i915_debugfs_create_charp(name, mode, parent, value);
0250 else
0251 WARN(1, "no debugfs fops defined for param type %s (i915.%s)\n",
0252 type, name);
0253 }
0254
0255
0256 struct dentry *i915_debugfs_params(struct drm_i915_private *i915)
0257 {
0258 struct drm_minor *minor = i915->drm.primary;
0259 struct i915_params *params = &i915->params;
0260 struct dentry *dir;
0261
0262 dir = debugfs_create_dir("i915_params", minor->debugfs_root);
0263 if (IS_ERR(dir))
0264 return dir;
0265
0266
0267
0268
0269
0270
0271
0272 #define REGISTER(T, x, unused, mode, ...) _i915_param_create_file(dir, #x, #T, mode, ¶ms->x);
0273 I915_PARAMS_FOR_EACH(REGISTER);
0274 #undef REGISTER
0275
0276 return dir;
0277 }