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

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

Merge branches 'pm-domains', 'pm-sleep' and 'pm-tools'

* pm-domains:
  ARM: shmobile: Convert to genpd flags for PM clocks for R-mobile
  ARM: shmobile: Convert to genpd flags for PM clocks for r8a7779
  PM / Domains: Initial PM clock support for genpd
  PM / Domains: Power on the PM domain right after attach completes
  PM / Domains: Move struct pm_domain_data to pm_domain.h
  PM / Domains: Extract code to power off/on a PM domain
  PM / Domains: Make genpd parameter of pm_genpd_present() const

* pm-sleep:
  PM / hibernate: Deletion of an unnecessary check before the function call "vfree"
  PM / Hibernate: Migrate to ktime_t

* pm-tools:
  tools: cpupower: fix return checks for sysfs_get_idlestate_count()
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -83,9 +83,8 @@ static void r8a7779_init_pm_domain(struct r8a7779_pm_domain *r8a7779_pd)
{
	struct generic_pm_domain *genpd = &r8a7779_pd->genpd;

	genpd->flags = GENPD_FLAG_PM_CLK;
	pm_genpd_init(genpd, NULL, false);
	genpd->dev_ops.stop = pm_clk_suspend;
	genpd->dev_ops.start = pm_clk_resume;
	genpd->dev_ops.active_wakeup = pd_active_wakeup;
	genpd->power_off = pd_power_down;
	genpd->power_on = pd_power_up;
+1 −2
Original line number Diff line number Diff line
@@ -106,9 +106,8 @@ static void rmobile_init_pm_domain(struct rmobile_pm_domain *rmobile_pd)
	struct generic_pm_domain *genpd = &rmobile_pd->genpd;
	struct dev_power_governor *gov = rmobile_pd->gov;

	genpd->flags = GENPD_FLAG_PM_CLK;
	pm_genpd_init(genpd, gov ? : &simple_qos_governor, false);
	genpd->dev_ops.stop		= pm_clk_suspend;
	genpd->dev_ops.start		= pm_clk_resume;
	genpd->dev_ops.active_wakeup	= rmobile_pd_active_wakeup;
	genpd->power_off		= rmobile_pd_power_down;
	genpd->power_on			= rmobile_pd_power_up;
+70 −43
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@
#include <linux/pm_runtime.h>
#include <linux/pm_domain.h>
#include <linux/pm_qos.h>
#include <linux/pm_clock.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/sched.h>
@@ -151,6 +152,59 @@ static void genpd_recalc_cpu_exit_latency(struct generic_pm_domain *genpd)
	genpd->cpuidle_data->idle_state->exit_latency = usecs64;
}

static int genpd_power_on(struct generic_pm_domain *genpd)
{
	ktime_t time_start;
	s64 elapsed_ns;
	int ret;

	if (!genpd->power_on)
		return 0;

	time_start = ktime_get();
	ret = genpd->power_on(genpd);
	if (ret)
		return ret;

	elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start));
	if (elapsed_ns <= genpd->power_on_latency_ns)
		return ret;

	genpd->power_on_latency_ns = elapsed_ns;
	genpd->max_off_time_changed = true;
	genpd_recalc_cpu_exit_latency(genpd);
	pr_warn("%s: Power-%s latency exceeded, new value %lld ns\n",
		genpd->name, "on", elapsed_ns);

	return ret;
}

static int genpd_power_off(struct generic_pm_domain *genpd)
{
	ktime_t time_start;
	s64 elapsed_ns;
	int ret;

	if (!genpd->power_off)
		return 0;

	time_start = ktime_get();
	ret = genpd->power_off(genpd);
	if (ret == -EBUSY)
		return ret;

	elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start));
	if (elapsed_ns <= genpd->power_off_latency_ns)
		return ret;

	genpd->power_off_latency_ns = elapsed_ns;
	genpd->max_off_time_changed = true;
	pr_warn("%s: Power-%s latency exceeded, new value %lld ns\n",
		genpd->name, "off", elapsed_ns);

	return ret;
}

