aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base
diff options
context:
space:
mode:
authorUlf Hansson <ulf.hansson@linaro.org>2018-05-09 06:17:52 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2018-05-14 16:58:44 -0400
commit919b7308fcc452cd4e282bab389c33384a9f3790 (patch)
treeaff8f55a43ae45af67ba91efde1a1f70ef798a02 /drivers/base
parent4f688748c958deb947759773be6dffe6b44d084d (diff)
PM / Domains: Allow a better error handling of dev_pm_domain_attach()
The callers of dev_pm_domain_attach() currently checks the returned error code for -EPROBE_DEFER and needs to ignore other error codes. This is an unnecessary limitation, which also leads to a rather strange behaviour in the error path. Address this limitation, by changing the return codes from acpi_dev_pm_attach() and genpd_dev_pm_attach(). More precisely, let them return 0, when no PM domain is needed for the device and then return 1, in case the device was successfully attached to its PM domain. In this way, dev_pm_domain_attach(), gets a better understanding of what happens in the attach attempts and also allowing its caller to better act on real errors codes. Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/power/common.c7
-rw-r--r--drivers/base/power/domain.c19
2 files changed, 14 insertions, 12 deletions
diff --git a/drivers/base/power/common.c b/drivers/base/power/common.c
index f3cf61f58f25..5e4b481595bd 100644
--- a/drivers/base/power/common.c
+++ b/drivers/base/power/common.c
@@ -98,7 +98,8 @@ EXPORT_SYMBOL_GPL(dev_pm_put_subsys_data);
98 * Callers must ensure proper synchronization of this function with power 98 * Callers must ensure proper synchronization of this function with power
99 * management callbacks. 99 * management callbacks.
100 * 100 *
101 * Returns 0 on successfully attached PM domain or negative error code. 101 * Returns 0 on successfully attached PM domain and when it found that the
102 * device don't need a PM domain, else a negative error code.
102 */ 103 */
103int dev_pm_domain_attach(struct device *dev, bool power_on) 104int dev_pm_domain_attach(struct device *dev, bool power_on)
104{ 105{
@@ -108,10 +109,10 @@ int dev_pm_domain_attach(struct device *dev, bool power_on)
108 return -EEXIST; 109 return -EEXIST;
109 110
110 ret = acpi_dev_pm_attach(dev, power_on); 111 ret = acpi_dev_pm_attach(dev, power_on);
111 if (ret) 112 if (!ret)
112 ret = genpd_dev_pm_attach(dev); 113 ret = genpd_dev_pm_attach(dev);
113 114
114 return ret; 115 return ret < 0 ? ret : 0;
115} 116}
116EXPORT_SYMBOL_GPL(dev_pm_domain_attach); 117EXPORT_SYMBOL_GPL(dev_pm_domain_attach);
117 118
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index b816adbe1e62..455ecea6c812 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -2180,10 +2180,11 @@ static void genpd_dev_pm_sync(struct device *dev)
2180 * Parse device's OF node to find a PM domain specifier. If such is found, 2180 * Parse device's OF node to find a PM domain specifier. If such is found,
2181 * attaches the device to retrieved pm_domain ops. 2181 * attaches the device to retrieved pm_domain ops.
2182 * 2182 *
2183 * Returns 0 on successfully attached PM domain or negative error code. Note 2183 * Returns 1 on successfully attached PM domain, 0 when the device don't need a
2184 * that if a power-domain exists for the device, but it cannot be found or 2184 * PM domain or a negative error code in case of failures. Note that if a
2185 * turned on, then return -EPROBE_DEFER to ensure that the device is not 2185 * power-domain exists for the device, but it cannot be found or turned on,
2186 * probed and to re-try again later. 2186 * then return -EPROBE_DEFER to ensure that the device is not probed and to
2187 * re-try again later.
2187 */ 2188 */
2188int genpd_dev_pm_attach(struct device *dev) 2189int genpd_dev_pm_attach(struct device *dev)
2189{ 2190{
@@ -2192,12 +2193,12 @@ int genpd_dev_pm_attach(struct device *dev)
2192 int ret; 2193 int ret;
2193 2194
2194 if (!dev->of_node) 2195 if (!dev->of_node)
2195 return -ENODEV; 2196 return 0;
2196 2197
2197 ret = of_parse_phandle_with_args(dev->of_node, "power-domains", 2198 ret = of_parse_phandle_with_args(dev->of_node, "power-domains",
2198 "#power-domain-cells", 0, &pd_args); 2199 "#power-domain-cells", 0, &pd_args);
2199 if (ret < 0) 2200 if (ret < 0)
2200 return ret; 2201 return 0;
2201 2202
2202 mutex_lock(&gpd_list_lock); 2203 mutex_lock(&gpd_list_lock);
2203 pd = genpd_get_from_provider(&pd_args); 2204 pd = genpd_get_from_provider(&pd_args);
@@ -2218,7 +2219,7 @@ int genpd_dev_pm_attach(struct device *dev)
2218 if (ret != -EPROBE_DEFER) 2219 if (ret != -EPROBE_DEFER)
2219 dev_err(dev, "failed to add to PM domain %s: %d", 2220 dev_err(dev, "failed to add to PM domain %s: %d",
2220 pd->name, ret); 2221 pd->name, ret);
2221 goto out; 2222 return ret;
2222 } 2223 }
2223 2224
2224 dev->pm_domain->detach = genpd_dev_pm_detach; 2225 dev->pm_domain->detach = genpd_dev_pm_detach;
@@ -2230,8 +2231,8 @@ int genpd_dev_pm_attach(struct device *dev)
2230 2231
2231 if (ret) 2232 if (ret)
2232 genpd_remove_device(pd, dev); 2233 genpd_remove_device(pd, dev);
2233out: 2234
2234 return ret ? -EPROBE_DEFER : 0; 2235 return ret ? -EPROBE_DEFER : 1;
2235} 2236}
2236EXPORT_SYMBOL_GPL(genpd_dev_pm_attach); 2237EXPORT_SYMBOL_GPL(genpd_dev_pm_attach);
2237 2238