Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.17-rc6 179 lines 4.5 kB view raw
1/* 2 * LED Kernel Timer Trigger 3 * 4 * Copyright 2005-2006 Openedhand Ltd. 5 * 6 * Author: Richard Purdie <rpurdie@openedhand.com> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License version 2 as 10 * published by the Free Software Foundation. 11 * 12 */ 13 14#include <linux/config.h> 15#include <linux/module.h> 16#include <linux/kernel.h> 17#include <linux/init.h> 18#include <linux/list.h> 19#include <linux/spinlock.h> 20#include <linux/device.h> 21#include <linux/sysdev.h> 22#include <linux/timer.h> 23#include <linux/ctype.h> 24#include <linux/leds.h> 25#include "leds.h" 26 27struct timer_trig_data { 28 unsigned long delay_on; /* milliseconds on */ 29 unsigned long delay_off; /* milliseconds off */ 30 struct timer_list timer; 31}; 32 33static void led_timer_function(unsigned long data) 34{ 35 struct led_classdev *led_cdev = (struct led_classdev *) data; 36 struct timer_trig_data *timer_data = led_cdev->trigger_data; 37 unsigned long brightness = LED_OFF; 38 unsigned long delay = timer_data->delay_off; 39 40 if (!timer_data->delay_on || !timer_data->delay_off) { 41 led_set_brightness(led_cdev, LED_OFF); 42 return; 43 } 44 45 if (!led_cdev->brightness) { 46 brightness = LED_FULL; 47 delay = timer_data->delay_on; 48 } 49 50 led_set_brightness(led_cdev, brightness); 51 52 mod_timer(&timer_data->timer, jiffies + msecs_to_jiffies(delay)); 53} 54 55static ssize_t led_delay_on_show(struct class_device *dev, char *buf) 56{ 57 struct led_classdev *led_cdev = class_get_devdata(dev); 58 struct timer_trig_data *timer_data = led_cdev->trigger_data; 59 60 sprintf(buf, "%lu\n", timer_data->delay_on); 61 62 return strlen(buf) + 1; 63} 64 65static ssize_t led_delay_on_store(struct class_device *dev, const char *buf, 66 size_t size) 67{ 68 struct led_classdev *led_cdev = class_get_devdata(dev); 69 struct timer_trig_data *timer_data = led_cdev->trigger_data; 70 int ret = -EINVAL; 71 char *after; 72 unsigned long state = simple_strtoul(buf, &after, 10); 73 size_t count = after - buf; 74 75 if (*after && isspace(*after)) 76 count++; 77 78 if (count == size) { 79 timer_data->delay_on = state; 80 mod_timer(&timer_data->timer, jiffies + 1); 81 ret = count; 82 } 83 84 return ret; 85} 86 87static ssize_t led_delay_off_show(struct class_device *dev, char *buf) 88{ 89 struct led_classdev *led_cdev = class_get_devdata(dev); 90 struct timer_trig_data *timer_data = led_cdev->trigger_data; 91 92 sprintf(buf, "%lu\n", timer_data->delay_off); 93 94 return strlen(buf) + 1; 95} 96 97static ssize_t led_delay_off_store(struct class_device *dev, const char *buf, 98 size_t size) 99{ 100 struct led_classdev *led_cdev = class_get_devdata(dev); 101 struct timer_trig_data *timer_data = led_cdev->trigger_data; 102 int ret = -EINVAL; 103 char *after; 104 unsigned long state = simple_strtoul(buf, &after, 10); 105 size_t count = after - buf; 106 107 if (*after && isspace(*after)) 108 count++; 109 110 if (count == size) { 111 timer_data->delay_off = state; 112 mod_timer(&timer_data->timer, jiffies + 1); 113 ret = count; 114 } 115 116 return ret; 117} 118 119static CLASS_DEVICE_ATTR(delay_on, 0644, led_delay_on_show, 120 led_delay_on_store); 121static CLASS_DEVICE_ATTR(delay_off, 0644, led_delay_off_show, 122 led_delay_off_store); 123 124static void timer_trig_activate(struct led_classdev *led_cdev) 125{ 126 struct timer_trig_data *timer_data; 127 128 timer_data = kzalloc(sizeof(struct timer_trig_data), GFP_KERNEL); 129 if (!timer_data) 130 return; 131 132 led_cdev->trigger_data = timer_data; 133 134 init_timer(&timer_data->timer); 135 timer_data->timer.function = led_timer_function; 136 timer_data->timer.data = (unsigned long) led_cdev; 137 138 class_device_create_file(led_cdev->class_dev, 139 &class_device_attr_delay_on); 140 class_device_create_file(led_cdev->class_dev, 141 &class_device_attr_delay_off); 142} 143 144static void timer_trig_deactivate(struct led_classdev *led_cdev) 145{ 146 struct timer_trig_data *timer_data = led_cdev->trigger_data; 147 148 if (timer_data) { 149 class_device_remove_file(led_cdev->class_dev, 150 &class_device_attr_delay_on); 151 class_device_remove_file(led_cdev->class_dev, 152 &class_device_attr_delay_off); 153 del_timer_sync(&timer_data->timer); 154 kfree(timer_data); 155 } 156} 157 158static struct led_trigger timer_led_trigger = { 159 .name = "timer", 160 .activate = timer_trig_activate, 161 .deactivate = timer_trig_deactivate, 162}; 163 164static int __init timer_trig_init(void) 165{ 166 return led_trigger_register(&timer_led_trigger); 167} 168 169static void __exit timer_trig_exit(void) 170{ 171 led_trigger_unregister(&timer_led_trigger); 172} 173 174module_init(timer_trig_init); 175module_exit(timer_trig_exit); 176 177MODULE_AUTHOR("Richard Purdie <rpurdie@openedhand.com>"); 178MODULE_DESCRIPTION("Timer LED trigger"); 179MODULE_LICENSE("GPL");