diff options
author | Ulf Hansson <ulf.hansson@linaro.org> | 2019-04-18 06:27:56 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2019-04-25 03:37:36 -0400 |
commit | e8b04de9da71b56dbbc5fa443d4ab52b617977bb (patch) | |
tree | 578cedf7ebdee221c964c617a15a91cabde4faa0 | |
parent | 71b77697af9ef06b559875e4bd8dc3d141807c93 (diff) |
PM / Domains: Allow OF lookup for multi PM domain case from ->attach_dev()
A genpd provider that uses the ->attach_dev() callback to look up
resources for a device fails to do so when the device has multiple
PM domains attached. That is because when genpd invokes the
->attach_dev() callback, it passes the allocated virtual device as
the in-parameter.
To address this problem, simply assign the dev->of_node for the
virtual device, based upon the original device's OF node.
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Acked-by: Niklas Cassel <niklas.cassel@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r-- | drivers/base/power/domain.c | 12 |
1 files changed, 7 insertions, 5 deletions
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 5422fc01dca3..a0b021d53084 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c | |||
@@ -2272,6 +2272,7 @@ EXPORT_SYMBOL_GPL(of_genpd_remove_last); | |||
2272 | 2272 | ||
2273 | static void genpd_release_dev(struct device *dev) | 2273 | static void genpd_release_dev(struct device *dev) |
2274 | { | 2274 | { |
2275 | of_node_put(dev->of_node); | ||
2275 | kfree(dev); | 2276 | kfree(dev); |
2276 | } | 2277 | } |
2277 | 2278 | ||
@@ -2333,14 +2334,14 @@ static void genpd_dev_pm_sync(struct device *dev) | |||
2333 | genpd_queue_power_off_work(pd); | 2334 | genpd_queue_power_off_work(pd); |
2334 | } | 2335 | } |
2335 | 2336 | ||
2336 | static int __genpd_dev_pm_attach(struct device *dev, struct device_node *np, | 2337 | static int __genpd_dev_pm_attach(struct device *dev, unsigned int index, |
2337 | unsigned int index, bool power_on) | 2338 | bool power_on) |
2338 | { | 2339 | { |
2339 | struct of_phandle_args pd_args; | 2340 | struct of_phandle_args pd_args; |
2340 | struct generic_pm_domain *pd; | 2341 | struct generic_pm_domain *pd; |
2341 | int ret; | 2342 | int ret; |
2342 | 2343 | ||
2343 | ret = of_parse_phandle_with_args(np, "power-domains", | 2344 | ret = of_parse_phandle_with_args(dev->of_node, "power-domains", |
2344 | "#power-domain-cells", index, &pd_args); | 2345 | "#power-domain-cells", index, &pd_args); |
2345 | if (ret < 0) | 2346 | if (ret < 0) |
2346 | return ret; | 2347 | return ret; |
@@ -2408,7 +2409,7 @@ int genpd_dev_pm_attach(struct device *dev) | |||
2408 | "#power-domain-cells") != 1) | 2409 | "#power-domain-cells") != 1) |
2409 | return 0; | 2410 | return 0; |
2410 | 2411 | ||
2411 | return __genpd_dev_pm_attach(dev, dev->of_node, 0, true); | 2412 | return __genpd_dev_pm_attach(dev, 0, true); |
2412 | } | 2413 | } |
2413 | EXPORT_SYMBOL_GPL(genpd_dev_pm_attach); | 2414 | EXPORT_SYMBOL_GPL(genpd_dev_pm_attach); |
2414 | 2415 | ||
@@ -2452,6 +2453,7 @@ struct device *genpd_dev_pm_attach_by_id(struct device *dev, | |||
2452 | dev_set_name(virt_dev, "genpd:%u:%s", index, dev_name(dev)); | 2453 | dev_set_name(virt_dev, "genpd:%u:%s", index, dev_name(dev)); |
2453 | virt_dev->bus = &genpd_bus_type; | 2454 | virt_dev->bus = &genpd_bus_type; |
2454 | virt_dev->release = genpd_release_dev; | 2455 | virt_dev->release = genpd_release_dev; |
2456 | virt_dev->of_node = of_node_get(dev->of_node); | ||
2455 | 2457 | ||
2456 | ret = device_register(virt_dev); | 2458 | ret = device_register(virt_dev); |
2457 | if (ret) { | 2459 | if (ret) { |
@@ -2460,7 +2462,7 @@ struct device *genpd_dev_pm_attach_by_id(struct device *dev, | |||
2460 | } | 2462 | } |
2461 | 2463 | ||
2462 | /* Try to attach the device to the PM domain at the specified index. */ | 2464 | /* Try to attach the device to the PM domain at the specified index. */ |
2463 | ret = __genpd_dev_pm_attach(virt_dev, dev->of_node, index, false); | 2465 | ret = __genpd_dev_pm_attach(virt_dev, index, false); |
2464 | if (ret < 1) { | 2466 | if (ret < 1) { |
2465 | device_unregister(virt_dev); | 2467 | device_unregister(virt_dev); |
2466 | return ret ? ERR_PTR(ret) : NULL; | 2468 | return ret ? ERR_PTR(ret) : NULL; |