diff options
-rw-r--r-- | arch/arm/mach-orion5x/dns323-setup.c | 22 | ||||
-rw-r--r-- | drivers/leds/leds-gpio.c | 31 | ||||
-rw-r--r-- | include/linux/leds.h | 12 |
3 files changed, 44 insertions, 21 deletions
diff --git a/arch/arm/mach-orion5x/dns323-setup.c b/arch/arm/mach-orion5x/dns323-setup.c index 685f34a9634..fe0de1698ed 100644 --- a/arch/arm/mach-orion5x/dns323-setup.c +++ b/arch/arm/mach-orion5x/dns323-setup.c | |||
@@ -240,22 +240,23 @@ error_fail: | |||
240 | 240 | ||
241 | #define ORION_BLINK_HALF_PERIOD 100 /* ms */ | 241 | #define ORION_BLINK_HALF_PERIOD 100 /* ms */ |
242 | 242 | ||
243 | static int dns323_gpio_blink_set(unsigned gpio, | 243 | static int dns323_gpio_blink_set(unsigned gpio, int state, |
244 | unsigned long *delay_on, unsigned long *delay_off) | 244 | unsigned long *delay_on, unsigned long *delay_off) |
245 | { | 245 | { |
246 | static int value = 0; | ||
247 | 246 | ||
248 | if (!*delay_on && !*delay_off) | 247 | if (delay_on && delay_off && !*delay_on && !*delay_off) |
249 | *delay_on = *delay_off = ORION_BLINK_HALF_PERIOD; | 248 | *delay_on = *delay_off = ORION_BLINK_HALF_PERIOD; |
250 | 249 | ||
251 | if (ORION_BLINK_HALF_PERIOD == *delay_on | 250 | switch(state) { |
252 | && ORION_BLINK_HALF_PERIOD == *delay_off) { | 251 | case GPIO_LED_NO_BLINK_LOW: |
253 | value = !value; | 252 | case GPIO_LED_NO_BLINK_HIGH: |
254 | orion_gpio_set_blink(gpio, value); | 253 | orion_gpio_set_blink(gpio, 0); |
255 | return 0; | 254 | gpio_set_value(gpio, state); |
255 | break; | ||
256 | case GPIO_LED_BLINK: | ||
257 | orion_gpio_set_blink(gpio, 1); | ||
256 | } | 258 | } |
257 | 259 | return 0; | |
258 | return -EINVAL; | ||
259 | } | 260 | } |
260 | 261 | ||
261 | static struct gpio_led dns323_leds[] = { | 262 | static struct gpio_led dns323_leds[] = { |
@@ -263,6 +264,7 @@ static struct gpio_led dns323_leds[] = { | |||
263 | .name = "power:blue", | 264 | .name = "power:blue", |
264 | .gpio = DNS323_GPIO_LED_POWER2, | 265 | .gpio = DNS323_GPIO_LED_POWER2, |
265 | .default_trigger = "timer", | 266 | .default_trigger = "timer", |
267 | .active_low = 1, | ||
266 | }, { | 268 | }, { |
267 | .name = "right:amber", | 269 | .name = "right:amber", |
268 | .gpio = DNS323_GPIO_LED_RIGHT_AMBER, | 270 | .gpio = DNS323_GPIO_LED_RIGHT_AMBER, |
diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c index 6d94b0b9979..26843dd6b85 100644 --- a/drivers/leds/leds-gpio.c +++ b/drivers/leds/leds-gpio.c | |||
@@ -26,7 +26,8 @@ struct gpio_led_data { | |||
26 | u8 new_level; | 26 | u8 new_level; |
27 | u8 can_sleep; | 27 | u8 can_sleep; |
28 | u8 active_low; | 28 | u8 active_low; |
29 | int (*platform_gpio_blink_set)(unsigned gpio, | 29 | u8 blinking; |
30 | int (*platform_gpio_blink_set)(unsigned gpio, int state, | ||
30 | unsigned long *delay_on, unsigned long *delay_off); | 31 | unsigned long *delay_on, unsigned long *delay_off); |
31 | }; | 32 | }; |
32 | 33 | ||
@@ -35,7 +36,13 @@ static void gpio_led_work(struct work_struct *work) | |||
35 | struct gpio_led_data *led_dat = | 36 | struct gpio_led_data *led_dat = |
36 | container_of(work, struct gpio_led_data, work); | 37 | container_of(work, struct gpio_led_data, work); |
37 | 38 | ||
38 | gpio_set_value_cansleep(led_dat->gpio, led_dat->new_level); | 39 | if (led_dat->blinking) { |
40 | led_dat->platform_gpio_blink_set(led_dat->gpio, | ||
41 | led_dat->new_level, | ||
42 | NULL, NULL); | ||
43 | led_dat->blinking = 0; | ||
44 | } else | ||
45 | gpio_set_value_cansleep(led_dat->gpio, led_dat->new_level); | ||
39 | } | 46 | } |
40 | 47 | ||
41 | static void gpio_led_set(struct led_classdev *led_cdev, | 48 | static void gpio_led_set(struct led_classdev *led_cdev, |
@@ -60,8 +67,14 @@ static void gpio_led_set(struct led_classdev *led_cdev, | |||
60 | if (led_dat->can_sleep) { | 67 | if (led_dat->can_sleep) { |
61 | led_dat->new_level = level; | 68 | led_dat->new_level = level; |
62 | schedule_work(&led_dat->work); | 69 | schedule_work(&led_dat->work); |
63 | } else | 70 | } else { |
64 | gpio_set_value(led_dat->gpio, level); | 71 | if (led_dat->blinking) { |
72 | led_dat->platform_gpio_blink_set(led_dat->gpio, level, | ||
73 | NULL, NULL); | ||
74 | led_dat->blinking = 0; | ||
75 | } else | ||
76 | gpio_set_value(led_dat->gpio, level); | ||
77 | } | ||
65 | } | 78 | } |
66 | 79 | ||
67 | static int gpio_blink_set(struct led_classdev *led_cdev, | 80 | static int gpio_blink_set(struct led_classdev *led_cdev, |
@@ -70,12 +83,14 @@ static int gpio_blink_set(struct led_classdev *led_cdev, | |||
70 | struct gpio_led_data *led_dat = | 83 | struct gpio_led_data *led_dat = |
71 | container_of(led_cdev, struct gpio_led_data, cdev); | 84 | container_of(led_cdev, struct gpio_led_data, cdev); |
72 | 85 | ||
73 | return led_dat->platform_gpio_blink_set(led_dat->gpio, delay_on, delay_off); | 86 | led_dat->blinking = 1; |
87 | return led_dat->platform_gpio_blink_set(led_dat->gpio, GPIO_LED_BLINK, | ||
88 | delay_on, delay_off); | ||
74 | } | 89 | } |
75 | 90 | ||
76 | static int __devinit create_gpio_led(const struct gpio_led *template, | 91 | static int __devinit create_gpio_led(const struct gpio_led *template, |
77 | struct gpio_led_data *led_dat, struct device *parent, | 92 | struct gpio_led_data *led_dat, struct device *parent, |
78 | int (*blink_set)(unsigned, unsigned long *, unsigned long *)) | 93 | int (*blink_set)(unsigned, int, unsigned long *, unsigned long *)) |
79 | { | 94 | { |
80 | int ret, state; | 95 | int ret, state; |
81 | 96 | ||
@@ -97,6 +112,7 @@ static int __devinit create_gpio_led(const struct gpio_led *template, | |||
97 | led_dat->gpio = template->gpio; | 112 | led_dat->gpio = template->gpio; |
98 | led_dat->can_sleep = gpio_cansleep(template->gpio); | 113 | led_dat->can_sleep = gpio_cansleep(template->gpio); |
99 | led_dat->active_low = template->active_low; | 114 | led_dat->active_low = template->active_low; |
115 | led_dat->blinking = 0; | ||
100 | if (blink_set) { | 116 | if (blink_set) { |
101 | led_dat->platform_gpio_blink_set = blink_set; | 117 | led_dat->platform_gpio_blink_set = blink_set; |
102 | led_dat->cdev.blink_set = gpio_blink_set; | 118 | led_dat->cdev.blink_set = gpio_blink_set; |
@@ -113,7 +129,7 @@ static int __devinit create_gpio_led(const struct gpio_led *template, | |||
113 | ret = gpio_direction_output(led_dat->gpio, led_dat->active_low ^ state); | 129 | ret = gpio_direction_output(led_dat->gpio, led_dat->active_low ^ state); |
114 | if (ret < 0) | 130 | if (ret < 0) |
115 | goto err; | 131 | goto err; |
116 | 132 | ||
117 | INIT_WORK(&led_dat->work, gpio_led_work); | 133 | INIT_WORK(&led_dat->work, gpio_led_work); |
118 | 134 | ||
119 | ret = led_classdev_register(parent, &led_dat->cdev); | 135 | ret = led_classdev_register(parent, &led_dat->cdev); |
@@ -234,6 +250,7 @@ static int __devinit of_gpio_leds_probe(struct of_device *ofdev, | |||
234 | led.gpio = of_get_gpio_flags(child, 0, &flags); | 250 | led.gpio = of_get_gpio_flags(child, 0, &flags); |
235 | led.active_low = flags & OF_GPIO_ACTIVE_LOW; | 251 | led.active_low = flags & OF_GPIO_ACTIVE_LOW; |
236 | led.name = of_get_property(child, "label", NULL) ? : child->name; | 252 | led.name = of_get_property(child, "label", NULL) ? : child->name; |
253 | led.blinking = 0; | ||
237 | led.default_trigger = | 254 | led.default_trigger = |
238 | of_get_property(child, "linux,default-trigger", NULL); | 255 | of_get_property(child, "linux,default-trigger", NULL); |
239 | state = of_get_property(child, "default-state", NULL); | 256 | state = of_get_property(child, "default-state", NULL); |
diff --git a/include/linux/leds.h b/include/linux/leds.h index d8bf9665e70..ba6986a1166 100644 --- a/include/linux/leds.h +++ b/include/linux/leds.h | |||
@@ -149,14 +149,18 @@ struct gpio_led { | |||
149 | unsigned default_state : 2; | 149 | unsigned default_state : 2; |
150 | /* default_state should be one of LEDS_GPIO_DEFSTATE_(ON|OFF|KEEP) */ | 150 | /* default_state should be one of LEDS_GPIO_DEFSTATE_(ON|OFF|KEEP) */ |
151 | }; | 151 | }; |
152 | #define LEDS_GPIO_DEFSTATE_OFF 0 | 152 | #define LEDS_GPIO_DEFSTATE_OFF 0 |
153 | #define LEDS_GPIO_DEFSTATE_ON 1 | 153 | #define LEDS_GPIO_DEFSTATE_ON 1 |
154 | #define LEDS_GPIO_DEFSTATE_KEEP 2 | 154 | #define LEDS_GPIO_DEFSTATE_KEEP 2 |
155 | 155 | ||
156 | struct gpio_led_platform_data { | 156 | struct gpio_led_platform_data { |
157 | int num_leds; | 157 | int num_leds; |
158 | struct gpio_led *leds; | 158 | struct gpio_led *leds; |
159 | int (*gpio_blink_set)(unsigned gpio, | 159 | |
160 | #define GPIO_LED_NO_BLINK_LOW 0 /* No blink GPIO state low */ | ||
161 | #define GPIO_LED_NO_BLINK_HIGH 1 /* No blink GPIO state high */ | ||
162 | #define GPIO_LED_BLINK 2 /* Plase, blink */ | ||
163 | int (*gpio_blink_set)(unsigned gpio, int state, | ||
160 | unsigned long *delay_on, | 164 | unsigned long *delay_on, |
161 | unsigned long *delay_off); | 165 | unsigned long *delay_off); |
162 | }; | 166 | }; |