diff options
Diffstat (limited to 'arch/arm/kernel/leds.c')
| -rw-r--r-- | arch/arm/kernel/leds.c | 115 | 
1 files changed, 115 insertions, 0 deletions
diff --git a/arch/arm/kernel/leds.c b/arch/arm/kernel/leds.c new file mode 100644 index 00000000000..31a316c1777 --- /dev/null +++ b/arch/arm/kernel/leds.c @@ -0,0 +1,115 @@ +/* + * LED support code, ripped out of arch/arm/kernel/time.c + * + *  Copyright (C) 1994-2001 Russell King + * + * 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/init.h> +#include <linux/sysdev.h> + +#include <asm/leds.h> + +static void dummy_leds_event(led_event_t evt) +{ +} + +void (*leds_event)(led_event_t) = dummy_leds_event; + +struct leds_evt_name { +	const char	name[8]; +	int		on; +	int		off; +}; + +static const struct leds_evt_name evt_names[] = { +	{ "amber", led_amber_on, led_amber_off }, +	{ "blue",  led_blue_on,  led_blue_off  }, +	{ "green", led_green_on, led_green_off }, +	{ "red",   led_red_on,   led_red_off   }, +}; + +static ssize_t leds_store(struct sys_device *dev, +			struct sysdev_attribute *attr, +			const char *buf, size_t size) +{ +	int ret = -EINVAL, len = strcspn(buf, " "); + +	if (len > 0 && buf[len] == '\0') +		len--; + +	if (strncmp(buf, "claim", len) == 0) { +		leds_event(led_claim); +		ret = size; +	} else if (strncmp(buf, "release", len) == 0) { +		leds_event(led_release); +		ret = size; +	} else { +		int i; + +		for (i = 0; i < ARRAY_SIZE(evt_names); i++) { +			if (strlen(evt_names[i].name) != len || +			    strncmp(buf, evt_names[i].name, len) != 0) +				continue; +			if (strncmp(buf+len, " on", 3) == 0) { +				leds_event(evt_names[i].on); +				ret = size; +			} else if (strncmp(buf+len, " off", 4) == 0) { +				leds_event(evt_names[i].off); +				ret = size; +			} +			break; +		} +	} +	return ret; +} + +static SYSDEV_ATTR(event, 0200, NULL, leds_store); + +static int leds_suspend(struct sys_device *dev, pm_message_t state) +{ +	leds_event(led_stop); +	return 0; +} + +static int leds_resume(struct sys_device *dev) +{ +	leds_event(led_start); +	return 0; +} + +static int leds_shutdown(struct sys_device *dev) +{ +	leds_event(led_halted); +	return 0; +} + +static struct sysdev_class leds_sysclass = { +	.name		= "leds", +	.shutdown	= leds_shutdown, +	.suspend	= leds_suspend, +	.resume		= leds_resume, +}; + +static struct sys_device leds_device = { +	.id		= 0, +	.cls		= &leds_sysclass, +}; + +static int __init leds_init(void) +{ +	int ret; +	ret = sysdev_class_register(&leds_sysclass); +	if (ret == 0) +		ret = sysdev_register(&leds_device); +	if (ret == 0) +		ret = sysdev_create_file(&leds_device, &attr_event); +	return ret; +} + +device_initcall(leds_init); + +EXPORT_SYMBOL(leds_event);  |