]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blame - arch/arm/mach-integrator/leds.c
ARM: integrator: localize the hardware.h header
[mirror_ubuntu-zesty-kernel.git] / arch / arm / mach-integrator / leds.c
CommitLineData
1da177e4 1/*
95f4965c
BW
2 * Driver for the 4 user LEDs found on the Integrator AP/CP baseboard
3 * Based on Versatile and RealView machine LED code
1da177e4 4 *
95f4965c
BW
5 * License terms: GNU General Public License (GPL) version 2
6 * Author: Bryan Wu <bryan.wu@canonical.com>
1da177e4
LT
7 */
8#include <linux/kernel.h>
9#include <linux/init.h>
fced80c7 10#include <linux/io.h>
95f4965c
BW
11#include <linux/slab.h>
12#include <linux/leds.h>
1da177e4 13
1b1ef755 14#include "hardware.h"
bb4dbefe
LW
15#include "cm.h"
16
95f4965c
BW
17#if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS)
18
19#define ALPHA_REG __io_address(INTEGRATOR_DBG_BASE)
20#define LEDREG (__io_address(INTEGRATOR_DBG_BASE) + INTEGRATOR_DBG_LEDS_OFFSET)
1da177e4 21
95f4965c
BW
22struct integrator_led {
23 struct led_classdev cdev;
24 u8 mask;
25};
26
27/*
28 * The triggers lines up below will only be used if the
29 * LED triggers are compiled in.
30 */
31static 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", },
40};
41
42static void integrator_led_set(struct led_classdev *cdev,
43 enum led_brightness b)
1da177e4 44{
95f4965c
BW
45 struct integrator_led *led = container_of(cdev,
46 struct integrator_led, cdev);
47 u32 reg = __raw_readl(LEDREG);
1f9c381f 48
95f4965c
BW
49 if (b != LED_OFF)
50 reg |= led->mask;
51 else
52 reg &= ~led->mask;
1da177e4 53
95f4965c
BW
54 while (__raw_readl(ALPHA_REG) & 1)
55 cpu_relax();
1da177e4 56
95f4965c
BW
57 __raw_writel(reg, LEDREG);
58}
1da177e4 59
95f4965c
BW
60static enum led_brightness integrator_led_get(struct led_classdev *cdev)
61{
62 struct integrator_led *led = container_of(cdev,
63 struct integrator_led, cdev);
64 u32 reg = __raw_readl(LEDREG);
1da177e4 65
95f4965c
BW
66 return (reg & led->mask) ? LED_FULL : LED_OFF;
67}
1da177e4 68
95f4965c
BW
69static void cm_led_set(struct led_classdev *cdev,
70 enum led_brightness b)
71{
72 if (b != LED_OFF)
73 cm_control(CM_CTRL_LED, CM_CTRL_LED);
74 else
75 cm_control(CM_CTRL_LED, 0);
76}
1da177e4 77
95f4965c
BW
78static enum led_brightness cm_led_get(struct led_classdev *cdev)
79{
fb61f862 80 u32 reg = cm_get();
1da177e4 81
95f4965c 82 return (reg & CM_CTRL_LED) ? LED_FULL : LED_OFF;
1da177e4
LT
83}
84
95f4965c 85static int __init integrator_leds_init(void)
1da177e4 86{
95f4965c
BW
87 int i;
88
89 for (i = 0; i < ARRAY_SIZE(integrator_leds); i++) {
90 struct integrator_led *led;
91
92 led = kzalloc(sizeof(*led), GFP_KERNEL);
93 if (!led)
94 break;
95
96
97 led->cdev.name = integrator_leds[i].name;
98
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;
105 }
106
107 led->cdev.default_trigger = integrator_leds[i].trigger;
108 led->mask = BIT(i);
109
110 if (led_classdev_register(NULL, &led->cdev) < 0) {
111 kfree(led);
112 break;
113 }
114 }
1da177e4
LT
115
116 return 0;
117}
118
95f4965c
BW
119/*
120 * Since we may have triggers on any subsystem, defer registration
121 * until after subsystem_init.
122 */
123fs_initcall(integrator_leds_init);
124#endif