aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pwm/core.c
diff options
context:
space:
mode:
authorThierry Reding <thierry.reding@avionic-design.de>2012-03-26 03:31:48 -0400
committerThierry Reding <thierry.reding@avionic-design.de>2012-06-15 06:56:53 -0400
commit62099abf67a20cfb98d4c031fb1925e10a78ee1b (patch)
tree5d4d68e642e4a632111f4f179c1e0edfc989429c /drivers/pwm/core.c
parentf051c466cf690ac661d713d3ceb56b4efcecc853 (diff)
pwm: Add debugfs interface
This commit adds a debugfs interface that can be used to list the current internal state of the PWM devices registered with the PWM framework. Reviewed-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Reviewed-by: Shawn Guo <shawn.guo@linaro.org> Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
Diffstat (limited to 'drivers/pwm/core.c')
-rw-r--r--drivers/pwm/core.c90
1 files changed, 90 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}
340EXPORT_SYMBOL_GPL(pwm_disable); 342EXPORT_SYMBOL_GPL(pwm_disable);
343
344#ifdef CONFIG_DEBUG_FS
345static 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
364static 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
372static 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
379static void pwm_seq_stop(struct seq_file *s, void *v)
380{
381 mutex_unlock(&pwm_lock);
382}
383
384static 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
401static 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
408static int pwm_seq_open(struct inode *inode, struct file *file)
409{
410 return seq_open(file, &pwm_seq_ops);
411}
412
413static 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
421static 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
429subsys_initcall(pwm_debugfs_init);
430#endif /* CONFIG_DEBUG_FS */