diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-15 15:52:42 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-15 15:52:42 -0500 |
commit | e81d372ff9f694e13fa46e8b5aaed505c7fd2a1f (patch) | |
tree | 058d5004b6ca7602aaec6ef2d992be9c71a8e81c /drivers/leds/leds-gpio.c | |
parent | 75e300c8ba5864367634d946c729d8fd05c1cbc2 (diff) | |
parent | 2f05e1d4458f9cb68d4d36fb47e6830fec03c80e (diff) |
Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/cooloney/linux-leds
Pull LED subsystem update from Bryan Wu.
* 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/cooloney/linux-leds: (47 commits)
leds: leds-lp5521: return an error code on error in probe()
leds: leds-clevo-mail: Use pr_* instead of printks
leds: leds-rb532: Fix checkpatch errors
leds: led-triggers: Fix checkpatch warnings
leds: ledtrig-backlight: Fix checkpatch error
leds: leds-wrap: Use <linux/io.h> instead of <asm/io.h>
leds: leds-wm8350: Use dev_err instead of printk
leds: leds-pwm: Fix checkpatch warning
leds: leds-pca955x: Use dev_info instead of printk
leds: leds-net48xx: Use linux/io.h instead of asm/io.h
leds: leds-lt3593: Fix checkpatch warnings
leds: leds-gpio: Use dev_info instead of printk
leds: leds-da903x: Fix checkpatch error and warnings
leds: leds-bd2802: Fix checkpatch warnings
leds: leds-adp5520: Fix checkpatch warnings
leds: led-class: Fix checkpatch warning
leds: leds-ns2: use devm_gpio_request_one
leds: leds-lt3593: use devm_gpio_request_one
leds: leds-gpio: use devm_gpio_request_one
leds: lp3944: Fix return value
...
Diffstat (limited to 'drivers/leds/leds-gpio.c')
-rw-r--r-- | drivers/leds/leds-gpio.c | 37 |
1 files changed, 18 insertions, 19 deletions
diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c index 291c20797ca0..1885a26776b1 100644 --- a/drivers/leds/leds-gpio.c +++ b/drivers/leds/leds-gpio.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/workqueue.h> | 21 | #include <linux/workqueue.h> |
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | #include <linux/pinctrl/consumer.h> | 23 | #include <linux/pinctrl/consumer.h> |
24 | #include <linux/err.h> | ||
24 | 25 | ||
25 | struct gpio_led_data { | 26 | struct gpio_led_data { |
26 | struct led_classdev cdev; | 27 | struct led_classdev cdev; |
@@ -101,15 +102,11 @@ static int create_gpio_led(const struct gpio_led *template, | |||
101 | 102 | ||
102 | /* skip leds that aren't available */ | 103 | /* skip leds that aren't available */ |
103 | if (!gpio_is_valid(template->gpio)) { | 104 | if (!gpio_is_valid(template->gpio)) { |
104 | printk(KERN_INFO "Skipping unavailable LED gpio %d (%s)\n", | 105 | dev_info(parent, "Skipping unavailable LED gpio %d (%s)\n", |
105 | template->gpio, template->name); | 106 | template->gpio, template->name); |
106 | return 0; | 107 | return 0; |
107 | } | 108 | } |
108 | 109 | ||
109 | ret = gpio_request(template->gpio, template->name); | ||
110 | if (ret < 0) | ||
111 | return ret; | ||
112 | |||
113 | led_dat->cdev.name = template->name; | 110 | led_dat->cdev.name = template->name; |
114 | led_dat->cdev.default_trigger = template->default_trigger; | 111 | led_dat->cdev.default_trigger = template->default_trigger; |
115 | led_dat->gpio = template->gpio; | 112 | led_dat->gpio = template->gpio; |
@@ -129,20 +126,19 @@ static int create_gpio_led(const struct gpio_led *template, | |||
129 | if (!template->retain_state_suspended) | 126 | if (!template->retain_state_suspended) |
130 | led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME; | 127 | led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME; |
131 | 128 | ||
132 | ret = gpio_direction_output(led_dat->gpio, led_dat->active_low ^ state); | 129 | ret = devm_gpio_request_one(parent, template->gpio, |
130 | GPIOF_DIR_OUT | (led_dat->active_low ^ state), | ||
131 | template->name); | ||
133 | if (ret < 0) | 132 | if (ret < 0) |
134 | goto err; | 133 | return ret; |
135 | 134 | ||
136 | INIT_WORK(&led_dat->work, gpio_led_work); | 135 | INIT_WORK(&led_dat->work, gpio_led_work); |
137 | 136 | ||
138 | ret = led_classdev_register(parent, &led_dat->cdev); | 137 | ret = led_classdev_register(parent, &led_dat->cdev); |
139 | if (ret < 0) | 138 | if (ret < 0) |
140 | goto err; | 139 | return ret; |
141 | 140 | ||
142 | return 0; | 141 | return 0; |
143 | err: | ||
144 | gpio_free(led_dat->gpio); | ||
145 | return ret; | ||
146 | } | 142 | } |
147 | 143 | ||
148 | static void delete_gpio_led(struct gpio_led_data *led) | 144 | static void delete_gpio_led(struct gpio_led_data *led) |
@@ -151,7 +147,6 @@ static void delete_gpio_led(struct gpio_led_data *led) | |||
151 | return; | 147 | return; |
152 | led_classdev_unregister(&led->cdev); | 148 | led_classdev_unregister(&led->cdev); |
153 | cancel_work_sync(&led->work); | 149 | cancel_work_sync(&led->work); |
154 | gpio_free(led->gpio); | ||
155 | } | 150 | } |
156 | 151 | ||
157 | struct gpio_leds_priv { | 152 | struct gpio_leds_priv { |
@@ -176,12 +171,16 @@ static struct gpio_leds_priv *gpio_leds_create_of(struct platform_device *pdev) | |||
176 | /* count LEDs in this device, so we know how much to allocate */ | 171 | /* count LEDs in this device, so we know how much to allocate */ |
177 | count = of_get_child_count(np); | 172 | count = of_get_child_count(np); |
178 | if (!count) | 173 | if (!count) |
179 | return NULL; | 174 | return ERR_PTR(-ENODEV); |
175 | |||
176 | for_each_child_of_node(np, child) | ||
177 | if (of_get_gpio(child, 0) == -EPROBE_DEFER) | ||
178 | return ERR_PTR(-EPROBE_DEFER); | ||
180 | 179 | ||
181 | priv = devm_kzalloc(&pdev->dev, sizeof_gpio_leds_priv(count), | 180 | priv = devm_kzalloc(&pdev->dev, sizeof_gpio_leds_priv(count), |
182 | GFP_KERNEL); | 181 | GFP_KERNEL); |
183 | if (!priv) | 182 | if (!priv) |
184 | return NULL; | 183 | return ERR_PTR(-ENOMEM); |
185 | 184 | ||
186 | for_each_child_of_node(np, child) { | 185 | for_each_child_of_node(np, child) { |
187 | struct gpio_led led = {}; | 186 | struct gpio_led led = {}; |
@@ -216,7 +215,7 @@ static struct gpio_leds_priv *gpio_leds_create_of(struct platform_device *pdev) | |||
216 | err: | 215 | err: |
217 | for (count = priv->num_leds - 2; count >= 0; count--) | 216 | for (count = priv->num_leds - 2; count >= 0; count--) |
218 | delete_gpio_led(&priv->leds[count]); | 217 | delete_gpio_led(&priv->leds[count]); |
219 | return NULL; | 218 | return ERR_PTR(-ENODEV); |
220 | } | 219 | } |
221 | 220 | ||
222 | static const struct of_device_id of_gpio_leds_match[] = { | 221 | static const struct of_device_id of_gpio_leds_match[] = { |
@@ -226,7 +225,7 @@ static const struct of_device_id of_gpio_leds_match[] = { | |||
226 | #else /* CONFIG_OF_GPIO */ | 225 | #else /* CONFIG_OF_GPIO */ |
227 | static struct gpio_leds_priv *gpio_leds_create_of(struct platform_device *pdev) | 226 | static struct gpio_leds_priv *gpio_leds_create_of(struct platform_device *pdev) |
228 | { | 227 | { |
229 | return NULL; | 228 | return ERR_PTR(-ENODEV); |
230 | } | 229 | } |
231 | #endif /* CONFIG_OF_GPIO */ | 230 | #endif /* CONFIG_OF_GPIO */ |
232 | 231 | ||
@@ -264,8 +263,8 @@ static int gpio_led_probe(struct platform_device *pdev) | |||
264 | } | 263 | } |
265 | } else { | 264 | } else { |
266 | priv = gpio_leds_create_of(pdev); | 265 | priv = gpio_leds_create_of(pdev); |
267 | if (!priv) | 266 | if (IS_ERR(priv)) |
268 | return -ENODEV; | 267 | return PTR_ERR(priv); |
269 | } | 268 | } |
270 | 269 | ||
271 | platform_set_drvdata(pdev, priv); | 270 | platform_set_drvdata(pdev, priv); |