aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2014-10-24 06:57:19 -0400
committerBryan Wu <cooloney@gmail.com>2014-11-14 17:29:35 -0500
commit3f6e42c808409c40dd0d0f8fe2022d197b27455e (patch)
tree635468ea8107231f6406bd24a0cf31961f70cedc
parent37fa70f026474db98fc395a45eda2bbceb210c74 (diff)
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: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Bryan Wu <cooloney@gmail.com>
-rw-r--r--drivers/leds/leds-syscon.c67
1 files changed, 36 insertions, 31 deletions
diff --git a/drivers/leds/leds-syscon.c b/drivers/leds/leds-syscon.c
index e0ccfc872c2f..6896e2d9ba58 100644
--- a/drivers/leds/leds-syscon.c
+++ b/drivers/leds/leds-syscon.c
@@ -66,39 +66,13 @@ static void syscon_led_set(struct led_classdev *led_cdev,
66 dev_err(sled->cdev.dev, "error updating LED status\n"); 66 dev_err(sled->cdev.dev, "error updating LED status\n");
67} 67}
68 68
69static const struct of_device_id syscon_match[] = { 69static int __init syscon_leds_spawn(struct device_node *np,
70 { .compatible = "syscon", }, 70 struct device *dev,
71 {}, 71 struct regmap *map)
72};
73
74static int __init syscon_leds_init(void)
75{ 72{
76 const struct of_device_id *devid;
77 struct device_node *np;
78 struct device_node *child; 73 struct device_node *child;
79 struct regmap *map;
80 struct platform_device *pdev;
81 struct device *dev;
82 int ret; 74 int ret;
83 75
84 np = of_find_matching_node_and_match(NULL, syscon_match,
85 &devid);
86 if (!np)
87 return -ENODEV;
88
89 map = syscon_node_to_regmap(np);
90 if (IS_ERR(map))
91 return PTR_ERR(map);
92
93 /*
94 * If the map is there, the device should be there, we allocate
95 * memory on the syscon device's behalf here.
96 */
97 pdev = of_find_device_by_node(np);
98 if (!pdev)
99 return -ENODEV;
100 dev = &pdev->dev;
101
102 for_each_available_child_of_node(np, child) { 76 for_each_available_child_of_node(np, child) {
103 struct syscon_led *sled; 77 struct syscon_led *sled;
104 const char *state; 78 const char *state;
@@ -146,7 +120,6 @@ static int __init syscon_leds_init(void)
146 if (ret < 0) 120 if (ret < 0)
147 return ret; 121 return ret;
148 } 122 }
149
150 } 123 }
151 sled->cdev.brightness_set = syscon_led_set; 124 sled->cdev.brightness_set = syscon_led_set;
152 125
@@ -156,7 +129,39 @@ static int __init syscon_leds_init(void)
156 129
157 dev_info(dev, "registered LED %s\n", sled->cdev.name); 130 dev_info(dev, "registered LED %s\n", sled->cdev.name);
158 } 131 }
132 return 0;
133}
134
135static int __init syscon_leds_init(void)
136{
137 struct device_node *np;
138
139 for_each_of_allnodes(np) {
140 struct platform_device *pdev;
141 struct regmap *map;
142 int ret;
143
144 if (!of_device_is_compatible(np, "syscon"))
145 continue;
146
147 map = syscon_node_to_regmap(np);
148 if (IS_ERR(map)) {
149 pr_err("error getting regmap for syscon LEDs\n");
150 continue;
151 }
152
153 /*
154 * If the map is there, the device should be there, we allocate
155 * memory on the syscon device's behalf here.
156 */
157 pdev = of_find_device_by_node(np);
158 if (!pdev)
159 return -ENODEV;
160 ret = syscon_leds_spawn(np, &pdev->dev, map);
161 if (ret)
162 dev_err(&pdev->dev, "could not spawn syscon LEDs\n");
163 }
159 164
160 return 0; 165 return 0;
161} 166}
162device_initcall(syscon_leds_init); 167device_initcall(syscon_leds_init);