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

Commit e2e3e4e5 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki
Browse files

PM / Domains: Do not measure start time for "irq safe" devices



The genpd_start_dev() routine used by pm_genpd_runtime_resume()
to put "irq safe" devices into the full power state measures the
time necessary to "start" the device and updates its PM QoS timing
data if necessary.  This may lead to a deadlock if the given device
is a clock source and genpd_start_dev() is invoked from within the
clock source's .enable() routine, which will happen if that routine
uses pm_runtime_get_sync(), for example, to ensure that the device
is operational.

For this reason, introduce a special routine analogous to
genpd_start_dev(), called genpd_start_dev_no_timing(), that doesn't
carry out the time measurement, and make pm_genpd_runtime_resume()
use it instead of genpd_start_dev() to power up "irq safe" devices.

Signed-off-by: default avatarRafael J. Wysocki <rjw@sisk.pl>
parent dbf37414
Loading
Loading
Loading
Loading
+7 −1
Original line number Original line Diff line number Diff line
@@ -75,6 +75,12 @@ static int genpd_start_dev(struct generic_pm_domain *genpd, struct device *dev)
					start_latency_ns, "start");
					start_latency_ns, "start");
}
}


static int genpd_start_dev_no_timing(struct generic_pm_domain *genpd,
				     struct device *dev)
{
	return GENPD_DEV_CALLBACK(genpd, int, start, dev);
}

static bool genpd_sd_counter_dec(struct generic_pm_domain *genpd)
static bool genpd_sd_counter_dec(struct generic_pm_domain *genpd)
{
{
	bool ret = false;
	bool ret = false;
@@ -626,7 +632,7 @@ static int pm_genpd_runtime_resume(struct device *dev)


	/* If power.irq_safe, the PM domain is never powered off. */
	/* If power.irq_safe, the PM domain is never powered off. */
	if (dev->power.irq_safe)
	if (dev->power.irq_safe)
		return genpd_start_dev(genpd, dev);
		return genpd_start_dev_no_timing(genpd, dev);


	mutex_lock(&genpd->lock);
	mutex_lock(&genpd->lock);
	ret = __pm_genpd_poweron(genpd);
	ret = __pm_genpd_poweron(genpd);