Blame view

drivers/leds/ledtrig-heartbeat.c 3.13 KB
891c668b9   Atsushi Nemoto   [PATCH] LED: add ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
  /*
   * LED Heartbeat Trigger
   *
   * Copyright (C) 2006 Atsushi Nemoto <anemo@mba.ocn.ne.jp>
   *
   * Based on Richard Purdie's ledtrig-timer.c and some arch's
   * CONFIG_HEARTBEAT code.
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License version 2 as
   * published by the Free Software Foundation.
   *
   */
  #include <linux/module.h>
  #include <linux/kernel.h>
  #include <linux/init.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
17
  #include <linux/slab.h>
891c668b9   Atsushi Nemoto   [PATCH] LED: add ...
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
  #include <linux/timer.h>
  #include <linux/sched.h>
  #include <linux/leds.h>
  #include "leds.h"
  
  struct heartbeat_trig_data {
  	unsigned int phase;
  	unsigned int period;
  	struct timer_list timer;
  };
  
  static void led_heartbeat_function(unsigned long data)
  {
  	struct led_classdev *led_cdev = (struct led_classdev *) data;
  	struct heartbeat_trig_data *heartbeat_data = led_cdev->trigger_data;
  	unsigned long brightness = LED_OFF;
  	unsigned long delay = 0;
  
  	/* acts like an actual heart beat -- ie thump-thump-pause... */
  	switch (heartbeat_data->phase) {
  	case 0:
  		/*
  		 * The hyperbolic function below modifies the
  		 * heartbeat period length in dependency of the
  		 * current (1min) load. It goes through the points
  		 * f(0)=1260, f(1)=860, f(5)=510, f(inf)->300.
  		 */
  		heartbeat_data->period = 300 +
  			(6720 << FSHIFT) / (5 * avenrun[0] + (7 << FSHIFT));
  		heartbeat_data->period =
  			msecs_to_jiffies(heartbeat_data->period);
  		delay = msecs_to_jiffies(70);
  		heartbeat_data->phase++;
1bd465e6b   Guennadi Liakhovetski   leds: allow led-d...
51
  		brightness = led_cdev->max_brightness;
891c668b9   Atsushi Nemoto   [PATCH] LED: add ...
52
53
54
55
56
57
58
59
  		break;
  	case 1:
  		delay = heartbeat_data->period / 4 - msecs_to_jiffies(70);
  		heartbeat_data->phase++;
  		break;
  	case 2:
  		delay = msecs_to_jiffies(70);
  		heartbeat_data->phase++;
1bd465e6b   Guennadi Liakhovetski   leds: allow led-d...
60
  		brightness = led_cdev->max_brightness;
891c668b9   Atsushi Nemoto   [PATCH] LED: add ...
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
  		break;
  	default:
  		delay = heartbeat_data->period - heartbeat_data->period / 4 -
  			msecs_to_jiffies(70);
  		heartbeat_data->phase = 0;
  		break;
  	}
  
  	led_set_brightness(led_cdev, brightness);
  	mod_timer(&heartbeat_data->timer, jiffies + delay);
  }
  
  static void heartbeat_trig_activate(struct led_classdev *led_cdev)
  {
  	struct heartbeat_trig_data *heartbeat_data;
  
  	heartbeat_data = kzalloc(sizeof(*heartbeat_data), GFP_KERNEL);
  	if (!heartbeat_data)
  		return;
  
  	led_cdev->trigger_data = heartbeat_data;
  	setup_timer(&heartbeat_data->timer,
  		    led_heartbeat_function, (unsigned long) led_cdev);
  	heartbeat_data->phase = 0;
  	led_heartbeat_function(heartbeat_data->timer.data);
  }
  
  static void heartbeat_trig_deactivate(struct led_classdev *led_cdev)
  {
  	struct heartbeat_trig_data *heartbeat_data = led_cdev->trigger_data;
  
  	if (heartbeat_data) {
  		del_timer_sync(&heartbeat_data->timer);
  		kfree(heartbeat_data);
  	}
  }
  
  static struct led_trigger heartbeat_led_trigger = {
  	.name     = "heartbeat",
  	.activate = heartbeat_trig_activate,
  	.deactivate = heartbeat_trig_deactivate,
  };
  
  static int __init heartbeat_trig_init(void)
  {
  	return led_trigger_register(&heartbeat_led_trigger);
  }
  
  static void __exit heartbeat_trig_exit(void)
  {
  	led_trigger_unregister(&heartbeat_led_trigger);
  }
  
  module_init(heartbeat_trig_init);
  module_exit(heartbeat_trig_exit);
  
  MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>");
  MODULE_DESCRIPTION("Heartbeat LED trigger");
  MODULE_LICENSE("GPL");