aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/leds/leds-gpio.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-12-15 15:52:42 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-12-15 15:52:42 -0500
commite81d372ff9f694e13fa46e8b5aaed505c7fd2a1f (patch)
tree058d5004b6ca7602aaec6ef2d992be9c71a8e81c /drivers/leds/leds-gpio.c
parent75e300c8ba5864367634d946c729d8fd05c1cbc2 (diff)
parent2f05e1d4458f9cb68d4d36fb47e6830fec03c80e (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.c37
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
25struct gpio_led_data { 26struct 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;
143err:
144 gpio_free(led_dat->gpio);
145 return ret;
146} 142}
147 143
148static void delete_gpio_led(struct gpio_led_data *led) 144static 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
157struct gpio_leds_priv { 152struct 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)
216err: 215err:
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
222static const struct of_device_id of_gpio_leds_match[] = { 221static 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 */
227static struct gpio_leds_priv *gpio_leds_create_of(struct platform_device *pdev) 226static 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);