Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v2.6.19-rc2 171 lines 4.4 kB view raw
1/* 2 * LED Class Core 3 * 4 * Copyright (C) 2005 John Lenz <lenz@cs.wisc.edu> 5 * Copyright (C) 2005-2006 Richard Purdie <rpurdie@openedhand.com> 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 as 9 * published by the Free Software Foundation. 10 */ 11 12#include <linux/module.h> 13#include <linux/kernel.h> 14#include <linux/init.h> 15#include <linux/list.h> 16#include <linux/spinlock.h> 17#include <linux/device.h> 18#include <linux/sysdev.h> 19#include <linux/timer.h> 20#include <linux/err.h> 21#include <linux/ctype.h> 22#include <linux/leds.h> 23#include "leds.h" 24 25static struct class *leds_class; 26 27static ssize_t led_brightness_show(struct class_device *dev, char *buf) 28{ 29 struct led_classdev *led_cdev = class_get_devdata(dev); 30 ssize_t ret = 0; 31 32 /* no lock needed for this */ 33 sprintf(buf, "%u\n", led_cdev->brightness); 34 ret = strlen(buf) + 1; 35 36 return ret; 37} 38 39static ssize_t led_brightness_store(struct class_device *dev, 40 const char *buf, size_t size) 41{ 42 struct led_classdev *led_cdev = class_get_devdata(dev); 43 ssize_t ret = -EINVAL; 44 char *after; 45 unsigned long state = simple_strtoul(buf, &after, 10); 46 size_t count = after - buf; 47 48 if (*after && isspace(*after)) 49 count++; 50 51 if (count == size) { 52 ret = count; 53 led_set_brightness(led_cdev, state); 54 } 55 56 return ret; 57} 58 59static CLASS_DEVICE_ATTR(brightness, 0644, led_brightness_show, 60 led_brightness_store); 61#ifdef CONFIG_LEDS_TRIGGERS 62static CLASS_DEVICE_ATTR(trigger, 0644, led_trigger_show, led_trigger_store); 63#endif 64 65/** 66 * led_classdev_suspend - suspend an led_classdev. 67 * @led_cdev: the led_classdev to suspend. 68 */ 69void led_classdev_suspend(struct led_classdev *led_cdev) 70{ 71 led_cdev->flags |= LED_SUSPENDED; 72 led_cdev->brightness_set(led_cdev, 0); 73} 74EXPORT_SYMBOL_GPL(led_classdev_suspend); 75 76/** 77 * led_classdev_resume - resume an led_classdev. 78 * @led_cdev: the led_classdev to resume. 79 */ 80void led_classdev_resume(struct led_classdev *led_cdev) 81{ 82 led_cdev->brightness_set(led_cdev, led_cdev->brightness); 83 led_cdev->flags &= ~LED_SUSPENDED; 84} 85EXPORT_SYMBOL_GPL(led_classdev_resume); 86 87/** 88 * led_classdev_register - register a new object of led_classdev class. 89 * @dev: The device to register. 90 * @led_cdev: the led_classdev structure for this device. 91 */ 92int led_classdev_register(struct device *parent, struct led_classdev *led_cdev) 93{ 94 led_cdev->class_dev = class_device_create(leds_class, NULL, 0, 95 parent, "%s", led_cdev->name); 96 if (unlikely(IS_ERR(led_cdev->class_dev))) 97 return PTR_ERR(led_cdev->class_dev); 98 99 class_set_devdata(led_cdev->class_dev, led_cdev); 100 101 /* register the attributes */ 102 class_device_create_file(led_cdev->class_dev, 103 &class_device_attr_brightness); 104 105 /* add to the list of leds */ 106 write_lock(&leds_list_lock); 107 list_add_tail(&led_cdev->node, &leds_list); 108 write_unlock(&leds_list_lock); 109 110#ifdef CONFIG_LEDS_TRIGGERS 111 rwlock_init(&led_cdev->trigger_lock); 112 113 led_trigger_set_default(led_cdev); 114 115 class_device_create_file(led_cdev->class_dev, 116 &class_device_attr_trigger); 117#endif 118 119 printk(KERN_INFO "Registered led device: %s\n", 120 led_cdev->class_dev->class_id); 121 122 return 0; 123} 124EXPORT_SYMBOL_GPL(led_classdev_register); 125 126/** 127 * led_classdev_unregister - unregisters a object of led_properties class. 128 * @led_cdev: the led device to unregister 129 * 130 * Unregisters a previously registered via led_classdev_register object. 131 */ 132void led_classdev_unregister(struct led_classdev *led_cdev) 133{ 134 class_device_remove_file(led_cdev->class_dev, 135 &class_device_attr_brightness); 136#ifdef CONFIG_LEDS_TRIGGERS 137 class_device_remove_file(led_cdev->class_dev, 138 &class_device_attr_trigger); 139 write_lock(&led_cdev->trigger_lock); 140 if (led_cdev->trigger) 141 led_trigger_set(led_cdev, NULL); 142 write_unlock(&led_cdev->trigger_lock); 143#endif 144 145 class_device_unregister(led_cdev->class_dev); 146 147 write_lock(&leds_list_lock); 148 list_del(&led_cdev->node); 149 write_unlock(&leds_list_lock); 150} 151EXPORT_SYMBOL_GPL(led_classdev_unregister); 152 153static int __init leds_init(void) 154{ 155 leds_class = class_create(THIS_MODULE, "leds"); 156 if (IS_ERR(leds_class)) 157 return PTR_ERR(leds_class); 158 return 0; 159} 160 161static void __exit leds_exit(void) 162{ 163 class_destroy(leds_class); 164} 165 166subsys_initcall(leds_init); 167module_exit(leds_exit); 168 169MODULE_AUTHOR("John Lenz, Richard Purdie"); 170MODULE_LICENSE("GPL"); 171MODULE_DESCRIPTION("LED Class Interface");