Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
[linux-drm-fsl-dcu.git] / arch / arm / mach-footbridge / ebsa285.c
1 /*
2  * linux/arch/arm/mach-footbridge/ebsa285.c
3  *
4  * EBSA285 machine fixup
5  */
6 #include <linux/init.h>
7 #include <linux/spinlock.h>
8 #include <linux/slab.h>
9 #include <linux/leds.h>
10
11 #include <asm/hardware/dec21285.h>
12 #include <asm/mach-types.h>
13
14 #include <asm/mach/arch.h>
15
16 #include "common.h"
17
18 /* LEDs */
19 #if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS)
20 struct ebsa285_led {
21         struct led_classdev     cdev;
22         u8                      mask;
23 };
24
25 /*
26  * The triggers lines up below will only be used if the
27  * LED triggers are compiled in.
28  */
29 static const struct {
30         const char *name;
31         const char *trigger;
32 } ebsa285_leds[] = {
33         { "ebsa285:amber", "cpu0", },
34         { "ebsa285:green", "heartbeat", },
35         { "ebsa285:red",},
36 };
37
38 static unsigned char hw_led_state;
39
40 static void ebsa285_led_set(struct led_classdev *cdev,
41                 enum led_brightness b)
42 {
43         struct ebsa285_led *led = container_of(cdev,
44                         struct ebsa285_led, cdev);
45
46         if (b == LED_OFF)
47                 hw_led_state |= led->mask;
48         else
49                 hw_led_state &= ~led->mask;
50         *XBUS_LEDS = hw_led_state;
51 }
52
53 static enum led_brightness ebsa285_led_get(struct led_classdev *cdev)
54 {
55         struct ebsa285_led *led = container_of(cdev,
56                         struct ebsa285_led, cdev);
57
58         return hw_led_state & led->mask ? LED_OFF : LED_FULL;
59 }
60
61 static int __init ebsa285_leds_init(void)
62 {
63         int i;
64
65         if (!machine_is_ebsa285())
66                 return -ENODEV;
67
68         /* 3 LEDS all off */
69         hw_led_state = XBUS_LED_AMBER | XBUS_LED_GREEN | XBUS_LED_RED;
70         *XBUS_LEDS = hw_led_state;
71
72         for (i = 0; i < ARRAY_SIZE(ebsa285_leds); i++) {
73                 struct ebsa285_led *led;
74
75                 led = kzalloc(sizeof(*led), GFP_KERNEL);
76                 if (!led)
77                         break;
78
79                 led->cdev.name = ebsa285_leds[i].name;
80                 led->cdev.brightness_set = ebsa285_led_set;
81                 led->cdev.brightness_get = ebsa285_led_get;
82                 led->cdev.default_trigger = ebsa285_leds[i].trigger;
83                 led->mask = BIT(i);
84
85                 if (led_classdev_register(NULL, &led->cdev) < 0) {
86                         kfree(led);
87                         break;
88                 }
89         }
90
91         return 0;
92 }
93
94 /*
95  * Since we may have triggers on any subsystem, defer registration
96  * until after subsystem_init.
97  */
98 fs_initcall(ebsa285_leds_init);
99 #endif
100
101 MACHINE_START(EBSA285, "EBSA285")
102         /* Maintainer: Russell King */
103         .atag_offset    = 0x100,
104         .video_start    = 0x000a0000,
105         .video_end      = 0x000bffff,
106         .map_io         = footbridge_map_io,
107         .init_irq       = footbridge_init_irq,
108         .init_time      = footbridge_timer_init,
109         .restart        = footbridge_restart,
110 MACHINE_END
111