diff options
28 files changed, 641 insertions, 619 deletions
diff --git a/Documentation/devicetree/bindings/leds/common.txt b/Documentation/devicetree/bindings/leds/common.txt index 1d4afe9644b6..aa1399814a2a 100644 --- a/Documentation/devicetree/bindings/leds/common.txt +++ b/Documentation/devicetree/bindings/leds/common.txt | |||
@@ -31,7 +31,7 @@ Optional properties for child nodes: | |||
31 | "backlight" - LED will act as a back-light, controlled by the framebuffer | 31 | "backlight" - LED will act as a back-light, controlled by the framebuffer |
32 | system | 32 | system |
33 | "default-on" - LED will turn on (but for leds-gpio see "default-state" | 33 | "default-on" - LED will turn on (but for leds-gpio see "default-state" |
34 | property in Documentation/devicetree/bindings/gpio/led.txt) | 34 | property in Documentation/devicetree/bindings/leds/leds-gpio.txt) |
35 | "heartbeat" - LED "double" flashes at a load average based rate | 35 | "heartbeat" - LED "double" flashes at a load average based rate |
36 | "disk-activity" - LED indicates disk activity | 36 | "disk-activity" - LED indicates disk activity |
37 | "ide-disk" - LED indicates IDE disk activity (deprecated), | 37 | "ide-disk" - LED indicates IDE disk activity (deprecated), |
diff --git a/Documentation/devicetree/bindings/leds/leds-lm3692x.txt b/Documentation/devicetree/bindings/leds/leds-lm3692x.txt index 6c9074f84a51..08b352840bd7 100644 --- a/Documentation/devicetree/bindings/leds/leds-lm3692x.txt +++ b/Documentation/devicetree/bindings/leds/leds-lm3692x.txt | |||
@@ -20,7 +20,10 @@ Optional properties: | |||
20 | - vled-supply : LED supply | 20 | - vled-supply : LED supply |
21 | 21 | ||
22 | Required child properties: | 22 | Required child properties: |
23 | - reg : 0 | 23 | - reg : 0 - Will enable all LED sync paths |
24 | 1 - Will enable the LED1 sync | ||
25 | 2 - Will enable the LED2 sync | ||
26 | 3 - Will enable the LED3 sync (LM36923 only) | ||
24 | 27 | ||
25 | Optional child properties: | 28 | Optional child properties: |
26 | - label : see Documentation/devicetree/bindings/leds/common.txt | 29 | - label : see Documentation/devicetree/bindings/leds/common.txt |
diff --git a/Documentation/devicetree/bindings/leds/leds-lt3593.txt b/Documentation/devicetree/bindings/leds/leds-lt3593.txt new file mode 100644 index 000000000000..6b2cabc36c0c --- /dev/null +++ b/Documentation/devicetree/bindings/leds/leds-lt3593.txt | |||
@@ -0,0 +1,32 @@ | |||
1 | Bindings for Linear Technologies LT3593 LED controller | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: Should be "lltc,lt3593". | ||
5 | - lltc,ctrl-gpios: A handle to the GPIO that is connected to the 'CTRL' | ||
6 | pin of the chip. | ||
7 | |||
8 | The hardware supports only one LED. The properties of this LED are | ||
9 | configured in a sub-node in the device node. | ||
10 | |||
11 | Optional sub-node properties: | ||
12 | - label: A label for the LED. If none is given, the LED will be | ||
13 | named "lt3595::". | ||
14 | - linux,default-trigger: The default trigger for the LED. | ||
15 | See Documentation/devicetree/bindings/leds/common.txt | ||
16 | - default-state: The initial state of the LED. | ||
17 | See Documentation/devicetree/bindings/leds/common.txt | ||
18 | |||
19 | If multiple chips of this type are found in a design, each one needs to | ||
20 | be handled by its own device node. | ||
21 | |||
22 | Example: | ||
23 | |||
24 | led-controller { | ||
25 | compatible = "lltc,lt3593"; | ||
26 | lltc,ctrl-gpios = <&gpio 0 GPIO_ACTIVE_HIGH>; | ||
27 | |||
28 | led { | ||
29 | label = "white:backlight"; | ||
30 | default-state = "on"; | ||
31 | }; | ||
32 | }; | ||
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index 6e3a998f3370..44097a3e0fcc 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig | |||
@@ -57,12 +57,13 @@ config LEDS_AAT1290 | |||
57 | depends on PINCTRL | 57 | depends on PINCTRL |
58 | help | 58 | help |
59 | This option enables support for the LEDs on the AAT1290. | 59 | This option enables support for the LEDs on the AAT1290. |
60 | |||
60 | config LEDS_APU | 61 | config LEDS_APU |
61 | tristate "Front panel LED support for PC Engines APU/APU2 boards" | 62 | tristate "Front panel LED support for PC Engines APU/APU2/APU3 boards" |
62 | depends on LEDS_CLASS | 63 | depends on LEDS_CLASS |
63 | depends on X86 && DMI | 64 | depends on X86 && DMI |
64 | help | 65 | help |
65 | This driver makes the PC Engines APU/APU2 front panel LEDs | 66 | This driver makes the PC Engines APU/APU2/APU3 front panel LEDs |
66 | accessible from userspace programs through the LED subsystem. | 67 | accessible from userspace programs through the LED subsystem. |
67 | 68 | ||
68 | To compile this driver as a module, choose M here: the | 69 | To compile this driver as a module, choose M here: the |
diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c index 431123b048a2..17d73db1456e 100644 --- a/drivers/leds/led-triggers.c +++ b/drivers/leds/led-triggers.c | |||
@@ -103,15 +103,16 @@ ssize_t led_trigger_show(struct device *dev, struct device_attribute *attr, | |||
103 | EXPORT_SYMBOL_GPL(led_trigger_show); | 103 | EXPORT_SYMBOL_GPL(led_trigger_show); |
104 | 104 | ||
105 | /* Caller must ensure led_cdev->trigger_lock held */ | 105 | /* Caller must ensure led_cdev->trigger_lock held */ |
106 | void led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trig) | 106 | int led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trig) |
107 | { | 107 | { |
108 | unsigned long flags; | 108 | unsigned long flags; |
109 | char *event = NULL; | 109 | char *event = NULL; |
110 | char *envp[2]; | 110 | char *envp[2]; |
111 | const char *name; | 111 | const char *name; |
112 | int ret; | ||
112 | 113 | ||
113 | if (!led_cdev->trigger && !trig) | 114 | if (!led_cdev->trigger && !trig) |
114 | return; | 115 | return 0; |
115 | 116 | ||
116 | name = trig ? trig->name : "none"; | 117 | name = trig ? trig->name : "none"; |
117 | event = kasprintf(GFP_KERNEL, "TRIGGER=%s", name); | 118 | event = kasprintf(GFP_KERNEL, "TRIGGER=%s", name); |
@@ -126,7 +127,10 @@ void led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trig) | |||
126 | led_stop_software_blink(led_cdev); | 127 | led_stop_software_blink(led_cdev); |
127 | if (led_cdev->trigger->deactivate) | 128 | if (led_cdev->trigger->deactivate) |
128 | led_cdev->trigger->deactivate(led_cdev); | 129 | led_cdev->trigger->deactivate(led_cdev); |
130 | device_remove_groups(led_cdev->dev, led_cdev->trigger->groups); | ||
129 | led_cdev->trigger = NULL; | 131 | led_cdev->trigger = NULL; |
132 | led_cdev->trigger_data = NULL; | ||
133 | led_cdev->activated = false; | ||
130 | led_set_brightness(led_cdev, LED_OFF); | 134 | led_set_brightness(led_cdev, LED_OFF); |
131 | } | 135 | } |
132 | if (trig) { | 136 | if (trig) { |
@@ -134,8 +138,20 @@ void led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trig) | |||
134 | list_add_tail(&led_cdev->trig_list, &trig->led_cdevs); | 138 | list_add_tail(&led_cdev->trig_list, &trig->led_cdevs); |
135 | write_unlock_irqrestore(&trig->leddev_list_lock, flags); | 139 | write_unlock_irqrestore(&trig->leddev_list_lock, flags); |
136 | led_cdev->trigger = trig; | 140 | led_cdev->trigger = trig; |
141 | |||
137 | if (trig->activate) | 142 | if (trig->activate) |
138 | trig->activate(led_cdev); | 143 | ret = trig->activate(led_cdev); |
144 | else | ||
145 | ret = 0; | ||
146 | |||
147 | if (ret) | ||
148 | goto err_activate; | ||
149 | |||
150 | ret = device_add_groups(led_cdev->dev, trig->groups); | ||
151 | if (ret) { | ||
152 | dev_err(led_cdev->dev, "Failed to add trigger attributes\n"); | ||
153 | goto err_add_groups; | ||
154 | } | ||
139 | } | 155 | } |
140 | 156 | ||
141 | if (event) { | 157 | if (event) { |
@@ -146,6 +162,23 @@ void led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trig) | |||
146 | "%s: Error sending uevent\n", __func__); | 162 | "%s: Error sending uevent\n", __func__); |
147 | kfree(event); | 163 | kfree(event); |
148 | } | 164 | } |
165 | |||
166 | return 0; | ||
167 | |||
168 | err_add_groups: | ||
169 | |||
170 | if (trig->deactivate) | ||
171 | trig->deactivate(led_cdev); | ||
172 | err_activate: | ||
173 | |||
174 | led_cdev->trigger = NULL; | ||
175 | led_cdev->trigger_data = NULL; | ||
176 | write_lock_irqsave(&led_cdev->trigger->leddev_list_lock, flags); | ||
177 | list_del(&led_cdev->trig_list); | ||
178 | write_unlock_irqrestore(&led_cdev->trigger->leddev_list_lock, flags); | ||
179 | led_set_brightness(led_cdev, LED_OFF); | ||
180 | |||
181 | return ret; | ||
149 | } | 182 | } |
150 | EXPORT_SYMBOL_GPL(led_trigger_set); | 183 | EXPORT_SYMBOL_GPL(led_trigger_set); |
151 | 184 | ||
diff --git a/drivers/leds/leds-apu.c b/drivers/leds/leds-apu.c index 8c93d68964c7..8d42e46e2de3 100644 --- a/drivers/leds/leds-apu.c +++ b/drivers/leds/leds-apu.c | |||
@@ -102,6 +102,13 @@ static const struct apu_led_profile apu2_led_profile[] = { | |||
102 | { "apu2:green:3", LED_OFF, APU2_FCH_GPIO_BASE + 70 * APU2_IOSIZE }, | 102 | { "apu2:green:3", LED_OFF, APU2_FCH_GPIO_BASE + 70 * APU2_IOSIZE }, |
103 | }; | 103 | }; |
104 | 104 | ||
105 | /* Same as apu2_led_profile, but with "3" in the LED names. */ | ||
106 | static const struct apu_led_profile apu3_led_profile[] = { | ||
107 | { "apu3:green:1", LED_ON, APU2_FCH_GPIO_BASE + 68 * APU2_IOSIZE }, | ||
108 | { "apu3:green:2", LED_OFF, APU2_FCH_GPIO_BASE + 69 * APU2_IOSIZE }, | ||
109 | { "apu3:green:3", LED_OFF, APU2_FCH_GPIO_BASE + 70 * APU2_IOSIZE }, | ||
110 | }; | ||
111 | |||
105 | static const struct dmi_system_id apu_led_dmi_table[] __initconst = { | 112 | static const struct dmi_system_id apu_led_dmi_table[] __initconst = { |
106 | { | 113 | { |
107 | .ident = "apu", | 114 | .ident = "apu", |
@@ -134,6 +141,30 @@ static const struct dmi_system_id apu_led_dmi_table[] __initconst = { | |||
134 | DMI_MATCH(DMI_BOARD_NAME, "PC Engines apu2") | 141 | DMI_MATCH(DMI_BOARD_NAME, "PC Engines apu2") |
135 | } | 142 | } |
136 | }, | 143 | }, |
144 | /* PC Engines APU3 with "Legacy" bios < 4.0.8 */ | ||
145 | { | ||
146 | .ident = "apu3", | ||
147 | .matches = { | ||
148 | DMI_MATCH(DMI_SYS_VENDOR, "PC Engines"), | ||
149 | DMI_MATCH(DMI_BOARD_NAME, "APU3") | ||
150 | } | ||
151 | }, | ||
152 | /* PC Engines APU3 with "Legacy" bios >= 4.0.8 */ | ||
153 | { | ||
154 | .ident = "apu3", | ||
155 | .matches = { | ||
156 | DMI_MATCH(DMI_SYS_VENDOR, "PC Engines"), | ||
157 | DMI_MATCH(DMI_BOARD_NAME, "apu3") | ||
158 | } | ||
159 | }, | ||
160 | /* PC Engines APU2 with "Mainline" bios */ | ||
161 | { | ||
162 | .ident = "apu3", | ||
163 | .matches = { | ||
164 | DMI_MATCH(DMI_SYS_VENDOR, "PC Engines"), | ||
165 | DMI_MATCH(DMI_BOARD_NAME, "PC Engines apu3") | ||
166 | } | ||
167 | }, | ||
137 | {} | 168 | {} |
138 | }; | 169 | }; |
139 | MODULE_DEVICE_TABLE(dmi, apu_led_dmi_table); | 170 | MODULE_DEVICE_TABLE(dmi, apu_led_dmi_table); |
@@ -235,6 +266,14 @@ static int __init apu_led_probe(struct platform_device *pdev) | |||
235 | apu_led->platform = APU2_LED_PLATFORM; | 266 | apu_led->platform = APU2_LED_PLATFORM; |
236 | apu_led->num_led_instances = ARRAY_SIZE(apu2_led_profile); | 267 | apu_led->num_led_instances = ARRAY_SIZE(apu2_led_profile); |
237 | apu_led->iosize = APU2_IOSIZE; | 268 | apu_led->iosize = APU2_IOSIZE; |
269 | } else if (dmi_match(DMI_BOARD_NAME, "APU3") || | ||
270 | dmi_match(DMI_BOARD_NAME, "apu3") || | ||
271 | dmi_match(DMI_BOARD_NAME, "PC Engines apu3")) { | ||
272 | apu_led->profile = apu3_led_profile; | ||
273 | /* Otherwise identical to APU2. */ | ||
274 | apu_led->platform = APU2_LED_PLATFORM; | ||
275 | apu_led->num_led_instances = ARRAY_SIZE(apu3_led_profile); | ||
276 | apu_led->iosize = APU2_IOSIZE; | ||
238 | } | 277 | } |
239 | 278 | ||
240 | spin_lock_init(&apu_led->lock); | 279 | spin_lock_init(&apu_led->lock); |
@@ -259,7 +298,10 @@ static int __init apu_led_init(void) | |||
259 | if (!(dmi_match(DMI_PRODUCT_NAME, "APU") || | 298 | if (!(dmi_match(DMI_PRODUCT_NAME, "APU") || |
260 | dmi_match(DMI_PRODUCT_NAME, "APU2") || | 299 | dmi_match(DMI_PRODUCT_NAME, "APU2") || |
261 | dmi_match(DMI_PRODUCT_NAME, "apu2") || | 300 | dmi_match(DMI_PRODUCT_NAME, "apu2") || |
262 | dmi_match(DMI_PRODUCT_NAME, "PC Engines apu2"))) { | 301 | dmi_match(DMI_PRODUCT_NAME, "PC Engines apu2") || |
302 | dmi_match(DMI_PRODUCT_NAME, "APU3") || | ||
303 | dmi_match(DMI_PRODUCT_NAME, "apu3") || | ||
304 | dmi_match(DMI_PRODUCT_NAME, "PC Engines apu3"))) { | ||
263 | pr_err("Unknown PC Engines board: %s\n", | 305 | pr_err("Unknown PC Engines board: %s\n", |
264 | dmi_get_system_info(DMI_PRODUCT_NAME)); | 306 | dmi_get_system_info(DMI_PRODUCT_NAME)); |
265 | return -ENODEV; | 307 | return -ENODEV; |
diff --git a/drivers/leds/leds-lm3692x.c b/drivers/leds/leds-lm3692x.c index 437173d1712c..4f413a7c5f05 100644 --- a/drivers/leds/leds-lm3692x.c +++ b/drivers/leds/leds-lm3692x.c | |||
@@ -1,17 +1,6 @@ | |||
1 | /* | 1 | // SPDX-License-Identifier: GPL-2.0 |
2 | * TI lm3692x LED Driver | 2 | // TI LM3692x LED chip family driver |
3 | * | 3 | // Copyright (C) 2017-18 Texas Instruments Incorporated - http://www.ti.com/ |
4 | * Copyright (C) 2017 Texas Instruments | ||
5 | * | ||
6 | * Author: Dan Murphy <dmurphy@ti.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License | ||
10 | * version 2 as published by the Free Software Foundation. | ||
11 | * | ||
12 | * Data sheet is located | ||
13 | * http://www.ti.com/lit/ds/snvsa29/snvsa29.pdf | ||
14 | */ | ||
15 | 4 | ||
16 | #include <linux/gpio/consumer.h> | 5 | #include <linux/gpio/consumer.h> |
17 | #include <linux/i2c.h> | 6 | #include <linux/i2c.h> |
@@ -26,6 +15,9 @@ | |||
26 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
27 | #include <uapi/linux/uleds.h> | 16 | #include <uapi/linux/uleds.h> |
28 | 17 | ||
18 | #define LM36922_MODEL 0 | ||
19 | #define LM36923_MODEL 1 | ||
20 | |||
29 | #define LM3692X_REV 0x0 | 21 | #define LM3692X_REV 0x0 |
30 | #define LM3692X_RESET 0x1 | 22 | #define LM3692X_RESET 0x1 |
31 | #define LM3692X_EN 0x10 | 23 | #define LM3692X_EN 0x10 |
@@ -44,6 +36,9 @@ | |||
44 | #define LM3692X_DEVICE_EN BIT(0) | 36 | #define LM3692X_DEVICE_EN BIT(0) |
45 | #define LM3692X_LED1_EN BIT(1) | 37 | #define LM3692X_LED1_EN BIT(1) |
46 | #define LM3692X_LED2_EN BIT(2) | 38 | #define LM3692X_LED2_EN BIT(2) |
39 | #define LM36923_LED3_EN BIT(3) | ||
40 | #define LM3692X_ENABLE_MASK (LM3692X_DEVICE_EN | LM3692X_LED1_EN | \ | ||
41 | LM3692X_LED2_EN | LM36923_LED3_EN) | ||
47 | 42 | ||
48 | /* Brightness Control Bits */ | 43 | /* Brightness Control Bits */ |
49 | #define LM3692X_BL_ADJ_POL BIT(0) | 44 | #define LM3692X_BL_ADJ_POL BIT(0) |
@@ -109,6 +104,8 @@ | |||
109 | * @enable_gpio - VDDIO/EN gpio to enable communication interface | 104 | * @enable_gpio - VDDIO/EN gpio to enable communication interface |
110 | * @regulator - LED supply regulator pointer | 105 | * @regulator - LED supply regulator pointer |
111 | * @label - LED label | 106 | * @label - LED label |
107 | * @led_enable - LED sync to be enabled | ||
108 | * @model_id - Current device model ID enumerated | ||
112 | */ | 109 | */ |
113 | struct lm3692x_led { | 110 | struct lm3692x_led { |
114 | struct mutex lock; | 111 | struct mutex lock; |
@@ -118,6 +115,8 @@ struct lm3692x_led { | |||
118 | struct gpio_desc *enable_gpio; | 115 | struct gpio_desc *enable_gpio; |
119 | struct regulator *regulator; | 116 | struct regulator *regulator; |
120 | char label[LED_MAX_NAME_SIZE]; | 117 | char label[LED_MAX_NAME_SIZE]; |
118 | int led_enable; | ||
119 | int model_id; | ||
121 | }; | 120 | }; |
122 | 121 | ||
123 | static const struct reg_default lm3692x_reg_defs[] = { | 122 | static const struct reg_default lm3692x_reg_defs[] = { |
@@ -200,6 +199,7 @@ out: | |||
200 | 199 | ||
201 | static int lm3692x_init(struct lm3692x_led *led) | 200 | static int lm3692x_init(struct lm3692x_led *led) |
202 | { | 201 | { |
202 | int enable_state; | ||
203 | int ret; | 203 | int ret; |
204 | 204 | ||
205 | if (led->regulator) { | 205 | if (led->regulator) { |
@@ -226,9 +226,25 @@ static int lm3692x_init(struct lm3692x_led *led) | |||
226 | 226 | ||
227 | /* | 227 | /* |
228 | * For glitch free operation, the following data should | 228 | * For glitch free operation, the following data should |
229 | * only be written while device enable bit is 0 | 229 | * only be written while LEDx enable bits are 0 and the device enable |
230 | * bit is set to 1. | ||
230 | * per Section 7.5.14 of the data sheet | 231 | * per Section 7.5.14 of the data sheet |
231 | */ | 232 | */ |
233 | ret = regmap_write(led->regmap, LM3692X_EN, LM3692X_DEVICE_EN); | ||
234 | if (ret) | ||
235 | goto out; | ||
236 | |||
237 | /* Set the brightness to 0 so when enabled the LEDs do not come | ||
238 | * on with full brightness. | ||
239 | */ | ||
240 | ret = regmap_write(led->regmap, LM3692X_BRT_MSB, 0); | ||
241 | if (ret) | ||
242 | goto out; | ||
243 | |||
244 | ret = regmap_write(led->regmap, LM3692X_BRT_LSB, 0); | ||
245 | if (ret) | ||
246 | goto out; | ||
247 | |||
232 | ret = regmap_write(led->regmap, LM3692X_PWM_CTRL, | 248 | ret = regmap_write(led->regmap, LM3692X_PWM_CTRL, |
233 | LM3692X_PWM_FILTER_100 | LM3692X_PWM_SAMP_24MHZ); | 249 | LM3692X_PWM_FILTER_100 | LM3692X_PWM_SAMP_24MHZ); |
234 | if (ret) | 250 | if (ret) |
@@ -258,6 +274,38 @@ static int lm3692x_init(struct lm3692x_led *led) | |||
258 | if (ret) | 274 | if (ret) |
259 | goto out; | 275 | goto out; |
260 | 276 | ||
277 | switch (led->led_enable) { | ||
278 | case 0: | ||
279 | default: | ||
280 | if (led->model_id == LM36923_MODEL) | ||
281 | enable_state = LM3692X_LED1_EN | LM3692X_LED2_EN | | ||
282 | LM36923_LED3_EN; | ||
283 | else | ||
284 | enable_state = LM3692X_LED1_EN | LM3692X_LED2_EN; | ||
285 | |||
286 | break; | ||
287 | case 1: | ||
288 | enable_state = LM3692X_LED1_EN; | ||
289 | break; | ||
290 | case 2: | ||
291 | enable_state = LM3692X_LED2_EN; | ||
292 | break; | ||
293 | |||
294 | case 3: | ||
295 | if (led->model_id == LM36923_MODEL) { | ||
296 | enable_state = LM36923_LED3_EN; | ||
297 | break; | ||
298 | } | ||
299 | |||
300 | ret = -EINVAL; | ||
301 | dev_err(&led->client->dev, | ||
302 | "LED3 sync not available on this device\n"); | ||
303 | goto out; | ||
304 | } | ||
305 | |||
306 | ret = regmap_update_bits(led->regmap, LM3692X_EN, LM3692X_ENABLE_MASK, | ||
307 | enable_state | LM3692X_DEVICE_EN); | ||
308 | |||
261 | return ret; | 309 | return ret; |
262 | out: | 310 | out: |
263 | dev_err(&led->client->dev, "Fail writing initialization values\n"); | 311 | dev_err(&led->client->dev, "Fail writing initialization values\n"); |
@@ -274,52 +322,75 @@ out: | |||
274 | 322 | ||
275 | return ret; | 323 | return ret; |
276 | } | 324 | } |
277 | 325 | static int lm3692x_probe_dt(struct lm3692x_led *led) | |
278 | static int lm3692x_probe(struct i2c_client *client, | ||
279 | const struct i2c_device_id *id) | ||
280 | { | 326 | { |
281 | int ret; | 327 | struct fwnode_handle *child = NULL; |
282 | struct lm3692x_led *led; | ||
283 | struct device_node *np = client->dev.of_node; | ||
284 | struct device_node *child_node; | ||
285 | const char *name; | 328 | const char *name; |
329 | int ret; | ||
286 | 330 | ||
287 | led = devm_kzalloc(&client->dev, sizeof(*led), GFP_KERNEL); | 331 | led->enable_gpio = devm_gpiod_get_optional(&led->client->dev, |
288 | if (!led) | ||
289 | return -ENOMEM; | ||
290 | |||
291 | for_each_available_child_of_node(np, child_node) { | ||
292 | led->led_dev.default_trigger = of_get_property(child_node, | ||
293 | "linux,default-trigger", | ||
294 | NULL); | ||
295 | |||
296 | ret = of_property_read_string(child_node, "label", &name); | ||
297 | if (!ret) | ||
298 | snprintf(led->label, sizeof(led->label), | ||
299 | "%s:%s", id->name, name); | ||
300 | else | ||
301 | snprintf(led->label, sizeof(led->label), | ||
302 | "%s::backlight_cluster", id->name); | ||
303 | }; | ||
304 | |||
305 | led->enable_gpio = devm_gpiod_get_optional(&client->dev, | ||
306 | "enable", GPIOD_OUT_LOW); | 332 | "enable", GPIOD_OUT_LOW); |
307 | if (IS_ERR(led->enable_gpio)) { | 333 | if (IS_ERR(led->enable_gpio)) { |
308 | ret = PTR_ERR(led->enable_gpio); | 334 | ret = PTR_ERR(led->enable_gpio); |
309 | dev_err(&client->dev, "Failed to get enable gpio: %d\n", ret); | 335 | dev_err(&led->client->dev, "Failed to get enable gpio: %d\n", |
336 | ret); | ||
310 | return ret; | 337 | return ret; |
311 | } | 338 | } |
312 | 339 | ||
313 | led->regulator = devm_regulator_get(&client->dev, "vled"); | 340 | led->regulator = devm_regulator_get(&led->client->dev, "vled"); |
314 | if (IS_ERR(led->regulator)) | 341 | if (IS_ERR(led->regulator)) |
315 | led->regulator = NULL; | 342 | led->regulator = NULL; |
316 | 343 | ||
317 | led->client = client; | 344 | child = device_get_next_child_node(&led->client->dev, child); |
345 | if (!child) { | ||
346 | dev_err(&led->client->dev, "No LED Child node\n"); | ||
347 | return -ENODEV; | ||
348 | } | ||
349 | |||
350 | fwnode_property_read_string(child, "linux,default-trigger", | ||
351 | &led->led_dev.default_trigger); | ||
352 | |||
353 | ret = fwnode_property_read_string(child, "label", &name); | ||
354 | if (ret) | ||
355 | snprintf(led->label, sizeof(led->label), | ||
356 | "%s::", led->client->name); | ||
357 | else | ||
358 | snprintf(led->label, sizeof(led->label), | ||
359 | "%s:%s", led->client->name, name); | ||
360 | |||
361 | ret = fwnode_property_read_u32(child, "reg", &led->led_enable); | ||
362 | if (ret) { | ||
363 | dev_err(&led->client->dev, "reg DT property missing\n"); | ||
364 | return ret; | ||
365 | } | ||
366 | |||
318 | led->led_dev.name = led->label; | 367 | led->led_dev.name = led->label; |
319 | led->led_dev.brightness_set_blocking = lm3692x_brightness_set; | ||
320 | 368 | ||
321 | mutex_init(&led->lock); | 369 | ret = devm_led_classdev_register(&led->client->dev, &led->led_dev); |
370 | if (ret) { | ||
371 | dev_err(&led->client->dev, "led register err: %d\n", ret); | ||
372 | return ret; | ||
373 | } | ||
374 | |||
375 | led->led_dev.dev->of_node = to_of_node(child); | ||
376 | |||
377 | return 0; | ||
378 | } | ||
322 | 379 | ||
380 | static int lm3692x_probe(struct i2c_client *client, | ||
381 | const struct i2c_device_id *id) | ||
382 | { | ||
383 | struct lm3692x_led *led; | ||
384 | int ret; | ||
385 | |||
386 | led = devm_kzalloc(&client->dev, sizeof(*led), GFP_KERNEL); | ||
387 | if (!led) | ||
388 | return -ENOMEM; | ||
389 | |||
390 | mutex_init(&led->lock); | ||
391 | led->client = client; | ||
392 | led->led_dev.brightness_set_blocking = lm3692x_brightness_set; | ||
393 | led->model_id = id->driver_data; | ||
323 | i2c_set_clientdata(client, led); | 394 | i2c_set_clientdata(client, led); |
324 | 395 | ||
325 | led->regmap = devm_regmap_init_i2c(client, &lm3692x_regmap_config); | 396 | led->regmap = devm_regmap_init_i2c(client, &lm3692x_regmap_config); |
@@ -330,15 +401,13 @@ static int lm3692x_probe(struct i2c_client *client, | |||
330 | return ret; | 401 | return ret; |
331 | } | 402 | } |
332 | 403 | ||
333 | ret = lm3692x_init(led); | 404 | ret = lm3692x_probe_dt(led); |
334 | if (ret) | 405 | if (ret) |
335 | return ret; | 406 | return ret; |
336 | 407 | ||
337 | ret = devm_led_classdev_register(&client->dev, &led->led_dev); | 408 | ret = lm3692x_init(led); |
338 | if (ret) { | 409 | if (ret) |
339 | dev_err(&client->dev, "led register err: %d\n", ret); | ||
340 | return ret; | 410 | return ret; |
341 | } | ||
342 | 411 | ||
343 | return 0; | 412 | return 0; |
344 | } | 413 | } |
@@ -348,6 +417,12 @@ static int lm3692x_remove(struct i2c_client *client) | |||
348 | struct lm3692x_led *led = i2c_get_clientdata(client); | 417 | struct lm3692x_led *led = i2c_get_clientdata(client); |
349 | int ret; | 418 | int ret; |
350 | 419 | ||
420 | ret = regmap_update_bits(led->regmap, LM3692X_EN, LM3692X_DEVICE_EN, 0); | ||
421 | if (ret) { | ||
422 | dev_err(&led->client->dev, "Failed to disable regulator\n"); | ||
423 | return ret; | ||
424 | } | ||
425 | |||
351 | if (led->enable_gpio) | 426 | if (led->enable_gpio) |
352 | gpiod_direction_output(led->enable_gpio, 0); | 427 | gpiod_direction_output(led->enable_gpio, 0); |
353 | 428 | ||
@@ -364,8 +439,8 @@ static int lm3692x_remove(struct i2c_client *client) | |||
364 | } | 439 | } |
365 | 440 | ||
366 | static const struct i2c_device_id lm3692x_id[] = { | 441 | static const struct i2c_device_id lm3692x_id[] = { |
367 | { "lm36922", 0 }, | 442 | { "lm36922", LM36922_MODEL }, |
368 | { "lm36923", 1 }, | 443 | { "lm36923", LM36923_MODEL }, |
369 | { } | 444 | { } |
370 | }; | 445 | }; |
371 | MODULE_DEVICE_TABLE(i2c, lm3692x_id); | 446 | MODULE_DEVICE_TABLE(i2c, lm3692x_id); |
diff --git a/drivers/leds/leds-lt3593.c b/drivers/leds/leds-lt3593.c index 5ec730a31b65..de3623e0d094 100644 --- a/drivers/leds/leds-lt3593.c +++ b/drivers/leds/leds-lt3593.c | |||
@@ -1,32 +1,21 @@ | |||
1 | /* | 1 | // SPDX-License-Identifier: GPL-2.0 |
2 | * LEDs driver for LT3593 controllers | 2 | // Copyright (c) 2009,2018 Daniel Mack <daniel@zonque.org> |
3 | * | ||
4 | * See the datasheet at http://cds.linear.com/docs/Datasheet/3593f.pdf | ||
5 | * | ||
6 | * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de> | ||
7 | * | ||
8 | * Based on leds-gpio.c, | ||
9 | * | ||
10 | * Copyright (C) 2007 8D Technologies inc. | ||
11 | * Raphael Assenat <raph@8d.com> | ||
12 | * Copyright (C) 2008 Freescale Semiconductor, Inc. | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or modify | ||
15 | * it under the terms of the GNU General Public License version 2 as | ||
16 | * published by the Free Software Foundation. | ||
17 | */ | ||
18 | 3 | ||
19 | #include <linux/kernel.h> | 4 | #include <linux/kernel.h> |
20 | #include <linux/platform_device.h> | 5 | #include <linux/platform_device.h> |
21 | #include <linux/leds.h> | 6 | #include <linux/leds.h> |
22 | #include <linux/delay.h> | 7 | #include <linux/delay.h> |
23 | #include <linux/gpio.h> | 8 | #include <linux/gpio.h> |
9 | #include <linux/gpio/consumer.h> | ||
24 | #include <linux/slab.h> | 10 | #include <linux/slab.h> |
25 | #include <linux/module.h> | 11 | #include <linux/module.h> |
12 | #include <linux/of.h> | ||
13 | #include <uapi/linux/uleds.h> | ||
26 | 14 | ||
27 | struct lt3593_led_data { | 15 | struct lt3593_led_data { |
16 | char name[LED_MAX_NAME_SIZE]; | ||
28 | struct led_classdev cdev; | 17 | struct led_classdev cdev; |
29 | unsigned gpio; | 18 | struct gpio_desc *gpiod; |
30 | }; | 19 | }; |
31 | 20 | ||
32 | static int lt3593_led_set(struct led_classdev *led_cdev, | 21 | static int lt3593_led_set(struct led_classdev *led_cdev, |
@@ -46,137 +35,168 @@ static int lt3593_led_set(struct led_classdev *led_cdev, | |||
46 | */ | 35 | */ |
47 | 36 | ||
48 | if (value == 0) { | 37 | if (value == 0) { |
49 | gpio_set_value_cansleep(led_dat->gpio, 0); | 38 | gpiod_set_value_cansleep(led_dat->gpiod, 0); |
50 | return 0; | 39 | return 0; |
51 | } | 40 | } |
52 | 41 | ||
53 | pulses = 32 - (value * 32) / 255; | 42 | pulses = 32 - (value * 32) / 255; |
54 | 43 | ||
55 | if (pulses == 0) { | 44 | if (pulses == 0) { |
56 | gpio_set_value_cansleep(led_dat->gpio, 0); | 45 | gpiod_set_value_cansleep(led_dat->gpiod, 0); |
57 | mdelay(1); | 46 | mdelay(1); |
58 | gpio_set_value_cansleep(led_dat->gpio, 1); | 47 | gpiod_set_value_cansleep(led_dat->gpiod, 1); |
59 | return 0; | 48 | return 0; |
60 | } | 49 | } |
61 | 50 | ||
62 | gpio_set_value_cansleep(led_dat->gpio, 1); | 51 | gpiod_set_value_cansleep(led_dat->gpiod, 1); |
63 | 52 | ||
64 | while (pulses--) { | 53 | while (pulses--) { |
65 | gpio_set_value_cansleep(led_dat->gpio, 0); | 54 | gpiod_set_value_cansleep(led_dat->gpiod, 0); |
66 | udelay(1); | 55 | udelay(1); |
67 | gpio_set_value_cansleep(led_dat->gpio, 1); | 56 | gpiod_set_value_cansleep(led_dat->gpiod, 1); |
68 | udelay(1); | 57 | udelay(1); |
69 | } | 58 | } |
70 | 59 | ||
71 | return 0; | 60 | return 0; |
72 | } | 61 | } |
73 | 62 | ||
74 | static int create_lt3593_led(const struct gpio_led *template, | 63 | static struct lt3593_led_data *lt3593_led_probe_pdata(struct device *dev) |
75 | struct lt3593_led_data *led_dat, struct device *parent) | ||
76 | { | 64 | { |
65 | struct gpio_led_platform_data *pdata = dev_get_platdata(dev); | ||
66 | const struct gpio_led *template = &pdata->leds[0]; | ||
67 | struct lt3593_led_data *led_data; | ||
77 | int ret, state; | 68 | int ret, state; |
78 | 69 | ||
79 | /* skip leds on GPIOs that aren't available */ | 70 | if (pdata->num_leds != 1) |
80 | if (!gpio_is_valid(template->gpio)) { | 71 | return ERR_PTR(-EINVAL); |
81 | dev_info(parent, "%s: skipping unavailable LT3593 LED at gpio %d (%s)\n", | ||
82 | KBUILD_MODNAME, template->gpio, template->name); | ||
83 | return 0; | ||
84 | } | ||
85 | 72 | ||
86 | led_dat->cdev.name = template->name; | 73 | led_data = devm_kzalloc(dev, sizeof(*led_data), GFP_KERNEL); |
87 | led_dat->cdev.default_trigger = template->default_trigger; | 74 | if (!led_data) |
88 | led_dat->gpio = template->gpio; | 75 | return ERR_PTR(-ENOMEM); |
89 | 76 | ||
90 | led_dat->cdev.brightness_set_blocking = lt3593_led_set; | 77 | led_data->cdev.name = template->name; |
78 | led_data->cdev.default_trigger = template->default_trigger; | ||
79 | led_data->cdev.brightness_set_blocking = lt3593_led_set; | ||
91 | 80 | ||
92 | state = (template->default_state == LEDS_GPIO_DEFSTATE_ON); | 81 | state = (template->default_state == LEDS_GPIO_DEFSTATE_ON); |
93 | led_dat->cdev.brightness = state ? LED_FULL : LED_OFF; | 82 | led_data->cdev.brightness = state ? LED_FULL : LED_OFF; |
94 | 83 | ||
95 | if (!template->retain_state_suspended) | 84 | if (!template->retain_state_suspended) |
96 | led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME; | 85 | led_data->cdev.flags |= LED_CORE_SUSPENDRESUME; |
97 | 86 | ||
98 | ret = devm_gpio_request_one(parent, template->gpio, state ? | 87 | ret = devm_gpio_request_one(dev, template->gpio, state ? |
99 | GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW, | 88 | GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW, |
100 | template->name); | 89 | template->name); |
101 | if (ret < 0) | 90 | if (ret < 0) |
102 | return ret; | 91 | return ERR_PTR(ret); |
103 | |||
104 | ret = led_classdev_register(parent, &led_dat->cdev); | ||
105 | if (ret < 0) | ||
106 | return ret; | ||
107 | 92 | ||
108 | dev_info(parent, "%s: registered LT3593 LED '%s' at GPIO %d\n", | 93 | led_data->gpiod = gpio_to_desc(template->gpio); |
109 | KBUILD_MODNAME, template->name, template->gpio); | 94 | if (!led_data->gpiod) |
95 | return ERR_PTR(-EPROBE_DEFER); | ||
110 | 96 | ||
111 | return 0; | 97 | ret = devm_led_classdev_register(dev, &led_data->cdev); |
112 | } | 98 | if (ret < 0) |
99 | return ERR_PTR(ret); | ||
113 | 100 | ||
114 | static void delete_lt3593_led(struct lt3593_led_data *led) | 101 | dev_info(dev, "registered LT3593 LED '%s' at GPIO %d\n", |
115 | { | 102 | template->name, template->gpio); |
116 | if (!gpio_is_valid(led->gpio)) | ||
117 | return; | ||
118 | 103 | ||
119 | led_classdev_unregister(&led->cdev); | 104 | return led_data; |
120 | } | 105 | } |
121 | 106 | ||
122 | static int lt3593_led_probe(struct platform_device *pdev) | 107 | static int lt3593_led_probe(struct platform_device *pdev) |
123 | { | 108 | { |
124 | struct gpio_led_platform_data *pdata = dev_get_platdata(&pdev->dev); | 109 | struct device *dev = &pdev->dev; |
125 | struct lt3593_led_data *leds_data; | 110 | struct lt3593_led_data *led_data; |
126 | int i, ret = 0; | 111 | struct fwnode_handle *child; |
112 | int ret, state = LEDS_GPIO_DEFSTATE_OFF; | ||
113 | enum gpiod_flags flags = GPIOD_OUT_LOW; | ||
114 | const char *tmp; | ||
115 | |||
116 | if (dev_get_platdata(dev)) { | ||
117 | led_data = lt3593_led_probe_pdata(dev); | ||
118 | if (IS_ERR(led_data)) | ||
119 | return PTR_ERR(led_data); | ||
120 | |||
121 | goto out; | ||
122 | } | ||
127 | 123 | ||
128 | if (!pdata) | 124 | if (!dev->of_node) |
129 | return -EBUSY; | 125 | return -ENODEV; |
130 | 126 | ||
131 | leds_data = devm_kcalloc(&pdev->dev, | 127 | led_data = devm_kzalloc(dev, sizeof(*led_data), GFP_KERNEL); |
132 | pdata->num_leds, sizeof(struct lt3593_led_data), | 128 | if (!led_data) |
133 | GFP_KERNEL); | ||
134 | if (!leds_data) | ||
135 | return -ENOMEM; | 129 | return -ENOMEM; |
136 | 130 | ||
137 | for (i = 0; i < pdata->num_leds; i++) { | 131 | if (device_get_child_node_count(dev) != 1) { |
138 | ret = create_lt3593_led(&pdata->leds[i], &leds_data[i], | 132 | dev_err(dev, "Device must have exactly one LED sub-node."); |
139 | &pdev->dev); | 133 | return -EINVAL; |
140 | if (ret < 0) | ||
141 | goto err; | ||
142 | } | 134 | } |
143 | 135 | ||
144 | platform_set_drvdata(pdev, leds_data); | 136 | led_data->gpiod = devm_gpiod_get(dev, "lltc,ctrl", 0); |
137 | if (IS_ERR(led_data->gpiod)) | ||
138 | return PTR_ERR(led_data->gpiod); | ||
145 | 139 | ||
146 | return 0; | 140 | child = device_get_next_child_node(dev, NULL); |
147 | 141 | ||
148 | err: | 142 | ret = fwnode_property_read_string(child, "label", &tmp); |
149 | for (i = i - 1; i >= 0; i--) | 143 | if (ret < 0) |
150 | delete_lt3593_led(&leds_data[i]); | 144 | snprintf(led_data->name, sizeof(led_data->name), |
145 | "lt3593::"); | ||
146 | else | ||
147 | snprintf(led_data->name, sizeof(led_data->name), | ||
148 | "lt3593:%s", tmp); | ||
149 | |||
150 | fwnode_property_read_string(child, "linux,default-trigger", | ||
151 | &led_data->cdev.default_trigger); | ||
152 | |||
153 | if (!fwnode_property_read_string(child, "default-state", &tmp)) { | ||
154 | if (!strcmp(tmp, "keep")) { | ||
155 | state = LEDS_GPIO_DEFSTATE_KEEP; | ||
156 | flags = GPIOD_ASIS; | ||
157 | } else if (!strcmp(tmp, "on")) { | ||
158 | state = LEDS_GPIO_DEFSTATE_ON; | ||
159 | flags = GPIOD_OUT_HIGH; | ||
160 | } | ||
161 | } | ||
151 | 162 | ||
152 | return ret; | 163 | led_data->cdev.name = led_data->name; |
153 | } | 164 | led_data->cdev.brightness_set_blocking = lt3593_led_set; |
165 | led_data->cdev.brightness = state ? LED_FULL : LED_OFF; | ||
154 | 166 | ||
155 | static int lt3593_led_remove(struct platform_device *pdev) | 167 | ret = devm_led_classdev_register(dev, &led_data->cdev); |
156 | { | 168 | if (ret < 0) { |
157 | int i; | 169 | fwnode_handle_put(child); |
158 | struct gpio_led_platform_data *pdata = dev_get_platdata(&pdev->dev); | 170 | return ret; |
159 | struct lt3593_led_data *leds_data; | 171 | } |
160 | 172 | ||
161 | leds_data = platform_get_drvdata(pdev); | 173 | led_data->cdev.dev->of_node = dev->of_node; |
162 | 174 | ||
163 | for (i = 0; i < pdata->num_leds; i++) | 175 | out: |
164 | delete_lt3593_led(&leds_data[i]); | 176 | platform_set_drvdata(pdev, led_data); |
165 | 177 | ||
166 | return 0; | 178 | return 0; |
167 | } | 179 | } |
168 | 180 | ||
181 | #ifdef CONFIG_OF | ||
182 | static const struct of_device_id of_lt3593_leds_match[] = { | ||
183 | { .compatible = "lltc,lt3593", }, | ||
184 | {}, | ||
185 | }; | ||
186 | MODULE_DEVICE_TABLE(of, of_lt3593_leds_match); | ||
187 | #endif | ||
188 | |||
169 | static struct platform_driver lt3593_led_driver = { | 189 | static struct platform_driver lt3593_led_driver = { |
170 | .probe = lt3593_led_probe, | 190 | .probe = lt3593_led_probe, |
171 | .remove = lt3593_led_remove, | ||
172 | .driver = { | 191 | .driver = { |
173 | .name = "leds-lt3593", | 192 | .name = "leds-lt3593", |
193 | .of_match_table = of_match_ptr(of_lt3593_leds_match), | ||
174 | }, | 194 | }, |
175 | }; | 195 | }; |
176 | 196 | ||
177 | module_platform_driver(lt3593_led_driver); | 197 | module_platform_driver(lt3593_led_driver); |
178 | 198 | ||
179 | MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>"); | 199 | MODULE_AUTHOR("Daniel Mack <daniel@zonque.org>"); |
180 | MODULE_DESCRIPTION("LED driver for LT3593 controllers"); | 200 | MODULE_DESCRIPTION("LED driver for LT3593 controllers"); |
181 | MODULE_LICENSE("GPL"); | 201 | MODULE_LICENSE("GPL v2"); |
182 | MODULE_ALIAS("platform:leds-lt3593"); | 202 | MODULE_ALIAS("platform:leds-lt3593"); |
diff --git a/drivers/leds/leds-max8997.c b/drivers/leds/leds-max8997.c index 4edf74f1d6d4..8c019c28f9f5 100644 --- a/drivers/leds/leds-max8997.c +++ b/drivers/leds/leds-max8997.c | |||
@@ -268,7 +268,7 @@ static int max8997_led_probe(struct platform_device *pdev) | |||
268 | mode = pdata->led_pdata->mode[led->id]; | 268 | mode = pdata->led_pdata->mode[led->id]; |
269 | brightness = pdata->led_pdata->brightness[led->id]; | 269 | brightness = pdata->led_pdata->brightness[led->id]; |
270 | 270 | ||
271 | max8997_led_set_mode(led, pdata->led_pdata->mode[led->id]); | 271 | max8997_led_set_mode(led, mode); |
272 | 272 | ||
273 | if (brightness > led->cdev.max_brightness) | 273 | if (brightness > led->cdev.max_brightness) |
274 | brightness = led->cdev.max_brightness; | 274 | brightness = led->cdev.max_brightness; |
diff --git a/drivers/leds/leds-ns2.c b/drivers/leds/leds-ns2.c index 14fe5cd43232..a0a7dc2ef87c 100644 --- a/drivers/leds/leds-ns2.c +++ b/drivers/leds/leds-ns2.c | |||
@@ -42,8 +42,8 @@ | |||
42 | 42 | ||
43 | struct ns2_led_data { | 43 | struct ns2_led_data { |
44 | struct led_classdev cdev; | 44 | struct led_classdev cdev; |
45 | unsigned cmd; | 45 | unsigned int cmd; |
46 | unsigned slow; | 46 | unsigned int slow; |
47 | bool can_sleep; | 47 | bool can_sleep; |
48 | unsigned char sata; /* True when SATA mode active. */ | 48 | unsigned char sata; /* True when SATA mode active. */ |
49 | rwlock_t rw_lock; /* Lock GPIOs. */ | 49 | rwlock_t rw_lock; /* Lock GPIOs. */ |
diff --git a/drivers/leds/trigger/Kconfig b/drivers/leds/trigger/Kconfig index a2559b4fdfff..4018af769969 100644 --- a/drivers/leds/trigger/Kconfig +++ b/drivers/leds/trigger/Kconfig | |||
@@ -10,7 +10,6 @@ if LEDS_TRIGGERS | |||
10 | 10 | ||
11 | config LEDS_TRIGGER_TIMER | 11 | config LEDS_TRIGGER_TIMER |
12 | tristate "LED Timer Trigger" | 12 | tristate "LED Timer Trigger" |
13 | depends on LEDS_TRIGGERS | ||
14 | help | 13 | help |
15 | This allows LEDs to be controlled by a programmable timer | 14 | This allows LEDs to be controlled by a programmable timer |
16 | via sysfs. Some LED hardware can be programmed to start | 15 | via sysfs. Some LED hardware can be programmed to start |
@@ -21,7 +20,6 @@ config LEDS_TRIGGER_TIMER | |||
21 | 20 | ||
22 | config LEDS_TRIGGER_ONESHOT | 21 | config LEDS_TRIGGER_ONESHOT |
23 | tristate "LED One-shot Trigger" | 22 | tristate "LED One-shot Trigger" |
24 | depends on LEDS_TRIGGERS | ||
25 | help | 23 | help |
26 | This allows LEDs to blink in one-shot pulses with parameters | 24 | This allows LEDs to blink in one-shot pulses with parameters |
27 | controlled via sysfs. It's useful to notify the user on | 25 | controlled via sysfs. It's useful to notify the user on |
@@ -36,7 +34,6 @@ config LEDS_TRIGGER_ONESHOT | |||
36 | config LEDS_TRIGGER_DISK | 34 | config LEDS_TRIGGER_DISK |
37 | bool "LED Disk Trigger" | 35 | bool "LED Disk Trigger" |
38 | depends on IDE_GD_ATA || ATA | 36 | depends on IDE_GD_ATA || ATA |
39 | depends on LEDS_TRIGGERS | ||
40 | help | 37 | help |
41 | This allows LEDs to be controlled by disk activity. | 38 | This allows LEDs to be controlled by disk activity. |
42 | If unsure, say Y. | 39 | If unsure, say Y. |
@@ -44,14 +41,12 @@ config LEDS_TRIGGER_DISK | |||
44 | config LEDS_TRIGGER_MTD | 41 | config LEDS_TRIGGER_MTD |
45 | bool "LED MTD (NAND/NOR) Trigger" | 42 | bool "LED MTD (NAND/NOR) Trigger" |
46 | depends on MTD | 43 | depends on MTD |
47 | depends on LEDS_TRIGGERS | ||
48 | help | 44 | help |
49 | This allows LEDs to be controlled by MTD activity. | 45 | This allows LEDs to be controlled by MTD activity. |
50 | If unsure, say N. | 46 | If unsure, say N. |
51 | 47 | ||
52 | config LEDS_TRIGGER_HEARTBEAT | 48 | config LEDS_TRIGGER_HEARTBEAT |
53 | tristate "LED Heartbeat Trigger" | 49 | tristate "LED Heartbeat Trigger" |
54 | depends on LEDS_TRIGGERS | ||
55 | help | 50 | help |
56 | This allows LEDs to be controlled by a CPU load average. | 51 | This allows LEDs to be controlled by a CPU load average. |
57 | The flash frequency is a hyperbolic function of the 1-minute | 52 | The flash frequency is a hyperbolic function of the 1-minute |
@@ -60,7 +55,6 @@ config LEDS_TRIGGER_HEARTBEAT | |||
60 | 55 | ||
61 | config LEDS_TRIGGER_BACKLIGHT | 56 | config LEDS_TRIGGER_BACKLIGHT |
62 | tristate "LED backlight Trigger" | 57 | tristate "LED backlight Trigger" |
63 | depends on LEDS_TRIGGERS | ||
64 | help | 58 | help |
65 | This allows LEDs to be controlled as a backlight device: they | 59 | This allows LEDs to be controlled as a backlight device: they |
66 | turn off and on when the display is blanked and unblanked. | 60 | turn off and on when the display is blanked and unblanked. |
@@ -69,7 +63,6 @@ config LEDS_TRIGGER_BACKLIGHT | |||
69 | 63 | ||
70 | config LEDS_TRIGGER_CPU | 64 | config LEDS_TRIGGER_CPU |
71 | bool "LED CPU Trigger" | 65 | bool "LED CPU Trigger" |
72 | depends on LEDS_TRIGGERS | ||
73 | help | 66 | help |
74 | This allows LEDs to be controlled by active CPUs. This shows | 67 | This allows LEDs to be controlled by active CPUs. This shows |
75 | the active CPUs across an array of LEDs so you can see which | 68 | the active CPUs across an array of LEDs so you can see which |
@@ -79,7 +72,6 @@ config LEDS_TRIGGER_CPU | |||
79 | 72 | ||
80 | config LEDS_TRIGGER_ACTIVITY | 73 | config LEDS_TRIGGER_ACTIVITY |
81 | tristate "LED activity Trigger" | 74 | tristate "LED activity Trigger" |
82 | depends on LEDS_TRIGGERS | ||
83 | help | 75 | help |
84 | This allows LEDs to be controlled by an immediate CPU usage. | 76 | This allows LEDs to be controlled by an immediate CPU usage. |
85 | The flash frequency and duty cycle varies from faint flashes to | 77 | The flash frequency and duty cycle varies from faint flashes to |
@@ -88,7 +80,6 @@ config LEDS_TRIGGER_ACTIVITY | |||
88 | 80 | ||
89 | config LEDS_TRIGGER_GPIO | 81 | config LEDS_TRIGGER_GPIO |
90 | tristate "LED GPIO Trigger" | 82 | tristate "LED GPIO Trigger" |
91 | depends on LEDS_TRIGGERS | ||
92 | depends on GPIOLIB || COMPILE_TEST | 83 | depends on GPIOLIB || COMPILE_TEST |
93 | help | 84 | help |
94 | This allows LEDs to be controlled by gpio events. It's good | 85 | This allows LEDs to be controlled by gpio events. It's good |
@@ -101,7 +92,6 @@ config LEDS_TRIGGER_GPIO | |||
101 | 92 | ||
102 | config LEDS_TRIGGER_DEFAULT_ON | 93 | config LEDS_TRIGGER_DEFAULT_ON |
103 | tristate "LED Default ON Trigger" | 94 | tristate "LED Default ON Trigger" |
104 | depends on LEDS_TRIGGERS | ||
105 | help | 95 | help |
106 | This allows LEDs to be initialised in the ON state. | 96 | This allows LEDs to be initialised in the ON state. |
107 | If unsure, say Y. | 97 | If unsure, say Y. |
@@ -111,7 +101,6 @@ comment "iptables trigger is under Netfilter config (LED target)" | |||
111 | 101 | ||
112 | config LEDS_TRIGGER_TRANSIENT | 102 | config LEDS_TRIGGER_TRANSIENT |
113 | tristate "LED Transient Trigger" | 103 | tristate "LED Transient Trigger" |
114 | depends on LEDS_TRIGGERS | ||
115 | help | 104 | help |
116 | This allows one time activation of a transient state on | 105 | This allows one time activation of a transient state on |
117 | GPIO/PWM based hardware. | 106 | GPIO/PWM based hardware. |
@@ -119,7 +108,6 @@ config LEDS_TRIGGER_TRANSIENT | |||
119 | 108 | ||
120 | config LEDS_TRIGGER_CAMERA | 109 | config LEDS_TRIGGER_CAMERA |
121 | tristate "LED Camera Flash/Torch Trigger" | 110 | tristate "LED Camera Flash/Torch Trigger" |
122 | depends on LEDS_TRIGGERS | ||
123 | help | 111 | help |
124 | This allows LEDs to be controlled as a camera flash/torch device. | 112 | This allows LEDs to be controlled as a camera flash/torch device. |
125 | This enables direct flash/torch on/off by the driver, kernel space. | 113 | This enables direct flash/torch on/off by the driver, kernel space. |
@@ -127,7 +115,6 @@ config LEDS_TRIGGER_CAMERA | |||
127 | 115 | ||
128 | config LEDS_TRIGGER_PANIC | 116 | config LEDS_TRIGGER_PANIC |
129 | bool "LED Panic Trigger" | 117 | bool "LED Panic Trigger" |
130 | depends on LEDS_TRIGGERS | ||
131 | help | 118 | help |
132 | This allows LEDs to be configured to blink on a kernel panic. | 119 | This allows LEDs to be configured to blink on a kernel panic. |
133 | Enabling this option will allow to mark certain LEDs as panic indicators, | 120 | Enabling this option will allow to mark certain LEDs as panic indicators, |
@@ -137,7 +124,7 @@ config LEDS_TRIGGER_PANIC | |||
137 | 124 | ||
138 | config LEDS_TRIGGER_NETDEV | 125 | config LEDS_TRIGGER_NETDEV |
139 | tristate "LED Netdev Trigger" | 126 | tristate "LED Netdev Trigger" |
140 | depends on NET && LEDS_TRIGGERS | 127 | depends on NET |
141 | help | 128 | help |
142 | This allows LEDs to be controlled by network device activity. | 129 | This allows LEDs to be controlled by network device activity. |
143 | If unsure, say Y. | 130 | If unsure, say Y. |
diff --git a/drivers/leds/trigger/ledtrig-activity.c b/drivers/leds/trigger/ledtrig-activity.c index 5081894082bd..bcbf41c90c30 100644 --- a/drivers/leds/trigger/ledtrig-activity.c +++ b/drivers/leds/trigger/ledtrig-activity.c | |||
@@ -7,8 +7,8 @@ | |||
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License version 2 as | 8 | * it under the terms of the GNU General Public License version 2 as |
9 | * published by the Free Software Foundation. | 9 | * published by the Free Software Foundation. |
10 | * | ||
11 | */ | 10 | */ |
11 | |||
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
14 | #include <linux/kernel_stat.h> | 14 | #include <linux/kernel_stat.h> |
@@ -37,7 +37,6 @@ static void led_activity_function(struct timer_list *t) | |||
37 | struct activity_data *activity_data = from_timer(activity_data, t, | 37 | struct activity_data *activity_data = from_timer(activity_data, t, |
38 | timer); | 38 | timer); |
39 | struct led_classdev *led_cdev = activity_data->led_cdev; | 39 | struct led_classdev *led_cdev = activity_data->led_cdev; |
40 | struct timespec boot_time; | ||
41 | unsigned int target; | 40 | unsigned int target; |
42 | unsigned int usage; | 41 | unsigned int usage; |
43 | int delay; | 42 | int delay; |
@@ -57,8 +56,6 @@ static void led_activity_function(struct timer_list *t) | |||
57 | return; | 56 | return; |
58 | } | 57 | } |
59 | 58 | ||
60 | get_monotonic_boottime(&boot_time); | ||
61 | |||
62 | cpus = 0; | 59 | cpus = 0; |
63 | curr_used = 0; | 60 | curr_used = 0; |
64 | 61 | ||
@@ -76,7 +73,7 @@ static void led_activity_function(struct timer_list *t) | |||
76 | * down to 16us, ensuring we won't overflow 32-bit computations below | 73 | * down to 16us, ensuring we won't overflow 32-bit computations below |
77 | * even up to 3k CPUs, while keeping divides cheap on smaller systems. | 74 | * even up to 3k CPUs, while keeping divides cheap on smaller systems. |
78 | */ | 75 | */ |
79 | curr_boot = timespec_to_ns(&boot_time) * cpus; | 76 | curr_boot = ktime_get_boot_ns() * cpus; |
80 | diff_boot = (curr_boot - activity_data->last_boot) >> 16; | 77 | diff_boot = (curr_boot - activity_data->last_boot) >> 16; |
81 | diff_used = (curr_used - activity_data->last_used) >> 16; | 78 | diff_used = (curr_used - activity_data->last_used) >> 16; |
82 | activity_data->last_boot = curr_boot; | 79 | activity_data->last_boot = curr_boot; |
@@ -155,8 +152,7 @@ static void led_activity_function(struct timer_list *t) | |||
155 | static ssize_t led_invert_show(struct device *dev, | 152 | static ssize_t led_invert_show(struct device *dev, |
156 | struct device_attribute *attr, char *buf) | 153 | struct device_attribute *attr, char *buf) |
157 | { | 154 | { |
158 | struct led_classdev *led_cdev = dev_get_drvdata(dev); | 155 | struct activity_data *activity_data = led_trigger_get_drvdata(dev); |
159 | struct activity_data *activity_data = led_cdev->trigger_data; | ||
160 | 156 | ||
161 | return sprintf(buf, "%u\n", activity_data->invert); | 157 | return sprintf(buf, "%u\n", activity_data->invert); |
162 | } | 158 | } |
@@ -165,8 +161,7 @@ static ssize_t led_invert_store(struct device *dev, | |||
165 | struct device_attribute *attr, | 161 | struct device_attribute *attr, |
166 | const char *buf, size_t size) | 162 | const char *buf, size_t size) |
167 | { | 163 | { |
168 | struct led_classdev *led_cdev = dev_get_drvdata(dev); | 164 | struct activity_data *activity_data = led_trigger_get_drvdata(dev); |
169 | struct activity_data *activity_data = led_cdev->trigger_data; | ||
170 | unsigned long state; | 165 | unsigned long state; |
171 | int ret; | 166 | int ret; |
172 | 167 | ||
@@ -181,21 +176,21 @@ static ssize_t led_invert_store(struct device *dev, | |||
181 | 176 | ||
182 | static DEVICE_ATTR(invert, 0644, led_invert_show, led_invert_store); | 177 | static DEVICE_ATTR(invert, 0644, led_invert_show, led_invert_store); |
183 | 178 | ||
184 | static void activity_activate(struct led_classdev *led_cdev) | 179 | static struct attribute *activity_led_attrs[] = { |
180 | &dev_attr_invert.attr, | ||
181 | NULL | ||
182 | }; | ||
183 | ATTRIBUTE_GROUPS(activity_led); | ||
184 | |||
185 | static int activity_activate(struct led_classdev *led_cdev) | ||
185 | { | 186 | { |
186 | struct activity_data *activity_data; | 187 | struct activity_data *activity_data; |
187 | int rc; | ||
188 | 188 | ||
189 | activity_data = kzalloc(sizeof(*activity_data), GFP_KERNEL); | 189 | activity_data = kzalloc(sizeof(*activity_data), GFP_KERNEL); |
190 | if (!activity_data) | 190 | if (!activity_data) |
191 | return; | 191 | return -ENOMEM; |
192 | 192 | ||
193 | led_cdev->trigger_data = activity_data; | 193 | led_set_trigger_data(led_cdev, activity_data); |
194 | rc = device_create_file(led_cdev->dev, &dev_attr_invert); | ||
195 | if (rc) { | ||
196 | kfree(led_cdev->trigger_data); | ||
197 | return; | ||
198 | } | ||
199 | 194 | ||
200 | activity_data->led_cdev = led_cdev; | 195 | activity_data->led_cdev = led_cdev; |
201 | timer_setup(&activity_data->timer, led_activity_function, 0); | 196 | timer_setup(&activity_data->timer, led_activity_function, 0); |
@@ -203,26 +198,24 @@ static void activity_activate(struct led_classdev *led_cdev) | |||
203 | led_cdev->blink_brightness = led_cdev->max_brightness; | 198 | led_cdev->blink_brightness = led_cdev->max_brightness; |
204 | led_activity_function(&activity_data->timer); | 199 | led_activity_function(&activity_data->timer); |
205 | set_bit(LED_BLINK_SW, &led_cdev->work_flags); | 200 | set_bit(LED_BLINK_SW, &led_cdev->work_flags); |
206 | led_cdev->activated = true; | 201 | |
202 | return 0; | ||
207 | } | 203 | } |
208 | 204 | ||
209 | static void activity_deactivate(struct led_classdev *led_cdev) | 205 | static void activity_deactivate(struct led_classdev *led_cdev) |
210 | { | 206 | { |
211 | struct activity_data *activity_data = led_cdev->trigger_data; | 207 | struct activity_data *activity_data = led_get_trigger_data(led_cdev); |
212 | 208 | ||
213 | if (led_cdev->activated) { | 209 | del_timer_sync(&activity_data->timer); |
214 | del_timer_sync(&activity_data->timer); | 210 | kfree(activity_data); |
215 | device_remove_file(led_cdev->dev, &dev_attr_invert); | 211 | clear_bit(LED_BLINK_SW, &led_cdev->work_flags); |
216 | kfree(activity_data); | ||
217 | clear_bit(LED_BLINK_SW, &led_cdev->work_flags); | ||
218 | led_cdev->activated = false; | ||
219 | } | ||
220 | } | 212 | } |
221 | 213 | ||
222 | static struct led_trigger activity_led_trigger = { | 214 | static struct led_trigger activity_led_trigger = { |
223 | .name = "activity", | 215 | .name = "activity", |
224 | .activate = activity_activate, | 216 | .activate = activity_activate, |
225 | .deactivate = activity_deactivate, | 217 | .deactivate = activity_deactivate, |
218 | .groups = activity_led_groups, | ||
226 | }; | 219 | }; |
227 | 220 | ||
228 | static int activity_reboot_notifier(struct notifier_block *nb, | 221 | static int activity_reboot_notifier(struct notifier_block *nb, |
@@ -272,4 +265,4 @@ module_exit(activity_exit); | |||
272 | 265 | ||
273 | MODULE_AUTHOR("Willy Tarreau <w@1wt.eu>"); | 266 | MODULE_AUTHOR("Willy Tarreau <w@1wt.eu>"); |
274 | MODULE_DESCRIPTION("Activity LED trigger"); | 267 | MODULE_DESCRIPTION("Activity LED trigger"); |
275 | MODULE_LICENSE("GPL"); | 268 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/leds/trigger/ledtrig-backlight.c b/drivers/leds/trigger/ledtrig-backlight.c index 1ca1f1608f76..c2b57beef718 100644 --- a/drivers/leds/trigger/ledtrig-backlight.c +++ b/drivers/leds/trigger/ledtrig-backlight.c | |||
@@ -64,8 +64,7 @@ static int fb_notifier_callback(struct notifier_block *p, | |||
64 | static ssize_t bl_trig_invert_show(struct device *dev, | 64 | static ssize_t bl_trig_invert_show(struct device *dev, |
65 | struct device_attribute *attr, char *buf) | 65 | struct device_attribute *attr, char *buf) |
66 | { | 66 | { |
67 | struct led_classdev *led = dev_get_drvdata(dev); | 67 | struct bl_trig_notifier *n = led_trigger_get_drvdata(dev); |
68 | struct bl_trig_notifier *n = led->trigger_data; | ||
69 | 68 | ||
70 | return sprintf(buf, "%u\n", n->invert); | 69 | return sprintf(buf, "%u\n", n->invert); |
71 | } | 70 | } |
@@ -73,8 +72,8 @@ static ssize_t bl_trig_invert_show(struct device *dev, | |||
73 | static ssize_t bl_trig_invert_store(struct device *dev, | 72 | static ssize_t bl_trig_invert_store(struct device *dev, |
74 | struct device_attribute *attr, const char *buf, size_t num) | 73 | struct device_attribute *attr, const char *buf, size_t num) |
75 | { | 74 | { |
76 | struct led_classdev *led = dev_get_drvdata(dev); | 75 | struct led_classdev *led = led_trigger_get_led(dev); |
77 | struct bl_trig_notifier *n = led->trigger_data; | 76 | struct bl_trig_notifier *n = led_trigger_get_drvdata(dev); |
78 | unsigned long invert; | 77 | unsigned long invert; |
79 | int ret; | 78 | int ret; |
80 | 79 | ||
@@ -97,22 +96,22 @@ static ssize_t bl_trig_invert_store(struct device *dev, | |||
97 | } | 96 | } |
98 | static DEVICE_ATTR(inverted, 0644, bl_trig_invert_show, bl_trig_invert_store); | 97 | static DEVICE_ATTR(inverted, 0644, bl_trig_invert_show, bl_trig_invert_store); |
99 | 98 | ||
100 | static void bl_trig_activate(struct led_classdev *led) | 99 | static struct attribute *bl_trig_attrs[] = { |
100 | &dev_attr_inverted.attr, | ||
101 | NULL, | ||
102 | }; | ||
103 | ATTRIBUTE_GROUPS(bl_trig); | ||
104 | |||
105 | static int bl_trig_activate(struct led_classdev *led) | ||
101 | { | 106 | { |
102 | int ret; | 107 | int ret; |
103 | 108 | ||
104 | struct bl_trig_notifier *n; | 109 | struct bl_trig_notifier *n; |
105 | 110 | ||
106 | n = kzalloc(sizeof(struct bl_trig_notifier), GFP_KERNEL); | 111 | n = kzalloc(sizeof(struct bl_trig_notifier), GFP_KERNEL); |
107 | led->trigger_data = n; | 112 | if (!n) |
108 | if (!n) { | 113 | return -ENOMEM; |
109 | dev_err(led->dev, "unable to allocate backlight trigger\n"); | 114 | led_set_trigger_data(led, n); |
110 | return; | ||
111 | } | ||
112 | |||
113 | ret = device_create_file(led->dev, &dev_attr_inverted); | ||
114 | if (ret) | ||
115 | goto err_invert; | ||
116 | 115 | ||
117 | n->led = led; | 116 | n->led = led; |
118 | n->brightness = led->brightness; | 117 | n->brightness = led->brightness; |
@@ -122,46 +121,25 @@ static void bl_trig_activate(struct led_classdev *led) | |||
122 | ret = fb_register_client(&n->notifier); | 121 | ret = fb_register_client(&n->notifier); |
123 | if (ret) | 122 | if (ret) |
124 | dev_err(led->dev, "unable to register backlight trigger\n"); | 123 | dev_err(led->dev, "unable to register backlight trigger\n"); |
125 | led->activated = true; | ||
126 | 124 | ||
127 | return; | 125 | return 0; |
128 | |||
129 | err_invert: | ||
130 | led->trigger_data = NULL; | ||
131 | kfree(n); | ||
132 | } | 126 | } |
133 | 127 | ||
134 | static void bl_trig_deactivate(struct led_classdev *led) | 128 | static void bl_trig_deactivate(struct led_classdev *led) |
135 | { | 129 | { |
136 | struct bl_trig_notifier *n = | 130 | struct bl_trig_notifier *n = led_get_trigger_data(led); |
137 | (struct bl_trig_notifier *) led->trigger_data; | 131 | |
138 | 132 | fb_unregister_client(&n->notifier); | |
139 | if (led->activated) { | 133 | kfree(n); |
140 | device_remove_file(led->dev, &dev_attr_inverted); | ||
141 | fb_unregister_client(&n->notifier); | ||
142 | kfree(n); | ||
143 | led->activated = false; | ||
144 | } | ||
145 | } | 134 | } |
146 | 135 | ||
147 | static struct led_trigger bl_led_trigger = { | 136 | static struct led_trigger bl_led_trigger = { |
148 | .name = "backlight", | 137 | .name = "backlight", |
149 | .activate = bl_trig_activate, | 138 | .activate = bl_trig_activate, |
150 | .deactivate = bl_trig_deactivate | 139 | .deactivate = bl_trig_deactivate, |
140 | .groups = bl_trig_groups, | ||
151 | }; | 141 | }; |
152 | 142 | module_led_trigger(bl_led_trigger); | |
153 | static int __init bl_trig_init(void) | ||
154 | { | ||
155 | return led_trigger_register(&bl_led_trigger); | ||
156 | } | ||
157 | |||
158 | static void __exit bl_trig_exit(void) | ||
159 | { | ||
160 | led_trigger_unregister(&bl_led_trigger); | ||
161 | } | ||
162 | |||
163 | module_init(bl_trig_init); | ||
164 | module_exit(bl_trig_exit); | ||
165 | 143 | ||
166 | MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>"); | 144 | MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>"); |
167 | MODULE_DESCRIPTION("Backlight emulation LED trigger"); | 145 | MODULE_DESCRIPTION("Backlight emulation LED trigger"); |
diff --git a/drivers/leds/trigger/ledtrig-camera.c b/drivers/leds/trigger/ledtrig-camera.c index 9bd73a8bad5c..091a09a20c58 100644 --- a/drivers/leds/trigger/ledtrig-camera.c +++ b/drivers/leds/trigger/ledtrig-camera.c | |||
@@ -10,7 +10,6 @@ | |||
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of the GNU General Public License version 2 as | 11 | * it under the terms of the GNU General Public License version 2 as |
12 | * published by the Free Software Foundation. | 12 | * published by the Free Software Foundation. |
13 | * | ||
14 | */ | 13 | */ |
15 | 14 | ||
16 | #include <linux/module.h> | 15 | #include <linux/module.h> |
@@ -54,4 +53,4 @@ module_exit(ledtrig_camera_exit); | |||
54 | 53 | ||
55 | MODULE_DESCRIPTION("LED Trigger for Camera Flash/Torch Control"); | 54 | MODULE_DESCRIPTION("LED Trigger for Camera Flash/Torch Control"); |
56 | MODULE_AUTHOR("Milo Kim"); | 55 | MODULE_AUTHOR("Milo Kim"); |
57 | MODULE_LICENSE("GPL"); | 56 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/leds/trigger/ledtrig-default-on.c b/drivers/leds/trigger/ledtrig-default-on.c index ff455cb46680..7f6d9219711e 100644 --- a/drivers/leds/trigger/ledtrig-default-on.c +++ b/drivers/leds/trigger/ledtrig-default-on.c | |||
@@ -8,7 +8,6 @@ | |||
8 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License version 2 as | 9 | * it under the terms of the GNU General Public License version 2 as |
10 | * published by the Free Software Foundation. | 10 | * published by the Free Software Foundation. |
11 | * | ||
12 | */ | 11 | */ |
13 | 12 | ||
14 | #include <linux/module.h> | 13 | #include <linux/module.h> |
@@ -17,29 +16,18 @@ | |||
17 | #include <linux/leds.h> | 16 | #include <linux/leds.h> |
18 | #include "../leds.h" | 17 | #include "../leds.h" |
19 | 18 | ||
20 | static void defon_trig_activate(struct led_classdev *led_cdev) | 19 | static int defon_trig_activate(struct led_classdev *led_cdev) |
21 | { | 20 | { |
22 | led_set_brightness_nosleep(led_cdev, led_cdev->max_brightness); | 21 | led_set_brightness_nosleep(led_cdev, led_cdev->max_brightness); |
22 | return 0; | ||
23 | } | 23 | } |
24 | 24 | ||
25 | static struct led_trigger defon_led_trigger = { | 25 | static struct led_trigger defon_led_trigger = { |
26 | .name = "default-on", | 26 | .name = "default-on", |
27 | .activate = defon_trig_activate, | 27 | .activate = defon_trig_activate, |
28 | }; | 28 | }; |
29 | 29 | module_led_trigger(defon_led_trigger); | |
30 | static int __init defon_trig_init(void) | ||
31 | { | ||
32 | return led_trigger_register(&defon_led_trigger); | ||
33 | } | ||
34 | |||
35 | static void __exit defon_trig_exit(void) | ||
36 | { | ||
37 | led_trigger_unregister(&defon_led_trigger); | ||
38 | } | ||
39 | |||
40 | module_init(defon_trig_init); | ||
41 | module_exit(defon_trig_exit); | ||
42 | 30 | ||
43 | MODULE_AUTHOR("Nick Forbes <nick.forbes@incepta.com>"); | 31 | MODULE_AUTHOR("Nick Forbes <nick.forbes@incepta.com>"); |
44 | MODULE_DESCRIPTION("Default-ON LED trigger"); | 32 | MODULE_DESCRIPTION("Default-ON LED trigger"); |
45 | MODULE_LICENSE("GPL"); | 33 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/leds/trigger/ledtrig-gpio.c b/drivers/leds/trigger/ledtrig-gpio.c index 8891e88d54dd..ed0db8ed825f 100644 --- a/drivers/leds/trigger/ledtrig-gpio.c +++ b/drivers/leds/trigger/ledtrig-gpio.c | |||
@@ -6,7 +6,6 @@ | |||
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License version 2 as | 7 | * it under the terms of the GNU General Public License version 2 as |
8 | * published by the Free Software Foundation. | 8 | * published by the Free Software Foundation. |
9 | * | ||
10 | */ | 9 | */ |
11 | 10 | ||
12 | #include <linux/module.h> | 11 | #include <linux/module.h> |
@@ -29,7 +28,7 @@ struct gpio_trig_data { | |||
29 | static irqreturn_t gpio_trig_irq(int irq, void *_led) | 28 | static irqreturn_t gpio_trig_irq(int irq, void *_led) |
30 | { | 29 | { |
31 | struct led_classdev *led = _led; | 30 | struct led_classdev *led = _led; |
32 | struct gpio_trig_data *gpio_data = led->trigger_data; | 31 | struct gpio_trig_data *gpio_data = led_get_trigger_data(led); |
33 | int tmp; | 32 | int tmp; |
34 | 33 | ||
35 | tmp = gpio_get_value_cansleep(gpio_data->gpio); | 34 | tmp = gpio_get_value_cansleep(gpio_data->gpio); |
@@ -52,8 +51,7 @@ static irqreturn_t gpio_trig_irq(int irq, void *_led) | |||
52 | static ssize_t gpio_trig_brightness_show(struct device *dev, | 51 | static ssize_t gpio_trig_brightness_show(struct device *dev, |
53 | struct device_attribute *attr, char *buf) | 52 | struct device_attribute *attr, char *buf) |
54 | { | 53 | { |
55 | struct led_classdev *led = dev_get_drvdata(dev); | 54 | struct gpio_trig_data *gpio_data = led_trigger_get_drvdata(dev); |
56 | struct gpio_trig_data *gpio_data = led->trigger_data; | ||
57 | 55 | ||
58 | return sprintf(buf, "%u\n", gpio_data->desired_brightness); | 56 | return sprintf(buf, "%u\n", gpio_data->desired_brightness); |
59 | } | 57 | } |
@@ -61,8 +59,7 @@ static ssize_t gpio_trig_brightness_show(struct device *dev, | |||
61 | static ssize_t gpio_trig_brightness_store(struct device *dev, | 59 | static ssize_t gpio_trig_brightness_store(struct device *dev, |
62 | struct device_attribute *attr, const char *buf, size_t n) | 60 | struct device_attribute *attr, const char *buf, size_t n) |
63 | { | 61 | { |
64 | struct led_classdev *led = dev_get_drvdata(dev); | 62 | struct gpio_trig_data *gpio_data = led_trigger_get_drvdata(dev); |
65 | struct gpio_trig_data *gpio_data = led->trigger_data; | ||
66 | unsigned desired_brightness; | 63 | unsigned desired_brightness; |
67 | int ret; | 64 | int ret; |
68 | 65 | ||
@@ -82,8 +79,7 @@ static DEVICE_ATTR(desired_brightness, 0644, gpio_trig_brightness_show, | |||
82 | static ssize_t gpio_trig_inverted_show(struct device *dev, | 79 | static ssize_t gpio_trig_inverted_show(struct device *dev, |
83 | struct device_attribute *attr, char *buf) | 80 | struct device_attribute *attr, char *buf) |
84 | { | 81 | { |
85 | struct led_classdev *led = dev_get_drvdata(dev); | 82 | struct gpio_trig_data *gpio_data = led_trigger_get_drvdata(dev); |
86 | struct gpio_trig_data *gpio_data = led->trigger_data; | ||
87 | 83 | ||
88 | return sprintf(buf, "%u\n", gpio_data->inverted); | 84 | return sprintf(buf, "%u\n", gpio_data->inverted); |
89 | } | 85 | } |
@@ -91,8 +87,8 @@ static ssize_t gpio_trig_inverted_show(struct device *dev, | |||
91 | static ssize_t gpio_trig_inverted_store(struct device *dev, | 87 | static ssize_t gpio_trig_inverted_store(struct device *dev, |
92 | struct device_attribute *attr, const char *buf, size_t n) | 88 | struct device_attribute *attr, const char *buf, size_t n) |
93 | { | 89 | { |
94 | struct led_classdev *led = dev_get_drvdata(dev); | 90 | struct led_classdev *led = led_trigger_get_led(dev); |
95 | struct gpio_trig_data *gpio_data = led->trigger_data; | 91 | struct gpio_trig_data *gpio_data = led_trigger_get_drvdata(dev); |
96 | unsigned long inverted; | 92 | unsigned long inverted; |
97 | int ret; | 93 | int ret; |
98 | 94 | ||
@@ -116,8 +112,7 @@ static DEVICE_ATTR(inverted, 0644, gpio_trig_inverted_show, | |||
116 | static ssize_t gpio_trig_gpio_show(struct device *dev, | 112 | static ssize_t gpio_trig_gpio_show(struct device *dev, |
117 | struct device_attribute *attr, char *buf) | 113 | struct device_attribute *attr, char *buf) |
118 | { | 114 | { |
119 | struct led_classdev *led = dev_get_drvdata(dev); | 115 | struct gpio_trig_data *gpio_data = led_trigger_get_drvdata(dev); |
120 | struct gpio_trig_data *gpio_data = led->trigger_data; | ||
121 | 116 | ||
122 | return sprintf(buf, "%u\n", gpio_data->gpio); | 117 | return sprintf(buf, "%u\n", gpio_data->gpio); |
123 | } | 118 | } |
@@ -125,8 +120,8 @@ static ssize_t gpio_trig_gpio_show(struct device *dev, | |||
125 | static ssize_t gpio_trig_gpio_store(struct device *dev, | 120 | static ssize_t gpio_trig_gpio_store(struct device *dev, |
126 | struct device_attribute *attr, const char *buf, size_t n) | 121 | struct device_attribute *attr, const char *buf, size_t n) |
127 | { | 122 | { |
128 | struct led_classdev *led = dev_get_drvdata(dev); | 123 | struct led_classdev *led = led_trigger_get_led(dev); |
129 | struct gpio_trig_data *gpio_data = led->trigger_data; | 124 | struct gpio_trig_data *gpio_data = led_trigger_get_drvdata(dev); |
130 | unsigned gpio; | 125 | unsigned gpio; |
131 | int ret; | 126 | int ret; |
132 | 127 | ||
@@ -163,76 +158,45 @@ static ssize_t gpio_trig_gpio_store(struct device *dev, | |||
163 | } | 158 | } |
164 | static DEVICE_ATTR(gpio, 0644, gpio_trig_gpio_show, gpio_trig_gpio_store); | 159 | static DEVICE_ATTR(gpio, 0644, gpio_trig_gpio_show, gpio_trig_gpio_store); |
165 | 160 | ||
166 | static void gpio_trig_activate(struct led_classdev *led) | 161 | static struct attribute *gpio_trig_attrs[] = { |
162 | &dev_attr_desired_brightness.attr, | ||
163 | &dev_attr_inverted.attr, | ||
164 | &dev_attr_gpio.attr, | ||
165 | NULL | ||
166 | }; | ||
167 | ATTRIBUTE_GROUPS(gpio_trig); | ||
168 | |||
169 | static int gpio_trig_activate(struct led_classdev *led) | ||
167 | { | 170 | { |
168 | struct gpio_trig_data *gpio_data; | 171 | struct gpio_trig_data *gpio_data; |
169 | int ret; | ||
170 | 172 | ||
171 | gpio_data = kzalloc(sizeof(*gpio_data), GFP_KERNEL); | 173 | gpio_data = kzalloc(sizeof(*gpio_data), GFP_KERNEL); |
172 | if (!gpio_data) | 174 | if (!gpio_data) |
173 | return; | 175 | return -ENOMEM; |
174 | |||
175 | ret = device_create_file(led->dev, &dev_attr_gpio); | ||
176 | if (ret) | ||
177 | goto err_gpio; | ||
178 | |||
179 | ret = device_create_file(led->dev, &dev_attr_inverted); | ||
180 | if (ret) | ||
181 | goto err_inverted; | ||
182 | |||
183 | ret = device_create_file(led->dev, &dev_attr_desired_brightness); | ||
184 | if (ret) | ||
185 | goto err_brightness; | ||
186 | 176 | ||
187 | gpio_data->led = led; | 177 | gpio_data->led = led; |
188 | led->trigger_data = gpio_data; | 178 | led_set_trigger_data(led, gpio_data); |
189 | led->activated = true; | ||
190 | |||
191 | return; | ||
192 | |||
193 | err_brightness: | ||
194 | device_remove_file(led->dev, &dev_attr_inverted); | ||
195 | 179 | ||
196 | err_inverted: | 180 | return 0; |
197 | device_remove_file(led->dev, &dev_attr_gpio); | ||
198 | |||
199 | err_gpio: | ||
200 | kfree(gpio_data); | ||
201 | } | 181 | } |
202 | 182 | ||
203 | static void gpio_trig_deactivate(struct led_classdev *led) | 183 | static void gpio_trig_deactivate(struct led_classdev *led) |
204 | { | 184 | { |
205 | struct gpio_trig_data *gpio_data = led->trigger_data; | 185 | struct gpio_trig_data *gpio_data = led_get_trigger_data(led); |
206 | 186 | ||
207 | if (led->activated) { | 187 | if (gpio_data->gpio != 0) |
208 | device_remove_file(led->dev, &dev_attr_gpio); | 188 | free_irq(gpio_to_irq(gpio_data->gpio), led); |
209 | device_remove_file(led->dev, &dev_attr_inverted); | 189 | kfree(gpio_data); |
210 | device_remove_file(led->dev, &dev_attr_desired_brightness); | ||
211 | if (gpio_data->gpio != 0) | ||
212 | free_irq(gpio_to_irq(gpio_data->gpio), led); | ||
213 | kfree(gpio_data); | ||
214 | led->activated = false; | ||
215 | } | ||
216 | } | 190 | } |
217 | 191 | ||
218 | static struct led_trigger gpio_led_trigger = { | 192 | static struct led_trigger gpio_led_trigger = { |
219 | .name = "gpio", | 193 | .name = "gpio", |
220 | .activate = gpio_trig_activate, | 194 | .activate = gpio_trig_activate, |
221 | .deactivate = gpio_trig_deactivate, | 195 | .deactivate = gpio_trig_deactivate, |
196 | .groups = gpio_trig_groups, | ||
222 | }; | 197 | }; |
223 | 198 | module_led_trigger(gpio_led_trigger); | |
224 | static int __init gpio_trig_init(void) | ||
225 | { | ||
226 | return led_trigger_register(&gpio_led_trigger); | ||
227 | } | ||
228 | module_init(gpio_trig_init); | ||
229 | |||
230 | static void __exit gpio_trig_exit(void) | ||
231 | { | ||
232 | led_trigger_unregister(&gpio_led_trigger); | ||
233 | } | ||
234 | module_exit(gpio_trig_exit); | ||
235 | 199 | ||
236 | MODULE_AUTHOR("Felipe Balbi <me@felipebalbi.com>"); | 200 | MODULE_AUTHOR("Felipe Balbi <me@felipebalbi.com>"); |
237 | MODULE_DESCRIPTION("GPIO LED trigger"); | 201 | MODULE_DESCRIPTION("GPIO LED trigger"); |
238 | MODULE_LICENSE("GPL"); | 202 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/leds/trigger/ledtrig-heartbeat.c b/drivers/leds/trigger/ledtrig-heartbeat.c index f0896de410b8..7a2b12e19329 100644 --- a/drivers/leds/trigger/ledtrig-heartbeat.c +++ b/drivers/leds/trigger/ledtrig-heartbeat.c | |||
@@ -9,8 +9,8 @@ | |||
9 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
10 | * it under the terms of the GNU General Public License version 2 as | 10 | * it under the terms of the GNU General Public License version 2 as |
11 | * published by the Free Software Foundation. | 11 | * published by the Free Software Foundation. |
12 | * | ||
13 | */ | 12 | */ |
13 | |||
14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
16 | #include <linux/init.h> | 16 | #include <linux/init.h> |
@@ -96,8 +96,8 @@ static void led_heartbeat_function(struct timer_list *t) | |||
96 | static ssize_t led_invert_show(struct device *dev, | 96 | static ssize_t led_invert_show(struct device *dev, |
97 | struct device_attribute *attr, char *buf) | 97 | struct device_attribute *attr, char *buf) |
98 | { | 98 | { |
99 | struct led_classdev *led_cdev = dev_get_drvdata(dev); | 99 | struct heartbeat_trig_data *heartbeat_data = |
100 | struct heartbeat_trig_data *heartbeat_data = led_cdev->trigger_data; | 100 | led_trigger_get_drvdata(dev); |
101 | 101 | ||
102 | return sprintf(buf, "%u\n", heartbeat_data->invert); | 102 | return sprintf(buf, "%u\n", heartbeat_data->invert); |
103 | } | 103 | } |
@@ -105,8 +105,8 @@ static ssize_t led_invert_show(struct device *dev, | |||
105 | static ssize_t led_invert_store(struct device *dev, | 105 | static ssize_t led_invert_store(struct device *dev, |
106 | struct device_attribute *attr, const char *buf, size_t size) | 106 | struct device_attribute *attr, const char *buf, size_t size) |
107 | { | 107 | { |
108 | struct led_classdev *led_cdev = dev_get_drvdata(dev); | 108 | struct heartbeat_trig_data *heartbeat_data = |
109 | struct heartbeat_trig_data *heartbeat_data = led_cdev->trigger_data; | 109 | led_trigger_get_drvdata(dev); |
110 | unsigned long state; | 110 | unsigned long state; |
111 | int ret; | 111 | int ret; |
112 | 112 | ||
@@ -121,22 +121,22 @@ static ssize_t led_invert_store(struct device *dev, | |||
121 | 121 | ||
122 | static DEVICE_ATTR(invert, 0644, led_invert_show, led_invert_store); | 122 | static DEVICE_ATTR(invert, 0644, led_invert_show, led_invert_store); |
123 | 123 | ||
124 | static void heartbeat_trig_activate(struct led_classdev *led_cdev) | 124 | static struct attribute *heartbeat_trig_attrs[] = { |
125 | &dev_attr_invert.attr, | ||
126 | NULL | ||
127 | }; | ||
128 | ATTRIBUTE_GROUPS(heartbeat_trig); | ||
129 | |||
130 | static int heartbeat_trig_activate(struct led_classdev *led_cdev) | ||
125 | { | 131 | { |
126 | struct heartbeat_trig_data *heartbeat_data; | 132 | struct heartbeat_trig_data *heartbeat_data; |
127 | int rc; | ||
128 | 133 | ||
129 | heartbeat_data = kzalloc(sizeof(*heartbeat_data), GFP_KERNEL); | 134 | heartbeat_data = kzalloc(sizeof(*heartbeat_data), GFP_KERNEL); |
130 | if (!heartbeat_data) | 135 | if (!heartbeat_data) |
131 | return; | 136 | return -ENOMEM; |
132 | 137 | ||
133 | led_cdev->trigger_data = heartbeat_data; | 138 | led_set_trigger_data(led_cdev, heartbeat_data); |
134 | heartbeat_data->led_cdev = led_cdev; | 139 | heartbeat_data->led_cdev = led_cdev; |
135 | rc = device_create_file(led_cdev->dev, &dev_attr_invert); | ||
136 | if (rc) { | ||
137 | kfree(led_cdev->trigger_data); | ||
138 | return; | ||
139 | } | ||
140 | 140 | ||
141 | timer_setup(&heartbeat_data->timer, led_heartbeat_function, 0); | 141 | timer_setup(&heartbeat_data->timer, led_heartbeat_function, 0); |
142 | heartbeat_data->phase = 0; | 142 | heartbeat_data->phase = 0; |
@@ -144,26 +144,25 @@ static void heartbeat_trig_activate(struct led_classdev *led_cdev) | |||
144 | led_cdev->blink_brightness = led_cdev->max_brightness; | 144 | led_cdev->blink_brightness = led_cdev->max_brightness; |
145 | led_heartbeat_function(&heartbeat_data->timer); | 145 | led_heartbeat_function(&heartbeat_data->timer); |
146 | set_bit(LED_BLINK_SW, &led_cdev->work_flags); | 146 | set_bit(LED_BLINK_SW, &led_cdev->work_flags); |
147 | led_cdev->activated = true; | 147 | |
148 | return 0; | ||
148 | } | 149 | } |
149 | 150 | ||
150 | static void heartbeat_trig_deactivate(struct led_classdev *led_cdev) | 151 | static void heartbeat_trig_deactivate(struct led_classdev *led_cdev) |
151 | { | 152 | { |
152 | struct heartbeat_trig_data *heartbeat_data = led_cdev->trigger_data; | 153 | struct heartbeat_trig_data *heartbeat_data = |
153 | 154 | led_get_trigger_data(led_cdev); | |
154 | if (led_cdev->activated) { | 155 | |
155 | del_timer_sync(&heartbeat_data->timer); | 156 | del_timer_sync(&heartbeat_data->timer); |
156 | device_remove_file(led_cdev->dev, &dev_attr_invert); | 157 | kfree(heartbeat_data); |
157 | kfree(heartbeat_data); | 158 | clear_bit(LED_BLINK_SW, &led_cdev->work_flags); |
158 | clear_bit(LED_BLINK_SW, &led_cdev->work_flags); | ||
159 | led_cdev->activated = false; | ||
160 | } | ||
161 | } | 159 | } |
162 | 160 | ||
163 | static struct led_trigger heartbeat_led_trigger = { | 161 | static struct led_trigger heartbeat_led_trigger = { |
164 | .name = "heartbeat", | 162 | .name = "heartbeat", |
165 | .activate = heartbeat_trig_activate, | 163 | .activate = heartbeat_trig_activate, |
166 | .deactivate = heartbeat_trig_deactivate, | 164 | .deactivate = heartbeat_trig_deactivate, |
165 | .groups = heartbeat_trig_groups, | ||
167 | }; | 166 | }; |
168 | 167 | ||
169 | static int heartbeat_reboot_notifier(struct notifier_block *nb, | 168 | static int heartbeat_reboot_notifier(struct notifier_block *nb, |
@@ -213,4 +212,4 @@ module_exit(heartbeat_trig_exit); | |||
213 | 212 | ||
214 | MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>"); | 213 | MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>"); |
215 | MODULE_DESCRIPTION("Heartbeat LED trigger"); | 214 | MODULE_DESCRIPTION("Heartbeat LED trigger"); |
216 | MODULE_LICENSE("GPL"); | 215 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/leds/trigger/ledtrig-netdev.c b/drivers/leds/trigger/ledtrig-netdev.c index 6df4781a6308..3dd3ed46d473 100644 --- a/drivers/leds/trigger/ledtrig-netdev.c +++ b/drivers/leds/trigger/ledtrig-netdev.c | |||
@@ -94,8 +94,7 @@ static void set_baseline_state(struct led_netdev_data *trigger_data) | |||
94 | static ssize_t device_name_show(struct device *dev, | 94 | static ssize_t device_name_show(struct device *dev, |
95 | struct device_attribute *attr, char *buf) | 95 | struct device_attribute *attr, char *buf) |
96 | { | 96 | { |
97 | struct led_classdev *led_cdev = dev_get_drvdata(dev); | 97 | struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev); |
98 | struct led_netdev_data *trigger_data = led_cdev->trigger_data; | ||
99 | ssize_t len; | 98 | ssize_t len; |
100 | 99 | ||
101 | spin_lock_bh(&trigger_data->lock); | 100 | spin_lock_bh(&trigger_data->lock); |
@@ -109,8 +108,7 @@ static ssize_t device_name_store(struct device *dev, | |||
109 | struct device_attribute *attr, const char *buf, | 108 | struct device_attribute *attr, const char *buf, |
110 | size_t size) | 109 | size_t size) |
111 | { | 110 | { |
112 | struct led_classdev *led_cdev = dev_get_drvdata(dev); | 111 | struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev); |
113 | struct led_netdev_data *trigger_data = led_cdev->trigger_data; | ||
114 | 112 | ||
115 | if (size >= IFNAMSIZ) | 113 | if (size >= IFNAMSIZ) |
116 | return -EINVAL; | 114 | return -EINVAL; |
@@ -150,8 +148,7 @@ static DEVICE_ATTR_RW(device_name); | |||
150 | static ssize_t netdev_led_attr_show(struct device *dev, char *buf, | 148 | static ssize_t netdev_led_attr_show(struct device *dev, char *buf, |
151 | enum netdev_led_attr attr) | 149 | enum netdev_led_attr attr) |
152 | { | 150 | { |
153 | struct led_classdev *led_cdev = dev_get_drvdata(dev); | 151 | struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev); |
154 | struct led_netdev_data *trigger_data = led_cdev->trigger_data; | ||
155 | int bit; | 152 | int bit; |
156 | 153 | ||
157 | switch (attr) { | 154 | switch (attr) { |
@@ -174,8 +171,7 @@ static ssize_t netdev_led_attr_show(struct device *dev, char *buf, | |||
174 | static ssize_t netdev_led_attr_store(struct device *dev, const char *buf, | 171 | static ssize_t netdev_led_attr_store(struct device *dev, const char *buf, |
175 | size_t size, enum netdev_led_attr attr) | 172 | size_t size, enum netdev_led_attr attr) |
176 | { | 173 | { |
177 | struct led_classdev *led_cdev = dev_get_drvdata(dev); | 174 | struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev); |
178 | struct led_netdev_data *trigger_data = led_cdev->trigger_data; | ||
179 | unsigned long state; | 175 | unsigned long state; |
180 | int ret; | 176 | int ret; |
181 | int bit; | 177 | int bit; |
@@ -255,8 +251,7 @@ static DEVICE_ATTR_RW(rx); | |||
255 | static ssize_t interval_show(struct device *dev, | 251 | static ssize_t interval_show(struct device *dev, |
256 | struct device_attribute *attr, char *buf) | 252 | struct device_attribute *attr, char *buf) |
257 | { | 253 | { |
258 | struct led_classdev *led_cdev = dev_get_drvdata(dev); | 254 | struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev); |
259 | struct led_netdev_data *trigger_data = led_cdev->trigger_data; | ||
260 | 255 | ||
261 | return sprintf(buf, "%u\n", | 256 | return sprintf(buf, "%u\n", |
262 | jiffies_to_msecs(atomic_read(&trigger_data->interval))); | 257 | jiffies_to_msecs(atomic_read(&trigger_data->interval))); |
@@ -266,8 +261,7 @@ static ssize_t interval_store(struct device *dev, | |||
266 | struct device_attribute *attr, const char *buf, | 261 | struct device_attribute *attr, const char *buf, |
267 | size_t size) | 262 | size_t size) |
268 | { | 263 | { |
269 | struct led_classdev *led_cdev = dev_get_drvdata(dev); | 264 | struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev); |
270 | struct led_netdev_data *trigger_data = led_cdev->trigger_data; | ||
271 | unsigned long value; | 265 | unsigned long value; |
272 | int ret; | 266 | int ret; |
273 | 267 | ||
@@ -288,15 +282,23 @@ static ssize_t interval_store(struct device *dev, | |||
288 | 282 | ||
289 | static DEVICE_ATTR_RW(interval); | 283 | static DEVICE_ATTR_RW(interval); |
290 | 284 | ||
285 | static struct attribute *netdev_trig_attrs[] = { | ||
286 | &dev_attr_device_name.attr, | ||
287 | &dev_attr_link.attr, | ||
288 | &dev_attr_rx.attr, | ||
289 | &dev_attr_tx.attr, | ||
290 | &dev_attr_interval.attr, | ||
291 | NULL | ||
292 | }; | ||
293 | ATTRIBUTE_GROUPS(netdev_trig); | ||
294 | |||
291 | static int netdev_trig_notify(struct notifier_block *nb, | 295 | static int netdev_trig_notify(struct notifier_block *nb, |
292 | unsigned long evt, void *dv) | 296 | unsigned long evt, void *dv) |
293 | { | 297 | { |
294 | struct net_device *dev = | 298 | struct net_device *dev = |
295 | netdev_notifier_info_to_dev((struct netdev_notifier_info *)dv); | 299 | netdev_notifier_info_to_dev((struct netdev_notifier_info *)dv); |
296 | struct led_netdev_data *trigger_data = container_of(nb, | 300 | struct led_netdev_data *trigger_data = |
297 | struct | 301 | container_of(nb, struct led_netdev_data, notifier); |
298 | led_netdev_data, | ||
299 | notifier); | ||
300 | 302 | ||
301 | if (evt != NETDEV_UP && evt != NETDEV_DOWN && evt != NETDEV_CHANGE | 303 | if (evt != NETDEV_UP && evt != NETDEV_DOWN && evt != NETDEV_CHANGE |
302 | && evt != NETDEV_REGISTER && evt != NETDEV_UNREGISTER | 304 | && evt != NETDEV_REGISTER && evt != NETDEV_UNREGISTER |
@@ -342,10 +344,8 @@ static int netdev_trig_notify(struct notifier_block *nb, | |||
342 | /* here's the real work! */ | 344 | /* here's the real work! */ |
343 | static void netdev_trig_work(struct work_struct *work) | 345 | static void netdev_trig_work(struct work_struct *work) |
344 | { | 346 | { |
345 | struct led_netdev_data *trigger_data = container_of(work, | 347 | struct led_netdev_data *trigger_data = |
346 | struct | 348 | container_of(work, struct led_netdev_data, work.work); |
347 | led_netdev_data, | ||
348 | work.work); | ||
349 | struct rtnl_link_stats64 *dev_stats; | 349 | struct rtnl_link_stats64 *dev_stats; |
350 | unsigned int new_activity; | 350 | unsigned int new_activity; |
351 | struct rtnl_link_stats64 temp; | 351 | struct rtnl_link_stats64 temp; |
@@ -388,14 +388,14 @@ static void netdev_trig_work(struct work_struct *work) | |||
388 | (atomic_read(&trigger_data->interval)*2)); | 388 | (atomic_read(&trigger_data->interval)*2)); |
389 | } | 389 | } |
390 | 390 | ||
391 | static void netdev_trig_activate(struct led_classdev *led_cdev) | 391 | static int netdev_trig_activate(struct led_classdev *led_cdev) |
392 | { | 392 | { |
393 | struct led_netdev_data *trigger_data; | 393 | struct led_netdev_data *trigger_data; |
394 | int rc; | 394 | int rc; |
395 | 395 | ||
396 | trigger_data = kzalloc(sizeof(struct led_netdev_data), GFP_KERNEL); | 396 | trigger_data = kzalloc(sizeof(struct led_netdev_data), GFP_KERNEL); |
397 | if (!trigger_data) | 397 | if (!trigger_data) |
398 | return; | 398 | return -ENOMEM; |
399 | 399 | ||
400 | spin_lock_init(&trigger_data->lock); | 400 | spin_lock_init(&trigger_data->lock); |
401 | 401 | ||
@@ -412,69 +412,34 @@ static void netdev_trig_activate(struct led_classdev *led_cdev) | |||
412 | atomic_set(&trigger_data->interval, msecs_to_jiffies(50)); | 412 | atomic_set(&trigger_data->interval, msecs_to_jiffies(50)); |
413 | trigger_data->last_activity = 0; | 413 | trigger_data->last_activity = 0; |
414 | 414 | ||
415 | led_cdev->trigger_data = trigger_data; | 415 | led_set_trigger_data(led_cdev, trigger_data); |
416 | 416 | ||
417 | rc = device_create_file(led_cdev->dev, &dev_attr_device_name); | ||
418 | if (rc) | ||
419 | goto err_out; | ||
420 | rc = device_create_file(led_cdev->dev, &dev_attr_link); | ||
421 | if (rc) | ||
422 | goto err_out_device_name; | ||
423 | rc = device_create_file(led_cdev->dev, &dev_attr_rx); | ||
424 | if (rc) | ||
425 | goto err_out_link; | ||
426 | rc = device_create_file(led_cdev->dev, &dev_attr_tx); | ||
427 | if (rc) | ||
428 | goto err_out_rx; | ||
429 | rc = device_create_file(led_cdev->dev, &dev_attr_interval); | ||
430 | if (rc) | ||
431 | goto err_out_tx; | ||
432 | rc = register_netdevice_notifier(&trigger_data->notifier); | 417 | rc = register_netdevice_notifier(&trigger_data->notifier); |
433 | if (rc) | 418 | if (rc) |
434 | goto err_out_interval; | 419 | kfree(trigger_data); |
435 | return; | 420 | |
436 | 421 | return rc; | |
437 | err_out_interval: | ||
438 | device_remove_file(led_cdev->dev, &dev_attr_interval); | ||
439 | err_out_tx: | ||
440 | device_remove_file(led_cdev->dev, &dev_attr_tx); | ||
441 | err_out_rx: | ||
442 | device_remove_file(led_cdev->dev, &dev_attr_rx); | ||
443 | err_out_link: | ||
444 | device_remove_file(led_cdev->dev, &dev_attr_link); | ||
445 | err_out_device_name: | ||
446 | device_remove_file(led_cdev->dev, &dev_attr_device_name); | ||
447 | err_out: | ||
448 | led_cdev->trigger_data = NULL; | ||
449 | kfree(trigger_data); | ||
450 | } | 422 | } |
451 | 423 | ||
452 | static void netdev_trig_deactivate(struct led_classdev *led_cdev) | 424 | static void netdev_trig_deactivate(struct led_classdev *led_cdev) |
453 | { | 425 | { |
454 | struct led_netdev_data *trigger_data = led_cdev->trigger_data; | 426 | struct led_netdev_data *trigger_data = led_get_trigger_data(led_cdev); |
455 | |||
456 | if (trigger_data) { | ||
457 | unregister_netdevice_notifier(&trigger_data->notifier); | ||
458 | 427 | ||
459 | device_remove_file(led_cdev->dev, &dev_attr_device_name); | 428 | unregister_netdevice_notifier(&trigger_data->notifier); |
460 | device_remove_file(led_cdev->dev, &dev_attr_link); | ||
461 | device_remove_file(led_cdev->dev, &dev_attr_rx); | ||
462 | device_remove_file(led_cdev->dev, &dev_attr_tx); | ||
463 | device_remove_file(led_cdev->dev, &dev_attr_interval); | ||
464 | 429 | ||
465 | cancel_delayed_work_sync(&trigger_data->work); | 430 | cancel_delayed_work_sync(&trigger_data->work); |
466 | 431 | ||
467 | if (trigger_data->net_dev) | 432 | if (trigger_data->net_dev) |
468 | dev_put(trigger_data->net_dev); | 433 | dev_put(trigger_data->net_dev); |
469 | 434 | ||
470 | kfree(trigger_data); | 435 | kfree(trigger_data); |
471 | } | ||
472 | } | 436 | } |
473 | 437 | ||
474 | static struct led_trigger netdev_led_trigger = { | 438 | static struct led_trigger netdev_led_trigger = { |
475 | .name = "netdev", | 439 | .name = "netdev", |
476 | .activate = netdev_trig_activate, | 440 | .activate = netdev_trig_activate, |
477 | .deactivate = netdev_trig_deactivate, | 441 | .deactivate = netdev_trig_deactivate, |
442 | .groups = netdev_trig_groups, | ||
478 | }; | 443 | }; |
479 | 444 | ||
480 | static int __init netdev_trig_init(void) | 445 | static int __init netdev_trig_init(void) |
diff --git a/drivers/leds/trigger/ledtrig-oneshot.c b/drivers/leds/trigger/ledtrig-oneshot.c index b8ea9f0f1e19..95c9be4b6e7e 100644 --- a/drivers/leds/trigger/ledtrig-oneshot.c +++ b/drivers/leds/trigger/ledtrig-oneshot.c | |||
@@ -8,7 +8,6 @@ | |||
8 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License version 2 as | 9 | * it under the terms of the GNU General Public License version 2 as |
10 | * published by the Free Software Foundation. | 10 | * published by the Free Software Foundation. |
11 | * | ||
12 | */ | 11 | */ |
13 | 12 | ||
14 | #include <linux/module.h> | 13 | #include <linux/module.h> |
@@ -29,8 +28,8 @@ struct oneshot_trig_data { | |||
29 | static ssize_t led_shot(struct device *dev, | 28 | static ssize_t led_shot(struct device *dev, |
30 | struct device_attribute *attr, const char *buf, size_t size) | 29 | struct device_attribute *attr, const char *buf, size_t size) |
31 | { | 30 | { |
32 | struct led_classdev *led_cdev = dev_get_drvdata(dev); | 31 | struct led_classdev *led_cdev = led_trigger_get_led(dev); |
33 | struct oneshot_trig_data *oneshot_data = led_cdev->trigger_data; | 32 | struct oneshot_trig_data *oneshot_data = led_trigger_get_drvdata(dev); |
34 | 33 | ||
35 | led_blink_set_oneshot(led_cdev, | 34 | led_blink_set_oneshot(led_cdev, |
36 | &led_cdev->blink_delay_on, &led_cdev->blink_delay_off, | 35 | &led_cdev->blink_delay_on, &led_cdev->blink_delay_off, |
@@ -42,8 +41,7 @@ static ssize_t led_shot(struct device *dev, | |||
42 | static ssize_t led_invert_show(struct device *dev, | 41 | static ssize_t led_invert_show(struct device *dev, |
43 | struct device_attribute *attr, char *buf) | 42 | struct device_attribute *attr, char *buf) |
44 | { | 43 | { |
45 | struct led_classdev *led_cdev = dev_get_drvdata(dev); | 44 | struct oneshot_trig_data *oneshot_data = led_trigger_get_drvdata(dev); |
46 | struct oneshot_trig_data *oneshot_data = led_cdev->trigger_data; | ||
47 | 45 | ||
48 | return sprintf(buf, "%u\n", oneshot_data->invert); | 46 | return sprintf(buf, "%u\n", oneshot_data->invert); |
49 | } | 47 | } |
@@ -51,8 +49,8 @@ static ssize_t led_invert_show(struct device *dev, | |||
51 | static ssize_t led_invert_store(struct device *dev, | 49 | static ssize_t led_invert_store(struct device *dev, |
52 | struct device_attribute *attr, const char *buf, size_t size) | 50 | struct device_attribute *attr, const char *buf, size_t size) |
53 | { | 51 | { |
54 | struct led_classdev *led_cdev = dev_get_drvdata(dev); | 52 | struct led_classdev *led_cdev = led_trigger_get_led(dev); |
55 | struct oneshot_trig_data *oneshot_data = led_cdev->trigger_data; | 53 | struct oneshot_trig_data *oneshot_data = led_trigger_get_drvdata(dev); |
56 | unsigned long state; | 54 | unsigned long state; |
57 | int ret; | 55 | int ret; |
58 | 56 | ||
@@ -73,7 +71,7 @@ static ssize_t led_invert_store(struct device *dev, | |||
73 | static ssize_t led_delay_on_show(struct device *dev, | 71 | static ssize_t led_delay_on_show(struct device *dev, |
74 | struct device_attribute *attr, char *buf) | 72 | struct device_attribute *attr, char *buf) |
75 | { | 73 | { |
76 | struct led_classdev *led_cdev = dev_get_drvdata(dev); | 74 | struct led_classdev *led_cdev = led_trigger_get_led(dev); |
77 | 75 | ||
78 | return sprintf(buf, "%lu\n", led_cdev->blink_delay_on); | 76 | return sprintf(buf, "%lu\n", led_cdev->blink_delay_on); |
79 | } | 77 | } |
@@ -81,7 +79,7 @@ static ssize_t led_delay_on_show(struct device *dev, | |||
81 | static ssize_t led_delay_on_store(struct device *dev, | 79 | static ssize_t led_delay_on_store(struct device *dev, |
82 | struct device_attribute *attr, const char *buf, size_t size) | 80 | struct device_attribute *attr, const char *buf, size_t size) |
83 | { | 81 | { |
84 | struct led_classdev *led_cdev = dev_get_drvdata(dev); | 82 | struct led_classdev *led_cdev = led_trigger_get_led(dev); |
85 | unsigned long state; | 83 | unsigned long state; |
86 | int ret; | 84 | int ret; |
87 | 85 | ||
@@ -93,10 +91,11 @@ static ssize_t led_delay_on_store(struct device *dev, | |||
93 | 91 | ||
94 | return size; | 92 | return size; |
95 | } | 93 | } |
94 | |||
96 | static ssize_t led_delay_off_show(struct device *dev, | 95 | static ssize_t led_delay_off_show(struct device *dev, |
97 | struct device_attribute *attr, char *buf) | 96 | struct device_attribute *attr, char *buf) |
98 | { | 97 | { |
99 | struct led_classdev *led_cdev = dev_get_drvdata(dev); | 98 | struct led_classdev *led_cdev = led_trigger_get_led(dev); |
100 | 99 | ||
101 | return sprintf(buf, "%lu\n", led_cdev->blink_delay_off); | 100 | return sprintf(buf, "%lu\n", led_cdev->blink_delay_off); |
102 | } | 101 | } |
@@ -104,7 +103,7 @@ static ssize_t led_delay_off_show(struct device *dev, | |||
104 | static ssize_t led_delay_off_store(struct device *dev, | 103 | static ssize_t led_delay_off_store(struct device *dev, |
105 | struct device_attribute *attr, const char *buf, size_t size) | 104 | struct device_attribute *attr, const char *buf, size_t size) |
106 | { | 105 | { |
107 | struct led_classdev *led_cdev = dev_get_drvdata(dev); | 106 | struct led_classdev *led_cdev = led_trigger_get_led(dev); |
108 | unsigned long state; | 107 | unsigned long state; |
109 | int ret; | 108 | int ret; |
110 | 109 | ||
@@ -122,59 +121,36 @@ static DEVICE_ATTR(delay_off, 0644, led_delay_off_show, led_delay_off_store); | |||
122 | static DEVICE_ATTR(invert, 0644, led_invert_show, led_invert_store); | 121 | static DEVICE_ATTR(invert, 0644, led_invert_show, led_invert_store); |
123 | static DEVICE_ATTR(shot, 0200, NULL, led_shot); | 122 | static DEVICE_ATTR(shot, 0200, NULL, led_shot); |
124 | 123 | ||
125 | static void oneshot_trig_activate(struct led_classdev *led_cdev) | 124 | static struct attribute *oneshot_trig_attrs[] = { |
125 | &dev_attr_delay_on.attr, | ||
126 | &dev_attr_delay_off.attr, | ||
127 | &dev_attr_invert.attr, | ||
128 | &dev_attr_shot.attr, | ||
129 | NULL | ||
130 | }; | ||
131 | ATTRIBUTE_GROUPS(oneshot_trig); | ||
132 | |||
133 | static int oneshot_trig_activate(struct led_classdev *led_cdev) | ||
126 | { | 134 | { |
127 | struct oneshot_trig_data *oneshot_data; | 135 | struct oneshot_trig_data *oneshot_data; |
128 | int rc; | ||
129 | 136 | ||
130 | oneshot_data = kzalloc(sizeof(*oneshot_data), GFP_KERNEL); | 137 | oneshot_data = kzalloc(sizeof(*oneshot_data), GFP_KERNEL); |
131 | if (!oneshot_data) | 138 | if (!oneshot_data) |
132 | return; | 139 | return -ENOMEM; |
133 | 140 | ||
134 | led_cdev->trigger_data = oneshot_data; | 141 | led_set_trigger_data(led_cdev, oneshot_data); |
135 | |||
136 | rc = device_create_file(led_cdev->dev, &dev_attr_delay_on); | ||
137 | if (rc) | ||
138 | goto err_out_trig_data; | ||
139 | rc = device_create_file(led_cdev->dev, &dev_attr_delay_off); | ||
140 | if (rc) | ||
141 | goto err_out_delayon; | ||
142 | rc = device_create_file(led_cdev->dev, &dev_attr_invert); | ||
143 | if (rc) | ||
144 | goto err_out_delayoff; | ||
145 | rc = device_create_file(led_cdev->dev, &dev_attr_shot); | ||
146 | if (rc) | ||
147 | goto err_out_invert; | ||
148 | 142 | ||
149 | led_cdev->blink_delay_on = DEFAULT_DELAY; | 143 | led_cdev->blink_delay_on = DEFAULT_DELAY; |
150 | led_cdev->blink_delay_off = DEFAULT_DELAY; | 144 | led_cdev->blink_delay_off = DEFAULT_DELAY; |
151 | 145 | ||
152 | led_cdev->activated = true; | 146 | return 0; |
153 | |||
154 | return; | ||
155 | |||
156 | err_out_invert: | ||
157 | device_remove_file(led_cdev->dev, &dev_attr_invert); | ||
158 | err_out_delayoff: | ||
159 | device_remove_file(led_cdev->dev, &dev_attr_delay_off); | ||
160 | err_out_delayon: | ||
161 | device_remove_file(led_cdev->dev, &dev_attr_delay_on); | ||
162 | err_out_trig_data: | ||
163 | kfree(led_cdev->trigger_data); | ||
164 | } | 147 | } |
165 | 148 | ||
166 | static void oneshot_trig_deactivate(struct led_classdev *led_cdev) | 149 | static void oneshot_trig_deactivate(struct led_classdev *led_cdev) |
167 | { | 150 | { |
168 | struct oneshot_trig_data *oneshot_data = led_cdev->trigger_data; | 151 | struct oneshot_trig_data *oneshot_data = led_get_trigger_data(led_cdev); |
169 | 152 | ||
170 | if (led_cdev->activated) { | 153 | kfree(oneshot_data); |
171 | device_remove_file(led_cdev->dev, &dev_attr_delay_on); | ||
172 | device_remove_file(led_cdev->dev, &dev_attr_delay_off); | ||
173 | device_remove_file(led_cdev->dev, &dev_attr_invert); | ||
174 | device_remove_file(led_cdev->dev, &dev_attr_shot); | ||
175 | kfree(oneshot_data); | ||
176 | led_cdev->activated = false; | ||
177 | } | ||
178 | 154 | ||
179 | /* Stop blinking */ | 155 | /* Stop blinking */ |
180 | led_set_brightness(led_cdev, LED_OFF); | 156 | led_set_brightness(led_cdev, LED_OFF); |
@@ -184,20 +160,9 @@ static struct led_trigger oneshot_led_trigger = { | |||
184 | .name = "oneshot", | 160 | .name = "oneshot", |
185 | .activate = oneshot_trig_activate, | 161 | .activate = oneshot_trig_activate, |
186 | .deactivate = oneshot_trig_deactivate, | 162 | .deactivate = oneshot_trig_deactivate, |
163 | .groups = oneshot_trig_groups, | ||
187 | }; | 164 | }; |
188 | 165 | module_led_trigger(oneshot_led_trigger); | |
189 | static int __init oneshot_trig_init(void) | ||
190 | { | ||
191 | return led_trigger_register(&oneshot_led_trigger); | ||
192 | } | ||
193 | |||
194 | static void __exit oneshot_trig_exit(void) | ||
195 | { | ||
196 | led_trigger_unregister(&oneshot_led_trigger); | ||
197 | } | ||
198 | |||
199 | module_init(oneshot_trig_init); | ||
200 | module_exit(oneshot_trig_exit); | ||
201 | 166 | ||
202 | MODULE_AUTHOR("Fabio Baltieri <fabio.baltieri@gmail.com>"); | 167 | MODULE_AUTHOR("Fabio Baltieri <fabio.baltieri@gmail.com>"); |
203 | MODULE_DESCRIPTION("One-shot LED trigger"); | 168 | MODULE_DESCRIPTION("One-shot LED trigger"); |
diff --git a/drivers/leds/trigger/ledtrig-timer.c b/drivers/leds/trigger/ledtrig-timer.c index 8d09327b5719..7c14983781ee 100644 --- a/drivers/leds/trigger/ledtrig-timer.c +++ b/drivers/leds/trigger/ledtrig-timer.c | |||
@@ -8,7 +8,6 @@ | |||
8 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License version 2 as | 9 | * it under the terms of the GNU General Public License version 2 as |
10 | * published by the Free Software Foundation. | 10 | * published by the Free Software Foundation. |
11 | * | ||
12 | */ | 11 | */ |
13 | 12 | ||
14 | #include <linux/module.h> | 13 | #include <linux/module.h> |
@@ -21,7 +20,7 @@ | |||
21 | static ssize_t led_delay_on_show(struct device *dev, | 20 | static ssize_t led_delay_on_show(struct device *dev, |
22 | struct device_attribute *attr, char *buf) | 21 | struct device_attribute *attr, char *buf) |
23 | { | 22 | { |
24 | struct led_classdev *led_cdev = dev_get_drvdata(dev); | 23 | struct led_classdev *led_cdev = led_trigger_get_led(dev); |
25 | 24 | ||
26 | return sprintf(buf, "%lu\n", led_cdev->blink_delay_on); | 25 | return sprintf(buf, "%lu\n", led_cdev->blink_delay_on); |
27 | } | 26 | } |
@@ -29,7 +28,7 @@ static ssize_t led_delay_on_show(struct device *dev, | |||
29 | static ssize_t led_delay_on_store(struct device *dev, | 28 | static ssize_t led_delay_on_store(struct device *dev, |
30 | struct device_attribute *attr, const char *buf, size_t size) | 29 | struct device_attribute *attr, const char *buf, size_t size) |
31 | { | 30 | { |
32 | struct led_classdev *led_cdev = dev_get_drvdata(dev); | 31 | struct led_classdev *led_cdev = led_trigger_get_led(dev); |
33 | unsigned long state; | 32 | unsigned long state; |
34 | ssize_t ret = -EINVAL; | 33 | ssize_t ret = -EINVAL; |
35 | 34 | ||
@@ -46,7 +45,7 @@ static ssize_t led_delay_on_store(struct device *dev, | |||
46 | static ssize_t led_delay_off_show(struct device *dev, | 45 | static ssize_t led_delay_off_show(struct device *dev, |
47 | struct device_attribute *attr, char *buf) | 46 | struct device_attribute *attr, char *buf) |
48 | { | 47 | { |
49 | struct led_classdev *led_cdev = dev_get_drvdata(dev); | 48 | struct led_classdev *led_cdev = led_trigger_get_led(dev); |
50 | 49 | ||
51 | return sprintf(buf, "%lu\n", led_cdev->blink_delay_off); | 50 | return sprintf(buf, "%lu\n", led_cdev->blink_delay_off); |
52 | } | 51 | } |
@@ -54,7 +53,7 @@ static ssize_t led_delay_off_show(struct device *dev, | |||
54 | static ssize_t led_delay_off_store(struct device *dev, | 53 | static ssize_t led_delay_off_store(struct device *dev, |
55 | struct device_attribute *attr, const char *buf, size_t size) | 54 | struct device_attribute *attr, const char *buf, size_t size) |
56 | { | 55 | { |
57 | struct led_classdev *led_cdev = dev_get_drvdata(dev); | 56 | struct led_classdev *led_cdev = led_trigger_get_led(dev); |
58 | unsigned long state; | 57 | unsigned long state; |
59 | ssize_t ret = -EINVAL; | 58 | ssize_t ret = -EINVAL; |
60 | 59 | ||
@@ -71,37 +70,23 @@ static ssize_t led_delay_off_store(struct device *dev, | |||
71 | static DEVICE_ATTR(delay_on, 0644, led_delay_on_show, led_delay_on_store); | 70 | static DEVICE_ATTR(delay_on, 0644, led_delay_on_show, led_delay_on_store); |
72 | static DEVICE_ATTR(delay_off, 0644, led_delay_off_show, led_delay_off_store); | 71 | static DEVICE_ATTR(delay_off, 0644, led_delay_off_show, led_delay_off_store); |
73 | 72 | ||
74 | static void timer_trig_activate(struct led_classdev *led_cdev) | 73 | static struct attribute *timer_trig_attrs[] = { |
75 | { | 74 | &dev_attr_delay_on.attr, |
76 | int rc; | 75 | &dev_attr_delay_off.attr, |
77 | 76 | NULL | |
78 | led_cdev->trigger_data = NULL; | 77 | }; |
79 | 78 | ATTRIBUTE_GROUPS(timer_trig); | |
80 | rc = device_create_file(led_cdev->dev, &dev_attr_delay_on); | ||
81 | if (rc) | ||
82 | return; | ||
83 | rc = device_create_file(led_cdev->dev, &dev_attr_delay_off); | ||
84 | if (rc) | ||
85 | goto err_out_delayon; | ||
86 | 79 | ||
80 | static int timer_trig_activate(struct led_classdev *led_cdev) | ||
81 | { | ||
87 | led_blink_set(led_cdev, &led_cdev->blink_delay_on, | 82 | led_blink_set(led_cdev, &led_cdev->blink_delay_on, |
88 | &led_cdev->blink_delay_off); | 83 | &led_cdev->blink_delay_off); |
89 | led_cdev->activated = true; | ||
90 | 84 | ||
91 | return; | 85 | return 0; |
92 | |||
93 | err_out_delayon: | ||
94 | device_remove_file(led_cdev->dev, &dev_attr_delay_on); | ||
95 | } | 86 | } |
96 | 87 | ||
97 | static void timer_trig_deactivate(struct led_classdev *led_cdev) | 88 | static void timer_trig_deactivate(struct led_classdev *led_cdev) |
98 | { | 89 | { |
99 | if (led_cdev->activated) { | ||
100 | device_remove_file(led_cdev->dev, &dev_attr_delay_on); | ||
101 | device_remove_file(led_cdev->dev, &dev_attr_delay_off); | ||
102 | led_cdev->activated = false; | ||
103 | } | ||
104 | |||
105 | /* Stop blinking */ | 90 | /* Stop blinking */ |
106 | led_set_brightness(led_cdev, LED_OFF); | 91 | led_set_brightness(led_cdev, LED_OFF); |
107 | } | 92 | } |
@@ -110,21 +95,10 @@ static struct led_trigger timer_led_trigger = { | |||
110 | .name = "timer", | 95 | .name = "timer", |
111 | .activate = timer_trig_activate, | 96 | .activate = timer_trig_activate, |
112 | .deactivate = timer_trig_deactivate, | 97 | .deactivate = timer_trig_deactivate, |
98 | .groups = timer_trig_groups, | ||
113 | }; | 99 | }; |
114 | 100 | module_led_trigger(timer_led_trigger); | |
115 | static int __init timer_trig_init(void) | ||
116 | { | ||
117 | return led_trigger_register(&timer_led_trigger); | ||
118 | } | ||
119 | |||
120 | static void __exit timer_trig_exit(void) | ||
121 | { | ||
122 | led_trigger_unregister(&timer_led_trigger); | ||
123 | } | ||
124 | |||
125 | module_init(timer_trig_init); | ||
126 | module_exit(timer_trig_exit); | ||
127 | 101 | ||
128 | MODULE_AUTHOR("Richard Purdie <rpurdie@openedhand.com>"); | 102 | MODULE_AUTHOR("Richard Purdie <rpurdie@openedhand.com>"); |
129 | MODULE_DESCRIPTION("Timer LED trigger"); | 103 | MODULE_DESCRIPTION("Timer LED trigger"); |
130 | MODULE_LICENSE("GPL"); | 104 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/leds/trigger/ledtrig-transient.c b/drivers/leds/trigger/ledtrig-transient.c index 9d1769073562..a80bb82aacc2 100644 --- a/drivers/leds/trigger/ledtrig-transient.c +++ b/drivers/leds/trigger/ledtrig-transient.c | |||
@@ -42,8 +42,8 @@ static void transient_timer_function(struct timer_list *t) | |||
42 | static ssize_t transient_activate_show(struct device *dev, | 42 | static ssize_t transient_activate_show(struct device *dev, |
43 | struct device_attribute *attr, char *buf) | 43 | struct device_attribute *attr, char *buf) |
44 | { | 44 | { |
45 | struct led_classdev *led_cdev = dev_get_drvdata(dev); | 45 | struct transient_trig_data *transient_data = |
46 | struct transient_trig_data *transient_data = led_cdev->trigger_data; | 46 | led_trigger_get_drvdata(dev); |
47 | 47 | ||
48 | return sprintf(buf, "%d\n", transient_data->activate); | 48 | return sprintf(buf, "%d\n", transient_data->activate); |
49 | } | 49 | } |
@@ -51,8 +51,9 @@ static ssize_t transient_activate_show(struct device *dev, | |||
51 | static ssize_t transient_activate_store(struct device *dev, | 51 | static ssize_t transient_activate_store(struct device *dev, |
52 | struct device_attribute *attr, const char *buf, size_t size) | 52 | struct device_attribute *attr, const char *buf, size_t size) |
53 | { | 53 | { |
54 | struct led_classdev *led_cdev = dev_get_drvdata(dev); | 54 | struct led_classdev *led_cdev = led_trigger_get_led(dev); |
55 | struct transient_trig_data *transient_data = led_cdev->trigger_data; | 55 | struct transient_trig_data *transient_data = |
56 | led_trigger_get_drvdata(dev); | ||
56 | unsigned long state; | 57 | unsigned long state; |
57 | ssize_t ret; | 58 | ssize_t ret; |
58 | 59 | ||
@@ -94,8 +95,7 @@ static ssize_t transient_activate_store(struct device *dev, | |||
94 | static ssize_t transient_duration_show(struct device *dev, | 95 | static ssize_t transient_duration_show(struct device *dev, |
95 | struct device_attribute *attr, char *buf) | 96 | struct device_attribute *attr, char *buf) |
96 | { | 97 | { |
97 | struct led_classdev *led_cdev = dev_get_drvdata(dev); | 98 | struct transient_trig_data *transient_data = led_trigger_get_drvdata(dev); |
98 | struct transient_trig_data *transient_data = led_cdev->trigger_data; | ||
99 | 99 | ||
100 | return sprintf(buf, "%lu\n", transient_data->duration); | 100 | return sprintf(buf, "%lu\n", transient_data->duration); |
101 | } | 101 | } |
@@ -103,8 +103,8 @@ static ssize_t transient_duration_show(struct device *dev, | |||
103 | static ssize_t transient_duration_store(struct device *dev, | 103 | static ssize_t transient_duration_store(struct device *dev, |
104 | struct device_attribute *attr, const char *buf, size_t size) | 104 | struct device_attribute *attr, const char *buf, size_t size) |
105 | { | 105 | { |
106 | struct led_classdev *led_cdev = dev_get_drvdata(dev); | 106 | struct transient_trig_data *transient_data = |
107 | struct transient_trig_data *transient_data = led_cdev->trigger_data; | 107 | led_trigger_get_drvdata(dev); |
108 | unsigned long state; | 108 | unsigned long state; |
109 | ssize_t ret; | 109 | ssize_t ret; |
110 | 110 | ||
@@ -119,8 +119,8 @@ static ssize_t transient_duration_store(struct device *dev, | |||
119 | static ssize_t transient_state_show(struct device *dev, | 119 | static ssize_t transient_state_show(struct device *dev, |
120 | struct device_attribute *attr, char *buf) | 120 | struct device_attribute *attr, char *buf) |
121 | { | 121 | { |
122 | struct led_classdev *led_cdev = dev_get_drvdata(dev); | 122 | struct transient_trig_data *transient_data = |
123 | struct transient_trig_data *transient_data = led_cdev->trigger_data; | 123 | led_trigger_get_drvdata(dev); |
124 | int state; | 124 | int state; |
125 | 125 | ||
126 | state = (transient_data->state == LED_FULL) ? 1 : 0; | 126 | state = (transient_data->state == LED_FULL) ? 1 : 0; |
@@ -130,8 +130,8 @@ static ssize_t transient_state_show(struct device *dev, | |||
130 | static ssize_t transient_state_store(struct device *dev, | 130 | static ssize_t transient_state_store(struct device *dev, |
131 | struct device_attribute *attr, const char *buf, size_t size) | 131 | struct device_attribute *attr, const char *buf, size_t size) |
132 | { | 132 | { |
133 | struct led_classdev *led_cdev = dev_get_drvdata(dev); | 133 | struct transient_trig_data *transient_data = |
134 | struct transient_trig_data *transient_data = led_cdev->trigger_data; | 134 | led_trigger_get_drvdata(dev); |
135 | unsigned long state; | 135 | unsigned long state; |
136 | ssize_t ret; | 136 | ssize_t ret; |
137 | 137 | ||
@@ -152,82 +152,46 @@ static DEVICE_ATTR(duration, 0644, transient_duration_show, | |||
152 | transient_duration_store); | 152 | transient_duration_store); |
153 | static DEVICE_ATTR(state, 0644, transient_state_show, transient_state_store); | 153 | static DEVICE_ATTR(state, 0644, transient_state_show, transient_state_store); |
154 | 154 | ||
155 | static void transient_trig_activate(struct led_classdev *led_cdev) | 155 | static struct attribute *transient_trig_attrs[] = { |
156 | &dev_attr_activate.attr, | ||
157 | &dev_attr_duration.attr, | ||
158 | &dev_attr_state.attr, | ||
159 | NULL | ||
160 | }; | ||
161 | ATTRIBUTE_GROUPS(transient_trig); | ||
162 | |||
163 | static int transient_trig_activate(struct led_classdev *led_cdev) | ||
156 | { | 164 | { |
157 | int rc; | ||
158 | struct transient_trig_data *tdata; | 165 | struct transient_trig_data *tdata; |
159 | 166 | ||
160 | tdata = kzalloc(sizeof(struct transient_trig_data), GFP_KERNEL); | 167 | tdata = kzalloc(sizeof(struct transient_trig_data), GFP_KERNEL); |
161 | if (!tdata) { | 168 | if (!tdata) |
162 | dev_err(led_cdev->dev, | 169 | return -ENOMEM; |
163 | "unable to allocate transient trigger\n"); | ||
164 | return; | ||
165 | } | ||
166 | led_cdev->trigger_data = tdata; | ||
167 | tdata->led_cdev = led_cdev; | ||
168 | 170 | ||
169 | rc = device_create_file(led_cdev->dev, &dev_attr_activate); | 171 | led_set_trigger_data(led_cdev, tdata); |
170 | if (rc) | 172 | tdata->led_cdev = led_cdev; |
171 | goto err_out; | ||
172 | |||
173 | rc = device_create_file(led_cdev->dev, &dev_attr_duration); | ||
174 | if (rc) | ||
175 | goto err_out_duration; | ||
176 | |||
177 | rc = device_create_file(led_cdev->dev, &dev_attr_state); | ||
178 | if (rc) | ||
179 | goto err_out_state; | ||
180 | 173 | ||
181 | timer_setup(&tdata->timer, transient_timer_function, 0); | 174 | timer_setup(&tdata->timer, transient_timer_function, 0); |
182 | led_cdev->activated = true; | 175 | |
183 | 176 | return 0; | |
184 | return; | ||
185 | |||
186 | err_out_state: | ||
187 | device_remove_file(led_cdev->dev, &dev_attr_duration); | ||
188 | err_out_duration: | ||
189 | device_remove_file(led_cdev->dev, &dev_attr_activate); | ||
190 | err_out: | ||
191 | dev_err(led_cdev->dev, "unable to register transient trigger\n"); | ||
192 | led_cdev->trigger_data = NULL; | ||
193 | kfree(tdata); | ||
194 | } | 177 | } |
195 | 178 | ||
196 | static void transient_trig_deactivate(struct led_classdev *led_cdev) | 179 | static void transient_trig_deactivate(struct led_classdev *led_cdev) |
197 | { | 180 | { |
198 | struct transient_trig_data *transient_data = led_cdev->trigger_data; | 181 | struct transient_trig_data *transient_data = led_get_trigger_data(led_cdev); |
199 | 182 | ||
200 | if (led_cdev->activated) { | 183 | del_timer_sync(&transient_data->timer); |
201 | del_timer_sync(&transient_data->timer); | 184 | led_set_brightness_nosleep(led_cdev, transient_data->restore_state); |
202 | led_set_brightness_nosleep(led_cdev, | 185 | kfree(transient_data); |
203 | transient_data->restore_state); | ||
204 | device_remove_file(led_cdev->dev, &dev_attr_activate); | ||
205 | device_remove_file(led_cdev->dev, &dev_attr_duration); | ||
206 | device_remove_file(led_cdev->dev, &dev_attr_state); | ||
207 | led_cdev->trigger_data = NULL; | ||
208 | led_cdev->activated = false; | ||
209 | kfree(transient_data); | ||
210 | } | ||
211 | } | 186 | } |
212 | 187 | ||
213 | static struct led_trigger transient_trigger = { | 188 | static struct led_trigger transient_trigger = { |
214 | .name = "transient", | 189 | .name = "transient", |
215 | .activate = transient_trig_activate, | 190 | .activate = transient_trig_activate, |
216 | .deactivate = transient_trig_deactivate, | 191 | .deactivate = transient_trig_deactivate, |
192 | .groups = transient_trig_groups, | ||
217 | }; | 193 | }; |
218 | 194 | module_led_trigger(transient_trigger); | |
219 | static int __init transient_trig_init(void) | ||
220 | { | ||
221 | return led_trigger_register(&transient_trigger); | ||
222 | } | ||
223 | |||
224 | static void __exit transient_trig_exit(void) | ||
225 | { | ||
226 | led_trigger_unregister(&transient_trigger); | ||
227 | } | ||
228 | |||
229 | module_init(transient_trig_init); | ||
230 | module_exit(transient_trig_exit); | ||
231 | 195 | ||
232 | MODULE_AUTHOR("Shuah Khan <shuahkhan@gmail.com>"); | 196 | MODULE_AUTHOR("Shuah Khan <shuahkhan@gmail.com>"); |
233 | MODULE_DESCRIPTION("Transient LED trigger"); | 197 | MODULE_DESCRIPTION("Transient LED trigger"); |
diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig index 2cb75988b328..7cdd0cead693 100644 --- a/drivers/net/can/Kconfig +++ b/drivers/net/can/Kconfig | |||
@@ -73,6 +73,12 @@ config CAN_CALC_BITTIMING | |||
73 | config CAN_LEDS | 73 | config CAN_LEDS |
74 | bool "Enable LED triggers for Netlink based drivers" | 74 | bool "Enable LED triggers for Netlink based drivers" |
75 | depends on LEDS_CLASS | 75 | depends on LEDS_CLASS |
76 | # The netdev trigger (LEDS_TRIGGER_NETDEV) should be able to do | ||
77 | # everything that this driver is doing. This is marked as broken | ||
78 | # because it uses stuff that is intended to be changed or removed. | ||
79 | # Please consider switching to the netdev trigger and confirm it | ||
80 | # fulfills your needs instead of fixing this driver. | ||
81 | depends on BROKEN | ||
76 | select LEDS_TRIGGERS | 82 | select LEDS_TRIGGERS |
77 | ---help--- | 83 | ---help--- |
78 | This option adds two LED triggers for packet receive and transmit | 84 | This option adds two LED triggers for packet receive and transmit |
diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c index d5b4a2b44ab8..de310621b8e7 100644 --- a/drivers/tty/vt/keyboard.c +++ b/drivers/tty/vt/keyboard.c | |||
@@ -959,7 +959,7 @@ struct kbd_led_trigger { | |||
959 | unsigned int mask; | 959 | unsigned int mask; |
960 | }; | 960 | }; |
961 | 961 | ||
962 | static void kbd_led_trigger_activate(struct led_classdev *cdev) | 962 | static int kbd_led_trigger_activate(struct led_classdev *cdev) |
963 | { | 963 | { |
964 | struct kbd_led_trigger *trigger = | 964 | struct kbd_led_trigger *trigger = |
965 | container_of(cdev->trigger, struct kbd_led_trigger, trigger); | 965 | container_of(cdev->trigger, struct kbd_led_trigger, trigger); |
@@ -970,6 +970,8 @@ static void kbd_led_trigger_activate(struct led_classdev *cdev) | |||
970 | ledstate & trigger->mask ? | 970 | ledstate & trigger->mask ? |
971 | LED_FULL : LED_OFF); | 971 | LED_FULL : LED_OFF); |
972 | tasklet_enable(&keyboard_tasklet); | 972 | tasklet_enable(&keyboard_tasklet); |
973 | |||
974 | return 0; | ||
973 | } | 975 | } |
974 | 976 | ||
975 | #define KBD_LED_TRIGGER(_led_bit, _name) { \ | 977 | #define KBD_LED_TRIGGER(_led_bit, _name) { \ |
diff --git a/drivers/usb/core/ledtrig-usbport.c b/drivers/usb/core/ledtrig-usbport.c index d775ffea20c3..dc7f7fd71684 100644 --- a/drivers/usb/core/ledtrig-usbport.c +++ b/drivers/usb/core/ledtrig-usbport.c | |||
@@ -113,11 +113,17 @@ static ssize_t usbport_trig_port_store(struct device *dev, | |||
113 | static struct attribute *ports_attrs[] = { | 113 | static struct attribute *ports_attrs[] = { |
114 | NULL, | 114 | NULL, |
115 | }; | 115 | }; |
116 | |||
116 | static const struct attribute_group ports_group = { | 117 | static const struct attribute_group ports_group = { |
117 | .name = "ports", | 118 | .name = "ports", |
118 | .attrs = ports_attrs, | 119 | .attrs = ports_attrs, |
119 | }; | 120 | }; |
120 | 121 | ||
122 | static const struct attribute_group *ports_groups[] = { | ||
123 | &ports_group, | ||
124 | NULL | ||
125 | }; | ||
126 | |||
121 | /*************************************** | 127 | /*************************************** |
122 | * Adding & removing ports | 128 | * Adding & removing ports |
123 | ***************************************/ | 129 | ***************************************/ |
@@ -298,61 +304,47 @@ static int usbport_trig_notify(struct notifier_block *nb, unsigned long action, | |||
298 | return NOTIFY_DONE; | 304 | return NOTIFY_DONE; |
299 | } | 305 | } |
300 | 306 | ||
301 | static void usbport_trig_activate(struct led_classdev *led_cdev) | 307 | static int usbport_trig_activate(struct led_classdev *led_cdev) |
302 | { | 308 | { |
303 | struct usbport_trig_data *usbport_data; | 309 | struct usbport_trig_data *usbport_data; |
304 | int err; | ||
305 | 310 | ||
306 | usbport_data = kzalloc(sizeof(*usbport_data), GFP_KERNEL); | 311 | usbport_data = kzalloc(sizeof(*usbport_data), GFP_KERNEL); |
307 | if (!usbport_data) | 312 | if (!usbport_data) |
308 | return; | 313 | return -ENOMEM; |
309 | usbport_data->led_cdev = led_cdev; | 314 | usbport_data->led_cdev = led_cdev; |
310 | 315 | ||
311 | /* List of ports */ | 316 | /* List of ports */ |
312 | INIT_LIST_HEAD(&usbport_data->ports); | 317 | INIT_LIST_HEAD(&usbport_data->ports); |
313 | err = sysfs_create_group(&led_cdev->dev->kobj, &ports_group); | ||
314 | if (err) | ||
315 | goto err_free; | ||
316 | usb_for_each_dev(usbport_data, usbport_trig_add_usb_dev_ports); | 318 | usb_for_each_dev(usbport_data, usbport_trig_add_usb_dev_ports); |
317 | usbport_trig_update_count(usbport_data); | 319 | usbport_trig_update_count(usbport_data); |
318 | 320 | ||
319 | /* Notifications */ | 321 | /* Notifications */ |
320 | usbport_data->nb.notifier_call = usbport_trig_notify, | 322 | usbport_data->nb.notifier_call = usbport_trig_notify; |
321 | led_cdev->trigger_data = usbport_data; | 323 | led_set_trigger_data(led_cdev, usbport_data); |
322 | usb_register_notify(&usbport_data->nb); | 324 | usb_register_notify(&usbport_data->nb); |
323 | 325 | ||
324 | led_cdev->activated = true; | 326 | return 0; |
325 | return; | ||
326 | |||
327 | err_free: | ||
328 | kfree(usbport_data); | ||
329 | } | 327 | } |
330 | 328 | ||
331 | static void usbport_trig_deactivate(struct led_classdev *led_cdev) | 329 | static void usbport_trig_deactivate(struct led_classdev *led_cdev) |
332 | { | 330 | { |
333 | struct usbport_trig_data *usbport_data = led_cdev->trigger_data; | 331 | struct usbport_trig_data *usbport_data = led_get_trigger_data(led_cdev); |
334 | struct usbport_trig_port *port, *tmp; | 332 | struct usbport_trig_port *port, *tmp; |
335 | 333 | ||
336 | if (!led_cdev->activated) | ||
337 | return; | ||
338 | |||
339 | list_for_each_entry_safe(port, tmp, &usbport_data->ports, list) { | 334 | list_for_each_entry_safe(port, tmp, &usbport_data->ports, list) { |
340 | usbport_trig_remove_port(usbport_data, port); | 335 | usbport_trig_remove_port(usbport_data, port); |
341 | } | 336 | } |
342 | 337 | ||
343 | usb_unregister_notify(&usbport_data->nb); | 338 | usb_unregister_notify(&usbport_data->nb); |
344 | 339 | ||
345 | sysfs_remove_group(&led_cdev->dev->kobj, &ports_group); | ||
346 | |||
347 | kfree(usbport_data); | 340 | kfree(usbport_data); |
348 | |||
349 | led_cdev->activated = false; | ||
350 | } | 341 | } |
351 | 342 | ||
352 | static struct led_trigger usbport_led_trigger = { | 343 | static struct led_trigger usbport_led_trigger = { |
353 | .name = "usbport", | 344 | .name = "usbport", |
354 | .activate = usbport_trig_activate, | 345 | .activate = usbport_trig_activate, |
355 | .deactivate = usbport_trig_deactivate, | 346 | .deactivate = usbport_trig_deactivate, |
347 | .groups = ports_groups, | ||
356 | }; | 348 | }; |
357 | 349 | ||
358 | static int __init usbport_trig_init(void) | 350 | static int __init usbport_trig_init(void) |
diff --git a/include/linux/leds.h b/include/linux/leds.h index b7e82550e655..834683d603f9 100644 --- a/include/linux/leds.h +++ b/include/linux/leds.h | |||
@@ -253,7 +253,7 @@ static inline bool led_sysfs_is_disabled(struct led_classdev *led_cdev) | |||
253 | struct led_trigger { | 253 | struct led_trigger { |
254 | /* Trigger Properties */ | 254 | /* Trigger Properties */ |
255 | const char *name; | 255 | const char *name; |
256 | void (*activate)(struct led_classdev *led_cdev); | 256 | int (*activate)(struct led_classdev *led_cdev); |
257 | void (*deactivate)(struct led_classdev *led_cdev); | 257 | void (*deactivate)(struct led_classdev *led_cdev); |
258 | 258 | ||
259 | /* LEDs under control by this trigger (for simple triggers) */ | 259 | /* LEDs under control by this trigger (for simple triggers) */ |
@@ -262,8 +262,19 @@ struct led_trigger { | |||
262 | 262 | ||
263 | /* Link to next registered trigger */ | 263 | /* Link to next registered trigger */ |
264 | struct list_head next_trig; | 264 | struct list_head next_trig; |
265 | |||
266 | const struct attribute_group **groups; | ||
265 | }; | 267 | }; |
266 | 268 | ||
269 | /* | ||
270 | * Currently the attributes in struct led_trigger::groups are added directly to | ||
271 | * the LED device. As this might change in the future, the following | ||
272 | * macros abstract getting the LED device and its trigger_data from the dev | ||
273 | * parameter passed to the attribute accessor functions. | ||
274 | */ | ||
275 | #define led_trigger_get_led(dev) ((struct led_classdev *)dev_get_drvdata((dev))) | ||
276 | #define led_trigger_get_drvdata(dev) (led_get_trigger_data(led_trigger_get_led(dev))) | ||
277 | |||
267 | ssize_t led_trigger_store(struct device *dev, struct device_attribute *attr, | 278 | ssize_t led_trigger_store(struct device *dev, struct device_attribute *attr, |
268 | const char *buf, size_t count); | 279 | const char *buf, size_t count); |
269 | ssize_t led_trigger_show(struct device *dev, struct device_attribute *attr, | 280 | ssize_t led_trigger_show(struct device *dev, struct device_attribute *attr, |
@@ -288,10 +299,16 @@ extern void led_trigger_blink_oneshot(struct led_trigger *trigger, | |||
288 | unsigned long *delay_off, | 299 | unsigned long *delay_off, |
289 | int invert); | 300 | int invert); |
290 | extern void led_trigger_set_default(struct led_classdev *led_cdev); | 301 | extern void led_trigger_set_default(struct led_classdev *led_cdev); |
291 | extern void led_trigger_set(struct led_classdev *led_cdev, | 302 | extern int led_trigger_set(struct led_classdev *led_cdev, |
292 | struct led_trigger *trigger); | 303 | struct led_trigger *trigger); |
293 | extern void led_trigger_remove(struct led_classdev *led_cdev); | 304 | extern void led_trigger_remove(struct led_classdev *led_cdev); |
294 | 305 | ||
306 | static inline void led_set_trigger_data(struct led_classdev *led_cdev, | ||
307 | void *trigger_data) | ||
308 | { | ||
309 | led_cdev->trigger_data = trigger_data; | ||
310 | } | ||
311 | |||
295 | static inline void *led_get_trigger_data(struct led_classdev *led_cdev) | 312 | static inline void *led_get_trigger_data(struct led_classdev *led_cdev) |
296 | { | 313 | { |
297 | return led_cdev->trigger_data; | 314 | return led_cdev->trigger_data; |
@@ -315,6 +332,10 @@ static inline void *led_get_trigger_data(struct led_classdev *led_cdev) | |||
315 | extern void led_trigger_rename_static(const char *name, | 332 | extern void led_trigger_rename_static(const char *name, |
316 | struct led_trigger *trig); | 333 | struct led_trigger *trig); |
317 | 334 | ||
335 | #define module_led_trigger(__led_trigger) \ | ||
336 | module_driver(__led_trigger, led_trigger_register, \ | ||
337 | led_trigger_unregister) | ||
338 | |||
318 | #else | 339 | #else |
319 | 340 | ||
320 | /* Trigger has no members */ | 341 | /* Trigger has no members */ |
@@ -334,9 +355,14 @@ static inline void led_trigger_blink_oneshot(struct led_trigger *trigger, | |||
334 | unsigned long *delay_off, | 355 | unsigned long *delay_off, |
335 | int invert) {} | 356 | int invert) {} |
336 | static inline void led_trigger_set_default(struct led_classdev *led_cdev) {} | 357 | static inline void led_trigger_set_default(struct led_classdev *led_cdev) {} |
337 | static inline void led_trigger_set(struct led_classdev *led_cdev, | 358 | static inline int led_trigger_set(struct led_classdev *led_cdev, |
338 | struct led_trigger *trigger) {} | 359 | struct led_trigger *trigger) |
360 | { | ||
361 | return 0; | ||
362 | } | ||
363 | |||
339 | static inline void led_trigger_remove(struct led_classdev *led_cdev) {} | 364 | static inline void led_trigger_remove(struct led_classdev *led_cdev) {} |
365 | static inline void led_set_trigger_data(struct led_classdev *led_cdev) {} | ||
340 | static inline void *led_get_trigger_data(struct led_classdev *led_cdev) | 366 | static inline void *led_get_trigger_data(struct led_classdev *led_cdev) |
341 | { | 367 | { |
342 | return NULL; | 368 | return NULL; |
diff --git a/net/bluetooth/leds.c b/net/bluetooth/leds.c index cb670b5594eb..6d59a5023231 100644 --- a/net/bluetooth/leds.c +++ b/net/bluetooth/leds.c | |||
@@ -43,7 +43,7 @@ void hci_leds_update_powered(struct hci_dev *hdev, bool enabled) | |||
43 | led_trigger_event(bt_power_led_trigger, enabled ? LED_FULL : LED_OFF); | 43 | led_trigger_event(bt_power_led_trigger, enabled ? LED_FULL : LED_OFF); |
44 | } | 44 | } |
45 | 45 | ||
46 | static void power_activate(struct led_classdev *led_cdev) | 46 | static int power_activate(struct led_classdev *led_cdev) |
47 | { | 47 | { |
48 | struct hci_basic_led_trigger *htrig; | 48 | struct hci_basic_led_trigger *htrig; |
49 | bool powered; | 49 | bool powered; |
@@ -52,10 +52,12 @@ static void power_activate(struct led_classdev *led_cdev) | |||
52 | powered = test_bit(HCI_UP, &htrig->hdev->flags); | 52 | powered = test_bit(HCI_UP, &htrig->hdev->flags); |
53 | 53 | ||
54 | led_trigger_event(led_cdev->trigger, powered ? LED_FULL : LED_OFF); | 54 | led_trigger_event(led_cdev->trigger, powered ? LED_FULL : LED_OFF); |
55 | |||
56 | return 0; | ||
55 | } | 57 | } |
56 | 58 | ||
57 | static struct led_trigger *led_allocate_basic(struct hci_dev *hdev, | 59 | static struct led_trigger *led_allocate_basic(struct hci_dev *hdev, |
58 | void (*activate)(struct led_classdev *led_cdev), | 60 | int (*activate)(struct led_classdev *led_cdev), |
59 | const char *name) | 61 | const char *name) |
60 | { | 62 | { |
61 | struct hci_basic_led_trigger *htrig; | 63 | struct hci_basic_led_trigger *htrig; |
diff --git a/net/mac80211/led.c b/net/mac80211/led.c index ba0b507ea691..d6c66fc19716 100644 --- a/net/mac80211/led.c +++ b/net/mac80211/led.c | |||
@@ -52,13 +52,15 @@ void ieee80211_free_led_names(struct ieee80211_local *local) | |||
52 | kfree(local->radio_led.name); | 52 | kfree(local->radio_led.name); |
53 | } | 53 | } |
54 | 54 | ||
55 | static void ieee80211_tx_led_activate(struct led_classdev *led_cdev) | 55 | static int ieee80211_tx_led_activate(struct led_classdev *led_cdev) |
56 | { | 56 | { |
57 | struct ieee80211_local *local = container_of(led_cdev->trigger, | 57 | struct ieee80211_local *local = container_of(led_cdev->trigger, |
58 | struct ieee80211_local, | 58 | struct ieee80211_local, |
59 | tx_led); | 59 | tx_led); |
60 | 60 | ||
61 | atomic_inc(&local->tx_led_active); | 61 | atomic_inc(&local->tx_led_active); |
62 | |||
63 | return 0; | ||
62 | } | 64 | } |
63 | 65 | ||
64 | static void ieee80211_tx_led_deactivate(struct led_classdev *led_cdev) | 66 | static void ieee80211_tx_led_deactivate(struct led_classdev *led_cdev) |
@@ -70,13 +72,15 @@ static void ieee80211_tx_led_deactivate(struct led_classdev *led_cdev) | |||
70 | atomic_dec(&local->tx_led_active); | 72 | atomic_dec(&local->tx_led_active); |
71 | } | 73 | } |
72 | 74 | ||
73 | static void ieee80211_rx_led_activate(struct led_classdev *led_cdev) | 75 | static int ieee80211_rx_led_activate(struct led_classdev *led_cdev) |
74 | { | 76 | { |
75 | struct ieee80211_local *local = container_of(led_cdev->trigger, | 77 | struct ieee80211_local *local = container_of(led_cdev->trigger, |
76 | struct ieee80211_local, | 78 | struct ieee80211_local, |
77 | rx_led); | 79 | rx_led); |
78 | 80 | ||
79 | atomic_inc(&local->rx_led_active); | 81 | atomic_inc(&local->rx_led_active); |
82 | |||
83 | return 0; | ||
80 | } | 84 | } |
81 | 85 | ||
82 | static void ieee80211_rx_led_deactivate(struct led_classdev *led_cdev) | 86 | static void ieee80211_rx_led_deactivate(struct led_classdev *led_cdev) |
@@ -88,13 +92,15 @@ static void ieee80211_rx_led_deactivate(struct led_classdev *led_cdev) | |||
88 | atomic_dec(&local->rx_led_active); | 92 | atomic_dec(&local->rx_led_active); |
89 | } | 93 | } |
90 | 94 | ||
91 | static void ieee80211_assoc_led_activate(struct led_classdev *led_cdev) | 95 | static int ieee80211_assoc_led_activate(struct led_classdev *led_cdev) |
92 | { | 96 | { |
93 | struct ieee80211_local *local = container_of(led_cdev->trigger, | 97 | struct ieee80211_local *local = container_of(led_cdev->trigger, |
94 | struct ieee80211_local, | 98 | struct ieee80211_local, |
95 | assoc_led); | 99 | assoc_led); |
96 | 100 | ||
97 | atomic_inc(&local->assoc_led_active); | 101 | atomic_inc(&local->assoc_led_active); |
102 | |||
103 | return 0; | ||
98 | } | 104 | } |
99 | 105 | ||
100 | static void ieee80211_assoc_led_deactivate(struct led_classdev *led_cdev) | 106 | static void ieee80211_assoc_led_deactivate(struct led_classdev *led_cdev) |
@@ -106,13 +112,15 @@ static void ieee80211_assoc_led_deactivate(struct led_classdev *led_cdev) | |||
106 | atomic_dec(&local->assoc_led_active); | 112 | atomic_dec(&local->assoc_led_active); |
107 | } | 113 | } |
108 | 114 | ||
109 | static void ieee80211_radio_led_activate(struct led_classdev *led_cdev) | 115 | static int ieee80211_radio_led_activate(struct led_classdev *led_cdev) |
110 | { | 116 | { |
111 | struct ieee80211_local *local = container_of(led_cdev->trigger, | 117 | struct ieee80211_local *local = container_of(led_cdev->trigger, |
112 | struct ieee80211_local, | 118 | struct ieee80211_local, |
113 | radio_led); | 119 | radio_led); |
114 | 120 | ||
115 | atomic_inc(&local->radio_led_active); | 121 | atomic_inc(&local->radio_led_active); |
122 | |||
123 | return 0; | ||
116 | } | 124 | } |
117 | 125 | ||
118 | static void ieee80211_radio_led_deactivate(struct led_classdev *led_cdev) | 126 | static void ieee80211_radio_led_deactivate(struct led_classdev *led_cdev) |
@@ -124,13 +132,15 @@ static void ieee80211_radio_led_deactivate(struct led_classdev *led_cdev) | |||
124 | atomic_dec(&local->radio_led_active); | 132 | atomic_dec(&local->radio_led_active); |
125 | } | 133 | } |
126 | 134 | ||
127 | static void ieee80211_tpt_led_activate(struct led_classdev *led_cdev) | 135 | static int ieee80211_tpt_led_activate(struct led_classdev *led_cdev) |
128 | { | 136 | { |
129 | struct ieee80211_local *local = container_of(led_cdev->trigger, | 137 | struct ieee80211_local *local = container_of(led_cdev->trigger, |
130 | struct ieee80211_local, | 138 | struct ieee80211_local, |
131 | tpt_led); | 139 | tpt_led); |
132 | 140 | ||
133 | atomic_inc(&local->tpt_led_active); | 141 | atomic_inc(&local->tpt_led_active); |
142 | |||
143 | return 0; | ||
134 | } | 144 | } |
135 | 145 | ||
136 | static void ieee80211_tpt_led_deactivate(struct led_classdev *led_cdev) | 146 | static void ieee80211_tpt_led_deactivate(struct led_classdev *led_cdev) |
diff --git a/net/rfkill/core.c b/net/rfkill/core.c index a7a4e6ff9be2..1355f5ca8d22 100644 --- a/net/rfkill/core.c +++ b/net/rfkill/core.c | |||
@@ -141,13 +141,15 @@ static void rfkill_led_trigger_event(struct rfkill *rfkill) | |||
141 | led_trigger_event(trigger, LED_FULL); | 141 | led_trigger_event(trigger, LED_FULL); |
142 | } | 142 | } |
143 | 143 | ||
144 | static void rfkill_led_trigger_activate(struct led_classdev *led) | 144 | static int rfkill_led_trigger_activate(struct led_classdev *led) |
145 | { | 145 | { |
146 | struct rfkill *rfkill; | 146 | struct rfkill *rfkill; |
147 | 147 | ||
148 | rfkill = container_of(led->trigger, struct rfkill, led_trigger); | 148 | rfkill = container_of(led->trigger, struct rfkill, led_trigger); |
149 | 149 | ||
150 | rfkill_led_trigger_event(rfkill); | 150 | rfkill_led_trigger_event(rfkill); |
151 | |||
152 | return 0; | ||
151 | } | 153 | } |
152 | 154 | ||
153 | const char *rfkill_get_led_trigger_name(struct rfkill *rfkill) | 155 | const char *rfkill_get_led_trigger_name(struct rfkill *rfkill) |