diff options
Diffstat (limited to 'drivers/base')
-rw-r--r-- | drivers/base/platform.c | 17 | ||||
-rw-r--r-- | drivers/base/power/common.c | 10 | ||||
-rw-r--r-- | drivers/base/power/domain.c | 45 |
3 files changed, 30 insertions, 42 deletions
diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 8075ddc70a17..9460139d9b02 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -572,17 +572,16 @@ static int platform_drv_probe(struct device *_dev) return ret; ret = dev_pm_domain_attach(_dev, true); - if (ret != -EPROBE_DEFER) { - if (drv->probe) { - ret = drv->probe(dev); - if (ret) - dev_pm_domain_detach(_dev, true); - } else { - /* don't fail if just dev_pm_domain_attach failed */ - ret = 0; - } + if (ret) + goto out; + + if (drv->probe) { + ret = drv->probe(dev); + if (ret) + dev_pm_domain_detach(_dev, true); } +out: if (drv->prevent_deferred_probe && ret == -EPROBE_DEFER) { dev_warn(_dev, "probe deferral not supported\n"); ret = -ENXIO; diff --git a/drivers/base/power/common.c b/drivers/base/power/common.c index f6a9ad52cbbf..5e4b481595bd 100644 --- a/drivers/base/power/common.c +++ b/drivers/base/power/common.c @@ -98,17 +98,21 @@ EXPORT_SYMBOL_GPL(dev_pm_put_subsys_data); * Callers must ensure proper synchronization of this function with power * management callbacks. * - * Returns 0 on successfully attached PM domain or negative error code. + * Returns 0 on successfully attached PM domain and when it found that the + * device don't need a PM domain, else a negative error code. */ int dev_pm_domain_attach(struct device *dev, bool power_on) { int ret; + if (dev->pm_domain) + return -EEXIST; + ret = acpi_dev_pm_attach(dev, power_on); - if (ret) + if (!ret) ret = genpd_dev_pm_attach(dev); - return ret; + return ret < 0 ? ret : 0; } EXPORT_SYMBOL_GPL(dev_pm_domain_attach); diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 29e25dc0584c..da6c8860c72e 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -1378,7 +1378,7 @@ static int genpd_add_device(struct generic_pm_domain *genpd, struct device *dev, struct gpd_timing_data *td) { struct generic_pm_domain_data *gpd_data; - int ret = 0; + int ret; dev_dbg(dev, "%s()\n", __func__); @@ -1391,11 +1391,6 @@ static int genpd_add_device(struct generic_pm_domain *genpd, struct device *dev, genpd_lock(genpd); - if (genpd->prepared_count > 0) { - ret = -EAGAIN; - goto out; - } - ret = genpd->attach_dev ? genpd->attach_dev(genpd, dev) : 0; if (ret) goto out; @@ -2236,31 +2231,25 @@ static void genpd_dev_pm_sync(struct device *dev) * Parse device's OF node to find a PM domain specifier. If such is found, * attaches the device to retrieved pm_domain ops. * - * Both generic and legacy Samsung-specific DT bindings are supported to keep - * backwards compatibility with existing DTBs. - * - * 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. + * Returns 1 on successfully attached PM domain, 0 when the device don't need a + * PM domain or a negative error code in case of failures. 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) { struct of_phandle_args pd_args; struct generic_pm_domain *pd; - unsigned int i; int ret; if (!dev->of_node) - return -ENODEV; - - if (dev->pm_domain) - return -EEXIST; + return 0; ret = of_parse_phandle_with_args(dev->of_node, "power-domains", "#power-domain-cells", 0, &pd_args); if (ret < 0) - return ret; + return 0; mutex_lock(&gpd_list_lock); pd = genpd_get_from_provider(&pd_args); @@ -2274,21 +2263,14 @@ int genpd_dev_pm_attach(struct device *dev) dev_dbg(dev, "adding to PM domain %s\n", pd->name); - for (i = 1; i < GENPD_RETRY_MAX_MS; i <<= 1) { - ret = genpd_add_device(pd, dev, NULL); - if (ret != -EAGAIN) - break; - - mdelay(i); - cond_resched(); - } + ret = genpd_add_device(pd, dev, NULL); mutex_unlock(&gpd_list_lock); if (ret < 0) { if (ret != -EPROBE_DEFER) dev_err(dev, "failed to add to PM domain %s: %d", pd->name, ret); - goto out; + return ret; } dev->pm_domain->detach = genpd_dev_pm_detach; @@ -2297,8 +2279,11 @@ int genpd_dev_pm_attach(struct device *dev) genpd_lock(pd); ret = genpd_power_on(pd, 0); genpd_unlock(pd); -out: - return ret ? -EPROBE_DEFER : 0; + + if (ret) + genpd_remove_device(pd, dev); + + return ret ? -EPROBE_DEFER : 1; } EXPORT_SYMBOL_GPL(genpd_dev_pm_attach); |