/**
 * __pm_genpd_poweron - Restore power to a given PM domain and its masters.
 * @genpd: PM domain to power up.
@@ -222,26 +276,10 @@ static int __pm_genpd_poweron(struct generic_pm_domain *genpd)
		}
	}

	if (genpd->power_on) {
		ktime_t time_start = ktime_get();
		s64 elapsed_ns;

		ret = genpd->power_on(genpd);
	ret = genpd_power_on(genpd);
	if (ret)
		goto err;

		elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start));
		if (elapsed_ns > genpd->power_on_latency_ns) {
			genpd->power_on_latency_ns = elapsed_ns;
			genpd->max_off_time_changed = true;
			genpd_recalc_cpu_exit_latency(genpd);
			if (genpd->name)
				pr_warning("%s: Power-on latency exceeded, "
					"new value %lld ns\n", genpd->name,
					elapsed_ns);
		}
	}

 out:
	genpd_set_active(genpd);

@@ -544,16 +582,11 @@ static int pm_genpd_poweroff(struct generic_pm_domain *genpd)
	}

	if (genpd->power_off) {
		ktime_t time_start;
		s64 elapsed_ns;

		if (atomic_read(&genpd->sd_count) > 0) {
			ret = -EBUSY;
			goto out;
		}

		time_start = ktime_get();

		/*
		 * If sd_count > 0 at this point, one of the subdomains hasn't
		 * managed to call pm_genpd_poweron() for the master yet after
@@ -562,21 +595,11 @@ static int pm_genpd_poweroff(struct generic_pm_domain *genpd)
		 * the pm_genpd_poweron() restore power for us (this shouldn't
		 * happen very often).
		 */
		ret = genpd->power_off(genpd);
		ret = genpd_power_off(genpd);
		if (ret == -EBUSY) {
			genpd_set_active(genpd);
			goto out;
		}

		elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start));
		if (elapsed_ns > genpd->power_off_latency_ns) {
			genpd->power_off_latency_ns = elapsed_ns;
			genpd->max_off_time_changed = true;
			if (genpd->name)
				pr_warning("%s: Power-off latency exceeded, "
					"new value %lld ns\n", genpd->name,
					elapsed_ns);
		}
	}

	genpd->status = GPD_STATE_POWER_OFF;
@@ -779,9 +802,9 @@ static inline void genpd_power_off_work_fn(struct work_struct *work) {}
 * pm_genpd_present - Check if the given PM domain has been initialized.
 * @genpd: PM domain to check.
 */
static bool pm_genpd_present(struct generic_pm_domain *genpd)
static bool pm_genpd_present(const struct generic_pm_domain *genpd)
{
	struct generic_pm_domain *gpd;
	const struct generic_pm_domain *gpd;

	if (IS_ERR_OR_NULL(genpd))
		return false;
@@ -822,8 +845,7 @@ static void pm_genpd_sync_poweroff(struct generic_pm_domain *genpd)
	    || atomic_read(&genpd->sd_count) > 0)
		return;

	if (genpd->power_off)
		genpd->power_off(genpd);
	genpd_power_off(genpd);

	genpd->status = GPD_STATE_POWER_OFF;

@@ -854,8 +876,7 @@ static void pm_genpd_sync_poweron(struct generic_pm_domain *genpd)
		genpd_sd_counter_inc(link->master);
	}

	if (genpd->power_on)
		genpd->power_on(genpd);
	genpd_power_on(genpd);

	genpd->status = GPD_STATE_ACTIVE;
}
@@ -1277,8 +1298,7 @@ static int pm_genpd_restore_noirq(struct device *dev)
			 * If the domain was off before the hibernation, make
			 * sure it will be off going forward.
			 */
			if (genpd->power_off)
				genpd->power_off(genpd);
			genpd_power_off(genpd);

			return 0;
		}
@@ -1929,6 +1949,12 @@ void pm_genpd_init(struct generic_pm_domain *genpd,
	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;
		genpd->dev_ops.start = pm_clk_resume;
	}

	mutex_lock(&gpd_list_lock);
	list_add(&genpd->gpd_list_node, &gpd_list);
	mutex_unlock(&gpd_list_lock);
@@ -2216,6 +2242,7 @@ int genpd_dev_pm_attach(struct device *dev)
	}

	dev->pm_domain->detach = genpd_dev_pm_detach;
	pm_genpd_poweron(pd);

	return 0;
}
+1 −5
Original line number Diff line number Diff line
@@ -538,11 +538,7 @@ enum rpm_request {
};

struct wakeup_source;

struct pm_domain_data {
	struct list_head list_node;
	struct device *dev;
};
struct pm_domain_data;

struct pm_subsys_data {
	spinlock_t lock;
+9 −0
Original line number Diff line number Diff line
@@ -17,6 +17,9 @@
#include <linux/notifier.h>
#include <linux/cpuidle.h>

/* Defines used for the flags field in the struct generic_pm_domain */
#define GENPD_FLAG_PM_CLK	(1U << 0) /* PM domain uses PM clk */

enum gpd_status {
	GPD_STATE_ACTIVE = 0,	/* PM domain is active */
	GPD_STATE_WAIT_MASTER,	/* PM domain's master is being waited for */
@@ -76,6 +79,7 @@ struct generic_pm_domain {
			  struct device *dev);
	void (*detach_dev)(struct generic_pm_domain *domain,
			   struct device *dev);
	unsigned int flags;		/* Bit field of configs for genpd */
};

static inline struct generic_pm_domain *pd_to_genpd(struct dev_pm_domain *pd)
@@ -100,6 +104,11 @@ struct gpd_timing_data {
	bool cached_stop_ok;
};

struct pm_domain_data {
	struct list_head list_node;
	struct device *dev;
};

struct generic_pm_domain_data {
	struct pm_domain_data base;
	struct gpd_timing_data td;
Loading