Merge tag 'locks-v3.16-2' of git://git.samba.org/jlayton/linux
[linux/fpc-iii.git] / arch / arm / mach-integrator / leds.c
blobf1dcb57a59e2feae26a54d29ee06f54caffc767f
1 /*
2 * Driver for the 4 user LEDs found on the Integrator AP/CP baseboard
3 * Based on Versatile and RealView machine LED code
5 * License terms: GNU General Public License (GPL) version 2
6 * Author: Bryan Wu <bryan.wu@canonical.com>
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>
14 #include "hardware.h"
15 #include "cm.h"
17 #if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS)
19 #define ALPHA_REG __io_address(INTEGRATOR_DBG_BASE)
20 #define LEDREG (__io_address(INTEGRATOR_DBG_BASE) + INTEGRATOR_DBG_LEDS_OFFSET)
22 struct integrator_led {
23 struct led_classdev cdev;
24 u8 mask;
28 * The triggers lines up below will only be used if the
29 * LED triggers are compiled in.
31 static const struct {
32 const char *name;
33 const char *trigger;
34 } integrator_leds[] = {
35 { "integrator:green0", "heartbeat", },
36 { "integrator:yellow", },
37 { "integrator:red", },
38 { "integrator:green1", },
39 { "integrator:core_module", "cpu0", },
42 static void integrator_led_set(struct led_classdev *cdev,
43 enum led_brightness b)
45 struct integrator_led *led = container_of(cdev,
46 struct integrator_led, cdev);
47 u32 reg = __raw_readl(LEDREG);
49 if (b != LED_OFF)
50 reg |= led->mask;
51 else
52 reg &= ~led->mask;
54 while (__raw_readl(ALPHA_REG) & 1)
55 cpu_relax();
57 __raw_writel(reg, LEDREG);
60 static enum led_brightness integrator_led_get(struct led_classdev *cdev)
62 struct integrator_led *led = container_of(cdev,
63 struct integrator_led, cdev);
64 u32 reg = __raw_readl(LEDREG);
66 return (reg & led->mask) ? LED_FULL : LED_OFF;
69 static void cm_led_set(struct led_classdev *cdev,
70 enum led_brightness b)
72 if (b != LED_OFF)
73 cm_control(CM_CTRL_LED, CM_CTRL_LED);
74 else
75 cm_control(CM_CTRL_LED, 0);
78 static enum led_brightness cm_led_get(struct led_classdev *cdev)
80 u32 reg = cm_get();
82 return (reg & CM_CTRL_LED) ? LED_FULL : LED_OFF;
85 static int __init integrator_leds_init(void)
87 int i;
89 for (i = 0; i < ARRAY_SIZE(integrator_leds); i++) {
90 struct integrator_led *led;
92 led = kzalloc(sizeof(*led), GFP_KERNEL);
93 if (!led)
94 break;
97 led->cdev.name = integrator_leds[i].name;
99 if (i == 4) { /* Setting for LED in core module */
100 led->cdev.brightness_set = cm_led_set;
101 led->cdev.brightness_get = cm_led_get;
102 } else {
103 led->cdev.brightness_set = integrator_led_set;
104 led->cdev.brightness_get = integrator_led_get;
107 led->cdev.default_trigger = integrator_leds[i].trigger;
108 led->mask = BIT(i);
110 if (led_classdev_register(NULL, &led->cdev) < 0) {
111 kfree(led);
112 break;
116 return 0;
120 * Since we may have triggers on any subsystem, defer registration
121 * until after subsystem_init.
123 fs_initcall(integrator_leds_init);
124 #endif