aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/leds/trigger/ledtrig-heartbeat.c
diff options
context:
space:
mode:
authorKim, Milo <Milo.Kim@ti.com>2013-02-20 03:36:01 -0500
committerBryan Wu <cooloney@gmail.com>2013-04-01 14:04:48 -0400
commitf07fb52107c881f35eaff09fe990a4dfd0f7e62a (patch)
treeb4b338f39799781648b5c6e0782c9ad746733bca /drivers/leds/trigger/ledtrig-heartbeat.c
parentff45262a85dbf1bc74463c5dcea1d71a406d4d8e (diff)
leds: move LED trigger drivers into new subdirectory
For better driver management, new subdirectory, 'trigger' is created. All LED trigger drivers are moved into this directory. Internal header, 'leds.h' is included in each LED trigger drivers. Fix the location of header file, "leds.h" -> "../leds.h" in driver files. One exception is here, 'ledtrig-timer.c'. There is no need to include 'leds.h'. so '#include "leds.h"' line was removed. Signed-off-by: Milo(Woogyom) Kim <milo.kim@ti.com> Signed-off-by: Bryan Wu <cooloney@gmail.com>
Diffstat (limited to 'drivers/leds/trigger/ledtrig-heartbeat.c')
-rw-r--r--drivers/leds/trigger/ledtrig-heartbeat.c161
1 files changed, 161 insertions, 0 deletions
diff --git a/drivers/leds/trigger/ledtrig-heartbeat.c b/drivers/leds/trigger/ledtrig-heartbeat.c
new file mode 100644
index 000000000000..5c8464a33172
--- /dev/null
+++ b/drivers/leds/trigger/ledtrig-heartbeat.c
@@ -0,0 +1,161 @@
1/*
2 * LED Heartbeat Trigger
3 *
4 * Copyright (C) 2006 Atsushi Nemoto <anemo@mba.ocn.ne.jp>
5 *
6 * Based on Richard Purdie's ledtrig-timer.c and some arch's
7 * CONFIG_HEARTBEAT code.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 */
14#include <linux/module.h>
15#include <linux/kernel.h>
16#include <linux/init.h>
17#include <linux/slab.h>
18#include <linux/timer.h>
19#include <linux/sched.h>
20#include <linux/leds.h>
21#include <linux/reboot.h>
22#include "../leds.h"
23
24static int panic_heartbeats;
25
26struct heartbeat_trig_data {
27 unsigned int phase;
28 unsigned int period;
29 struct timer_list timer;
30};
31
32static void led_heartbeat_function(unsigned long data)
33{
34 struct led_classdev *led_cdev = (struct led_classdev *) data;
35 struct heartbeat_trig_data *heartbeat_data = led_cdev->trigger_data;
36 unsigned long brightness = LED_OFF;
37 unsigned long delay = 0;
38
39 if (unlikely(panic_heartbeats)) {
40 led_set_brightness(led_cdev, LED_OFF);
41 return;
42 }
43
44 /* acts like an actual heart beat -- ie thump-thump-pause... */
45 switch (heartbeat_data->phase) {
46 case 0:
47 /*
48 * The hyperbolic function below modifies the
49 * heartbeat period length in dependency of the
50 * current (1min) load. It goes through the points
51 * f(0)=1260, f(1)=860, f(5)=510, f(inf)->300.
52 */
53 heartbeat_data->period = 300 +
54 (6720 << FSHIFT) / (5 * avenrun[0] + (7 << FSHIFT));
55 heartbeat_data->period =
56 msecs_to_jiffies(heartbeat_data->period);
57 delay = msecs_to_jiffies(70);
58 heartbeat_data->phase++;
59 brightness = led_cdev->max_brightness;
60 break;
61 case 1:
62 delay = heartbeat_data->period / 4 - msecs_to_jiffies(70);
63 heartbeat_data->phase++;
64 break;
65 case 2:
66 delay = msecs_to_jiffies(70);
67 heartbeat_data->phase++;
68 brightness = led_cdev->max_brightness;
69 break;
70 default:
71 delay = heartbeat_data->period - heartbeat_data->period / 4 -
72 msecs_to_jiffies(70);
73 heartbeat_data->phase = 0;
74 break;
75 }
76
77 __led_set_brightness(led_cdev, brightness);
78 mod_timer(&heartbeat_data->timer, jiffies + delay);
79}
80
81static void heartbeat_trig_activate(struct led_classdev *led_cdev)
82{
83 struct heartbeat_trig_data *heartbeat_data;
84
85 heartbeat_data = kzalloc(sizeof(*heartbeat_data), GFP_KERNEL);
86 if (!heartbeat_data)
87 return;
88
89 led_cdev->trigger_data = heartbeat_data;
90 setup_timer(&heartbeat_data->timer,
91 led_heartbeat_function, (unsigned long) led_cdev);
92 heartbeat_data->phase = 0;
93 led_heartbeat_function(heartbeat_data->timer.data);
94 led_cdev->activated = true;
95}
96
97static void heartbeat_trig_deactivate(struct led_classdev *led_cdev)
98{
99 struct heartbeat_trig_data *heartbeat_data = led_cdev->trigger_data;
100
101 if (led_cdev->activated) {
102 del_timer_sync(&heartbeat_data->timer);
103 kfree(heartbeat_data);
104 led_cdev->activated = false;
105 }
106}
107
108static struct led_trigger heartbeat_led_trigger = {
109 .name = "heartbeat",
110 .activate = heartbeat_trig_activate,
111 .deactivate = heartbeat_trig_deactivate,
112};
113
114static int heartbeat_reboot_notifier(struct notifier_block *nb,
115 unsigned long code, void *unused)
116{
117 led_trigger_unregister(&heartbeat_led_trigger);
118 return NOTIFY_DONE;
119}
120
121static int heartbeat_panic_notifier(struct notifier_block *nb,
122 unsigned long code, void *unused)
123{
124 panic_heartbeats = 1;
125 return NOTIFY_DONE;
126}
127
128static struct notifier_block heartbeat_reboot_nb = {
129 .notifier_call = heartbeat_reboot_notifier,
130};
131
132static struct notifier_block heartbeat_panic_nb = {
133 .notifier_call = heartbeat_panic_notifier,
134};
135
136static int __init heartbeat_trig_init(void)
137{
138 int rc = led_trigger_register(&heartbeat_led_trigger);
139
140 if (!rc) {
141 atomic_notifier_chain_register(&panic_notifier_list,
142 &heartbeat_panic_nb);
143 register_reboot_notifier(&heartbeat_reboot_nb);
144 }
145 return rc;
146}
147
148static void __exit heartbeat_trig_exit(void)
149{
150 unregister_reboot_notifier(&heartbeat_reboot_nb);
151 atomic_notifier_chain_unregister(&panic_notifier_list,
152 &heartbeat_panic_nb);
153 led_trigger_unregister(&heartbeat_led_trigger);
154}
155
156module_init(heartbeat_trig_init);
157module_exit(heartbeat_trig_exit);
158
159MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>");
160MODULE_DESCRIPTION("Heartbeat LED trigger");
161MODULE_LICENSE("GPL");