diff options
Diffstat (limited to 'arch/arm/plat-samsung/clock.c')
-rw-r--r-- | arch/arm/plat-samsung/clock.c | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/arch/arm/plat-samsung/clock.c b/arch/arm/plat-samsung/clock.c index e8d20b0bc50e..772892826ffc 100644 --- a/arch/arm/plat-samsung/clock.c +++ b/arch/arm/plat-samsung/clock.c | |||
@@ -39,6 +39,9 @@ | |||
39 | #include <linux/clk.h> | 39 | #include <linux/clk.h> |
40 | #include <linux/spinlock.h> | 40 | #include <linux/spinlock.h> |
41 | #include <linux/io.h> | 41 | #include <linux/io.h> |
42 | #if defined(CONFIG_DEBUG_FS) | ||
43 | #include <linux/debugfs.h> | ||
44 | #endif | ||
42 | 45 | ||
43 | #include <mach/hardware.h> | 46 | #include <mach/hardware.h> |
44 | #include <asm/irq.h> | 47 | #include <asm/irq.h> |
@@ -447,3 +450,92 @@ int __init s3c24xx_register_baseclocks(unsigned long xtal) | |||
447 | return 0; | 450 | return 0; |
448 | } | 451 | } |
449 | 452 | ||
453 | #if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS) | ||
454 | /* debugfs support to trace clock tree hierarchy and attributes */ | ||
455 | |||
456 | static struct dentry *clk_debugfs_root; | ||
457 | |||
458 | static int clk_debugfs_register_one(struct clk *c) | ||
459 | { | ||
460 | int err; | ||
461 | struct dentry *d, *child, *child_tmp; | ||
462 | struct clk *pa = c->parent; | ||
463 | char s[255]; | ||
464 | char *p = s; | ||
465 | |||
466 | p += sprintf(p, "%s", c->name); | ||
467 | |||
468 | if (c->id >= 0) | ||
469 | sprintf(p, ":%d", c->id); | ||
470 | |||
471 | d = debugfs_create_dir(s, pa ? pa->dent : clk_debugfs_root); | ||
472 | if (!d) | ||
473 | return -ENOMEM; | ||
474 | |||
475 | c->dent = d; | ||
476 | |||
477 | d = debugfs_create_u8("usecount", S_IRUGO, c->dent, (u8 *)&c->usage); | ||
478 | if (!d) { | ||
479 | err = -ENOMEM; | ||
480 | goto err_out; | ||
481 | } | ||
482 | |||
483 | d = debugfs_create_u32("rate", S_IRUGO, c->dent, (u32 *)&c->rate); | ||
484 | if (!d) { | ||
485 | err = -ENOMEM; | ||
486 | goto err_out; | ||
487 | } | ||
488 | return 0; | ||
489 | |||
490 | err_out: | ||
491 | d = c->dent; | ||
492 | list_for_each_entry_safe(child, child_tmp, &d->d_subdirs, d_u.d_child) | ||
493 | debugfs_remove(child); | ||
494 | debugfs_remove(c->dent); | ||
495 | return err; | ||
496 | } | ||
497 | |||
498 | static int clk_debugfs_register(struct clk *c) | ||
499 | { | ||
500 | int err; | ||
501 | struct clk *pa = c->parent; | ||
502 | |||
503 | if (pa && !pa->dent) { | ||
504 | err = clk_debugfs_register(pa); | ||
505 | if (err) | ||
506 | return err; | ||
507 | } | ||
508 | |||
509 | if (!c->dent) { | ||
510 | err = clk_debugfs_register_one(c); | ||
511 | if (err) | ||
512 | return err; | ||
513 | } | ||
514 | return 0; | ||
515 | } | ||
516 | |||
517 | static int __init clk_debugfs_init(void) | ||
518 | { | ||
519 | struct clk *c; | ||
520 | struct dentry *d; | ||
521 | int err; | ||
522 | |||
523 | d = debugfs_create_dir("clock", NULL); | ||
524 | if (!d) | ||
525 | return -ENOMEM; | ||
526 | clk_debugfs_root = d; | ||
527 | |||
528 | list_for_each_entry(c, &clocks, list) { | ||
529 | err = clk_debugfs_register(c); | ||
530 | if (err) | ||
531 | goto err_out; | ||
532 | } | ||
533 | return 0; | ||
534 | |||
535 | err_out: | ||
536 | debugfs_remove_recursive(clk_debugfs_root); | ||
537 | return err; | ||
538 | } | ||
539 | late_initcall(clk_debugfs_init); | ||
540 | |||
541 | #endif /* defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS) */ | ||