aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/leds/leds-gpio.c63
1 files changed, 26 insertions, 37 deletions
diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c
index 1ff95ce9487a..edd370dbb22f 100644
--- a/drivers/leds/leds-gpio.c
+++ b/drivers/leds/leds-gpio.c
@@ -16,10 +16,8 @@
16#include <linux/kernel.h> 16#include <linux/kernel.h>
17#include <linux/leds.h> 17#include <linux/leds.h>
18#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/of.h>
20#include <linux/of_gpio.h>
21#include <linux/of_platform.h>
22#include <linux/platform_device.h> 19#include <linux/platform_device.h>
20#include <linux/property.h>
23#include <linux/slab.h> 21#include <linux/slab.h>
24#include <linux/workqueue.h> 22#include <linux/workqueue.h>
25 23
@@ -171,40 +169,37 @@ static inline int sizeof_gpio_leds_priv(int num_leds)
171 (sizeof(struct gpio_led_data) * num_leds); 169 (sizeof(struct gpio_led_data) * num_leds);
172} 170}
173 171
174/* Code to create from OpenFirmware platform devices */ 172static struct gpio_leds_priv *gpio_leds_create(struct platform_device *pdev)
175#ifdef CONFIG_OF_GPIO
176static struct gpio_leds_priv *gpio_leds_create_of(struct platform_device *pdev)
177{ 173{
178 struct device_node *np = pdev->dev.of_node, *child; 174 struct device *dev = &pdev->dev;
175 struct fwnode_handle *child;
179 struct gpio_leds_priv *priv; 176 struct gpio_leds_priv *priv;
180 int count, ret; 177 int count, ret;
181 178
182 /* count LEDs in this device, so we know how much to allocate */ 179 count = device_get_child_node_count(dev);
183 count = of_get_available_child_count(np);
184 if (!count) 180 if (!count)
185 return ERR_PTR(-ENODEV); 181 return ERR_PTR(-ENODEV);
186 182
187 for_each_available_child_of_node(np, child) 183 priv = devm_kzalloc(dev, sizeof_gpio_leds_priv(count), GFP_KERNEL);
188 if (of_get_gpio(child, 0) == -EPROBE_DEFER)
189 return ERR_PTR(-EPROBE_DEFER);
190
191 priv = devm_kzalloc(&pdev->dev, sizeof_gpio_leds_priv(count),
192 GFP_KERNEL);
193 if (!priv) 184 if (!priv)
194 return ERR_PTR(-ENOMEM); 185 return ERR_PTR(-ENOMEM);
195 186
196 for_each_available_child_of_node(np, child) { 187 device_for_each_child_node(dev, child) {
197 struct gpio_led led = {}; 188 struct gpio_led led = {};
198 enum of_gpio_flags flags; 189 const char *state = NULL;
199 const char *state; 190
200 191 led.gpiod = devm_get_gpiod_from_child(dev, child);
201 led.gpio = of_get_gpio_flags(child, 0, &flags); 192 if (IS_ERR(led.gpiod)) {
202 led.active_low = flags & OF_GPIO_ACTIVE_LOW; 193 fwnode_handle_put(child);
203 led.name = of_get_property(child, "label", NULL) ? : child->name; 194 goto err;
204 led.default_trigger = 195 }
205 of_get_property(child, "linux,default-trigger", NULL); 196
206 state = of_get_property(child, "default-state", NULL); 197 fwnode_property_read_string(child, "label", &led.name);
207 if (state) { 198 fwnode_property_read_string(child, "linux,default-trigger",
199 &led.default_trigger);
200
201 if (!fwnode_property_read_string(child, "linux,default_state",
202 &state)) {
208 if (!strcmp(state, "keep")) 203 if (!strcmp(state, "keep"))
209 led.default_state = LEDS_GPIO_DEFSTATE_KEEP; 204 led.default_state = LEDS_GPIO_DEFSTATE_KEEP;
210 else if (!strcmp(state, "on")) 205 else if (!strcmp(state, "on"))
@@ -213,13 +208,13 @@ static struct gpio_leds_priv *gpio_leds_create_of(struct platform_device *pdev)
213 led.default_state = LEDS_GPIO_DEFSTATE_OFF; 208 led.default_state = LEDS_GPIO_DEFSTATE_OFF;
214 } 209 }
215 210
216 if (of_get_property(child, "retain-state-suspended", NULL)) 211 if (fwnode_property_present(child, "retain-state-suspended"))
217 led.retain_state_suspended = 1; 212 led.retain_state_suspended = 1;
218 213
219 ret = create_gpio_led(&led, &priv->leds[priv->num_leds++], 214 ret = create_gpio_led(&led, &priv->leds[priv->num_leds++],
220 &pdev->dev, NULL); 215 dev, NULL);
221 if (ret < 0) { 216 if (ret < 0) {
222 of_node_put(child); 217 fwnode_handle_put(child);
223 goto err; 218 goto err;
224 } 219 }
225 } 220 }
@@ -238,12 +233,6 @@ static const struct of_device_id of_gpio_leds_match[] = {
238}; 233};
239 234
240MODULE_DEVICE_TABLE(of, of_gpio_leds_match); 235MODULE_DEVICE_TABLE(of, of_gpio_leds_match);
241#else /* CONFIG_OF_GPIO */
242static struct gpio_leds_priv *gpio_leds_create_of(struct platform_device *pdev)
243{
244 return ERR_PTR(-ENODEV);
245}
246#endif /* CONFIG_OF_GPIO */
247 236
248static int gpio_led_probe(struct platform_device *pdev) 237static int gpio_led_probe(struct platform_device *pdev)
249{ 238{
@@ -271,7 +260,7 @@ static int gpio_led_probe(struct platform_device *pdev)
271 } 260 }
272 } 261 }
273 } else { 262 } else {
274 priv = gpio_leds_create_of(pdev); 263 priv = gpio_leds_create(pdev);
275 if (IS_ERR(priv)) 264 if (IS_ERR(priv))
276 return PTR_ERR(priv); 265 return PTR_ERR(priv);
277 } 266 }
@@ -298,7 +287,7 @@ static struct platform_driver gpio_led_driver = {
298 .driver = { 287 .driver = {
299 .name = "leds-gpio", 288 .name = "leds-gpio",
300 .owner = THIS_MODULE, 289 .owner = THIS_MODULE,
301 .of_match_table = of_match_ptr(of_gpio_leds_match), 290 .of_match_table = of_gpio_leds_match,
302 }, 291 },
303}; 292};
304 293