hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/drivers/opp/debugfs.c
....@@ -1,11 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Generic OPP debugfs interface
34 *
45 * Copyright (C) 2015-2016 Viresh Kumar <viresh.kumar@linaro.org>
5
- *
6
- * This program is free software; you can redistribute it and/or modify
7
- * it under the terms of the GNU General Public License version 2 as
8
- * published by the Free Software Foundation.
96 */
107
118 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
....@@ -35,7 +32,48 @@
3532 debugfs_remove_recursive(opp->dentry);
3633 }
3734
38
-static bool opp_debug_create_supplies(struct dev_pm_opp *opp,
35
+static ssize_t bw_name_read(struct file *fp, char __user *userbuf,
36
+ size_t count, loff_t *ppos)
37
+{
38
+ struct icc_path *path = fp->private_data;
39
+ char buf[64];
40
+ int i;
41
+
42
+ i = scnprintf(buf, sizeof(buf), "%.62s\n", icc_get_name(path));
43
+
44
+ return simple_read_from_buffer(userbuf, count, ppos, buf, i);
45
+}
46
+
47
+static const struct file_operations bw_name_fops = {
48
+ .open = simple_open,
49
+ .read = bw_name_read,
50
+ .llseek = default_llseek,
51
+};
52
+
53
+static void opp_debug_create_bw(struct dev_pm_opp *opp,
54
+ struct opp_table *opp_table,
55
+ struct dentry *pdentry)
56
+{
57
+ struct dentry *d;
58
+ char name[11];
59
+ int i;
60
+
61
+ for (i = 0; i < opp_table->path_count; i++) {
62
+ snprintf(name, sizeof(name), "icc-path-%.1d", i);
63
+
64
+ /* Create per-path directory */
65
+ d = debugfs_create_dir(name, pdentry);
66
+
67
+ debugfs_create_file("name", S_IRUGO, d, opp_table->paths[i],
68
+ &bw_name_fops);
69
+ debugfs_create_u32("peak_bw", S_IRUGO, d,
70
+ &opp->bandwidth[i].peak);
71
+ debugfs_create_u32("avg_bw", S_IRUGO, d,
72
+ &opp->bandwidth[i].avg);
73
+ }
74
+}
75
+
76
+static void opp_debug_create_supplies(struct dev_pm_opp *opp,
3977 struct opp_table *opp_table,
4078 struct dentry *pdentry)
4179 {
....@@ -50,30 +88,21 @@
5088 /* Create per-opp directory */
5189 d = debugfs_create_dir(name, pdentry);
5290
53
- if (!d)
54
- return false;
91
+ debugfs_create_ulong("u_volt_target", S_IRUGO, d,
92
+ &opp->supplies[i].u_volt);
5593
56
- if (!debugfs_create_ulong("u_volt_target", S_IRUGO, d,
57
- &opp->supplies[i].u_volt))
58
- return false;
94
+ debugfs_create_ulong("u_volt_min", S_IRUGO, d,
95
+ &opp->supplies[i].u_volt_min);
5996
60
- if (!debugfs_create_ulong("u_volt_min", S_IRUGO, d,
61
- &opp->supplies[i].u_volt_min))
62
- return false;
97
+ debugfs_create_ulong("u_volt_max", S_IRUGO, d,
98
+ &opp->supplies[i].u_volt_max);
6399
64
- if (!debugfs_create_ulong("u_volt_max", S_IRUGO, d,
65
- &opp->supplies[i].u_volt_max))
66
- return false;
67
-
68
- if (!debugfs_create_ulong("u_amp", S_IRUGO, d,
69
- &opp->supplies[i].u_amp))
70
- return false;
100
+ debugfs_create_ulong("u_amp", S_IRUGO, d,
101
+ &opp->supplies[i].u_amp);
71102 }
72
-
73
- return true;
74103 }
75104
76
-int opp_debug_create_one(struct dev_pm_opp *opp, struct opp_table *opp_table)
105
+void opp_debug_create_one(struct dev_pm_opp *opp, struct opp_table *opp_table)
77106 {
78107 struct dentry *pdentry = opp_table->dentry;
79108 struct dentry *d;
....@@ -95,40 +124,24 @@
95124
96125 /* Create per-opp directory */
97126 d = debugfs_create_dir(name, pdentry);
98
- if (!d)
99
- return -ENOMEM;
100127
101
- if (!debugfs_create_bool("available", S_IRUGO, d, &opp->available))
102
- return -ENOMEM;
128
+ debugfs_create_bool("available", S_IRUGO, d, &opp->available);
129
+ debugfs_create_bool("dynamic", S_IRUGO, d, &opp->dynamic);
130
+ debugfs_create_bool("turbo", S_IRUGO, d, &opp->turbo);
131
+ debugfs_create_bool("suspend", S_IRUGO, d, &opp->suspend);
132
+ debugfs_create_u32("performance_state", S_IRUGO, d, &opp->pstate);
133
+ debugfs_create_ulong("rate_hz", S_IRUGO, d, &opp->rate);
134
+ debugfs_create_ulong("clock_latency_ns", S_IRUGO, d,
135
+ &opp->clock_latency_ns);
103136
104
- if (!debugfs_create_bool("dynamic", S_IRUGO, d, &opp->dynamic))
105
- return -ENOMEM;
106
-
107
- if (!debugfs_create_bool("turbo", S_IRUGO, d, &opp->turbo))
108
- return -ENOMEM;
109
-
110
- if (!debugfs_create_bool("suspend", S_IRUGO, d, &opp->suspend))
111
- return -ENOMEM;
112
-
113
- if (!debugfs_create_u32("performance_state", S_IRUGO, d, &opp->pstate))
114
- return -ENOMEM;
115
-
116
- if (!debugfs_create_ulong("rate_hz", S_IRUGO, d, &opp->rate))
117
- return -ENOMEM;
118
-
119
- if (!opp_debug_create_supplies(opp, opp_table, d))
120
- return -ENOMEM;
121
-
122
- if (!debugfs_create_ulong("clock_latency_ns", S_IRUGO, d,
123
- &opp->clock_latency_ns))
124
- return -ENOMEM;
137
+ opp_debug_create_supplies(opp, opp_table, d);
138
+ opp_debug_create_bw(opp, opp_table, d);
125139
126140 opp->dentry = d;
127
- return 0;
128141 }
129142
130
-static int opp_list_debug_create_dir(struct opp_device *opp_dev,
131
- struct opp_table *opp_table)
143
+static void opp_list_debug_create_dir(struct opp_device *opp_dev,
144
+ struct opp_table *opp_table)
132145 {
133146 const struct device *dev = opp_dev->dev;
134147 struct dentry *d;
....@@ -137,36 +150,21 @@
137150
138151 /* Create device specific directory */
139152 d = debugfs_create_dir(opp_table->dentry_name, rootdir);
140
- if (!d) {
141
- dev_err(dev, "%s: Failed to create debugfs dir\n", __func__);
142
- return -ENOMEM;
143
- }
144153
145154 opp_dev->dentry = d;
146155 opp_table->dentry = d;
147
-
148
- return 0;
149156 }
150157
151
-static int opp_list_debug_create_link(struct opp_device *opp_dev,
152
- struct opp_table *opp_table)
158
+static void opp_list_debug_create_link(struct opp_device *opp_dev,
159
+ struct opp_table *opp_table)
153160 {
154
- const struct device *dev = opp_dev->dev;
155161 char name[NAME_MAX];
156
- struct dentry *d;
157162
158163 opp_set_dev_name(opp_dev->dev, name);
159164
160165 /* Create device specific directory link */
161
- d = debugfs_create_symlink(name, rootdir, opp_table->dentry_name);
162
- if (!d) {
163
- dev_err(dev, "%s: Failed to create link\n", __func__);
164
- return -ENOMEM;
165
- }
166
-
167
- opp_dev->dentry = d;
168
-
169
- return 0;
166
+ opp_dev->dentry = debugfs_create_symlink(name, rootdir,
167
+ opp_table->dentry_name);
170168 }
171169
172170 /**
....@@ -177,20 +175,13 @@
177175 * Dynamically adds device specific directory in debugfs 'opp' directory. If the
178176 * device-opp is shared with other devices, then links will be created for all
179177 * devices except the first.
180
- *
181
- * Return: 0 on success, otherwise negative error.
182178 */
183
-int opp_debug_register(struct opp_device *opp_dev, struct opp_table *opp_table)
179
+void opp_debug_register(struct opp_device *opp_dev, struct opp_table *opp_table)
184180 {
185
- if (!rootdir) {
186
- pr_debug("%s: Uninitialized rootdir\n", __func__);
187
- return -EINVAL;
188
- }
189
-
190181 if (opp_table->dentry)
191
- return opp_list_debug_create_link(opp_dev, opp_table);
192
-
193
- return opp_list_debug_create_dir(opp_dev, opp_table);
182
+ opp_list_debug_create_link(opp_dev, opp_table);
183
+ else
184
+ opp_list_debug_create_dir(opp_dev, opp_table);
194185 }
195186
196187 static void opp_migrate_dentry(struct opp_device *opp_dev,
....@@ -213,7 +204,7 @@
213204
214205 dentry = debugfs_rename(rootdir, opp_dev->dentry, rootdir,
215206 opp_table->dentry_name);
216
- if (!dentry) {
207
+ if (IS_ERR(dentry)) {
217208 dev_err(dev, "%s: Failed to rename link from: %s to %s\n",
218209 __func__, dev_name(opp_dev->dev), dev_name(dev));
219210 return;
....@@ -248,19 +239,62 @@
248239 opp_dev->dentry = NULL;
249240 }
250241
242
+static int opp_summary_show(struct seq_file *s, void *data)
243
+{
244
+ struct list_head *lists = (struct list_head *)s->private;
245
+ struct opp_table *opp_table;
246
+ struct dev_pm_opp *opp;
247
+
248
+ mutex_lock(&opp_table_lock);
249
+
250
+ seq_puts(s, " device rate(Hz) target(uV) min(uV) max(uV)\n");
251
+ seq_puts(s, "-------------------------------------------------------------------\n");
252
+
253
+ list_for_each_entry(opp_table, lists, node) {
254
+ seq_printf(s, " %s\n", opp_table->dentry_name);
255
+ mutex_lock(&opp_table->lock);
256
+ list_for_each_entry(opp, &opp_table->opp_list, node) {
257
+ if (!opp->available)
258
+ continue;
259
+ seq_printf(s, "%31lu %12lu %11lu %11lu\n",
260
+ opp->rate,
261
+ opp->supplies[0].u_volt,
262
+ opp->supplies[0].u_volt_min,
263
+ opp->supplies[0].u_volt_max);
264
+ if (opp_table->regulator_count > 1)
265
+ seq_printf(s, "%44lu %11lu %11lu\n",
266
+ opp->supplies[1].u_volt,
267
+ opp->supplies[1].u_volt_min,
268
+ opp->supplies[1].u_volt_max);
269
+ }
270
+ mutex_unlock(&opp_table->lock);
271
+ }
272
+
273
+ mutex_unlock(&opp_table_lock);
274
+
275
+ return 0;
276
+}
277
+
278
+static int opp_summary_open(struct inode *inode, struct file *file)
279
+{
280
+ return single_open(file, opp_summary_show, inode->i_private);
281
+}
282
+
283
+static const struct file_operations opp_summary_fops = {
284
+ .open = opp_summary_open,
285
+ .read = seq_read,
286
+ .llseek = seq_lseek,
287
+ .release = single_release,
288
+};
289
+
251290 static int __init opp_debug_init(void)
252291 {
253292 /* Create /sys/kernel/debug/opp directory */
254293 rootdir = debugfs_create_dir("opp", NULL);
255
- if (!rootdir) {
256
- pr_err("%s: Failed to create root directory\n", __func__);
257
- return -ENOMEM;
258
- }
294
+
295
+ debugfs_create_file("opp_summary", 0444, rootdir, &opp_tables,
296
+ &opp_summary_fops);
259297
260298 return 0;
261299 }
262
-#ifdef CONFIG_ROCKCHIP_THUNDER_BOOT
263
-core_initcall_sync(opp_debug_init);
264
-#else
265300 core_initcall(opp_debug_init);
266
-#endif