diff options
| -rw-r--r-- | arch/arm/plat-versatile/Makefile | 7 | ||||
| -rw-r--r-- | arch/arm/plat-versatile/leds.c | 103 |
2 files changed, 108 insertions, 2 deletions
diff --git a/arch/arm/plat-versatile/Makefile b/arch/arm/plat-versatile/Makefile index 9b1a66816aa6..505a8f89601c 100644 --- a/arch/arm/plat-versatile/Makefile +++ b/arch/arm/plat-versatile/Makefile | |||
| @@ -1,4 +1,7 @@ | |||
| 1 | obj-y := clock.o | 1 | obj-y := clock.o |
| 2 | obj-$(CONFIG_ARM_TIMER_SP804) += timer-sp.o | 2 | obj-$(CONFIG_ARM_TIMER_SP804) += timer-sp.o |
| 3 | obj-$(CONFIG_ARCH_REALVIEW) += sched-clock.o | 3 | # For all but the Integrator, compile these |
| 4 | obj-$(CONFIG_ARCH_VERSATILE) += sched-clock.o | 4 | ifeq ($(CONFIG_ARCH_INTEGRATOR),) |
| 5 | obj-y += sched-clock.o | ||
| 6 | obj-$(CONFIG_LEDS_CLASS) += leds.o | ||
| 7 | endif | ||
diff --git a/arch/arm/plat-versatile/leds.c b/arch/arm/plat-versatile/leds.c new file mode 100644 index 000000000000..3169fa555ea6 --- /dev/null +++ b/arch/arm/plat-versatile/leds.c | |||
| @@ -0,0 +1,103 @@ | |||
| 1 | /* | ||
| 2 | * Driver for the 8 user LEDs found on the RealViews and Versatiles | ||
| 3 | * Based on DaVinci's DM365 board code | ||
| 4 | * | ||
| 5 | * License terms: GNU General Public License (GPL) version 2 | ||
| 6 | * Author: Linus Walleij <triad@df.lth.se> | ||
| 7 | */ | ||
| 8 | #include <linux/kernel.h> | ||
| 9 | #include <linux/init.h> | ||
| 10 | #include <linux/io.h> | ||
| 11 | #include <linux/slab.h> | ||
| 12 | #include <linux/leds.h> | ||
| 13 | |||
| 14 | #include <mach/hardware.h> | ||
| 15 | #include <mach/platform.h> | ||
| 16 | |||
| 17 | #ifdef VERSATILE_SYS_BASE | ||
| 18 | #define LEDREG (__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_LED_OFFSET) | ||
| 19 | #endif | ||
| 20 | |||
| 21 | #ifdef REALVIEW_SYS_BASE | ||
| 22 | #define LEDREG (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_LED_OFFSET) | ||
| 23 | #endif | ||
| 24 | |||
| 25 | struct versatile_led { | ||
| 26 | struct led_classdev cdev; | ||
| 27 | u8 mask; | ||
| 28 | }; | ||
| 29 | |||
| 30 | /* | ||
| 31 | * The triggers lines up below will only be used if the | ||
| 32 | * LED triggers are compiled in. | ||
| 33 | */ | ||
| 34 | static const struct { | ||
| 35 | const char *name; | ||
| 36 | const char *trigger; | ||
| 37 | } versatile_leds[] = { | ||
| 38 | { "versatile:0", "heartbeat", }, | ||
| 39 | { "versatile:1", "mmc0", }, | ||
| 40 | { "versatile:2", }, | ||
| 41 | { "versatile:3", }, | ||
| 42 | { "versatile:4", }, | ||
| 43 | { "versatile:5", }, | ||
| 44 | { "versatile:6", }, | ||
| 45 | { "versatile:7", }, | ||
| 46 | }; | ||
| 47 | |||
| 48 | static void versatile_led_set(struct led_classdev *cdev, | ||
| 49 | enum led_brightness b) | ||
| 50 | { | ||
| 51 | struct versatile_led *led = container_of(cdev, | ||
| 52 | struct versatile_led, cdev); | ||
| 53 | u32 reg = readl(LEDREG); | ||
| 54 | |||
| 55 | if (b != LED_OFF) | ||
| 56 | reg |= led->mask; | ||
| 57 | else | ||
| 58 | reg &= ~led->mask; | ||
| 59 | writel(reg, LEDREG); | ||
| 60 | } | ||
| 61 | |||
| 62 | static enum led_brightness versatile_led_get(struct led_classdev *cdev) | ||
| 63 | { | ||
| 64 | struct versatile_led *led = container_of(cdev, | ||
| 65 | struct versatile_led, cdev); | ||
| 66 | u32 reg = readl(LEDREG); | ||
| 67 | |||
| 68 | return (reg & led->mask) ? LED_FULL : LED_OFF; | ||
| 69 | } | ||
| 70 | |||
| 71 | static int __init versatile_leds_init(void) | ||
| 72 | { | ||
| 73 | int i; | ||
| 74 | |||
| 75 | /* All ON */ | ||
| 76 | writel(0xff, LEDREG); | ||
| 77 | for (i = 0; i < ARRAY_SIZE(versatile_leds); i++) { | ||
| 78 | struct versatile_led *led; | ||
| 79 | |||
| 80 | led = kzalloc(sizeof(*led), GFP_KERNEL); | ||
| 81 | if (!led) | ||
| 82 | break; | ||
| 83 | |||
| 84 | led->cdev.name = versatile_leds[i].name; | ||
| 85 | led->cdev.brightness_set = versatile_led_set; | ||
| 86 | led->cdev.brightness_get = versatile_led_get; | ||
| 87 | led->cdev.default_trigger = versatile_leds[i].trigger; | ||
| 88 | led->mask = BIT(i); | ||
| 89 | |||
| 90 | if (led_classdev_register(NULL, &led->cdev) < 0) { | ||
| 91 | kfree(led); | ||
| 92 | break; | ||
| 93 | } | ||
| 94 | } | ||
| 95 | |||
| 96 | return 0; | ||
| 97 | } | ||
| 98 | |||
| 99 | /* | ||
| 100 | * Since we may have triggers on any subsystem, defer registration | ||
| 101 | * until after subsystem_init. | ||
| 102 | */ | ||
| 103 | fs_initcall(versatile_leds_init); | ||
