diff options
-rw-r--r-- | drivers/pwm/core.c | 90 | ||||
-rw-r--r-- | include/linux/pwm.h | 6 |
2 files changed, 96 insertions, 0 deletions
diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c index a447be128328..aadc1d797449 100644 --- a/drivers/pwm/core.c +++ b/drivers/pwm/core.c | |||
@@ -27,6 +27,8 @@ | |||
27 | #include <linux/err.h> | 27 | #include <linux/err.h> |
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <linux/device.h> | 29 | #include <linux/device.h> |
30 | #include <linux/debugfs.h> | ||
31 | #include <linux/seq_file.h> | ||
30 | 32 | ||
31 | #define MAX_PWMS 1024 | 33 | #define MAX_PWMS 1024 |
32 | 34 | ||
@@ -338,3 +340,91 @@ void pwm_disable(struct pwm_device *pwm) | |||
338 | pwm->chip->ops->disable(pwm->chip, pwm); | 340 | pwm->chip->ops->disable(pwm->chip, pwm); |
339 | } | 341 | } |
340 | EXPORT_SYMBOL_GPL(pwm_disable); | 342 | EXPORT_SYMBOL_GPL(pwm_disable); |
343 | |||
344 | #ifdef CONFIG_DEBUG_FS | ||
345 | static void pwm_dbg_show(struct pwm_chip *chip, struct seq_file *s) | ||
346 | { | ||
347 | unsigned int i; | ||
348 | |||
349 | for (i = 0; i < chip->npwm; i++) { | ||
350 | struct pwm_device *pwm = &chip->pwms[i]; | ||
351 | |||
352 | seq_printf(s, " pwm-%-3d (%-20.20s):", i, pwm->label); | ||
353 | |||
354 | if (test_bit(PWMF_REQUESTED, &pwm->flags)) | ||
355 | seq_printf(s, " requested"); | ||
356 | |||
357 | if (test_bit(PWMF_ENABLED, &pwm->flags)) | ||
358 | seq_printf(s, " enabled"); | ||
359 | |||
360 | seq_printf(s, "\n"); | ||
361 | } | ||
362 | } | ||
363 | |||
364 | static void *pwm_seq_start(struct seq_file *s, loff_t *pos) | ||
365 | { | ||
366 | mutex_lock(&pwm_lock); | ||
367 | s->private = ""; | ||
368 | |||
369 | return seq_list_start(&pwm_chips, *pos); | ||
370 | } | ||
371 | |||
372 | static void *pwm_seq_next(struct seq_file *s, void *v, loff_t *pos) | ||
373 | { | ||
374 | s->private = "\n"; | ||
375 | |||
376 | return seq_list_next(v, &pwm_chips, pos); | ||
377 | } | ||
378 | |||
379 | static void pwm_seq_stop(struct seq_file *s, void *v) | ||
380 | { | ||
381 | mutex_unlock(&pwm_lock); | ||
382 | } | ||
383 | |||
384 | static int pwm_seq_show(struct seq_file *s, void *v) | ||
385 | { | ||
386 | struct pwm_chip *chip = list_entry(v, struct pwm_chip, list); | ||
387 | |||
388 | seq_printf(s, "%s%s/%s, %d PWM device%s\n", (char *)s->private, | ||
389 | chip->dev->bus ? chip->dev->bus->name : "no-bus", | ||
390 | dev_name(chip->dev), chip->npwm, | ||
391 | (chip->npwm != 1) ? "s" : ""); | ||
392 | |||
393 | if (chip->ops->dbg_show) | ||
394 | chip->ops->dbg_show(chip, s); | ||
395 | else | ||
396 | pwm_dbg_show(chip, s); | ||
397 | |||
398 | return 0; | ||
399 | } | ||
400 | |||
401 | static const struct seq_operations pwm_seq_ops = { | ||
402 | .start = pwm_seq_start, | ||
403 | .next = pwm_seq_next, | ||
404 | .stop = pwm_seq_stop, | ||
405 | .show = pwm_seq_show, | ||
406 | }; | ||
407 | |||
408 | static int pwm_seq_open(struct inode *inode, struct file *file) | ||
409 | { | ||
410 | return seq_open(file, &pwm_seq_ops); | ||
411 | } | ||
412 | |||
413 | static const struct file_operations pwm_debugfs_ops = { | ||
414 | .owner = THIS_MODULE, | ||
415 | .open = pwm_seq_open, | ||
416 | .read = seq_read, | ||
417 | .llseek = seq_lseek, | ||
418 | .release = seq_release, | ||
419 | }; | ||
420 | |||
421 | static int __init pwm_debugfs_init(void) | ||
422 | { | ||
423 | debugfs_create_file("pwm", S_IFREG | S_IRUGO, NULL, NULL, | ||
424 | &pwm_debugfs_ops); | ||
425 | |||
426 | return 0; | ||
427 | } | ||
428 | |||
429 | subsys_initcall(pwm_debugfs_init); | ||
430 | #endif /* CONFIG_DEBUG_FS */ | ||
diff --git a/include/linux/pwm.h b/include/linux/pwm.h index 57103911f4c7..047cd5351a3b 100644 --- a/include/linux/pwm.h +++ b/include/linux/pwm.h | |||
@@ -2,6 +2,7 @@ | |||
2 | #define __LINUX_PWM_H | 2 | #define __LINUX_PWM_H |
3 | 3 | ||
4 | struct pwm_device; | 4 | struct pwm_device; |
5 | struct seq_file; | ||
5 | 6 | ||
6 | /* | 7 | /* |
7 | * pwm_request - request a PWM device | 8 | * pwm_request - request a PWM device |
@@ -65,6 +66,7 @@ static inline unsigned int pwm_get_period(struct pwm_device *pwm) | |||
65 | * @config: configure duty cycles and period length for this PWM | 66 | * @config: configure duty cycles and period length for this PWM |
66 | * @enable: enable PWM output toggling | 67 | * @enable: enable PWM output toggling |
67 | * @disable: disable PWM output toggling | 68 | * @disable: disable PWM output toggling |
69 | * @dbg_show: optional routine to show contents in debugfs | ||
68 | * @owner: helps prevent removal of modules exporting active PWMs | 70 | * @owner: helps prevent removal of modules exporting active PWMs |
69 | */ | 71 | */ |
70 | struct pwm_ops { | 72 | struct pwm_ops { |
@@ -79,6 +81,10 @@ struct pwm_ops { | |||
79 | struct pwm_device *pwm); | 81 | struct pwm_device *pwm); |
80 | void (*disable)(struct pwm_chip *chip, | 82 | void (*disable)(struct pwm_chip *chip, |
81 | struct pwm_device *pwm); | 83 | struct pwm_device *pwm); |
84 | #ifdef CONFIG_DEBUG_FS | ||
85 | void (*dbg_show)(struct pwm_chip *chip, | ||
86 | struct seq_file *s); | ||
87 | #endif | ||
82 | struct module *owner; | 88 | struct module *owner; |
83 | }; | 89 | }; |
84 | 90 | ||