diff options
Diffstat (limited to 'packages/linux/ixp4xx-kernel/2.6.16/leds-class.patch')
| -rw-r--r-- | packages/linux/ixp4xx-kernel/2.6.16/leds-class.patch | 1862 |
1 files changed, 0 insertions, 1862 deletions
diff --git a/packages/linux/ixp4xx-kernel/2.6.16/leds-class.patch b/packages/linux/ixp4xx-kernel/2.6.16/leds-class.patch deleted file mode 100644 index c0146b6fe4..0000000000 --- a/packages/linux/ixp4xx-kernel/2.6.16/leds-class.patch +++ /dev/null @@ -1,1862 +0,0 @@ - -From: Richard Purdie <rpurdie@rpsys.net> - -Add the foundations of a new LEDs subsystem. This patch adds a class which -presents LED devices within sysfs and allows their brightness to be -controlled. - -Signed-off-by: Richard Purdie <rpurdie@rpsys.net> -Cc: Russell King <rmk@arm.linux.org.uk> -Cc: Greg KH <greg@kroah.com> -Signed-off-by: Andrew Morton <akpm@osdl.org> ---- - - arch/arm/Kconfig | 2 - arch/arm/mach-pxa/corgi.c | 9 + - arch/arm/mach-pxa/spitz.c | 9 + - arch/arm/mach-pxa/tosa.c | 9 + - drivers/Kconfig | 2 - drivers/Makefile | 1 - drivers/ide/ide-disk.c | 22 +++ - drivers/leds/Kconfig | 70 +++++++++++ - drivers/leds/Makefile | 15 ++ - drivers/leds/led-class.c | 174 +++++++++++++++++++++++++++++ - drivers/leds/led-core.c | 25 ++++ - drivers/leds/led-triggers.c | 239 ++++++++++++++++++++++++++++++++++++++++ - drivers/leds/leds-corgi.c | 121 ++++++++++++++++++++ - drivers/leds/leds-ixp4xx-gpio.c | 215 +++++++++++++++++++++++++++++++++++ - drivers/leds/leds-locomo.c | 95 +++++++++++++++ - drivers/leds/leds-spitz.c | 125 ++++++++++++++++++++ - drivers/leds/leds-tosa.c | 131 +++++++++++++++++++++ - drivers/leds/leds.h | 45 +++++++ - drivers/leds/ledtrig-timer.c | 174 +++++++++++++++++++++++++++++ - drivers/mtd/nand/nand_base.c | 26 ++++ - include/linux/leds.h | 105 +++++++++++++++++ - 21 files changed, 1610 insertions(+), 4 deletions(-) - ---- linux-ixp4xx.orig/arch/arm/Kconfig 2006-03-07 22:57:47.000000000 +0100 -+++ linux-ixp4xx/arch/arm/Kconfig 2006-03-07 22:59:04.000000000 +0100 -@@ -807,6 +807,8 @@ source "drivers/misc/Kconfig" - - source "drivers/mfd/Kconfig" - -+source "drivers/leds/Kconfig" -+ - source "drivers/media/Kconfig" - - source "drivers/video/Kconfig" ---- linux-ixp4xx.orig/drivers/Kconfig 2006-03-07 22:57:47.000000000 +0100 -+++ linux-ixp4xx/drivers/Kconfig 2006-03-07 22:59:04.000000000 +0100 -@@ -64,6 +64,8 @@ source "drivers/usb/Kconfig" - - source "drivers/mmc/Kconfig" - -+source "drivers/leds/Kconfig" -+ - source "drivers/infiniband/Kconfig" - - source "drivers/sn/Kconfig" ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-ixp4xx/drivers/leds/Kconfig 2006-03-07 22:59:04.000000000 +0100 -@@ -0,0 +1,70 @@ -+ -+menu "LED devices" -+ -+config NEW_LEDS -+ bool "LED Support" -+ help -+ Say Y to enable Linux LED support. This is not related to standard -+ keyboard LEDs which are controlled via the input system. -+ -+config LEDS_CLASS -+ tristate "LED Class Support" -+ depends NEW_LEDS -+ help -+ This option enables the led sysfs class in /sys/class/leds. You'll -+ need this to do anything useful with LEDs. If unsure, say N. -+ -+config LEDS_TRIGGERS -+ bool "LED Trigger support" -+ depends NEW_LEDS -+ help -+ This option enables trigger support for the leds class. -+ These triggers allow kernel events to drive the LEDs and can -+ be configured via sysfs. If unsure, say Y. -+ -+config LEDS_CORGI -+ tristate "LED Support for the Sharp SL-C7x0 series" -+ depends LEDS_CLASS && PXA_SHARP_C7xx -+ help -+ This option enables support for the LEDs on Sharp Zaurus -+ SL-C7x0 series (C700, C750, C760, C860). -+ -+config LEDS_LOCOMO -+ tristate "LED Support for Locomo device" -+ depends LEDS_CLASS && SHARP_LOCOMO -+ help -+ This option enables support for the LEDs on Sharp Locomo. -+ Zaurus models SL-5500 and SL-5600. -+ -+config LEDS_SPITZ -+ tristate "LED Support for the Sharp SL-Cxx00 series" -+ depends LEDS_CLASS && PXA_SHARP_Cxx00 -+ help -+ This option enables support for the LEDs on Sharp Zaurus -+ SL-Cxx00 series (C1000, C3000, C3100). -+ -+config LEDS_IXP4XX -+ tristate "LED Support for GPIO connected LEDs on IXP4XX processors" -+ depends LEDS_CLASS && ARCH_IXP4XX -+ help -+ This option enables support for the LEDs connected to GPIO -+ outputs of the Intel IXP4XX processors. To be useful the -+ particular board must have LEDs and they must be connected -+ to the GPIO lines. If unsure, say Y. -+ -+config LEDS_TOSA -+ tristate "LED Support for the Sharp SL-6000 series" -+ depends LEDS_CLASS && PXA_SHARPSL -+ help -+ This option enables support for the LEDs on Sharp Zaurus -+ SL-6000 series. -+ -+config LEDS_TRIGGER_TIMER -+ tristate "LED Timer Trigger" -+ depends LEDS_TRIGGERS -+ help -+ This allows LEDs to be controlled by a programmable timer -+ via sysfs. If unsure, say Y. -+ -+endmenu -+ ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-ixp4xx/drivers/leds/led-class.c 2006-03-07 22:59:04.000000000 +0100 -@@ -0,0 +1,174 @@ -+/* -+ * LED Class Core -+ * -+ * Copyright (C) 2005 John Lenz <lenz@cs.wisc.edu> -+ * Copyright (C) 2005-2006 Richard Purdie <rpurdie@openedhand.com> -+ * -+ * 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/config.h> -+#include <linux/module.h> -+#include <linux/kernel.h> -+#include <linux/init.h> -+#include <linux/list.h> -+#include <linux/spinlock.h> -+#include <linux/device.h> -+#include <linux/sysdev.h> -+#include <linux/timer.h> -+#include <linux/err.h> -+#include <linux/leds.h> -+#include "leds.h" -+ -+static struct class *leds_class; -+ -+static ssize_t led_brightness_show(struct class_device *dev, char *buf) -+{ -+ struct led_classdev *led_cdev = class_get_devdata(dev); -+ ssize_t ret = 0; -+ -+ /* no lock needed for this */ -+ sprintf(buf, "%u\n", led_cdev->brightness); -+ ret = strlen(buf) + 1; -+ -+ return ret; -+} -+ -+static ssize_t led_brightness_store(struct class_device *dev, -+ const char *buf, size_t size) -+{ -+ struct led_classdev *led_cdev = class_get_devdata(dev); -+ ssize_t ret = -EINVAL; -+ char *after; -+ unsigned long state = simple_strtoul(buf, &after, 10); -+ -+ if (after - buf > 0) { -+ ret = after - buf; -+ write_lock(&led_cdev->lock); -+ led_set_brightness(led_cdev, state); -+ write_unlock(&led_cdev->lock); -+ } -+ -+ return ret; -+} -+ -+static CLASS_DEVICE_ATTR(brightness, 0644, led_brightness_show, -+ led_brightness_store); -+#ifdef CONFIG_LEDS_TRIGGERS -+static CLASS_DEVICE_ATTR(trigger, 0644, led_trigger_show, led_trigger_store); -+#endif -+ -+/** -+ * led_classdev_suspend - suspend an led_classdev. -+ * @led_cdev: the led_classdev to suspend. -+ */ -+void led_classdev_suspend(struct led_classdev *led_cdev) -+{ -+ write_lock(&led_cdev->lock); -+ led_cdev->flags |= LED_SUSPENDED; -+ led_cdev->brightness_set(led_cdev, 0); -+ write_unlock(&led_cdev->lock); -+} -+EXPORT_SYMBOL_GPL(led_classdev_suspend); -+ -+/** -+ * led_classdev_resume - resume an led_classdev. -+ * @led_cdev: the led_classdev to resume. -+ */ -+void led_classdev_resume(struct led_classdev *led_cdev) -+{ -+ write_lock(&led_cdev->lock); -+ led_cdev->flags &= ~LED_SUSPENDED; -+ led_cdev->brightness_set(led_cdev, led_cdev->brightness); -+ write_unlock(&led_cdev->lock); -+} -+EXPORT_SYMBOL_GPL(led_classdev_resume); -+ -+/** -+ * led_classdev_register - register a new object of led_classdev class. -+ * @dev: The device to register. -+ * @led_cdev: the led_classdev structure for this device. -+ */ -+int led_classdev_register(struct device *parent, struct led_classdev *led_cdev) -+{ -+ led_cdev->class_dev = class_device_create(leds_class, NULL, 0, -+ parent, "%s", led_cdev->name); -+ if (unlikely(IS_ERR(led_cdev->class_dev))) -+ return PTR_ERR(led_cdev->class_dev); -+ -+ rwlock_init(&led_cdev->lock); -+ class_set_devdata(led_cdev->class_dev, led_cdev); -+ -+ /* register the attributes */ -+ class_device_create_file(led_cdev->class_dev, -+ &class_device_attr_brightness); -+ -+ /* add to the list of leds */ -+ write_lock(&leds_list_lock); -+ list_add_tail(&led_cdev->node, &leds_list); -+ write_unlock(&leds_list_lock); -+ -+#ifdef CONFIG_LEDS_TRIGGERS -+ rwlock_init(&led_cdev->trigger_lock); -+ -+ led_trigger_set_default(led_cdev); -+ -+ class_device_create_file(led_cdev->class_dev, -+ &class_device_attr_trigger); -+#endif -+ -+ printk(KERN_INFO "Registered led device: %s\n", -+ led_cdev->class_dev->class_id); -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(led_classdev_register); -+ -+/** -+ * led_classdev_unregister - unregisters a object of led_properties class. -+ * @led_cdev: the led device to unreigister -+ * -+ * Unregisters a previously registered via led_classdev_register object. -+ */ -+void led_classdev_unregister(struct led_classdev *led_cdev) -+{ -+ class_device_remove_file(led_cdev->class_dev, -+ &class_device_attr_brightness); -+#ifdef CONFIG_LEDS_TRIGGERS -+ class_device_remove_file(led_cdev->class_dev, -+ &class_device_attr_trigger); -+ write_lock(&led_cdev->trigger_lock); -+ if (led_cdev->trigger) -+ led_trigger_set(led_cdev, NULL); -+ write_unlock(&led_cdev->trigger_lock); -+#endif -+ -+ class_device_unregister(led_cdev->class_dev); -+ -+ write_lock(&leds_list_lock); -+ list_del(&led_cdev->node); -+ write_unlock(&leds_list_lock); -+} -+EXPORT_SYMBOL_GPL(led_classdev_unregister); -+ -+static int __init leds_init(void) -+{ -+ leds_class = class_create(THIS_MODULE, "leds"); -+ if (IS_ERR(leds_class)) -+ return PTR_ERR(leds_class); -+ return 0; -+} -+ -+static void __exit leds_exit(void) -+{ -+ class_destroy(leds_class); -+} -+ -+subsys_initcall(leds_init); -+module_exit(leds_exit); -+ -+MODULE_AUTHOR("John Lenz, Richard Purdie"); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("LED Class Interface"); ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-ixp4xx/drivers/leds/led-core.c 2006-03-07 22:59:04.000000000 +0100 -@@ -0,0 +1,25 @@ -+/* -+ * LED Class Core -+ * -+ * Copyright 2005-2006 Openedhand Ltd. -+ * -+ * Author: Richard Purdie <rpurdie@openedhand.com> -+ * -+ * 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/kernel.h> -+#include <linux/list.h> -+#include <linux/module.h> -+#include <linux/spinlock.h> -+#include <linux/leds.h> -+#include "leds.h" -+ -+rwlock_t leds_list_lock = RW_LOCK_UNLOCKED; -+LIST_HEAD(leds_list); -+ -+EXPORT_SYMBOL_GPL(leds_list); -+EXPORT_SYMBOL_GPL(leds_list_lock); ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-ixp4xx/drivers/leds/leds.h 2006-03-07 22:59:04.000000000 +0100 -@@ -0,0 +1,45 @@ -+/* -+ * LED Core -+ * -+ * Copyright 2005 Openedhand Ltd. -+ * -+ * Author: Richard Purdie <rpurdie@openedhand.com> -+ * -+ * 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. -+ * -+ */ -+#ifndef __LEDS_H_INCLUDED -+#define __LEDS_H_INCLUDED -+ -+#include <linux/leds.h> -+ -+/* led_cdev->lock must be held as write */ -+static inline void led_set_brightness(struct led_classdev *led_cdev, -+ enum led_brightness value) -+{ -+ if (value > LED_FULL) -+ value = LED_FULL; -+ led_cdev->brightness = value; -+ if (!(led_cdev->flags & LED_SUSPENDED)) -+ led_cdev->brightness_set(led_cdev, value); -+} -+ -+extern rwlock_t leds_list_lock; -+extern struct list_head leds_list; -+ -+#ifdef CONFIG_LEDS_TRIGGERS -+void led_trigger_set_default(struct led_classdev *led_cdev); -+void led_trigger_set(struct led_classdev *led_cdev, -+ struct led_trigger *trigger); -+#else -+#define led_trigger_set_default(x) do {} while(0) -+#define led_trigger_set(x, y) do {} while(0) -+#endif -+ -+ssize_t led_trigger_store(struct class_device *dev, const char *buf, -+ size_t count); -+ssize_t led_trigger_show(struct class_device *dev, char *buf); -+ -+#endif /* __LEDS_H_INCLUDED */ ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-ixp4xx/drivers/leds/Makefile 2006-03-07 22:59:04.000000000 +0100 -@@ -0,0 +1,15 @@ -+ -+# LED Core -+obj-$(CONFIG_NEW_LEDS) += led-core.o -+obj-$(CONFIG_LEDS_CLASS) += led-class.o -+obj-$(CONFIG_LEDS_TRIGGERS) += led-triggers.o -+ -+# LED Platform Drivers -+obj-$(CONFIG_LEDS_CORGI) += leds-corgi.o -+obj-$(CONFIG_LEDS_LOCOMO) += leds-locomo.o -+obj-$(CONFIG_LEDS_SPITZ) += leds-spitz.o -+obj-$(CONFIG_LEDS_IXP4XX) += leds-ixp4xx-gpio.o -+obj-$(CONFIG_LEDS_TOSA) += leds-tosa.o -+ -+# LED Triggers -+obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o ---- linux-ixp4xx.orig/drivers/Makefile 2006-03-07 22:57:47.000000000 +0100 -+++ linux-ixp4xx/drivers/Makefile 2006-03-07 22:59:04.000000000 +0100 -@@ -68,6 +68,7 @@ obj-$(CONFIG_MCA) += mca/ - obj-$(CONFIG_EISA) += eisa/ - obj-$(CONFIG_CPU_FREQ) += cpufreq/ - obj-$(CONFIG_MMC) += mmc/ -+obj-$(CONFIG_NEW_LEDS) += leds/ - obj-$(CONFIG_INFINIBAND) += infiniband/ - obj-$(CONFIG_SGI_SN) += sn/ - obj-y += firmware/ ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-ixp4xx/include/linux/leds.h 2006-03-07 22:59:04.000000000 +0100 -@@ -0,0 +1,105 @@ -+/* -+ * Driver model for leds and led triggers -+ * -+ * Copyright (C) 2005 John Lenz <lenz@cs.wisc.edu> -+ * Copyright (C) 2005 Richard Purdie <rpurdie@openedhand.com> -+ * -+ * 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. -+ * -+ */ -+#ifndef __LINUX_LEDS_H_INCLUDED -+#define __LINUX_LEDS_H_INCLUDED -+ -+struct device; -+struct class_device; -+/* -+ * LED Core -+ */ -+ -+enum led_brightness { -+ LED_OFF = 0, -+ LED_HALF = 127, -+ LED_FULL = 255, -+}; -+ -+struct led_classdev { -+ const char *name; -+ int brightness; -+ int flags; -+#define LED_SUSPENDED (1 << 0) -+ -+ /* A function to set the brightness of the led */ -+ void (*brightness_set)(struct led_classdev *led_cdev, -+ enum led_brightness brightness); -+ -+ struct class_device *class_dev; -+ /* LED Device linked list */ -+ struct list_head node; -+ -+ /* Protects the LED properties data above */ -+ rwlock_t lock; -+ -+ /* Trigger data */ -+ char *default_trigger; -+#ifdef CONFIG_LEDS_TRIGGERS -+ rwlock_t trigger_lock; -+ /* Protects the trigger data below */ -+ -+ struct led_trigger *trigger; -+ struct list_head trig_list; -+ void *trigger_data; -+#endif -+}; -+ -+extern int led_classdev_register(struct device *parent, -+ struct led_classdev *led_cdev); -+extern void led_classdev_unregister(struct led_classdev *led_cdev); -+extern void led_classdev_suspend(struct led_classdev *led_cdev); -+extern void led_classdev_resume(struct led_classdev *led_cdev); -+ -+/* -+ * LED Triggers -+ */ -+#ifdef CONFIG_LEDS_TRIGGERS -+ -+#define TRIG_NAME_MAX 50 -+ -+struct led_trigger { -+ /* Trigger Properties */ -+ const char *name; -+ void (*activate)(struct led_classdev *led_cdev); -+ void (*deactivate)(struct led_classdev *led_cdev); -+ -+ /* LEDs under control by this trigger (for simple triggers) */ -+ rwlock_t leddev_list_lock; -+ struct list_head led_cdevs; -+ -+ /* Link to next registered trigger */ -+ struct list_head next_trig; -+}; -+ -+/* Registration functions for complex triggers */ -+int led_trigger_register(struct led_trigger *trigger); -+void led_trigger_unregister(struct led_trigger *trigger); -+ -+/* Registration functions for simple triggers */ -+#define DEFINE_LED_TRIGGER(x) static struct led_trigger *x; -+#define DEFINE_LED_TRIGGER_GLOBAL(x) struct led_trigger *x; -+void led_trigger_register_simple(const char *name, -+ struct led_trigger **trigger); -+void led_trigger_unregister_simple(struct led_trigger *trigger); -+void led_trigger_event(struct led_trigger *trigger, enum led_brightness event); -+ -+#else -+ -+/* Triggers aren't active - null macros */ -+#define DEFINE_LED_TRIGGER(x) -+#define DEFINE_LED_TRIGGER_GLOBAL(x) -+#define led_trigger_register_simple(x, y) do {} while(0) -+#define led_trigger_unregister_simple(x) do {} while(0) -+#define led_trigger_event(x, y) do {} while(0) -+ -+#endif -+#endif /* __LINUX_LEDS_H_INCLUDED */ ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-ixp4xx/drivers/leds/led-triggers.c 2006-03-07 22:59:04.000000000 +0100 -@@ -0,0 +1,239 @@ -+/* -+ * LED Triggers Core -+ * -+ * Copyright 2005-2006 Openedhand Ltd. -+ * -+ * Author: Richard Purdie <rpurdie@openedhand.com> -+ * -+ * 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/config.h> -+#include <linux/module.h> -+#include <linux/kernel.h> -+#include <linux/init.h> -+#include <linux/list.h> -+#include <linux/spinlock.h> -+#include <linux/device.h> -+#include <linux/sysdev.h> -+#include <linux/timer.h> -+#include <linux/leds.h> -+#include "leds.h" -+ -+/* -+ * Nests outside led_cdev->lock and led_cdev->trigger_lock -+ */ -+static rwlock_t triggers_list_lock = RW_LOCK_UNLOCKED; -+static LIST_HEAD(trigger_list); -+ -+ssize_t led_trigger_store(struct class_device *dev, const char *buf, -+ size_t count) -+{ -+ struct led_classdev *led_cdev = class_get_devdata(dev); -+ char trigger_name[TRIG_NAME_MAX]; -+ struct led_trigger *trig; -+ size_t len; -+ -+ trigger_name[sizeof(trigger_name) - 1] = '\0'; -+ strncpy(trigger_name, buf, sizeof(trigger_name) - 1); -+ len = strlen(trigger_name); -+ -+ if (len && trigger_name[len - 1] == '\n') -+ trigger_name[len - 1] = '\0'; -+ -+ if (!strcmp(trigger_name, "none")) { -+ write_lock(&led_cdev->trigger_lock); -+ led_trigger_set(led_cdev, NULL); -+ write_unlock(&led_cdev->trigger_lock); -+ return count; -+ } -+ -+ read_lock(&triggers_list_lock); -+ list_for_each_entry(trig, &trigger_list, next_trig) { -+ if (!strcmp(trigger_name, trig->name)) { -+ write_lock(&led_cdev->trigger_lock); -+ led_trigger_set(led_cdev, trig); -+ write_unlock(&led_cdev->trigger_lock); -+ -+ read_unlock(&triggers_list_lock); -+ return count; -+ } -+ } -+ read_unlock(&triggers_list_lock); -+ -+ return -EINVAL; -+} -+ -+ -+ssize_t led_trigger_show(struct class_device *dev, char *buf) -+{ -+ struct led_classdev *led_cdev = class_get_devdata(dev); -+ struct led_trigger *trig; -+ int len = 0; -+ -+ read_lock(&triggers_list_lock); -+ read_lock(&led_cdev->trigger_lock); -+ -+ if (!led_cdev->trigger) -+ len += sprintf(buf+len, "[none] "); -+ else -+ len += sprintf(buf+len, "none "); -+ -+ list_for_each_entry(trig, &trigger_list, next_trig) { -+ if (led_cdev->trigger && !strcmp(led_cdev->trigger->name, -+ trig->name)) -+ len += sprintf(buf+len, "[%s] ", trig->name); -+ else -+ len += sprintf(buf+len, "%s ", trig->name); -+ } -+ read_unlock(&led_cdev->trigger_lock); -+ read_unlock(&triggers_list_lock); -+ -+ len += sprintf(len+buf, "\n"); -+ return len; -+} -+ -+void led_trigger_event(struct led_trigger *trigger, -+ enum led_brightness brightness) -+{ -+ struct list_head *entry; -+ -+ if (!trigger) -+ return; -+ -+ read_lock(&trigger->leddev_list_lock); -+ list_for_each(entry, &trigger->led_cdevs) { -+ struct led_classdev *led_cdev; -+ -+ led_cdev = list_entry(entry, struct led_classdev, trig_list); -+ write_lock(&led_cdev->lock); -+ led_set_brightness(led_cdev, brightness); -+ write_unlock(&led_cdev->lock); -+ } -+ read_unlock(&trigger->leddev_list_lock); -+} -+ -+/* Caller must ensure led_cdev->trigger_lock held */ -+void led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trigger) -+{ -+ /* Remove any existing trigger */ -+ if (led_cdev->trigger) { -+ write_lock(&led_cdev->trigger->leddev_list_lock); -+ list_del(&led_cdev->trig_list); -+ write_unlock(&led_cdev->trigger->leddev_list_lock); -+ if (led_cdev->trigger->deactivate) -+ led_cdev->trigger->deactivate(led_cdev); -+ } -+ if (trigger) { -+ write_lock(&trigger->leddev_list_lock); -+ list_add_tail(&led_cdev->trig_list, &trigger->led_cdevs); -+ write_unlock(&trigger->leddev_list_lock); -+ if (trigger->activate) -+ trigger->activate(led_cdev); -+ } -+ led_cdev->trigger = trigger; -+} -+ -+void led_trigger_set_default(struct led_classdev *led_cdev) -+{ -+ struct led_trigger *trig; -+ -+ if (!led_cdev->default_trigger) -+ return; -+ -+ read_lock(&triggers_list_lock); -+ write_lock(&led_cdev->trigger_lock); -+ list_for_each_entry(trig, &trigger_list, next_trig) { -+ if (!strcmp(led_cdev->default_trigger, trig->name)) -+ led_trigger_set(led_cdev, trig); -+ } -+ write_unlock(&led_cdev->trigger_lock); -+ read_unlock(&triggers_list_lock); -+} -+ -+int led_trigger_register(struct led_trigger *trigger) -+{ -+ struct led_classdev *led_cdev; -+ -+ rwlock_init(&trigger->leddev_list_lock); -+ INIT_LIST_HEAD(&trigger->led_cdevs); -+ -+ /* Add to the list of led triggers */ -+ write_lock(&triggers_list_lock); -+ list_add_tail(&trigger->next_trig, &trigger_list); -+ write_unlock(&triggers_list_lock); -+ -+ /* Register with any LEDs that have this as a default trigger */ -+ read_lock(&leds_list_lock); -+ list_for_each_entry(led_cdev, &leds_list, node) { -+ write_lock(&led_cdev->trigger_lock); -+ if (!led_cdev->trigger && led_cdev->default_trigger && -+ !strcmp(led_cdev->default_trigger, trigger->name)) -+ led_trigger_set(led_cdev, trigger); -+ write_unlock(&led_cdev->trigger_lock); -+ } -+ read_unlock(&leds_list_lock); -+ -+ return 0; -+} -+ -+void led_trigger_register_simple(const char *name, struct led_trigger **tp) -+{ -+ struct led_trigger *trigger; -+ -+ trigger = kzalloc(sizeof(struct led_trigger), GFP_KERNEL); -+ -+ if (trigger) { -+ trigger->name = name; -+ led_trigger_register(trigger); -+ } -+ *tp = trigger; -+} -+ -+void led_trigger_unregister(struct led_trigger *trigger) -+{ -+ struct led_classdev *led_cdev; -+ -+ /* Remove from the list of led triggers */ -+ write_lock(&triggers_list_lock); -+ list_del(&trigger->next_trig); -+ write_unlock(&triggers_list_lock); -+ -+ /* Remove anyone actively using this trigger */ -+ read_lock(&leds_list_lock); -+ list_for_each_entry(led_cdev, &leds_list, node) { -+ write_lock(&led_cdev->trigger_lock); -+ if (led_cdev->trigger == trigger) -+ led_trigger_set(led_cdev, NULL); -+ write_unlock(&led_cdev->trigger_lock); -+ } -+ read_unlock(&leds_list_lock); -+} -+ -+void led_trigger_unregister_simple(struct led_trigger *trigger) -+{ -+ led_trigger_unregister(trigger); -+ kfree(trigger); -+} -+ -+/* Used by LED Class */ -+EXPORT_SYMBOL_GPL(led_trigger_set); -+EXPORT_SYMBOL_GPL(led_trigger_set_default); -+EXPORT_SYMBOL_GPL(led_trigger_show); -+EXPORT_SYMBOL_GPL(led_trigger_store); -+ -+/* LED Trigger Interface */ -+EXPORT_SYMBOL_GPL(led_trigger_register); -+EXPORT_SYMBOL_GPL(led_trigger_unregister); -+ -+/* Simple LED Tigger Interface */ -+EXPORT_SYMBOL_GPL(led_trigger_register_simple); -+EXPORT_SYMBOL_GPL(led_trigger_unregister_simple); -+EXPORT_SYMBOL_GPL(led_trigger_event); -+ -+MODULE_AUTHOR("Richard Purdie"); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("LED Triggers Core"); ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-ixp4xx/drivers/leds/ledtrig-timer.c 2006-03-07 22:59:04.000000000 +0100 -@@ -0,0 +1,174 @@ -+/* -+ * LED Kernel Timer Trigger -+ * -+ * Copyright 2005-2006 Openedhand Ltd. -+ * -+ * Author: Richard Purdie <rpurdie@openedhand.com> -+ * -+ * 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/config.h> -+#include <linux/module.h> -+#include <linux/kernel.h> -+#include <linux/init.h> -+#include <linux/list.h> -+#include <linux/spinlock.h> -+#include <linux/device.h> -+#include <linux/sysdev.h> -+#include <linux/timer.h> -+#include <linux/leds.h> -+#include "leds.h" -+ -+struct timer_trig_data { -+ unsigned long delay_on; /* milliseconds on */ -+ unsigned long delay_off; /* milliseconds off */ -+ struct timer_list timer; -+}; -+ -+static void led_timer_function(unsigned long data) -+{ -+ struct led_classdev *led_cdev = (struct led_classdev *) data; -+ struct timer_trig_data *timer_data = led_cdev->trigger_data; -+ unsigned long brightness = LED_OFF; -+ unsigned long delay = timer_data->delay_off; -+ -+ if (!timer_data->delay_on || !timer_data->delay_off) { -+ write_lock(&led_cdev->lock); -+ led_set_brightness(led_cdev, LED_OFF); -+ write_unlock(&led_cdev->lock); -+ return; -+ } -+ -+ if (!led_cdev->brightness) { -+ brightness = LED_FULL; -+ delay = timer_data->delay_on; -+ } -+ -+ write_lock(&led_cdev->lock); -+ led_set_brightness(led_cdev, brightness); -+ write_unlock(&led_cdev->lock); -+ -+ mod_timer(&timer_data->timer, jiffies + msecs_to_jiffies(delay)); -+} -+ -+static ssize_t led_delay_on_show(struct class_device *dev, char *buf) -+{ -+ struct led_classdev *led_cdev = class_get_devdata(dev); -+ struct timer_trig_data *timer_data = led_cdev->trigger_data; -+ -+ sprintf(buf, "%lu\n", timer_data->delay_on); -+ -+ return strlen(buf) + 1; -+} -+ -+static ssize_t led_delay_on_store(struct class_device *dev, const char *buf, -+ size_t size) -+{ -+ struct led_classdev *led_cdev = class_get_devdata(dev); -+ struct timer_trig_data *timer_data = led_cdev->trigger_data; -+ int ret = -EINVAL; -+ char *after; -+ unsigned long state = simple_strtoul(buf, &after, 10); -+ -+ if (after - buf > 0) { -+ timer_data->delay_on = state; -+ mod_timer(&timer_data->timer, jiffies + 1); -+ ret = after - buf; -+ } -+ -+ return ret; -+} -+ -+static ssize_t led_delay_off_show(struct class_device *dev, char *buf) -+{ -+ struct led_classdev *led_cdev = class_get_devdata(dev); -+ struct timer_trig_data *timer_data = led_cdev->trigger_data; -+ -+ sprintf(buf, "%lu\n", timer_data->delay_off); -+ -+ return strlen(buf) + 1; -+} -+ -+static ssize_t led_delay_off_store(struct class_device *dev, const char *buf, -+ size_t size) -+{ -+ struct led_classdev *led_cdev = class_get_devdata(dev); -+ struct timer_trig_data *timer_data = led_cdev->trigger_data; -+ int ret = -EINVAL; -+ char *after; -+ unsigned long state = simple_strtoul(buf, &after, 10); -+ -+ if (after - buf > 0) { -+ timer_data->delay_off = state; -+ mod_timer(&timer_data->timer, jiffies + 1); -+ ret = after - buf; -+ } -+ -+ return ret; -+} -+ -+static CLASS_DEVICE_ATTR(delay_on, 0644, led_delay_on_show, -+ led_delay_on_store); -+static CLASS_DEVICE_ATTR(delay_off, 0644, led_delay_off_show, -+ led_delay_off_store); -+ -+static void timer_trig_activate(struct led_classdev *led_cdev) -+{ -+ struct timer_trig_data *timer_data; -+ -+ timer_data = kzalloc(sizeof(struct timer_trig_data), GFP_KERNEL); -+ if (!timer_data) -+ return; -+ -+ led_cdev->trigger_data = timer_data; -+ -+ init_timer(&timer_data->timer); -+ timer_data->timer.function = led_timer_function; -+ timer_data->timer.data = (unsigned long) led_cdev; -+ -+ class_device_create_file(led_cdev->class_dev, -+ &class_device_attr_delay_on); -+ class_device_create_file(led_cdev->class_dev, -+ &class_device_attr_delay_off); -+} -+ -+static void timer_trig_deactivate(struct led_classdev *led_cdev) -+{ -+ struct timer_trig_data *timer_data = led_cdev->trigger_data; -+ -+ if (timer_data) { -+ class_device_remove_file(led_cdev->class_dev, -+ &class_device_attr_delay_on); -+ class_device_remove_file(led_cdev->class_dev, -+ &class_device_attr_delay_off); -+ del_timer_sync(&timer_data->timer); -+ kfree(timer_data); -+ } -+} -+ -+static struct led_trigger timer_led_trigger = { -+ .name = "timer", -+ .activate = timer_trig_activate, -+ .deactivate = timer_trig_deactivate, -+}; -+ -+static int __init timer_trig_init(void) -+{ -+ return led_trigger_register(&timer_led_trigger); -+} -+ -+static void __exit timer_trig_exit(void) -+{ -+ led_trigger_unregister(&timer_led_trigger); -+} -+ -+module_init(timer_trig_init); -+module_exit(timer_trig_exit); -+ -+MODULE_AUTHOR("Richard Purdie <rpurdie@openedhand.com>"); -+MODULE_DESCRIPTION("Timer LED trigger"); -+MODULE_LICENSE("GPL"); ---- linux-ixp4xx.orig/arch/arm/mach-pxa/corgi.c 2006-03-07 22:57:47.000000000 +0100 -+++ linux-ixp4xx/arch/arm/mach-pxa/corgi.c 2006-03-07 22:59:04.000000000 +0100 -@@ -165,6 +165,14 @@ static struct platform_device corgikbd_d - - - /* -+ * Corgi LEDs -+ */ -+static struct platform_device corgiled_device = { -+ .name = "corgi-led", -+ .id = -1, -+}; -+ -+/* - * Corgi Touch Screen Device - */ - static struct resource corgits_resources[] = { -@@ -298,6 +306,7 @@ static struct platform_device *devices[] - &corgikbd_device, - &corgibl_device, - &corgits_device, -+ &corgiled_device, - }; - - static void __init corgi_init(void) ---- linux-ixp4xx.orig/arch/arm/mach-pxa/spitz.c 2006-03-07 22:57:47.000000000 +0100 -+++ linux-ixp4xx/arch/arm/mach-pxa/spitz.c 2006-03-07 22:59:04.000000000 +0100 -@@ -243,6 +243,14 @@ static struct platform_device spitzkbd_d - - - /* -+ * Spitz LEDs -+ */ -+static struct platform_device spitzled_device = { -+ .name = "spitz-led", -+ .id = -1, -+}; -+ -+/* - * Spitz Touch Screen Device - */ - static struct resource spitzts_resources[] = { -@@ -419,6 +427,7 @@ static struct platform_device *devices[] - &spitzkbd_device, - &spitzts_device, - &spitzbl_device, -+ &spitzled_device, - }; - - static void __init common_init(void) ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-ixp4xx/drivers/leds/leds-corgi.c 2006-03-07 22:59:04.000000000 +0100 -@@ -0,0 +1,121 @@ -+/* -+ * LED Triggers Core -+ * -+ * Copyright 2005-2006 Openedhand Ltd. -+ * -+ * Author: Richard Purdie <rpurdie@openedhand.com> -+ * -+ * 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/config.h> -+#include <linux/kernel.h> -+#include <linux/init.h> -+#include <linux/platform_device.h> -+#include <linux/leds.h> -+#include <asm/mach-types.h> -+#include <asm/arch/corgi.h> -+#include <asm/arch/hardware.h> -+#include <asm/arch/pxa-regs.h> -+#include <asm/hardware/scoop.h> -+ -+static void corgiled_amber_set(struct led_classdev *led_cdev, enum led_brightness value) -+{ -+ if (value) -+ GPSR0 = GPIO_bit(CORGI_GPIO_LED_ORANGE); -+ else -+ GPCR0 = GPIO_bit(CORGI_GPIO_LED_ORANGE); -+} -+ -+static void corgiled_green_set(struct led_classdev *led_cdev, enum led_brightness value) -+{ -+ if (value) -+ set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_LED_GREEN); -+ else -+ reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_LED_GREEN); -+} -+ -+static struct led_classdev corgi_amber_led = { -+ .name = "corgi:amber", -+ .default_trigger = "sharpsl-charge", -+ .brightness_set = corgiled_amber_set, -+}; -+ -+static struct led_classdev corgi_green_led = { -+ .name = "corgi:green", -+ .default_trigger = "nand-disk", -+ .brightness_set = corgiled_green_set, -+}; -+ -+#ifdef CONFIG_PM -+static int corgiled_suspend(struct platform_device *dev, pm_message_t state) -+{ -+#ifdef CONFIG_LEDS_TRIGGERS -+ if (corgi_amber_led.trigger && strcmp(corgi_amber_led.trigger->name, "sharpsl-charge")) -+#endif -+ led_classdev_suspend(&corgi_amber_led); -+ led_classdev_suspend(&corgi_green_led); -+ return 0; -+} -+ -+static int corgiled_resume(struct platform_device *dev) -+{ -+ led_classdev_resume(&corgi_amber_led); -+ led_classdev_resume(&corgi_green_led); -+ return 0; -+} -+#endif -+ -+static int corgiled_probe(struct platform_device *pdev) -+{ -+ int ret; -+ -+ ret = led_classdev_register(&pdev->dev, &corgi_amber_led); -+ if (ret < 0) -+ return ret; -+ -+ ret = led_classdev_register(&pdev->dev, &corgi_green_led); -+ if (ret < 0) -+ led_classdev_unregister(&corgi_amber_led); -+ -+ return ret; -+} -+ -+static int corgiled_remove(struct platform_device *pdev) -+{ -+ led_classdev_unregister(&corgi_amber_led); -+ led_classdev_unregister(&corgi_green_led); -+ return 0; -+} -+ -+static struct platform_driver corgiled_driver = { -+ .probe = corgiled_probe, -+ .remove = corgiled_remove, -+#ifdef CONFIG_PM -+ .suspend = corgiled_suspend, -+ .resume = corgiled_resume, -+#endif -+ .driver = { -+ .name = "corgi-led", -+ }, -+}; -+ -+static int __init corgiled_init(void) -+{ -+ return platform_driver_register(&corgiled_driver); -+} -+ -+static void __exit corgiled_exit(void) -+{ -+ platform_driver_unregister(&corgiled_driver); -+} -+ -+module_init(corgiled_init); -+module_exit(corgiled_exit); -+ -+MODULE_AUTHOR("Richard Purdie <rpurdie@openedhand.com>"); -+MODULE_DESCRIPTION("Corgi LED driver"); -+MODULE_LICENSE("GPL"); ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-ixp4xx/drivers/leds/leds-spitz.c 2006-03-07 22:59:04.000000000 +0100 -@@ -0,0 +1,125 @@ -+/* -+ * LED Triggers Core -+ * -+ * Copyright 2005-2006 Openedhand Ltd. -+ * -+ * Author: Richard Purdie <rpurdie@openedhand.com> -+ * -+ * 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. -+ * -+ */ |
