mirror of
https://github.com/FEX-Emu/linux.git
synced 2024-12-30 21:46:31 +00:00
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>
This commit is contained in:
parent
40b7318319
commit
a43f2cbbb0
@ -16,10 +16,8 @@
|
|||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/leds.h>
|
#include <linux/leds.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/of.h>
|
|
||||||
#include <linux/of_gpio.h>
|
|
||||||
#include <linux/of_platform.h>
|
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/property.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/workqueue.h>
|
#include <linux/workqueue.h>
|
||||||
|
|
||||||
@ -171,40 +169,37 @@ static inline int sizeof_gpio_leds_priv(int num_leds)
|
|||||||
(sizeof(struct gpio_led_data) * num_leds);
|
(sizeof(struct gpio_led_data) * num_leds);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Code to create from OpenFirmware platform devices */
|
static struct gpio_leds_priv *gpio_leds_create(struct platform_device *pdev)
|
||||||
#ifdef CONFIG_OF_GPIO
|
|
||||||
static struct gpio_leds_priv *gpio_leds_create_of(struct platform_device *pdev)
|
|
||||||
{
|
{
|
||||||
struct device_node *np = pdev->dev.of_node, *child;
|
struct device *dev = &pdev->dev;
|
||||||
|
struct fwnode_handle *child;
|
||||||
struct gpio_leds_priv *priv;
|
struct gpio_leds_priv *priv;
|
||||||
int count, ret;
|
int count, ret;
|
||||||
|
|
||||||
/* count LEDs in this device, so we know how much to allocate */
|
count = device_get_child_node_count(dev);
|
||||||
count = of_get_available_child_count(np);
|
|
||||||
if (!count)
|
if (!count)
|
||||||
return ERR_PTR(-ENODEV);
|
return ERR_PTR(-ENODEV);
|
||||||
|
|
||||||
for_each_available_child_of_node(np, child)
|
priv = devm_kzalloc(dev, sizeof_gpio_leds_priv(count), GFP_KERNEL);
|
||||||
if (of_get_gpio(child, 0) == -EPROBE_DEFER)
|
|
||||||
return ERR_PTR(-EPROBE_DEFER);
|
|
||||||
|
|
||||||
priv = devm_kzalloc(&pdev->dev, sizeof_gpio_leds_priv(count),
|
|
||||||
GFP_KERNEL);
|
|
||||||
if (!priv)
|
if (!priv)
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|
||||||
for_each_available_child_of_node(np, child) {
|
device_for_each_child_node(dev, child) {
|
||||||
struct gpio_led led = {};
|
struct gpio_led led = {};
|
||||||
enum of_gpio_flags flags;
|
const char *state = NULL;
|
||||||
const char *state;
|
|
||||||
|
|
||||||
led.gpio = of_get_gpio_flags(child, 0, &flags);
|
led.gpiod = devm_get_gpiod_from_child(dev, child);
|
||||||
led.active_low = flags & OF_GPIO_ACTIVE_LOW;
|
if (IS_ERR(led.gpiod)) {
|
||||||
led.name = of_get_property(child, "label", NULL) ? : child->name;
|
fwnode_handle_put(child);
|
||||||
led.default_trigger =
|
goto err;
|
||||||
of_get_property(child, "linux,default-trigger", NULL);
|
}
|
||||||
state = of_get_property(child, "default-state", NULL);
|
|
||||||
if (state) {
|
fwnode_property_read_string(child, "label", &led.name);
|
||||||
|
fwnode_property_read_string(child, "linux,default-trigger",
|
||||||
|
&led.default_trigger);
|
||||||
|
|
||||||
|
if (!fwnode_property_read_string(child, "linux,default_state",
|
||||||
|
&state)) {
|
||||||
if (!strcmp(state, "keep"))
|
if (!strcmp(state, "keep"))
|
||||||
led.default_state = LEDS_GPIO_DEFSTATE_KEEP;
|
led.default_state = LEDS_GPIO_DEFSTATE_KEEP;
|
||||||
else if (!strcmp(state, "on"))
|
else if (!strcmp(state, "on"))
|
||||||
@ -213,13 +208,13 @@ static struct gpio_leds_priv *gpio_leds_create_of(struct platform_device *pdev)
|
|||||||
led.default_state = LEDS_GPIO_DEFSTATE_OFF;
|
led.default_state = LEDS_GPIO_DEFSTATE_OFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (of_get_property(child, "retain-state-suspended", NULL))
|
if (fwnode_property_present(child, "retain-state-suspended"))
|
||||||
led.retain_state_suspended = 1;
|
led.retain_state_suspended = 1;
|
||||||
|
|
||||||
ret = create_gpio_led(&led, &priv->leds[priv->num_leds++],
|
ret = create_gpio_led(&led, &priv->leds[priv->num_leds++],
|
||||||
&pdev->dev, NULL);
|
dev, NULL);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
of_node_put(child);
|
fwnode_handle_put(child);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -238,12 +233,6 @@ static const struct of_device_id of_gpio_leds_match[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
MODULE_DEVICE_TABLE(of, of_gpio_leds_match);
|
MODULE_DEVICE_TABLE(of, of_gpio_leds_match);
|
||||||
#else /* CONFIG_OF_GPIO */
|
|
||||||
static struct gpio_leds_priv *gpio_leds_create_of(struct platform_device *pdev)
|
|
||||||
{
|
|
||||||
return ERR_PTR(-ENODEV);
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_OF_GPIO */
|
|
||||||
|
|
||||||
static int gpio_led_probe(struct platform_device *pdev)
|
static int gpio_led_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
@ -271,7 +260,7 @@ static int gpio_led_probe(struct platform_device *pdev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
priv = gpio_leds_create_of(pdev);
|
priv = gpio_leds_create(pdev);
|
||||||
if (IS_ERR(priv))
|
if (IS_ERR(priv))
|
||||||
return PTR_ERR(priv);
|
return PTR_ERR(priv);
|
||||||
}
|
}
|
||||||
@ -298,7 +287,7 @@ static struct platform_driver gpio_led_driver = {
|
|||||||
.driver = {
|
.driver = {
|
||||||
.name = "leds-gpio",
|
.name = "leds-gpio",
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.of_match_table = of_match_ptr(of_gpio_leds_match),
|
.of_match_table = of_gpio_leds_match,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user