Commit 3f6e42c8 authored by Linus Walleij's avatar Linus Walleij Committed by Bryan Wu

leds: syscon: handle multiple syscon instances

Currently the syscon LED driver will only handle LEDs on the
first syscon found in the system. But there can be several of
them, so augment the driver to traverse all syscon nodes and
check for syscon LEDs on them.
Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Signed-off-by: default avatarBryan Wu <cooloney@gmail.com>
parent 37fa70f0
...@@ -66,39 +66,13 @@ static void syscon_led_set(struct led_classdev *led_cdev, ...@@ -66,39 +66,13 @@ static void syscon_led_set(struct led_classdev *led_cdev,
dev_err(sled->cdev.dev, "error updating LED status\n"); dev_err(sled->cdev.dev, "error updating LED status\n");
} }
static const struct of_device_id syscon_match[] = { static int __init syscon_leds_spawn(struct device_node *np,
{ .compatible = "syscon", }, struct device *dev,
{}, struct regmap *map)
};
static int __init syscon_leds_init(void)
{ {
const struct of_device_id *devid;
struct device_node *np;
struct device_node *child; struct device_node *child;
struct regmap *map;
struct platform_device *pdev;
struct device *dev;
int ret; int ret;
np = of_find_matching_node_and_match(NULL, syscon_match,
&devid);
if (!np)
return -ENODEV;
map = syscon_node_to_regmap(np);
if (IS_ERR(map))
return PTR_ERR(map);
/*
* If the map is there, the device should be there, we allocate
* memory on the syscon device's behalf here.
*/
pdev = of_find_device_by_node(np);
if (!pdev)
return -ENODEV;
dev = &pdev->dev;
for_each_available_child_of_node(np, child) { for_each_available_child_of_node(np, child) {
struct syscon_led *sled; struct syscon_led *sled;
const char *state; const char *state;
...@@ -146,7 +120,6 @@ static int __init syscon_leds_init(void) ...@@ -146,7 +120,6 @@ static int __init syscon_leds_init(void)
if (ret < 0) if (ret < 0)
return ret; return ret;
} }
} }
sled->cdev.brightness_set = syscon_led_set; sled->cdev.brightness_set = syscon_led_set;
...@@ -156,7 +129,39 @@ static int __init syscon_leds_init(void) ...@@ -156,7 +129,39 @@ static int __init syscon_leds_init(void)
dev_info(dev, "registered LED %s\n", sled->cdev.name); dev_info(dev, "registered LED %s\n", sled->cdev.name);
} }
return 0;
}
static int __init syscon_leds_init(void)
{
struct device_node *np;
for_each_of_allnodes(np) {
struct platform_device *pdev;
struct regmap *map;
int ret;
if (!of_device_is_compatible(np, "syscon"))
continue;
map = syscon_node_to_regmap(np);
if (IS_ERR(map)) {
pr_err("error getting regmap for syscon LEDs\n");
continue;
}
/*
* If the map is there, the device should be there, we allocate
* memory on the syscon device's behalf here.
*/
pdev = of_find_device_by_node(np);
if (!pdev)
return -ENODEV;
ret = syscon_leds_spawn(np, &pdev->dev, map);
if (ret)
dev_err(&pdev->dev, "could not spawn syscon LEDs\n");
}
return 0; return 0;
} }
device_initcall(syscon_leds_init); device_initcall(syscon_leds_init);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment