PM / Domains: Return -EPROBE_DEFER if we fail to init or turn-on domain
When a device is probed, the function dev_pm_domain_attach() is called to see if there is a power-domain that is associated with the device and needs to be turned on. If dev_pm_domain_attach() does not return -EPROBE_DEFER then the device will be probed. For devices using genpd, dev_pm_domain_attach() will call genpd_dev_pm_attach(). If genpd_dev_pm_attach() does not find a power domain associated with the device then it returns an error code not equal to -EPROBE_DEFER to allow the device to be probed. However, if genpd_dev_pm_attach() does find a power-domain that is associated with the device, then it does not return -EPROBE_DEFER on failure and hence the device will still be probed. Furthermore, genpd_dev_pm_attach() does not check the error code returned by pm_genpd_poweron() to see if the power-domain was turned on successfully. Fix this by checking the return code from pm_genpd_poweron() and returning -EPROBE_DEFER from genpd_dev_pm_attach on failure, if there is a power-domain associated with the device. Signed-off-by: Jon Hunter <jonathanh@nvidia.com> Acked-by: Ulf Hansson <ulf.hansson@linaro.org> Acked-by: Kevin Hilman <khilman@linaro.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
This commit is contained in:
parent
885fb909dc
commit
311fa6adf9
1 changed files with 9 additions and 5 deletions
|
@ -1947,7 +1947,10 @@ static void genpd_dev_pm_sync(struct device *dev)
|
||||||
* Both generic and legacy Samsung-specific DT bindings are supported to keep
|
* Both generic and legacy Samsung-specific DT bindings are supported to keep
|
||||||
* backwards compatibility with existing DTBs.
|
* backwards compatibility with existing DTBs.
|
||||||
*
|
*
|
||||||
* Returns 0 on successfully attached PM domain or negative error code.
|
* Returns 0 on successfully attached PM domain or negative error code. Note
|
||||||
|
* that if a power-domain exists for the device, but it cannot be found or
|
||||||
|
* turned on, then return -EPROBE_DEFER to ensure that the device is not
|
||||||
|
* probed and to re-try again later.
|
||||||
*/
|
*/
|
||||||
int genpd_dev_pm_attach(struct device *dev)
|
int genpd_dev_pm_attach(struct device *dev)
|
||||||
{
|
{
|
||||||
|
@ -1984,7 +1987,7 @@ int genpd_dev_pm_attach(struct device *dev)
|
||||||
dev_dbg(dev, "%s() failed to find PM domain: %ld\n",
|
dev_dbg(dev, "%s() failed to find PM domain: %ld\n",
|
||||||
__func__, PTR_ERR(pd));
|
__func__, PTR_ERR(pd));
|
||||||
of_node_put(dev->of_node);
|
of_node_put(dev->of_node);
|
||||||
return PTR_ERR(pd);
|
return -EPROBE_DEFER;
|
||||||
}
|
}
|
||||||
|
|
||||||
dev_dbg(dev, "adding to PM domain %s\n", pd->name);
|
dev_dbg(dev, "adding to PM domain %s\n", pd->name);
|
||||||
|
@ -2002,14 +2005,15 @@ int genpd_dev_pm_attach(struct device *dev)
|
||||||
dev_err(dev, "failed to add to PM domain %s: %d",
|
dev_err(dev, "failed to add to PM domain %s: %d",
|
||||||
pd->name, ret);
|
pd->name, ret);
|
||||||
of_node_put(dev->of_node);
|
of_node_put(dev->of_node);
|
||||||
return ret;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
dev->pm_domain->detach = genpd_dev_pm_detach;
|
dev->pm_domain->detach = genpd_dev_pm_detach;
|
||||||
dev->pm_domain->sync = genpd_dev_pm_sync;
|
dev->pm_domain->sync = genpd_dev_pm_sync;
|
||||||
pm_genpd_poweron(pd);
|
ret = pm_genpd_poweron(pd);
|
||||||
|
|
||||||
return 0;
|
out:
|
||||||
|
return ret ? -EPROBE_DEFER : 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(genpd_dev_pm_attach);
|
EXPORT_SYMBOL_GPL(genpd_dev_pm_attach);
|
||||||
#endif /* CONFIG_PM_GENERIC_DOMAINS_OF */
|
#endif /* CONFIG_PM_GENERIC_DOMAINS_OF */
|
||||||
|
|
Loading…
Add table
Reference in a new issue