Commit | Line | Data |
---|---|---|
d8187177 RC |
1 | /* |
2 | * Copyright (C) 2016 Red Hat | |
3 | * | |
4 | * Permission is hereby granted, free of charge, to any person obtaining a | |
5 | * copy of this software and associated documentation files (the "Software"), | |
6 | * to deal in the Software without restriction, including without limitation | |
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
8 | * and/or sell copies of the Software, and to permit persons to whom the | |
9 | * Software is furnished to do so, subject to the following conditions: | |
10 | * | |
11 | * The above copyright notice and this permission notice shall be included in | |
12 | * all copies or substantial portions of the Software. | |
13 | * | |
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
20 | * OTHER DEALINGS IN THE SOFTWARE. | |
21 | * | |
22 | * Authors: | |
23 | * Rob Clark <robdclark@gmail.com> | |
24 | */ | |
25 | ||
26 | #ifndef DRM_PRINT_H_ | |
27 | #define DRM_PRINT_H_ | |
28 | ||
3c6d6e0f JP |
29 | #include <linux/compiler.h> |
30 | #include <linux/printk.h> | |
d8187177 RC |
31 | #include <linux/seq_file.h> |
32 | #include <linux/device.h> | |
33 | ||
34 | /** | |
35 | * DOC: print | |
36 | * | |
37 | * A simple wrapper for dev_printk(), seq_printf(), etc. Allows same | |
38 | * debug code to be used for both debugfs and printk logging. | |
39 | * | |
40 | * For example:: | |
41 | * | |
42 | * void log_some_info(struct drm_printer *p) | |
43 | * { | |
44 | * drm_printf(p, "foo=%d\n", foo); | |
45 | * drm_printf(p, "bar=%d\n", bar); | |
46 | * } | |
47 | * | |
48 | * #ifdef CONFIG_DEBUG_FS | |
49 | * void debugfs_show(struct seq_file *f) | |
50 | * { | |
51 | * struct drm_printer p = drm_seq_file_printer(f); | |
52 | * log_some_info(&p); | |
53 | * } | |
54 | * #endif | |
55 | * | |
56 | * void some_other_function(...) | |
57 | * { | |
58 | * struct drm_printer p = drm_info_printer(drm->dev); | |
59 | * log_some_info(&p); | |
60 | * } | |
61 | */ | |
62 | ||
63 | /** | |
64 | * struct drm_printer - drm output "stream" | |
d8187177 RC |
65 | * |
66 | * Do not use struct members directly. Use drm_printer_seq_file(), | |
67 | * drm_printer_info(), etc to initialize. And drm_printf() for output. | |
68 | */ | |
69 | struct drm_printer { | |
3d387d92 | 70 | /* private: */ |
d8187177 | 71 | void (*printfn)(struct drm_printer *p, struct va_format *vaf); |
63f4cc01 | 72 | void (*puts)(struct drm_printer *p, const char *str); |
d8187177 | 73 | void *arg; |
3d387d92 | 74 | const char *prefix; |
d8187177 RC |
75 | }; |
76 | ||
cfc57a18 | 77 | void __drm_printfn_coredump(struct drm_printer *p, struct va_format *vaf); |
5dc634bd | 78 | void __drm_puts_coredump(struct drm_printer *p, const char *str); |
d8187177 | 79 | void __drm_printfn_seq_file(struct drm_printer *p, struct va_format *vaf); |
4538d732 | 80 | void __drm_puts_seq_file(struct drm_printer *p, const char *str); |
d8187177 | 81 | void __drm_printfn_info(struct drm_printer *p, struct va_format *vaf); |
3d387d92 | 82 | void __drm_printfn_debug(struct drm_printer *p, struct va_format *vaf); |
d8187177 | 83 | |
3c6d6e0f | 84 | __printf(2, 3) |
d8187177 | 85 | void drm_printf(struct drm_printer *p, const char *f, ...); |
63f4cc01 | 86 | void drm_puts(struct drm_printer *p, const char *str); |
d8187177 | 87 | |
42f1b310 | 88 | __printf(2, 0) |
e2b155e9 CW |
89 | /** |
90 | * drm_vprintf - print to a &drm_printer stream | |
91 | * @p: the &drm_printer | |
92 | * @fmt: format string | |
93 | * @va: the va_list | |
94 | */ | |
e2b155e9 CW |
95 | static inline void |
96 | drm_vprintf(struct drm_printer *p, const char *fmt, va_list *va) | |
97 | { | |
98 | struct va_format vaf = { .fmt = fmt, .va = va }; | |
99 | ||
100 | p->printfn(p, &vaf); | |
101 | } | |
102 | ||
bf6234a2 NT |
103 | /** |
104 | * drm_printf_indent - Print to a &drm_printer stream with indentation | |
105 | * @printer: DRM printer | |
106 | * @indent: Tab indentation level (max 5) | |
107 | * @fmt: Format string | |
108 | */ | |
109 | #define drm_printf_indent(printer, indent, fmt, ...) \ | |
110 | drm_printf((printer), "%.*s" fmt, (indent), "\t\t\t\t\tX", ##__VA_ARGS__) | |
d8187177 | 111 | |
cfc57a18 JC |
112 | /** |
113 | * struct drm_print_iterator - local struct used with drm_printer_coredump | |
114 | * @data: Pointer to the devcoredump output buffer | |
115 | * @start: The offset within the buffer to start writing | |
116 | * @remain: The number of bytes to write for this iteration | |
117 | */ | |
118 | struct drm_print_iterator { | |
119 | void *data; | |
120 | ssize_t start; | |
121 | ssize_t remain; | |
122 | /* private: */ | |
123 | ssize_t offset; | |
124 | }; | |
125 | ||
126 | /** | |
127 | * drm_coredump_printer - construct a &drm_printer that can output to a buffer | |
128 | * from the read function for devcoredump | |
129 | * @iter: A pointer to a struct drm_print_iterator for the read instance | |
130 | * | |
131 | * This wrapper extends drm_printf() to work with a dev_coredumpm() callback | |
132 | * function. The passed in drm_print_iterator struct contains the buffer | |
133 | * pointer, size and offset as passed in from devcoredump. | |
134 | * | |
135 | * For example:: | |
136 | * | |
137 | * void coredump_read(char *buffer, loff_t offset, size_t count, | |
138 | * void *data, size_t datalen) | |
139 | * { | |
140 | * struct drm_print_iterator iter; | |
141 | * struct drm_printer p; | |
142 | * | |
143 | * iter.data = buffer; | |
144 | * iter.start = offset; | |
145 | * iter.remain = count; | |
146 | * | |
147 | * p = drm_coredump_printer(&iter); | |
148 | * | |
149 | * drm_printf(p, "foo=%d\n", foo); | |
150 | * } | |
151 | * | |
152 | * void makecoredump(...) | |
153 | * { | |
154 | * ... | |
155 | * dev_coredumpm(dev, THIS_MODULE, data, 0, GFP_KERNEL, | |
156 | * coredump_read, ...) | |
157 | * } | |
158 | * | |
159 | * RETURNS: | |
160 | * The &drm_printer object | |
161 | */ | |
162 | static inline struct drm_printer | |
163 | drm_coredump_printer(struct drm_print_iterator *iter) | |
164 | { | |
165 | struct drm_printer p = { | |
166 | .printfn = __drm_printfn_coredump, | |
5dc634bd | 167 | .puts = __drm_puts_coredump, |
cfc57a18 JC |
168 | .arg = iter, |
169 | }; | |
170 | ||
171 | /* Set the internal offset of the iterator to zero */ | |
172 | iter->offset = 0; | |
173 | ||
174 | return p; | |
175 | } | |
176 | ||
d8187177 RC |
177 | /** |
178 | * drm_seq_file_printer - construct a &drm_printer that outputs to &seq_file | |
ea0dd85a | 179 | * @f: the &struct seq_file to output to |
d8187177 RC |
180 | * |
181 | * RETURNS: | |
182 | * The &drm_printer object | |
183 | */ | |
184 | static inline struct drm_printer drm_seq_file_printer(struct seq_file *f) | |
185 | { | |
186 | struct drm_printer p = { | |
187 | .printfn = __drm_printfn_seq_file, | |
4538d732 | 188 | .puts = __drm_puts_seq_file, |
d8187177 RC |
189 | .arg = f, |
190 | }; | |
191 | return p; | |
192 | } | |
193 | ||
194 | /** | |
195 | * drm_info_printer - construct a &drm_printer that outputs to dev_printk() | |
ea0dd85a | 196 | * @dev: the &struct device pointer |
d8187177 RC |
197 | * |
198 | * RETURNS: | |
199 | * The &drm_printer object | |
200 | */ | |
201 | static inline struct drm_printer drm_info_printer(struct device *dev) | |
202 | { | |
203 | struct drm_printer p = { | |
204 | .printfn = __drm_printfn_info, | |
205 | .arg = dev, | |
206 | }; | |
207 | return p; | |
208 | } | |
209 | ||
3d387d92 DV |
210 | /** |
211 | * drm_debug_printer - construct a &drm_printer that outputs to pr_debug() | |
212 | * @prefix: debug output prefix | |
213 | * | |
214 | * RETURNS: | |
215 | * The &drm_printer object | |
216 | */ | |
217 | static inline struct drm_printer drm_debug_printer(const char *prefix) | |
218 | { | |
219 | struct drm_printer p = { | |
220 | .printfn = __drm_printfn_debug, | |
221 | .prefix = prefix | |
222 | }; | |
223 | return p; | |
224 | } | |
02c9656b HM |
225 | |
226 | /* | |
227 | * The following categories are defined: | |
228 | * | |
229 | * CORE: Used in the generic drm code: drm_ioctl.c, drm_mm.c, drm_memory.c, ... | |
230 | * This is the category used by the DRM_DEBUG() macro. | |
231 | * | |
232 | * DRIVER: Used in the vendor specific part of the driver: i915, radeon, ... | |
233 | * This is the category used by the DRM_DEBUG_DRIVER() macro. | |
234 | * | |
235 | * KMS: used in the modesetting code. | |
236 | * This is the category used by the DRM_DEBUG_KMS() macro. | |
237 | * | |
238 | * PRIME: used in the prime code. | |
239 | * This is the category used by the DRM_DEBUG_PRIME() macro. | |
240 | * | |
241 | * ATOMIC: used in the atomic code. | |
242 | * This is the category used by the DRM_DEBUG_ATOMIC() macro. | |
243 | * | |
244 | * VBL: used for verbose debug message in the vblank code | |
245 | * This is the category used by the DRM_DEBUG_VBL() macro. | |
246 | * | |
247 | * Enabling verbose debug messages is done through the drm.debug parameter, | |
248 | * each category being enabled by a bit. | |
249 | * | |
250 | * drm.debug=0x1 will enable CORE messages | |
251 | * drm.debug=0x2 will enable DRIVER messages | |
252 | * drm.debug=0x3 will enable CORE and DRIVER messages | |
253 | * ... | |
254 | * drm.debug=0x3f will enable all messages | |
255 | * | |
256 | * An interesting feature is that it's possible to enable verbose logging at | |
257 | * run-time by echoing the debug value in its sysfs node: | |
258 | * # echo 0xf > /sys/module/drm/parameters/debug | |
259 | */ | |
260 | #define DRM_UT_NONE 0x00 | |
261 | #define DRM_UT_CORE 0x01 | |
262 | #define DRM_UT_DRIVER 0x02 | |
263 | #define DRM_UT_KMS 0x04 | |
264 | #define DRM_UT_PRIME 0x08 | |
265 | #define DRM_UT_ATOMIC 0x10 | |
266 | #define DRM_UT_VBL 0x20 | |
267 | #define DRM_UT_STATE 0x40 | |
70c5f936 | 268 | #define DRM_UT_LEASE 0x80 |
a18b2192 | 269 | #define DRM_UT_DP 0x100 |
02c9656b | 270 | |
db870864 | 271 | __printf(3, 4) |
02c9656b | 272 | void drm_dev_printk(const struct device *dev, const char *level, |
db870864 JP |
273 | const char *format, ...); |
274 | __printf(3, 4) | |
275 | void drm_dev_dbg(const struct device *dev, unsigned int category, | |
276 | const char *format, ...); | |
277 | ||
99a95487 JP |
278 | __printf(2, 3) |
279 | void drm_dbg(unsigned int category, const char *format, ...); | |
280 | __printf(1, 2) | |
281 | void drm_err(const char *format, ...); | |
091756bb HM |
282 | |
283 | /* Macros to make printk easier */ | |
02c9656b HM |
284 | |
285 | #define _DRM_PRINTK(once, level, fmt, ...) \ | |
db870864 | 286 | printk##once(KERN_##level "[" DRM_NAME "] " fmt, ##__VA_ARGS__) |
02c9656b HM |
287 | |
288 | #define DRM_INFO(fmt, ...) \ | |
289 | _DRM_PRINTK(, INFO, fmt, ##__VA_ARGS__) | |
290 | #define DRM_NOTE(fmt, ...) \ | |
291 | _DRM_PRINTK(, NOTICE, fmt, ##__VA_ARGS__) | |
292 | #define DRM_WARN(fmt, ...) \ | |
293 | _DRM_PRINTK(, WARNING, fmt, ##__VA_ARGS__) | |
294 | ||
295 | #define DRM_INFO_ONCE(fmt, ...) \ | |
296 | _DRM_PRINTK(_once, INFO, fmt, ##__VA_ARGS__) | |
297 | #define DRM_NOTE_ONCE(fmt, ...) \ | |
298 | _DRM_PRINTK(_once, NOTICE, fmt, ##__VA_ARGS__) | |
299 | #define DRM_WARN_ONCE(fmt, ...) \ | |
300 | _DRM_PRINTK(_once, WARNING, fmt, ##__VA_ARGS__) | |
301 | ||
302 | /** | |
303 | * Error output. | |
304 | * | |
091756bb HM |
305 | * @dev: device pointer |
306 | * @fmt: printf() like format string. | |
02c9656b HM |
307 | */ |
308 | #define DRM_DEV_ERROR(dev, fmt, ...) \ | |
db870864 | 309 | drm_dev_printk(dev, KERN_ERR, "*ERROR* " fmt, ##__VA_ARGS__) |
02c9656b | 310 | #define DRM_ERROR(fmt, ...) \ |
99a95487 | 311 | drm_err(fmt, ##__VA_ARGS__) |
02c9656b HM |
312 | |
313 | /** | |
314 | * Rate limited error output. Like DRM_ERROR() but won't flood the log. | |
315 | * | |
091756bb HM |
316 | * @dev: device pointer |
317 | * @fmt: printf() like format string. | |
02c9656b HM |
318 | */ |
319 | #define DRM_DEV_ERROR_RATELIMITED(dev, fmt, ...) \ | |
320 | ({ \ | |
321 | static DEFINE_RATELIMIT_STATE(_rs, \ | |
322 | DEFAULT_RATELIMIT_INTERVAL, \ | |
323 | DEFAULT_RATELIMIT_BURST); \ | |
324 | \ | |
325 | if (__ratelimit(&_rs)) \ | |
326 | DRM_DEV_ERROR(dev, fmt, ##__VA_ARGS__); \ | |
327 | }) | |
328 | #define DRM_ERROR_RATELIMITED(fmt, ...) \ | |
329 | DRM_DEV_ERROR_RATELIMITED(NULL, fmt, ##__VA_ARGS__) | |
330 | ||
331 | #define DRM_DEV_INFO(dev, fmt, ...) \ | |
db870864 | 332 | drm_dev_printk(dev, KERN_INFO, fmt, ##__VA_ARGS__) |
02c9656b HM |
333 | |
334 | #define DRM_DEV_INFO_ONCE(dev, fmt, ...) \ | |
335 | ({ \ | |
336 | static bool __print_once __read_mostly; \ | |
337 | if (!__print_once) { \ | |
338 | __print_once = true; \ | |
339 | DRM_DEV_INFO(dev, fmt, ##__VA_ARGS__); \ | |
340 | } \ | |
341 | }) | |
342 | ||
343 | /** | |
344 | * Debug output. | |
345 | * | |
091756bb HM |
346 | * @dev: device pointer |
347 | * @fmt: printf() like format string. | |
02c9656b | 348 | */ |
db870864 JP |
349 | #define DRM_DEV_DEBUG(dev, fmt, ...) \ |
350 | drm_dev_dbg(dev, DRM_UT_CORE, fmt, ##__VA_ARGS__) | |
02c9656b | 351 | #define DRM_DEBUG(fmt, ...) \ |
99a95487 | 352 | drm_dbg(DRM_UT_CORE, fmt, ##__VA_ARGS__) |
02c9656b | 353 | |
db870864 JP |
354 | #define DRM_DEV_DEBUG_DRIVER(dev, fmt, ...) \ |
355 | drm_dev_dbg(dev, DRM_UT_DRIVER, fmt, ##__VA_ARGS__) | |
02c9656b | 356 | #define DRM_DEBUG_DRIVER(fmt, ...) \ |
99a95487 | 357 | drm_dbg(DRM_UT_DRIVER, fmt, ##__VA_ARGS__) |
02c9656b | 358 | |
db870864 JP |
359 | #define DRM_DEV_DEBUG_KMS(dev, fmt, ...) \ |
360 | drm_dev_dbg(dev, DRM_UT_KMS, fmt, ##__VA_ARGS__) | |
99a95487 JP |
361 | #define DRM_DEBUG_KMS(fmt, ...) \ |
362 | drm_dbg(DRM_UT_KMS, fmt, ##__VA_ARGS__) | |
02c9656b | 363 | |
db870864 JP |
364 | #define DRM_DEV_DEBUG_PRIME(dev, fmt, ...) \ |
365 | drm_dev_dbg(dev, DRM_UT_PRIME, fmt, ##__VA_ARGS__) | |
02c9656b | 366 | #define DRM_DEBUG_PRIME(fmt, ...) \ |
99a95487 | 367 | drm_dbg(DRM_UT_PRIME, fmt, ##__VA_ARGS__) |
02c9656b | 368 | |
db870864 JP |
369 | #define DRM_DEV_DEBUG_ATOMIC(dev, fmt, ...) \ |
370 | drm_dev_dbg(dev, DRM_UT_ATOMIC, fmt, ##__VA_ARGS__) | |
02c9656b | 371 | #define DRM_DEBUG_ATOMIC(fmt, ...) \ |
99a95487 | 372 | drm_dbg(DRM_UT_ATOMIC, fmt, ##__VA_ARGS__) |
02c9656b | 373 | |
db870864 JP |
374 | #define DRM_DEV_DEBUG_VBL(dev, fmt, ...) \ |
375 | drm_dev_dbg(dev, DRM_UT_VBL, fmt, ##__VA_ARGS__) | |
99a95487 JP |
376 | #define DRM_DEBUG_VBL(fmt, ...) \ |
377 | drm_dbg(DRM_UT_VBL, fmt, ##__VA_ARGS__) | |
02c9656b | 378 | |
70c5f936 | 379 | #define DRM_DEBUG_LEASE(fmt, ...) \ |
99a95487 | 380 | drm_dbg(DRM_UT_LEASE, fmt, ##__VA_ARGS__) |
70c5f936 | 381 | |
a18b2192 LP |
382 | #define DRM_DEV_DEBUG_DP(dev, fmt, ...) \ |
383 | drm_dev_dbg(dev, DRM_UT_DP, fmt, ## __VA_ARGS__) | |
384 | #define DRM_DEBUG_DP(dev, fmt, ...) \ | |
385 | drm_dbg(DRM_UT_DP, fmt, ## __VA_ARGS__) | |
386 | ||
db870864 | 387 | #define _DRM_DEV_DEFINE_DEBUG_RATELIMITED(dev, category, fmt, ...) \ |
02c9656b HM |
388 | ({ \ |
389 | static DEFINE_RATELIMIT_STATE(_rs, \ | |
390 | DEFAULT_RATELIMIT_INTERVAL, \ | |
391 | DEFAULT_RATELIMIT_BURST); \ | |
392 | if (__ratelimit(&_rs)) \ | |
db870864 | 393 | drm_dev_dbg(dev, category, fmt, ##__VA_ARGS__); \ |
02c9656b HM |
394 | }) |
395 | ||
396 | /** | |
397 | * Rate limited debug output. Like DRM_DEBUG() but won't flood the log. | |
398 | * | |
091756bb HM |
399 | * @dev: device pointer |
400 | * @fmt: printf() like format string. | |
02c9656b | 401 | */ |
db870864 JP |
402 | #define DRM_DEV_DEBUG_RATELIMITED(dev, fmt, ...) \ |
403 | _DEV_DRM_DEFINE_DEBUG_RATELIMITED(dev, DRM_UT_CORE, \ | |
404 | fmt, ##__VA_ARGS__) | |
405 | #define DRM_DEBUG_RATELIMITED(fmt, ...) \ | |
406 | DRM_DEV_DEBUG_RATELIMITED(NULL, fmt, ##__VA_ARGS__) | |
407 | ||
408 | #define DRM_DEV_DEBUG_DRIVER_RATELIMITED(dev, fmt, ...) \ | |
409 | _DRM_DEV_DEFINE_DEBUG_RATELIMITED(dev, DRM_UT_DRIVER, \ | |
410 | fmt, ##__VA_ARGS__) | |
411 | #define DRM_DEBUG_DRIVER_RATELIMITED(fmt, ...) \ | |
412 | DRM_DEV_DEBUG_DRIVER_RATELIMITED(NULL, fmt, ##__VA_ARGS__) | |
413 | ||
414 | #define DRM_DEV_DEBUG_KMS_RATELIMITED(dev, fmt, ...) \ | |
415 | _DRM_DEV_DEFINE_DEBUG_RATELIMITED(dev, DRM_UT_KMS, \ | |
416 | fmt, ##__VA_ARGS__) | |
417 | #define DRM_DEBUG_KMS_RATELIMITED(fmt, ...) \ | |
418 | DRM_DEV_DEBUG_KMS_RATELIMITED(NULL, fmt, ##__VA_ARGS__) | |
419 | ||
420 | #define DRM_DEV_DEBUG_PRIME_RATELIMITED(dev, fmt, ...) \ | |
421 | _DRM_DEV_DEFINE_DEBUG_RATELIMITED(dev, DRM_UT_PRIME, \ | |
422 | fmt, ##__VA_ARGS__) | |
423 | #define DRM_DEBUG_PRIME_RATELIMITED(fmt, ...) \ | |
424 | DRM_DEV_DEBUG_PRIME_RATELIMITED(NULL, fmt, ##__VA_ARGS__) | |
02c9656b | 425 | |
d8187177 | 426 | #endif /* DRM_PRINT_H_ */ |