From 11c0e42114d10d5ce33b873a1b502b21187a2d28 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 20 Jul 2010 22:32:00 +0100 Subject: [PATCH] --- yaml --- r: 201468 b: refs/heads/master c: b5417019a6e614f5285f9eb8f9e5b2d62395965b h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/arch/arm/plat-versatile/Makefile | 7 +- trunk/arch/arm/plat-versatile/leds.c | 103 +++++++++++++++++++++++++ 3 files changed, 109 insertions(+), 3 deletions(-) create mode 100644 trunk/arch/arm/plat-versatile/leds.c diff --git a/[refs] b/[refs] index d3d1e1a80c8e..5bcd46925eb1 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: ce8962455e902ffa08d59fd2b113942eaaffb0d6 +refs/heads/master: b5417019a6e614f5285f9eb8f9e5b2d62395965b diff --git a/trunk/arch/arm/plat-versatile/Makefile b/trunk/arch/arm/plat-versatile/Makefile index 9b1a66816aa6..505a8f89601c 100644 --- a/trunk/arch/arm/plat-versatile/Makefile +++ b/trunk/arch/arm/plat-versatile/Makefile @@ -1,4 +1,7 @@ obj-y := clock.o obj-$(CONFIG_ARM_TIMER_SP804) += timer-sp.o -obj-$(CONFIG_ARCH_REALVIEW) += sched-clock.o -obj-$(CONFIG_ARCH_VERSATILE) += sched-clock.o +# For all but the Integrator, compile these +ifeq ($(CONFIG_ARCH_INTEGRATOR),) +obj-y += sched-clock.o +obj-$(CONFIG_LEDS_CLASS) += leds.o +endif diff --git a/trunk/arch/arm/plat-versatile/leds.c b/trunk/arch/arm/plat-versatile/leds.c new file mode 100644 index 000000000000..3169fa555ea6 --- /dev/null +++ b/trunk/arch/arm/plat-versatile/leds.c @@ -0,0 +1,103 @@ +/* + * Driver for the 8 user LEDs found on the RealViews and Versatiles + * Based on DaVinci's DM365 board code + * + * License terms: GNU General Public License (GPL) version 2 + * Author: Linus Walleij + */ +#include +#include +#include +#include +#include + +#include +#include + +#ifdef VERSATILE_SYS_BASE +#define LEDREG (__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_LED_OFFSET) +#endif + +#ifdef REALVIEW_SYS_BASE +#define LEDREG (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_LED_OFFSET) +#endif + +struct versatile_led { + struct led_classdev cdev; + u8 mask; +}; + +/* + * The triggers lines up below will only be used if the + * LED triggers are compiled in. + */ +static const struct { + const char *name; + const char *trigger; +} versatile_leds[] = { + { "versatile:0", "heartbeat", }, + { "versatile:1", "mmc0", }, + { "versatile:2", }, + { "versatile:3", }, + { "versatile:4", }, + { "versatile:5", }, + { "versatile:6", }, + { "versatile:7", }, +}; + +static void versatile_led_set(struct led_classdev *cdev, + enum led_brightness b) +{ + struct versatile_led *led = container_of(cdev, + struct versatile_led, cdev); + u32 reg = readl(LEDREG); + + if (b != LED_OFF) + reg |= led->mask; + else + reg &= ~led->mask; + writel(reg, LEDREG); +} + +static enum led_brightness versatile_led_get(struct led_classdev *cdev) +{ + struct versatile_led *led = container_of(cdev, + struct versatile_led, cdev); + u32 reg = readl(LEDREG); + + return (reg & led->mask) ? LED_FULL : LED_OFF; +} + +static int __init versatile_leds_init(void) +{ + int i; + + /* All ON */ + writel(0xff, LEDREG); + for (i = 0; i < ARRAY_SIZE(versatile_leds); i++) { + struct versatile_led *led; + + led = kzalloc(sizeof(*led), GFP_KERNEL); + if (!led) + break; + + led->cdev.name = versatile_leds[i].name; + led->cdev.brightness_set = versatile_led_set; + led->cdev.brightness_get = versatile_led_get; + led->cdev.default_trigger = versatile_leds[i].trigger; + led->mask = BIT(i); + + if (led_classdev_register(NULL, &led->cdev) < 0) { + kfree(led); + break; + } + } + + return 0; +} + +/* + * Since we may have triggers on any subsystem, defer registration + * until after subsystem_init. + */ +fs_initcall(versatile_leds_init);