diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2013-04-25 16:31:49 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2013-05-16 05:09:17 -0400 |
commit | 501f867064e95f9a6f540e60705be0937280e7ec (patch) | |
tree | 92cabb49d9e67f9824bd2d09a9872b02d69b3a97 /kernel/time/clockevents.c | |
parent | ccf33d6880f39a35158fff66db13000ae4943fac (diff) |
clockevents: Provide sysfs interface
Provide a simple sysfs interface for the clockevent devices. Show the
current active clockevent device.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: John Stultz <john.stultz@linaro.org>
Cc: Magnus Damm <magnus.damm@gmail.com>
Link: http://lkml.kernel.org/r/20130425143436.371634778@linutronix.de
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'kernel/time/clockevents.c')
-rw-r--r-- | kernel/time/clockevents.c | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c index 89e394caa769..0a23f4f29934 100644 --- a/kernel/time/clockevents.c +++ b/kernel/time/clockevents.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/init.h> | 16 | #include <linux/init.h> |
17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
18 | #include <linux/smp.h> | 18 | #include <linux/smp.h> |
19 | #include <linux/device.h> | ||
19 | 20 | ||
20 | #include "tick-internal.h" | 21 | #include "tick-internal.h" |
21 | 22 | ||
@@ -460,4 +461,89 @@ void clockevents_notify(unsigned long reason, void *arg) | |||
460 | raw_spin_unlock_irqrestore(&clockevents_lock, flags); | 461 | raw_spin_unlock_irqrestore(&clockevents_lock, flags); |
461 | } | 462 | } |
462 | EXPORT_SYMBOL_GPL(clockevents_notify); | 463 | EXPORT_SYMBOL_GPL(clockevents_notify); |
464 | |||
465 | #ifdef CONFIG_SYSFS | ||
466 | struct bus_type clockevents_subsys = { | ||
467 | .name = "clockevents", | ||
468 | .dev_name = "clockevent", | ||
469 | }; | ||
470 | |||
471 | static DEFINE_PER_CPU(struct device, tick_percpu_dev); | ||
472 | static struct tick_device *tick_get_tick_dev(struct device *dev); | ||
473 | |||
474 | static ssize_t sysfs_show_current_tick_dev(struct device *dev, | ||
475 | struct device_attribute *attr, | ||
476 | char *buf) | ||
477 | { | ||
478 | struct tick_device *td; | ||
479 | ssize_t count = 0; | ||
480 | |||
481 | raw_spin_lock_irq(&clockevents_lock); | ||
482 | td = tick_get_tick_dev(dev); | ||
483 | if (td && td->evtdev) | ||
484 | count = snprintf(buf, PAGE_SIZE, "%s\n", td->evtdev->name); | ||
485 | raw_spin_unlock_irq(&clockevents_lock); | ||
486 | return count; | ||
487 | } | ||
488 | static DEVICE_ATTR(current_device, 0444, sysfs_show_current_tick_dev, NULL); | ||
489 | |||
490 | #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST | ||
491 | static struct device tick_bc_dev = { | ||
492 | .init_name = "broadcast", | ||
493 | .id = 0, | ||
494 | .bus = &clockevents_subsys, | ||
495 | }; | ||
496 | |||
497 | static struct tick_device *tick_get_tick_dev(struct device *dev) | ||
498 | { | ||
499 | return dev == &tick_bc_dev ? tick_get_broadcast_device() : | ||
500 | &per_cpu(tick_cpu_device, dev->id); | ||
501 | } | ||
502 | |||
503 | static __init int tick_broadcast_init_sysfs(void) | ||
504 | { | ||
505 | int err = device_register(&tick_bc_dev); | ||
506 | |||
507 | if (!err) | ||
508 | err = device_create_file(&tick_bc_dev, &dev_attr_current_device); | ||
509 | return err; | ||
510 | } | ||
511 | #else | ||
512 | static struct tick_device *tick_get_tick_dev(struct device *dev) | ||
513 | { | ||
514 | return &per_cpu(tick_cpu_device, dev->id); | ||
515 | } | ||
516 | static inline int tick_broadcast_init_sysfs(void) { return 0; } | ||
463 | #endif | 517 | #endif |
518 | |||
519 | static int __init tick_init_sysfs(void) | ||
520 | { | ||
521 | int cpu; | ||
522 | |||
523 | for_each_possible_cpu(cpu) { | ||
524 | struct device *dev = &per_cpu(tick_percpu_dev, cpu); | ||
525 | int err; | ||
526 | |||
527 | dev->id = cpu; | ||
528 | dev->bus = &clockevents_subsys; | ||
529 | err = device_register(dev); | ||
530 | if (!err) | ||
531 | err = device_create_file(dev, &dev_attr_current_device); | ||
532 | if (err) | ||
533 | return err; | ||
534 | } | ||
535 | return tick_broadcast_init_sysfs(); | ||
536 | } | ||
537 | |||
538 | static int __init clockevents_init_sysfs(void) | ||
539 | { | ||
540 | int err = subsys_system_register(&clockevents_subsys, NULL); | ||
541 | |||
542 | if (!err) | ||
543 | err = tick_init_sysfs(); | ||
544 | return err; | ||
545 | } | ||
546 | device_initcall(clockevents_init_sysfs); | ||
547 | #endif /* SYSFS */ | ||
548 | |||
549 | #endif /* GENERIC_CLOCK_EVENTS */ | ||