Commit d42c7c6f authored by Claudiu Beznea's avatar Claudiu Beznea Committed by Rafael J. Wysocki
Browse files

PM: domains: Add flags to specify power on attach/detach



Calling dev_pm_domain_attach()/dev_pm_domain_detach() in bus driver
probe/remove functions can affect system behavior when the drivers
attached to the bus use devres-managed resources. Since devres actions
may need to access device registers, calling dev_pm_domain_detach() too
early, i.e., before these actions complete, can cause failures on some
systems. One such example is Renesas RZ/G3S SoC-based platforms.

If the device clocks are managed via PM domains, invoking
dev_pm_domain_detach() in the bus driver's remove function removes the
device's clocks from the PM domain, preventing any subsequent
pm_runtime_resume*() calls from enabling those clocks.

The second argument of dev_pm_domain_attach() specifies whether the PM
domain should be powered on during attachment. Likewise, the second
argument of dev_pm_domain_detach() indicates whether the domain should be
powered off during detachment.

Upcoming changes address the issue described above (initially for the
platform bus only) by deferring the call to dev_pm_domain_detach() until
after devres_release_all() in device_unbind_cleanup(). The detach_power_off
field in struct dev_pm_info stores the detach power off info from the
second argument of dev_pm_domain_attach().

Because there are cases where the device's PM domain power-on/off behavior
must be conditional (e.g., in i2c_device_probe()), the patch introduces
PD_FLAG_ATTACH_POWER_ON and PD_FLAG_DETACH_POWER_OFF flags to be passed
to dev_pm_domain_attach().

Finally, dev_pm_domain_attach() and its users are updated to use the newly
introduced PD_FLAG_ATTACH_POWER_ON and PD_FLAG_DETACH_POWER_OFF macros.

This change is preparatory.

Signed-off-by: default avatarClaudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
Reviewed-by: default avatarMathieu Poirier <mathieu.poirier@linaro.org>
Acked-by: Wolfram Sang <wsa+renesas@sang-engineering.com> # I2C
Reviewed-by: default avatarUlf Hansson <ulf.hansson@linaro.org>
Link: https://patch.msgid.link/20250703112708.1621607-2-claudiu.beznea.uj@bp.renesas.com


[ rjw: Changelog adjustments ]
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent 9047685c
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -138,7 +138,7 @@ static int amba_read_periphid(struct amba_device *dev)
	void __iomem *tmp;
	int i, ret;

	ret = dev_pm_domain_attach(&dev->dev, true);
	ret = dev_pm_domain_attach(&dev->dev, PD_FLAG_ATTACH_POWER_ON);
	if (ret) {
		dev_dbg(&dev->dev, "can't get PM domain: %d\n", ret);
		goto err_out;
@@ -291,7 +291,7 @@ static int amba_probe(struct device *dev)
		if (ret < 0)
			break;

		ret = dev_pm_domain_attach(dev, true);
		ret = dev_pm_domain_attach(dev, PD_FLAG_ATTACH_POWER_ON);
		if (ret)
			break;

+1 −1
Original line number Diff line number Diff line
@@ -217,7 +217,7 @@ static int auxiliary_bus_probe(struct device *dev)
	struct auxiliary_device *auxdev = to_auxiliary_dev(dev);
	int ret;

	ret = dev_pm_domain_attach(dev, true);
	ret = dev_pm_domain_attach(dev, PD_FLAG_ATTACH_POWER_ON);
	if (ret) {
		dev_warn(dev, "Failed to attach to PM Domain : %d\n", ret);
		return ret;
+1 −1
Original line number Diff line number Diff line
@@ -1396,7 +1396,7 @@ static int platform_probe(struct device *_dev)
	if (ret < 0)
		return ret;

	ret = dev_pm_domain_attach(_dev, true);
	ret = dev_pm_domain_attach(_dev, PD_FLAG_ATTACH_POWER_ON);
	if (ret)
		goto out;

+3 −3
Original line number Diff line number Diff line
@@ -83,7 +83,7 @@ EXPORT_SYMBOL_GPL(dev_pm_put_subsys_data);
/**
 * dev_pm_domain_attach - Attach a device to its PM domain.
 * @dev: Device to attach.
 * @power_on: Used to indicate whether we should power on the device.
 * @flags: indicate whether we should power on/off the device on attach/detach
 *
 * The @dev may only be attached to a single PM domain. By iterating through
 * the available alternatives we try to find a valid PM domain for the device.
@@ -100,14 +100,14 @@ EXPORT_SYMBOL_GPL(dev_pm_put_subsys_data);
 * Returns 0 on successfully attached PM domain, or when it is found that the
 * device doesn't need a PM domain, else a negative error code.
 */
int dev_pm_domain_attach(struct device *dev, bool power_on)
int dev_pm_domain_attach(struct device *dev, u32 flags)
{
	int ret;

	if (dev->pm_domain)
		return 0;

	ret = acpi_dev_pm_attach(dev, power_on);
	ret = acpi_dev_pm_attach(dev, !!(flags & PD_FLAG_ATTACH_POWER_ON));
	if (!ret)
		ret = genpd_dev_pm_attach(dev);

+1 −1
Original line number Diff line number Diff line
@@ -111,7 +111,7 @@ static int qcom_apcs_sdx55_clk_probe(struct platform_device *pdev)
	 * driver, there seems to be no better place to do this. So do it here!
	 */
	cpu_dev = get_cpu_device(0);
	ret = dev_pm_domain_attach(cpu_dev, true);
	ret = dev_pm_domain_attach(cpu_dev, PD_FLAG_ATTACH_POWER_ON);
	if (ret) {
		dev_err_probe(dev, ret, "can't get PM domain: %d\n", ret);
		goto err;
Loading