Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/leds/ledtrig-heartbeat.c
15109 views
1
/*
2
* LED Heartbeat Trigger
3
*
4
* Copyright (C) 2006 Atsushi Nemoto <[email protected]>
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 "leds.h"
22
23
struct heartbeat_trig_data {
24
unsigned int phase;
25
unsigned int period;
26
struct timer_list timer;
27
};
28
29
static void led_heartbeat_function(unsigned long data)
30
{
31
struct led_classdev *led_cdev = (struct led_classdev *) data;
32
struct heartbeat_trig_data *heartbeat_data = led_cdev->trigger_data;
33
unsigned long brightness = LED_OFF;
34
unsigned long delay = 0;
35
36
/* acts like an actual heart beat -- ie thump-thump-pause... */
37
switch (heartbeat_data->phase) {
38
case 0:
39
/*
40
* The hyperbolic function below modifies the
41
* heartbeat period length in dependency of the
42
* current (1min) load. It goes through the points
43
* f(0)=1260, f(1)=860, f(5)=510, f(inf)->300.
44
*/
45
heartbeat_data->period = 300 +
46
(6720 << FSHIFT) / (5 * avenrun[0] + (7 << FSHIFT));
47
heartbeat_data->period =
48
msecs_to_jiffies(heartbeat_data->period);
49
delay = msecs_to_jiffies(70);
50
heartbeat_data->phase++;
51
brightness = led_cdev->max_brightness;
52
break;
53
case 1:
54
delay = heartbeat_data->period / 4 - msecs_to_jiffies(70);
55
heartbeat_data->phase++;
56
break;
57
case 2:
58
delay = msecs_to_jiffies(70);
59
heartbeat_data->phase++;
60
brightness = led_cdev->max_brightness;
61
break;
62
default:
63
delay = heartbeat_data->period - heartbeat_data->period / 4 -
64
msecs_to_jiffies(70);
65
heartbeat_data->phase = 0;
66
break;
67
}
68
69
led_set_brightness(led_cdev, brightness);
70
mod_timer(&heartbeat_data->timer, jiffies + delay);
71
}
72
73
static void heartbeat_trig_activate(struct led_classdev *led_cdev)
74
{
75
struct heartbeat_trig_data *heartbeat_data;
76
77
heartbeat_data = kzalloc(sizeof(*heartbeat_data), GFP_KERNEL);
78
if (!heartbeat_data)
79
return;
80
81
led_cdev->trigger_data = heartbeat_data;
82
setup_timer(&heartbeat_data->timer,
83
led_heartbeat_function, (unsigned long) led_cdev);
84
heartbeat_data->phase = 0;
85
led_heartbeat_function(heartbeat_data->timer.data);
86
}
87
88
static void heartbeat_trig_deactivate(struct led_classdev *led_cdev)
89
{
90
struct heartbeat_trig_data *heartbeat_data = led_cdev->trigger_data;
91
92
if (heartbeat_data) {
93
del_timer_sync(&heartbeat_data->timer);
94
kfree(heartbeat_data);
95
}
96
}
97
98
static struct led_trigger heartbeat_led_trigger = {
99
.name = "heartbeat",
100
.activate = heartbeat_trig_activate,
101
.deactivate = heartbeat_trig_deactivate,
102
};
103
104
static int __init heartbeat_trig_init(void)
105
{
106
return led_trigger_register(&heartbeat_led_trigger);
107
}
108
109
static void __exit heartbeat_trig_exit(void)
110
{
111
led_trigger_unregister(&heartbeat_led_trigger);
112
}
113
114
module_init(heartbeat_trig_init);
115
module_exit(heartbeat_trig_exit);
116
117
MODULE_AUTHOR("Atsushi Nemoto <[email protected]>");
118
MODULE_DESCRIPTION("Heartbeat LED trigger");
119
MODULE_LICENSE("GPL");
120
121