aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-10-27 18:30:10 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-11-04 15:58:23 -0500
commita43f2cbbb009f96231bbbe24ad4f824215dedb81 (patch)
treebf7e0285e23b673aa30ccf90533d49e3d9e7f60a
parent40b7318319281b1bdec804f6435f26cadd329c13 (diff)
leds: leds-gpio: Make use of device property API
Make use of device property API in this driver so that both OF and ACPI based system can use the same driver. This change contains material from Max Eliaser and Mika Westerberg. Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com> Acked-by: Bryan Wu <cooloney@gmail.com> Acked-by: Grant Likely <grant.likely@linaro.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-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