aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/base/power/domain.c76
1 files changed, 45 insertions, 31 deletions
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index 528b24149bc7..1ea0e2502e8e 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -2290,6 +2290,38 @@ static int genpd_parse_state(struct genpd_power_state *genpd_state,
2290 return 0; 2290 return 0;
2291} 2291}
2292 2292
2293static int genpd_iterate_idle_states(struct device_node *dn,
2294 struct genpd_power_state *states)
2295{
2296 int ret;
2297 struct of_phandle_iterator it;
2298 struct device_node *np;
2299 int i = 0;
2300
2301 ret = of_count_phandle_with_args(dn, "domain-idle-states", NULL);
2302 if (ret <= 0)
2303 return ret;
2304
2305 /* Loop over the phandles until all the requested entry is found */
2306 of_for_each_phandle(&it, ret, dn, "domain-idle-states", NULL, 0) {
2307 np = it.node;
2308 if (!of_match_node(idle_state_match, np))
2309 continue;
2310 if (states) {
2311 ret = genpd_parse_state(&states[i], np);
2312 if (ret) {
2313 pr_err("Parsing idle state node %pOF failed with err %d\n",
2314 np, ret);
2315 of_node_put(np);
2316 return ret;
2317 }
2318 }
2319 i++;
2320 }
2321
2322 return i;
2323}
2324
2293/** 2325/**
2294 * of_genpd_parse_idle_states: Return array of idle states for the genpd. 2326 * of_genpd_parse_idle_states: Return array of idle states for the genpd.
2295 * 2327 *
@@ -2299,49 +2331,31 @@ static int genpd_parse_state(struct genpd_power_state *genpd_state,
2299 * 2331 *
2300 * Returns the device states parsed from the OF node. The memory for the states 2332 * Returns the device states parsed from the OF node. The memory for the states
2301 * is allocated by this function and is the responsibility of the caller to 2333 * is allocated by this function and is the responsibility of the caller to
2302 * free the memory after use. 2334 * free the memory after use. If no domain idle states is found it returns
2335 * -EINVAL and in case of errors, a negative error code.
2303 */ 2336 */
2304int of_genpd_parse_idle_states(struct device_node *dn, 2337int of_genpd_parse_idle_states(struct device_node *dn,
2305 struct genpd_power_state **states, int *n) 2338 struct genpd_power_state **states, int *n)
2306{ 2339{
2307 struct genpd_power_state *st; 2340 struct genpd_power_state *st;
2308 struct device_node *np; 2341 int ret;
2309 int i = 0;
2310 int err, ret;
2311 int count;
2312 struct of_phandle_iterator it;
2313 const struct of_device_id *match_id;
2314 2342
2315 count = of_count_phandle_with_args(dn, "domain-idle-states", NULL); 2343 ret = genpd_iterate_idle_states(dn, NULL);
2316 if (count <= 0) 2344 if (ret <= 0)
2317 return -EINVAL; 2345 return ret < 0 ? ret : -EINVAL;
2318 2346
2319 st = kcalloc(count, sizeof(*st), GFP_KERNEL); 2347 st = kcalloc(ret, sizeof(*st), GFP_KERNEL);
2320 if (!st) 2348 if (!st)
2321 return -ENOMEM; 2349 return -ENOMEM;
2322 2350
2323 /* Loop over the phandles until all the requested entry is found */ 2351 ret = genpd_iterate_idle_states(dn, st);
2324 of_for_each_phandle(&it, err, dn, "domain-idle-states", NULL, 0) { 2352 if (ret <= 0) {
2325 np = it.node; 2353 kfree(st);
2326 match_id = of_match_node(idle_state_match, np); 2354 return ret < 0 ? ret : -EINVAL;
2327 if (!match_id)
2328 continue;
2329 ret = genpd_parse_state(&st[i++], np);
2330 if (ret) {
2331 pr_err
2332 ("Parsing idle state node %pOF failed with err %d\n",
2333 np, ret);
2334 of_node_put(np);
2335 kfree(st);
2336 return ret;
2337 }
2338 } 2355 }
2339 2356
2340 *n = i; 2357 *states = st;
2341 if (!i) 2358 *n = ret;
2342 kfree(st);
2343 else
2344 *states = st;
2345 2359
2346 return 0; 2360 return 0;
2347} 2361}