diff options
-rw-r--r-- | drivers/base/power/domain.c | 76 |
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 | ||
2293 | static 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 | */ |
2304 | int of_genpd_parse_idle_states(struct device_node *dn, | 2337 | int 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 | } |