diff options
author | Paul Mundt <lethal@linux-sh.org> | 2009-05-13 08:51:28 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2009-05-13 08:51:28 -0400 |
commit | cedcf3366f2191885aff92d33d6078ef08203e52 (patch) | |
tree | 23d46b2735b7ab2df213751fcf50d667596ae3ae /arch/sh/kernel/cpu/clock.c | |
parent | cc96eace48fdf0f8925a74c6c1f7ffa512e458d2 (diff) |
sh: clkfwk: Map tree hierarchy in debugfs.
This adopts the OMAP clock framework debugfs bits and replaces the aging
procfs bits. The procfs clocks entry was primarily a debugging aid, and
used to be tied in to cpuinfo before the clock list grew too unweildly.
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/kernel/cpu/clock.c')
-rw-r--r-- | arch/sh/kernel/cpu/clock.c | 110 |
1 files changed, 84 insertions, 26 deletions
diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c index 56c6e11fa83b..686477f8ae5b 100644 --- a/arch/sh/kernel/cpu/clock.c +++ b/arch/sh/kernel/cpu/clock.c | |||
@@ -28,7 +28,7 @@ | |||
28 | #include <linux/seq_file.h> | 28 | #include <linux/seq_file.h> |
29 | #include <linux/err.h> | 29 | #include <linux/err.h> |
30 | #include <linux/platform_device.h> | 30 | #include <linux/platform_device.h> |
31 | #include <linux/proc_fs.h> | 31 | #include <linux/debugfs.h> |
32 | #include <asm/clock.h> | 32 | #include <asm/clock.h> |
33 | #include <asm/machvec.h> | 33 | #include <asm/machvec.h> |
34 | 34 | ||
@@ -404,24 +404,6 @@ void clk_put(struct clk *clk) | |||
404 | } | 404 | } |
405 | EXPORT_SYMBOL_GPL(clk_put); | 405 | EXPORT_SYMBOL_GPL(clk_put); |
406 | 406 | ||
407 | |||
408 | static int show_clocks(char *buf, char **start, off_t off, | ||
409 | int len, int *eof, void *data) | ||
410 | { | ||
411 | struct clk *clk; | ||
412 | char *p = buf; | ||
413 | |||
414 | list_for_each_entry_reverse(clk, &clock_list, node) { | ||
415 | unsigned long rate = clk_get_rate(clk); | ||
416 | |||
417 | p += sprintf(p, "%-12s\t: %ld.%02ldMHz\t%s\n", clk->name, | ||
418 | rate / 1000000, (rate % 1000000) / 10000, | ||
419 | (clk->usecount > 0) ? "enabled" : "disabled"); | ||
420 | } | ||
421 | |||
422 | return p - buf; | ||
423 | } | ||
424 | |||
425 | #ifdef CONFIG_PM | 407 | #ifdef CONFIG_PM |
426 | static int clks_sysdev_suspend(struct sys_device *dev, pm_message_t state) | 408 | static int clks_sysdev_suspend(struct sys_device *dev, pm_message_t state) |
427 | { | 409 | { |
@@ -516,14 +498,90 @@ int __init clk_init(void) | |||
516 | return ret; | 498 | return ret; |
517 | } | 499 | } |
518 | 500 | ||
519 | static int __init clk_proc_init(void) | 501 | /* |
502 | * debugfs support to trace clock tree hierarchy and attributes | ||
503 | */ | ||
504 | static struct dentry *clk_debugfs_root; | ||
505 | |||
506 | static int clk_debugfs_register_one(struct clk *c) | ||
520 | { | 507 | { |
521 | struct proc_dir_entry *p; | 508 | int err; |
522 | p = create_proc_read_entry("clocks", S_IRUSR, NULL, | 509 | struct dentry *d, *child; |
523 | show_clocks, NULL); | 510 | struct clk *pa = c->parent; |
524 | if (unlikely(!p)) | 511 | char s[255]; |
525 | return -EINVAL; | 512 | char *p = s; |
513 | |||
514 | p += sprintf(p, "%s", c->name); | ||
515 | if (c->id > 0) | ||
516 | sprintf(p, ":%d", c->id); | ||
517 | d = debugfs_create_dir(s, pa ? pa->dentry : clk_debugfs_root); | ||
518 | if (!d) | ||
519 | return -ENOMEM; | ||
520 | c->dentry = d; | ||
521 | |||
522 | d = debugfs_create_u8("usecount", S_IRUGO, c->dentry, (u8 *)&c->usecount); | ||
523 | if (!d) { | ||
524 | err = -ENOMEM; | ||
525 | goto err_out; | ||
526 | } | ||
527 | d = debugfs_create_u32("rate", S_IRUGO, c->dentry, (u32 *)&c->rate); | ||
528 | if (!d) { | ||
529 | err = -ENOMEM; | ||
530 | goto err_out; | ||
531 | } | ||
532 | d = debugfs_create_x32("flags", S_IRUGO, c->dentry, (u32 *)&c->flags); | ||
533 | if (!d) { | ||
534 | err = -ENOMEM; | ||
535 | goto err_out; | ||
536 | } | ||
537 | return 0; | ||
538 | |||
539 | err_out: | ||
540 | d = c->dentry; | ||
541 | list_for_each_entry(child, &d->d_subdirs, d_u.d_child) | ||
542 | debugfs_remove(child); | ||
543 | debugfs_remove(c->dentry); | ||
544 | return err; | ||
545 | } | ||
546 | |||
547 | static int clk_debugfs_register(struct clk *c) | ||
548 | { | ||
549 | int err; | ||
550 | struct clk *pa = c->parent; | ||
551 | |||
552 | if (pa && !pa->dentry) { | ||
553 | err = clk_debugfs_register(pa); | ||
554 | if (err) | ||
555 | return err; | ||
556 | } | ||
526 | 557 | ||
558 | if (!c->dentry) { | ||
559 | err = clk_debugfs_register_one(c); | ||
560 | if (err) | ||
561 | return err; | ||
562 | } | ||
563 | return 0; | ||
564 | } | ||
565 | |||
566 | static int __init clk_debugfs_init(void) | ||
567 | { | ||
568 | struct clk *c; | ||
569 | struct dentry *d; | ||
570 | int err; | ||
571 | |||
572 | d = debugfs_create_dir("clock", NULL); | ||
573 | if (!d) | ||
574 | return -ENOMEM; | ||
575 | clk_debugfs_root = d; | ||
576 | |||
577 | list_for_each_entry(c, &clock_list, node) { | ||
578 | err = clk_debugfs_register(c); | ||
579 | if (err) | ||
580 | goto err_out; | ||
581 | } | ||
527 | return 0; | 582 | return 0; |
583 | err_out: | ||
584 | debugfs_remove(clk_debugfs_root); /* REVISIT: Cleanup correctly */ | ||
585 | return err; | ||
528 | } | 586 | } |
529 | subsys_initcall(clk_proc_init); | 587 | late_initcall(clk_debugfs_init); |