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

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

Merge branches 'pm-core' and 'pm-domains'

* pm-core:
  PM / sleep: Drop unused `info' variable
  PM / Runtime: Move ignore_children flag under CONFIG_PM
  PM / Runtime: Fix error path in pm_runtime_force_resume()

* pm-domains:
  PM / Domains: Drop unnecessary wakeup code from pm_genpd_prepare()
  PM / Domains: Remove redundant pm_runtime_get|put*() in pm_genpd_prepare()
  PM / Domains: Remove ->save|restore_state() callbacks
  PM / Domains: Rename pm_genpd_runtime_suspend|resume()
  PM / Domains: Rename stop_ok to suspend_ok for the genpd governor
Loading
Loading
Loading
Loading
+59 −86
Original line number Diff line number Diff line
@@ -229,17 +229,6 @@ static int genpd_poweron(struct generic_pm_domain *genpd, unsigned int depth)
	return ret;
}

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

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

static int genpd_dev_pm_qos_notifier(struct notifier_block *nb,
				     unsigned long val, void *ptr)
{
@@ -372,17 +361,63 @@ static void genpd_power_off_work_fn(struct work_struct *work)
}

/**
 * pm_genpd_runtime_suspend - Suspend a device belonging to I/O PM domain.
 * __genpd_runtime_suspend - walk the hierarchy of ->runtime_suspend() callbacks
 * @dev: Device to handle.
 */
static int __genpd_runtime_suspend(struct device *dev)
{
	int (*cb)(struct device *__dev);

	if (dev->type && dev->type->pm)
		cb = dev->type->pm->runtime_suspend;
	else if (dev->class && dev->class->pm)
		cb = dev->class->pm->runtime_suspend;
	else if (dev->bus && dev->bus->pm)
		cb = dev->bus->pm->runtime_suspend;
	else
		cb = NULL;

	if (!cb && dev->driver && dev->driver->pm)
		cb = dev->driver->pm->runtime_suspend;

	return cb ? cb(dev) : 0;
}

/**
 * __genpd_runtime_resume - walk the hierarchy of ->runtime_resume() callbacks
 * @dev: Device to handle.
 */
static int __genpd_runtime_resume(struct device *dev)
{
	int (*cb)(struct device *__dev);

	if (dev->type && dev->type->pm)
		cb = dev->type->pm->runtime_resume;
	else if (dev->class && dev->class->pm)
		cb = dev->class->pm->runtime_resume;
	else if (dev->bus && dev->bus->pm)
		cb = dev->bus->pm->runtime_resume;
	else
		cb = NULL;

	if (!cb && dev->driver && dev->driver->pm)
		cb = dev->driver->pm->runtime_resume;

	return cb ? cb(dev) : 0;
}

/**
 * genpd_runtime_suspend - Suspend a device belonging to I/O PM domain.
 * @dev: Device to suspend.
 *
 * Carry out a runtime suspend of a device under the assumption that its
 * pm_domain field points to the domain member of an object of type
 * struct generic_pm_domain representing a PM domain consisting of I/O devices.
 */
static int pm_genpd_runtime_suspend(struct device *dev)
static int genpd_runtime_suspend(struct device *dev)
{
	struct generic_pm_domain *genpd;
	bool (*stop_ok)(struct device *__dev);
	bool (*suspend_ok)(struct device *__dev);
	struct gpd_timing_data *td = &dev_gpd_data(dev)->td;
	bool runtime_pm = pm_runtime_enabled(dev);
	ktime_t time_start;
@@ -401,21 +436,21 @@ static int pm_genpd_runtime_suspend(struct device *dev)
	 * runtime PM is disabled. Under these circumstances, we shall skip
	 * validating/measuring the PM QoS latency.
	 */
	stop_ok = genpd->gov ? genpd->gov->stop_ok : NULL;
	if (runtime_pm && stop_ok && !stop_ok(dev))
	suspend_ok = genpd->gov ? genpd->gov->suspend_ok : NULL;
	if (runtime_pm && suspend_ok && !suspend_ok(dev))
		return -EBUSY;

	/* Measure suspend latency. */
	if (runtime_pm)
		time_start = ktime_get();

	ret = genpd_save_dev(genpd, dev);
	ret = __genpd_runtime_suspend(dev);
	if (ret)
		return ret;

	ret = genpd_stop_dev(genpd, dev);
	if (ret) {
		genpd_restore_dev(genpd, dev);
		__genpd_runtime_resume(dev);
		return ret;
	}

@@ -446,14 +481,14 @@ static int pm_genpd_runtime_suspend(struct device *dev)
}

/**
 * pm_genpd_runtime_resume - Resume a device belonging to I/O PM domain.
 * genpd_runtime_resume - Resume a device belonging to I/O PM domain.
 * @dev: Device to resume.
 *
 * Carry out a runtime resume of a device under the assumption that its
 * pm_domain field points to the domain member of an object of type
 * struct generic_pm_domain representing a PM domain consisting of I/O devices.
 */
static int pm_genpd_runtime_resume(struct device *dev)
static int genpd_runtime_resume(struct device *dev)
{
	struct generic_pm_domain *genpd;
	struct gpd_timing_data *td = &dev_gpd_data(dev)->td;
@@ -491,7 +526,7 @@ static int pm_genpd_runtime_resume(struct device *dev)
	if (ret)
		goto err_poweroff;

	ret = genpd_restore_dev(genpd, dev);
	ret = __genpd_runtime_resume(dev);
	if (ret)
		goto err_stop;

@@ -695,15 +730,6 @@ static int pm_genpd_prepare(struct device *dev)
	 * at this point and a system wakeup event should be reported if it's
	 * set up to wake up the system from sleep states.
	 */
	pm_runtime_get_noresume(dev);
	if (pm_runtime_barrier(dev) && device_may_wakeup(dev))
		pm_wakeup_event(dev, 0);

	if (pm_wakeup_pending()) {
		pm_runtime_put(dev);
		return -EBUSY;
	}

	if (resume_needed(dev, genpd))
		pm_runtime_resume(dev);

@@ -716,10 +742,8 @@ static int pm_genpd_prepare(struct device *dev)

	mutex_unlock(&genpd->lock);

	if (genpd->suspend_power_off) {
		pm_runtime_put_noidle(dev);
	if (genpd->suspend_power_off)
		return 0;
	}

	/*
	 * The PM domain must be in the GPD_STATE_ACTIVE state at this point,
@@ -741,7 +765,6 @@ static int pm_genpd_prepare(struct device *dev)
		pm_runtime_enable(dev);
	}

	pm_runtime_put(dev);
	return ret;
}

@@ -1427,54 +1450,6 @@ int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
}
EXPORT_SYMBOL_GPL(pm_genpd_remove_subdomain);

/* Default device callbacks for generic PM domains. */

/**
 * pm_genpd_default_save_state - Default "save device state" for PM domains.
 * @dev: Device to handle.
 */
static int pm_genpd_default_save_state(struct device *dev)
{
	int (*cb)(struct device *__dev);

	if (dev->type && dev->type->pm)
		cb = dev->type->pm->runtime_suspend;
	else if (dev->class && dev->class->pm)
		cb = dev->class->pm->runtime_suspend;
	else if (dev->bus && dev->bus->pm)
		cb = dev->bus->pm->runtime_suspend;
	else
		cb = NULL;

	if (!cb && dev->driver && dev->driver->pm)
		cb = dev->driver->pm->runtime_suspend;

	return cb ? cb(dev) : 0;
}

/**
 * pm_genpd_default_restore_state - Default PM domains "restore device state".
 * @dev: Device to handle.
 */
static int pm_genpd_default_restore_state(struct device *dev)
{
	int (*cb)(struct device *__dev);

	if (dev->type && dev->type->pm)
		cb = dev->type->pm->runtime_resume;
	else if (dev->class && dev->class->pm)
		cb = dev->class->pm->runtime_resume;
	else if (dev->bus && dev->bus->pm)
		cb = dev->bus->pm->runtime_resume;
	else
		cb = NULL;

	if (!cb && dev->driver && dev->driver->pm)
		cb = dev->driver->pm->runtime_resume;

	return cb ? cb(dev) : 0;
}

/**
 * pm_genpd_init - Initialize a generic I/O PM domain object.
 * @genpd: PM domain object to initialize.
@@ -1498,8 +1473,8 @@ void pm_genpd_init(struct generic_pm_domain *genpd,
	genpd->device_count = 0;
	genpd->max_off_time_ns = -1;
	genpd->max_off_time_changed = true;
	genpd->domain.ops.runtime_suspend = pm_genpd_runtime_suspend;
	genpd->domain.ops.runtime_resume = pm_genpd_runtime_resume;
	genpd->domain.ops.runtime_suspend = genpd_runtime_suspend;
	genpd->domain.ops.runtime_resume = genpd_runtime_resume;
	genpd->domain.ops.prepare = pm_genpd_prepare;
	genpd->domain.ops.suspend = pm_genpd_suspend;
	genpd->domain.ops.suspend_late = pm_genpd_suspend_late;
@@ -1520,8 +1495,6 @@ void pm_genpd_init(struct generic_pm_domain *genpd,
	genpd->domain.ops.restore_early = pm_genpd_resume_early;
	genpd->domain.ops.restore = pm_genpd_resume;
	genpd->domain.ops.complete = pm_genpd_complete;
	genpd->dev_ops.save_state = pm_genpd_default_save_state;
	genpd->dev_ops.restore_state = pm_genpd_default_restore_state;

	if (genpd->flags & GENPD_FLAG_PM_CLK) {
		genpd->dev_ops.stop = pm_clk_suspend;
+10 −10
Original line number Diff line number Diff line
@@ -37,10 +37,10 @@ static int dev_update_qos_constraint(struct device *dev, void *data)
}

/**
 * default_stop_ok - Default PM domain governor routine for stopping devices.
 * default_suspend_ok - Default PM domain governor routine to suspend devices.
 * @dev: Device to check.
 */
static bool default_stop_ok(struct device *dev)
static bool default_suspend_ok(struct device *dev)
{
	struct gpd_timing_data *td = &dev_gpd_data(dev)->td;
	unsigned long flags;
@@ -51,13 +51,13 @@ static bool default_stop_ok(struct device *dev)
	spin_lock_irqsave(&dev->power.lock, flags);

	if (!td->constraint_changed) {
		bool ret = td->cached_stop_ok;
		bool ret = td->cached_suspend_ok;

		spin_unlock_irqrestore(&dev->power.lock, flags);
		return ret;
	}
	td->constraint_changed = false;
	td->cached_stop_ok = false;
	td->cached_suspend_ok = false;
	td->effective_constraint_ns = -1;
	constraint_ns = __dev_pm_qos_read_value(dev);

@@ -83,13 +83,13 @@ static bool default_stop_ok(struct device *dev)
			return false;
	}
	td->effective_constraint_ns = constraint_ns;
	td->cached_stop_ok = constraint_ns >= 0;
	td->cached_suspend_ok = constraint_ns >= 0;

	/*
	 * The children have been suspended already, so we don't need to take
	 * their stop latencies into account here.
	 * their suspend latencies into account here.
	 */
	return td->cached_stop_ok;
	return td->cached_suspend_ok;
}

/**
@@ -150,7 +150,7 @@ static bool __default_power_down_ok(struct dev_pm_domain *pd,
		 */
		td = &to_gpd_data(pdd)->td;
		constraint_ns = td->effective_constraint_ns;
		/* default_stop_ok() need not be called before us. */
		/* default_suspend_ok() need not be called before us. */
		if (constraint_ns < 0) {
			constraint_ns = dev_pm_qos_read_value(pdd->dev);
			constraint_ns *= NSEC_PER_USEC;
@@ -227,7 +227,7 @@ static bool always_on_power_down_ok(struct dev_pm_domain *domain)
}

struct dev_power_governor simple_qos_governor = {
	.stop_ok = default_stop_ok,
	.suspend_ok = default_suspend_ok,
	.power_down_ok = default_power_down_ok,
};

@@ -236,5 +236,5 @@ struct dev_power_governor simple_qos_governor = {
 */
struct dev_power_governor pm_domain_always_on_gov = {
	.power_down_ok = always_on_power_down_ok,
	.stop_ok = default_stop_ok,
	.suspend_ok = default_suspend_ok,
};
+5 −13
Original line number Diff line number Diff line
@@ -1556,7 +1556,6 @@ int dpm_suspend(pm_message_t state)
static int device_prepare(struct device *dev, pm_message_t state)
{
	int (*callback)(struct device *) = NULL;
	char *info = NULL;
	int ret = 0;

	if (dev->power.syscore)
@@ -1579,24 +1578,17 @@ static int device_prepare(struct device *dev, pm_message_t state)
		goto unlock;
	}

	if (dev->pm_domain) {
		info = "preparing power domain ";
	if (dev->pm_domain)
		callback = dev->pm_domain->ops.prepare;
	} else if (dev->type && dev->type->pm) {
		info = "preparing type ";
	else if (dev->type && dev->type->pm)
		callback = dev->type->pm->prepare;
	} else if (dev->class && dev->class->pm) {
		info = "preparing class ";
	else if (dev->class && dev->class->pm)
		callback = dev->class->pm->prepare;
	} else if (dev->bus && dev->bus->pm) {
		info = "preparing bus ";
	else if (dev->bus && dev->bus->pm)
		callback = dev->bus->pm->prepare;
	}

	if (!callback && dev->driver && dev->driver->pm) {
		info = "preparing driver ";
	if (!callback && dev->driver && dev->driver->pm)
		callback = dev->driver->pm->prepare;
	}

	if (callback)
		ret = callback(dev);
+7 −2
Original line number Diff line number Diff line
@@ -1506,11 +1506,16 @@ int pm_runtime_force_resume(struct device *dev)
		goto out;
	}

	ret = callback(dev);
	ret = pm_runtime_set_active(dev);
	if (ret)
		goto out;

	pm_runtime_set_active(dev);
	ret = callback(dev);
	if (ret) {
		pm_runtime_set_suspended(dev);
		goto out;
	}

	pm_runtime_mark_last_busy(dev);
out:
	pm_runtime_enable(dev);
+1 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/pm.h>
#include <linux/pm_runtime.h>
#include <linux/mmc/host.h>
#include <linux/mmc/mmc.h>

Loading