Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 311fa6ad authored by Jon Hunter's avatar Jon Hunter Committed by Rafael J. Wysocki
Browse files

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: default avatarJon Hunter <jonathanh@nvidia.com>
Acked-by: default avatarUlf Hansson <ulf.hansson@linaro.org>
Acked-by: default avatarKevin Hilman <khilman@linaro.org>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent 885fb909
Loading
Loading
Loading
Loading
+9 −5
Original line number Original line Diff line number Diff line
@@ -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 */