linux-pm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH V4 0/6] cpufreq: suspend early/resume late: dpm_{suspend|resume}()
@ 2013-12-02  5:52 Viresh Kumar
       [not found] ` <cover.1385962528.git.viresh.kumar-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Viresh Kumar @ 2013-12-02  5:52 UTC (permalink / raw)
  To: rjw-LthD3rsA81gm4RdzfppkhA
  Cc: linaro-kernel-cunTk1MwBs8s++Sfvej+rw,
	patches-QSEj5FYQhm4dnm+yROfE0A, cpufreq-u79uwXL29TY76Z2rM5mHXA,
	linux-pm-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, nm-l0cyMroinI0,
	swarren-3lzwWm7+Weoh9ZMKESR00Q, kgene.kim-Sze3O3UU22JBDgjK7y7TUQ,
	linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	tianyu.lan-ral2JQCrhuEAvxtiuMwx3w,
	jhbird.choi-Sze3O3UU22JBDgjK7y7TUQ, Viresh Kumar

This patchset moves cpufreq callbacks to dpm_{suspend|resume}() from
dpm_{suspend|resume}_noirq() for handling suspend/resume of cpufreq governors
and core. This is required for early suspend and late resume of governors as
there are drivers which want to change cpu frequency before suspending governors
and they want to do it before devices get suspended, as some of them might be
required to change frequency.

Following patch is already pushed for v3.13 as it was required for fixing some
bugs in there. And the remaining was decided to be pushed for v3.14.

commit 5a87182aa21d6d5d306840feab9321818dd3e2a3
Author: Viresh Kumar <viresh.kumar-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Date:   Wed Nov 27 09:09:42 2013 +0530

    cpufreq: suspend governors on system suspend/hibernate

This is already tested by few people and so incorporating their Tested-by as
well.

For: v3.14.

Viresh Kumar (6):
  cpufreq: suspend governors from dpm_{suspend|resume}()
  cpufreq: call driver's suspend/resume for each policy
  cpufreq: Implement cpufreq_generic_suspend()
  cpufreq: exynos: Use cpufreq_generic_suspend()
  cpufreq: s5pv210: Use cpufreq_generic_suspend()
  cpufreq: Tegra: Use cpufreq_generic_suspend()

 drivers/base/power/main.c         |   6 +-
 drivers/cpufreq/cpufreq.c         | 137 ++++++++++++++++----------------------
 drivers/cpufreq/exynos-cpufreq.c  |  96 ++------------------------
 drivers/cpufreq/s5pv210-cpufreq.c |  49 +-------------
 drivers/cpufreq/tegra-cpufreq.c   |  46 ++-----------
 include/linux/cpufreq.h           |   3 +
 6 files changed, 79 insertions(+), 258 deletions(-)

-- 
1.7.12.rc2.18.g61b472e

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH V4 1/6] cpufreq: suspend governors from dpm_{suspend|resume}()
       [not found] ` <cover.1385962528.git.viresh.kumar-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
@ 2013-12-02  5:52   ` Viresh Kumar
  2013-12-02  5:52   ` [PATCH V4 4/6] cpufreq: exynos: Use cpufreq_generic_suspend() Viresh Kumar
  2013-12-02  5:52   ` [PATCH V4 6/6] cpufreq: Tegra: " Viresh Kumar
  2 siblings, 0 replies; 7+ messages in thread
From: Viresh Kumar @ 2013-12-02  5:52 UTC (permalink / raw)
  To: rjw-LthD3rsA81gm4RdzfppkhA
  Cc: linaro-kernel-cunTk1MwBs8s++Sfvej+rw,
	patches-QSEj5FYQhm4dnm+yROfE0A, cpufreq-u79uwXL29TY76Z2rM5mHXA,
	linux-pm-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, nm-l0cyMroinI0,
	swarren-3lzwWm7+Weoh9ZMKESR00Q, kgene.kim-Sze3O3UU22JBDgjK7y7TUQ,
	linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	tianyu.lan-ral2JQCrhuEAvxtiuMwx3w,
	jhbird.choi-Sze3O3UU22JBDgjK7y7TUQ, Viresh Kumar

Recently support for suspending governors has been added in cpufreq and
callbacks are called from dpm_{suspend|resume}_noirq(). The problem here is that
most of the devices (i.e. devices with ->suspend() callbacks) have already been
suspended by now and so if drivers want to change frequency before suspending,
then it might not be possible for many platforms (which depend on other
peripherals like i2c, regulators, etc).

So, we actually need to do this from dpm_{suspend|resume}() instead. This patch
does it.

Tested-by: Lan Tianyu <tianyu.lan-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Tested-by: Nishanth Menon <nm-l0cyMroinI0@public.gmane.org>
Tested-by: Stephen Warren <swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Viresh Kumar <viresh.kumar-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
 drivers/base/power/main.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index e3219df..c9fbb9d 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -541,7 +541,6 @@ static void dpm_resume_noirq(pm_message_t state)
 	dpm_show_time(starttime, state, "noirq");
 	resume_device_irqs();
 	cpuidle_resume();
-	cpufreq_resume();
 }
 
 /**
@@ -791,6 +790,8 @@ void dpm_resume(pm_message_t state)
 	mutex_unlock(&dpm_list_mtx);
 	async_synchronize_full();
 	dpm_show_time(starttime, state, NULL);
+
+	cpufreq_resume();
 }
 
 /**
@@ -957,7 +958,6 @@ static int dpm_suspend_noirq(pm_message_t state)
 	ktime_t starttime = ktime_get();
 	int error = 0;
 
-	cpufreq_suspend();
 	cpuidle_pause();
 	suspend_device_irqs();
 	mutex_lock(&dpm_list_mtx);
@@ -1262,6 +1262,8 @@ int dpm_suspend(pm_message_t state)
 
 	might_sleep();
 
+	cpufreq_suspend();
+
 	mutex_lock(&dpm_list_mtx);
 	pm_transition = state;
 	async_error = 0;
-- 
1.7.12.rc2.18.g61b472e

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH V4 2/6] cpufreq: call driver's suspend/resume for each policy
  2013-12-02  5:52 [PATCH V4 0/6] cpufreq: suspend early/resume late: dpm_{suspend|resume}() Viresh Kumar
       [not found] ` <cover.1385962528.git.viresh.kumar-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
@ 2013-12-02  5:52 ` Viresh Kumar
  2013-12-02  5:52 ` [PATCH V4 3/6] cpufreq: Implement cpufreq_generic_suspend() Viresh Kumar
  2013-12-02  5:52 ` [PATCH V4 5/6] cpufreq: s5pv210: Use cpufreq_generic_suspend() Viresh Kumar
  3 siblings, 0 replies; 7+ messages in thread
From: Viresh Kumar @ 2013-12-02  5:52 UTC (permalink / raw)
  To: rjw
  Cc: linaro-kernel, patches, cpufreq, linux-pm, linux-kernel, nm,
	swarren, kgene.kim, linux-samsung-soc, linux-tegra, tianyu.lan,
	jhbird.choi, Viresh Kumar

Earlier cpufreq suspend/resume callbacks into drivers were getting called only
for the boot CPU, as by the time callbacks were called non-boot CPUs were
already removed. Because we might still need driver specific actions on
suspend/resume, its better to use earlier infrastructure from the early
suspend/late resume calls.

In effect, we call suspend/resume for each policy. The resume part also takes
care of synchronising frequency for boot CPU, which might turn out be different
than what cpufreq core believes.

Hence, the earlier syscore infrastructure is getting removed now.

Tested-by: Lan Tianyu <tianyu.lan@intel.com>
Tested-by: Nishanth Menon <nm@ti.com>
Tested-by: Stephen Warren <swarren@nvidia.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 drivers/cpufreq/cpufreq.c | 112 +++++++++++++---------------------------------
 1 file changed, 32 insertions(+), 80 deletions(-)

diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index a7fcb84..443c053 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -27,7 +27,6 @@
 #include <linux/mutex.h>
 #include <linux/slab.h>
 #include <linux/suspend.h>
-#include <linux/syscore_ops.h>
 #include <linux/tick.h>
 #include <trace/events/power.h>
 
@@ -1531,6 +1530,14 @@ static struct subsys_interface cpufreq_interface = {
 	.remove_dev	= cpufreq_remove_dev,
 };
 
+/**
+ * cpufreq_suspend() - Suspend CPUFreq governors
+ *
+ * Called during system wide Suspend/Hibernate cycles for suspending governors
+ * as some platforms can't change frequency after this point in suspend cycle.
+ * Because some of the devices (like: i2c, regulators, etc) they use for
+ * changing frequency are suspended quickly after this point.
+ */
 void cpufreq_suspend(void)
 {
 	struct cpufreq_policy *policy;
@@ -1540,14 +1547,25 @@ void cpufreq_suspend(void)
 
 	pr_debug("%s: Suspending Governors\n", __func__);
 
-	list_for_each_entry(policy, &cpufreq_policy_list, policy_list)
+	list_for_each_entry(policy, &cpufreq_policy_list, policy_list) {
 		if (__cpufreq_governor(policy, CPUFREQ_GOV_STOP))
 			pr_err("%s: Failed to stop governor for policy: %p\n",
 				__func__, policy);
+		else if (cpufreq_driver->suspend
+		    && cpufreq_driver->suspend(policy))
+			pr_err("%s: Failed to suspend driver: %p\n", __func__,
+				policy);
+	}
 
 	cpufreq_suspended = true;
 }
 
+/**
+ * cpufreq_resume() - Resume CPUFreq governors
+ *
+ * Called during system wide Suspend/Hibernate cycle for resuming governors that
+ * are suspended with cpufreq_suspend().
+ */
 void cpufreq_resume(void)
 {
 	struct cpufreq_policy *policy;
@@ -1559,91 +1577,26 @@ void cpufreq_resume(void)
 
 	cpufreq_suspended = false;
 
-	list_for_each_entry(policy, &cpufreq_policy_list, policy_list)
+	list_for_each_entry(policy, &cpufreq_policy_list, policy_list) {
 		if (__cpufreq_governor(policy, CPUFREQ_GOV_START)
 		    || __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS))
 			pr_err("%s: Failed to start governor for policy: %p\n",
 				__func__, policy);
-}
-
-/**
- * cpufreq_bp_suspend - Prepare the boot CPU for system suspend.
- *
- * This function is only executed for the boot processor.  The other CPUs
- * have been put offline by means of CPU hotplug.
- */
-static int cpufreq_bp_suspend(void)
-{
-	int ret = 0;
-
-	int cpu = smp_processor_id();
-	struct cpufreq_policy *policy;
-
-	pr_debug("suspending cpu %u\n", cpu);
-
-	/* If there's no policy for the boot CPU, we have nothing to do. */
-	policy = cpufreq_cpu_get(cpu);
-	if (!policy)
-		return 0;
-
-	if (cpufreq_driver->suspend) {
-		ret = cpufreq_driver->suspend(policy);
-		if (ret)
-			printk(KERN_ERR "cpufreq: suspend failed in ->suspend "
-					"step on CPU %u\n", policy->cpu);
-	}
-
-	cpufreq_cpu_put(policy);
-	return ret;
-}
-
-/**
- * cpufreq_bp_resume - Restore proper frequency handling of the boot CPU.
- *
- *	1.) resume CPUfreq hardware support (cpufreq_driver->resume())
- *	2.) schedule call cpufreq_update_policy() ASAP as interrupts are
- *	    restored. It will verify that the current freq is in sync with
- *	    what we believe it to be. This is a bit later than when it
- *	    should be, but nonethteless it's better than calling
- *	    cpufreq_driver->get() here which might re-enable interrupts...
- *
- * This function is only executed for the boot CPU.  The other CPUs have not
- * been turned on yet.
- */
-static void cpufreq_bp_resume(void)
-{
-	int ret = 0;
-
-	int cpu = smp_processor_id();
-	struct cpufreq_policy *policy;
-
-	pr_debug("resuming cpu %u\n", cpu);
-
-	/* If there's no policy for the boot CPU, we have nothing to do. */
-	policy = cpufreq_cpu_get(cpu);
-	if (!policy)
-		return;
+		else if (cpufreq_driver->resume
+		    && cpufreq_driver->resume(policy))
+			pr_err("%s: Failed to resume driver: %p\n", __func__,
+				policy);
 
-	if (cpufreq_driver->resume) {
-		ret = cpufreq_driver->resume(policy);
-		if (ret) {
-			printk(KERN_ERR "cpufreq: resume failed in ->resume "
-					"step on CPU %u\n", policy->cpu);
-			goto fail;
-		}
+		/*
+		 * schedule call cpufreq_update_policy() for boot CPU, i.e. last
+		 * policy in list. It will verify that the current freq is in
+		 * sync with what we believe it to be.
+		 */
+		if (list_is_last(&policy->policy_list, &cpufreq_policy_list))
+			schedule_work(&policy->update);
 	}
-
-	schedule_work(&policy->update);
-
-fail:
-	cpufreq_cpu_put(policy);
 }
 
-static struct syscore_ops cpufreq_syscore_ops = {
-	.suspend	= cpufreq_bp_suspend,
-	.resume		= cpufreq_bp_resume,
-};
-
 /**
  *	cpufreq_get_current_driver - return current driver's name
  *
@@ -2320,7 +2273,6 @@ static int __init cpufreq_core_init(void)
 
 	cpufreq_global_kobject = kobject_create();
 	BUG_ON(!cpufreq_global_kobject);
-	register_syscore_ops(&cpufreq_syscore_ops);
 
 	return 0;
 }
-- 
1.7.12.rc2.18.g61b472e

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH V4 3/6] cpufreq: Implement cpufreq_generic_suspend()
  2013-12-02  5:52 [PATCH V4 0/6] cpufreq: suspend early/resume late: dpm_{suspend|resume}() Viresh Kumar
       [not found] ` <cover.1385962528.git.viresh.kumar-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
  2013-12-02  5:52 ` [PATCH V4 2/6] cpufreq: call driver's suspend/resume for each policy Viresh Kumar
@ 2013-12-02  5:52 ` Viresh Kumar
  2013-12-02  5:52 ` [PATCH V4 5/6] cpufreq: s5pv210: Use cpufreq_generic_suspend() Viresh Kumar
  3 siblings, 0 replies; 7+ messages in thread
From: Viresh Kumar @ 2013-12-02  5:52 UTC (permalink / raw)
  To: rjw
  Cc: linaro-kernel, patches, cpufreq, linux-pm, linux-kernel, nm,
	swarren, kgene.kim, linux-samsung-soc, linux-tegra, tianyu.lan,
	jhbird.choi, Viresh Kumar

Multiple platforms need to set CPU to a particular frequency before suspending
system. And so they need a common infrastructure which is provided by this
patch. Those platforms just need to initialize their ->suspend() pointers with
the generic routine.

Tested-by: Stephen Warren <swarren@nvidia.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 drivers/cpufreq/cpufreq.c | 25 +++++++++++++++++++++++++
 include/linux/cpufreq.h   |  3 +++
 2 files changed, 28 insertions(+)

diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 443c053..ae4923e 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -1530,6 +1530,31 @@ static struct subsys_interface cpufreq_interface = {
 	.remove_dev	= cpufreq_remove_dev,
 };
 
+/*
+ * In case platform wants some specific frequency to be configured
+ * during suspend..
+ */
+int cpufreq_generic_suspend(struct cpufreq_policy *policy)
+{
+	int ret;
+
+	if (!policy->suspend_freq) {
+		pr_err("%s: suspend_freq can't be zero\n", __func__);
+		return -EINVAL;
+	}
+
+	pr_debug("%s: Setting suspend-freq: %u\n", __func__,
+			policy->suspend_freq);
+
+	ret = __cpufreq_driver_target(policy, policy->suspend_freq,
+			CPUFREQ_RELATION_H);
+	if (ret)
+		pr_err("%s: unable to set suspend-freq: %u. err: %d\n",
+				__func__, policy->suspend_freq, ret);
+
+	return ret;
+}
+
 /**
  * cpufreq_suspend() - Suspend CPUFreq governors
  *
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index b26bfab..ce6f06f 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -74,6 +74,8 @@ struct cpufreq_policy {
 	unsigned int		max;    /* in kHz */
 	unsigned int		cur;    /* in kHz, only needed if cpufreq
 					 * governors are used */
+	unsigned int		suspend_freq; /* freq to set during suspend */
+
 	unsigned int		policy; /* see above */
 	struct cpufreq_governor	*governor; /* see below */
 	void			*governor_data;
@@ -285,6 +287,7 @@ cpufreq_verify_within_cpu_limits(struct cpufreq_policy *policy)
 #ifdef CONFIG_CPU_FREQ
 void cpufreq_suspend(void);
 void cpufreq_resume(void);
+int cpufreq_generic_suspend(struct cpufreq_policy *policy);
 #else
 static inline void cpufreq_suspend(void) {}
 static inline void cpufreq_resume(void) {}
-- 
1.7.12.rc2.18.g61b472e


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH V4 4/6] cpufreq: exynos: Use cpufreq_generic_suspend()
       [not found] ` <cover.1385962528.git.viresh.kumar-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
  2013-12-02  5:52   ` [PATCH V4 1/6] cpufreq: suspend governors from dpm_{suspend|resume}() Viresh Kumar
@ 2013-12-02  5:52   ` Viresh Kumar
  2013-12-02  5:52   ` [PATCH V4 6/6] cpufreq: Tegra: " Viresh Kumar
  2 siblings, 0 replies; 7+ messages in thread
From: Viresh Kumar @ 2013-12-02  5:52 UTC (permalink / raw)
  To: rjw-LthD3rsA81gm4RdzfppkhA
  Cc: linaro-kernel-cunTk1MwBs8s++Sfvej+rw,
	patches-QSEj5FYQhm4dnm+yROfE0A, cpufreq-u79uwXL29TY76Z2rM5mHXA,
	linux-pm-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, nm-l0cyMroinI0,
	swarren-3lzwWm7+Weoh9ZMKESR00Q, kgene.kim-Sze3O3UU22JBDgjK7y7TUQ,
	linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	tianyu.lan-ral2JQCrhuEAvxtiuMwx3w,
	jhbird.choi-Sze3O3UU22JBDgjK7y7TUQ, Viresh Kumar

Currently we have implemented PM notifiers to disable/enable ->target() routines
functionality during suspend/resume.

Now we have support present in cpufreq core, lets use it.

Signed-off-by: Viresh Kumar <viresh.kumar-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
 drivers/cpufreq/exynos-cpufreq.c | 96 +++-------------------------------------
 1 file changed, 7 insertions(+), 89 deletions(-)

diff --git a/drivers/cpufreq/exynos-cpufreq.c b/drivers/cpufreq/exynos-cpufreq.c
index 0b3689c..ded4cf8 100644
--- a/drivers/cpufreq/exynos-cpufreq.c
+++ b/drivers/cpufreq/exynos-cpufreq.c
@@ -16,19 +16,14 @@
 #include <linux/slab.h>
 #include <linux/regulator/consumer.h>
 #include <linux/cpufreq.h>
-#include <linux/suspend.h>
 
 #include <plat/cpu.h>
 
 #include "exynos-cpufreq.h"
 
 static struct exynos_dvfs_info *exynos_info;
-
 static struct regulator *arm_regulator;
-
 static unsigned int locking_frequency;
-static bool frequency_locked;
-static DEFINE_MUTEX(cpufreq_lock);
 
 static int exynos_cpufreq_get_index(unsigned int freq)
 {
@@ -133,83 +128,13 @@ out:
 
 static int exynos_target(struct cpufreq_policy *policy, unsigned int index)
 {
-	struct cpufreq_frequency_table *freq_table = exynos_info->freq_table;
-	int ret = 0;
-
-	mutex_lock(&cpufreq_lock);
-
-	if (frequency_locked)
-		goto out;
-
-	ret = exynos_cpufreq_scale(freq_table[index].frequency);
-
-out:
-	mutex_unlock(&cpufreq_lock);
-
-	return ret;
-}
-
-#ifdef CONFIG_PM
-static int exynos_cpufreq_suspend(struct cpufreq_policy *policy)
-{
-	return 0;
-}
-
-static int exynos_cpufreq_resume(struct cpufreq_policy *policy)
-{
-	return 0;
-}
-#endif
-
-/**
- * exynos_cpufreq_pm_notifier - block CPUFREQ's activities in suspend-resume
- *			context
- * @notifier
- * @pm_event
- * @v
- *
- * While frequency_locked == true, target() ignores every frequency but
- * locking_frequency. The locking_frequency value is the initial frequency,
- * which is set by the bootloader. In order to eliminate possible
- * inconsistency in clock values, we save and restore frequencies during
- * suspend and resume and block CPUFREQ activities. Note that the standard
- * suspend/resume cannot be used as they are too deep (syscore_ops) for
- * regulator actions.
- */
-static int exynos_cpufreq_pm_notifier(struct notifier_block *notifier,
-				       unsigned long pm_event, void *v)
-{
-	int ret;
-
-	switch (pm_event) {
-	case PM_SUSPEND_PREPARE:
-		mutex_lock(&cpufreq_lock);
-		frequency_locked = true;
-		mutex_unlock(&cpufreq_lock);
-
-		ret = exynos_cpufreq_scale(locking_frequency);
-		if (ret < 0)
-			return NOTIFY_BAD;
-
-		break;
-
-	case PM_POST_SUSPEND:
-		mutex_lock(&cpufreq_lock);
-		frequency_locked = false;
-		mutex_unlock(&cpufreq_lock);
-		break;
-	}
-
-	return NOTIFY_OK;
+	return exynos_cpufreq_scale(exynos_info->freq_table[index].frequency);
 }
 
-static struct notifier_block exynos_cpufreq_nb = {
-	.notifier_call = exynos_cpufreq_pm_notifier,
-};
-
 static int exynos_cpufreq_cpu_init(struct cpufreq_policy *policy)
 {
 	policy->clk = exynos_info->cpu_clk;
+	policy->suspend_freq = locking_frequency;
 	return cpufreq_generic_init(policy, exynos_info->freq_table, 100000);
 }
 
@@ -223,8 +148,7 @@ static struct cpufreq_driver exynos_driver = {
 	.name		= "exynos_cpufreq",
 	.attr		= cpufreq_generic_attr,
 #ifdef CONFIG_PM
-	.suspend	= exynos_cpufreq_suspend,
-	.resume		= exynos_cpufreq_resume,
+	.suspend	= cpufreq_generic_suspend,
 #endif
 };
 
@@ -259,19 +183,13 @@ static int __init exynos_cpufreq_init(void)
 		goto err_vdd_arm;
 	}
 
+	/* Done here as we want to capture boot frequency */
 	locking_frequency = clk_get_rate(exynos_info->cpu_clk) / 1000;
 
-	register_pm_notifier(&exynos_cpufreq_nb);
-
-	if (cpufreq_register_driver(&exynos_driver)) {
-		pr_err("%s: failed to register cpufreq driver\n", __func__);
-		goto err_cpufreq;
-	}
-
-	return 0;
-err_cpufreq:
-	unregister_pm_notifier(&exynos_cpufreq_nb);
+	if (!cpufreq_register_driver(&exynos_driver))
+		return 0;
 
+	pr_err("%s: failed to register cpufreq driver\n", __func__);
 	regulator_put(arm_regulator);
 err_vdd_arm:
 	kfree(exynos_info);
-- 
1.7.12.rc2.18.g61b472e

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH V4 5/6] cpufreq: s5pv210: Use cpufreq_generic_suspend()
  2013-12-02  5:52 [PATCH V4 0/6] cpufreq: suspend early/resume late: dpm_{suspend|resume}() Viresh Kumar
                   ` (2 preceding siblings ...)
  2013-12-02  5:52 ` [PATCH V4 3/6] cpufreq: Implement cpufreq_generic_suspend() Viresh Kumar
@ 2013-12-02  5:52 ` Viresh Kumar
  3 siblings, 0 replies; 7+ messages in thread
From: Viresh Kumar @ 2013-12-02  5:52 UTC (permalink / raw)
  To: rjw
  Cc: linaro-kernel, patches, cpufreq, linux-pm, linux-kernel, nm,
	swarren, kgene.kim, linux-samsung-soc, linux-tegra, tianyu.lan,
	jhbird.choi, Viresh Kumar

Currently we have implemented PM notifiers to disable/enable ->target() routines
functionality during suspend/resume.

Now we have support present in cpufreq core, lets use it.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 drivers/cpufreq/s5pv210-cpufreq.c | 49 +++------------------------------------
 1 file changed, 3 insertions(+), 46 deletions(-)

diff --git a/drivers/cpufreq/s5pv210-cpufreq.c b/drivers/cpufreq/s5pv210-cpufreq.c
index da0e291..72e77eb 100644
--- a/drivers/cpufreq/s5pv210-cpufreq.c
+++ b/drivers/cpufreq/s5pv210-cpufreq.c
@@ -18,7 +18,6 @@
 #include <linux/cpufreq.h>
 #include <linux/reboot.h>
 #include <linux/regulator/consumer.h>
-#include <linux/suspend.h>
 
 #include <mach/map.h>
 #include <mach/regs-clock.h>
@@ -435,18 +434,6 @@ exit:
 	return ret;
 }
 
-#ifdef CONFIG_PM
-static int s5pv210_cpufreq_suspend(struct cpufreq_policy *policy)
-{
-	return 0;
-}
-
-static int s5pv210_cpufreq_resume(struct cpufreq_policy *policy)
-{
-	return 0;
-}
-#endif
-
 static int check_mem_type(void __iomem *dmc_reg)
 {
 	unsigned long val;
@@ -502,6 +489,7 @@ static int __init s5pv210_cpu_init(struct cpufreq_policy *policy)
 	s5pv210_dram_conf[1].refresh = (__raw_readl(S5P_VA_DMC1 + 0x30) * 1000);
 	s5pv210_dram_conf[1].freq = clk_get_rate(dmc1_clk);
 
+	policy->suspend_freq = SLEEP_FREQ;
 	return cpufreq_generic_init(policy, s5pv210_freq_table, 40000);
 
 out_dmc1:
@@ -511,32 +499,6 @@ out_dmc0:
 	return ret;
 }
 
-static int s5pv210_cpufreq_notifier_event(struct notifier_block *this,
-					  unsigned long event, void *ptr)
-{
-	int ret;
-
-	switch (event) {
-	case PM_SUSPEND_PREPARE:
-		ret = cpufreq_driver_target(cpufreq_cpu_get(0), SLEEP_FREQ, 0);
-		if (ret < 0)
-			return NOTIFY_BAD;
-
-		/* Disable updation of cpu frequency */
-		no_cpufreq_access = true;
-		return NOTIFY_OK;
-	case PM_POST_RESTORE:
-	case PM_POST_SUSPEND:
-		/* Enable updation of cpu frequency */
-		no_cpufreq_access = false;
-		cpufreq_driver_target(cpufreq_cpu_get(0), SLEEP_FREQ, 0);
-
-		return NOTIFY_OK;
-	}
-
-	return NOTIFY_DONE;
-}
-
 static int s5pv210_cpufreq_reboot_notifier_event(struct notifier_block *this,
 						 unsigned long event, void *ptr)
 {
@@ -558,15 +520,11 @@ static struct cpufreq_driver s5pv210_driver = {
 	.init		= s5pv210_cpu_init,
 	.name		= "s5pv210",
 #ifdef CONFIG_PM
-	.suspend	= s5pv210_cpufreq_suspend,
-	.resume		= s5pv210_cpufreq_resume,
+	.suspend	= cpufreq_generic_suspend,
+	.resume		= cpufreq_generic_suspend, /* We need to set SLEEP FREQ again */
 #endif
 };
 
-static struct notifier_block s5pv210_cpufreq_notifier = {
-	.notifier_call = s5pv210_cpufreq_notifier_event,
-};
-
 static struct notifier_block s5pv210_cpufreq_reboot_notifier = {
 	.notifier_call = s5pv210_cpufreq_reboot_notifier_event,
 };
@@ -586,7 +544,6 @@ static int __init s5pv210_cpufreq_init(void)
 		return PTR_ERR(int_regulator);
 	}
 
-	register_pm_notifier(&s5pv210_cpufreq_notifier);
 	register_reboot_notifier(&s5pv210_cpufreq_reboot_notifier);
 
 	return cpufreq_register_driver(&s5pv210_driver);
-- 
1.7.12.rc2.18.g61b472e

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH V4 6/6] cpufreq: Tegra: Use cpufreq_generic_suspend()
       [not found] ` <cover.1385962528.git.viresh.kumar-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
  2013-12-02  5:52   ` [PATCH V4 1/6] cpufreq: suspend governors from dpm_{suspend|resume}() Viresh Kumar
  2013-12-02  5:52   ` [PATCH V4 4/6] cpufreq: exynos: Use cpufreq_generic_suspend() Viresh Kumar
@ 2013-12-02  5:52   ` Viresh Kumar
  2 siblings, 0 replies; 7+ messages in thread
From: Viresh Kumar @ 2013-12-02  5:52 UTC (permalink / raw)
  To: rjw-LthD3rsA81gm4RdzfppkhA
  Cc: linaro-kernel-cunTk1MwBs8s++Sfvej+rw,
	patches-QSEj5FYQhm4dnm+yROfE0A, cpufreq-u79uwXL29TY76Z2rM5mHXA,
	linux-pm-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, nm-l0cyMroinI0,
	swarren-3lzwWm7+Weoh9ZMKESR00Q, kgene.kim-Sze3O3UU22JBDgjK7y7TUQ,
	linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	tianyu.lan-ral2JQCrhuEAvxtiuMwx3w,
	jhbird.choi-Sze3O3UU22JBDgjK7y7TUQ, Viresh Kumar

Currently we have implemented PM notifiers to disable/enable ->target() routines
functionality during suspend/resume.

Now we have support present in cpufreq core, lets use it.

Acked-and-tested-by: Stephen Warren <swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Viresh Kumar <viresh.kumar-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
 drivers/cpufreq/tegra-cpufreq.c | 46 +++++------------------------------------
 1 file changed, 5 insertions(+), 41 deletions(-)

diff --git a/drivers/cpufreq/tegra-cpufreq.c b/drivers/cpufreq/tegra-cpufreq.c
index 360d1a7..9e4f0a2b 100644
--- a/drivers/cpufreq/tegra-cpufreq.c
+++ b/drivers/cpufreq/tegra-cpufreq.c
@@ -26,7 +26,6 @@
 #include <linux/err.h>
 #include <linux/clk.h>
 #include <linux/io.h>
-#include <linux/suspend.h>
 
 static struct cpufreq_frequency_table freq_table[] = {
 	{ .frequency = 216000 },
@@ -47,9 +46,6 @@ static struct clk *pll_x_clk;
 static struct clk *pll_p_clk;
 static struct clk *emc_clk;
 
-static DEFINE_MUTEX(tegra_cpu_lock);
-static bool is_suspended;
-
 static int tegra_cpu_clk_set_rate(unsigned long rate)
 {
 	int ret;
@@ -112,42 +108,9 @@ static int tegra_update_cpu_speed(struct cpufreq_policy *policy,
 
 static int tegra_target(struct cpufreq_policy *policy, unsigned int index)
 {
-	int ret = -EBUSY;
-
-	mutex_lock(&tegra_cpu_lock);
-
-	if (!is_suspended)
-		ret = tegra_update_cpu_speed(policy,
-				freq_table[index].frequency);
-
-	mutex_unlock(&tegra_cpu_lock);
-	return ret;
+	return tegra_update_cpu_speed(policy, freq_table[index].frequency);
 }
 
-static int tegra_pm_notify(struct notifier_block *nb, unsigned long event,
-	void *dummy)
-{
-	mutex_lock(&tegra_cpu_lock);
-	if (event == PM_SUSPEND_PREPARE) {
-		struct cpufreq_policy *policy = cpufreq_cpu_get(0);
-		is_suspended = true;
-		pr_info("Tegra cpufreq suspend: setting frequency to %d kHz\n",
-			freq_table[0].frequency);
-		if (clk_get_rate(cpu_clk) / 1000 != freq_table[0].frequency)
-			tegra_update_cpu_speed(policy, freq_table[0].frequency);
-		cpufreq_cpu_put(policy);
-	} else if (event == PM_POST_SUSPEND) {
-		is_suspended = false;
-	}
-	mutex_unlock(&tegra_cpu_lock);
-
-	return NOTIFY_OK;
-}
-
-static struct notifier_block tegra_cpu_pm_notifier = {
-	.notifier_call = tegra_pm_notify,
-};
-
 static int tegra_cpu_init(struct cpufreq_policy *policy)
 {
 	int ret;
@@ -166,10 +129,8 @@ static int tegra_cpu_init(struct cpufreq_policy *policy)
 		return ret;
 	}
 
-	if (policy->cpu == 0)
-		register_pm_notifier(&tegra_cpu_pm_notifier);
-
 	policy->clk = cpu_clk;
+	policy->suspend_freq = freq_table[0].frequency;
 	return 0;
 }
 
@@ -189,6 +150,9 @@ static struct cpufreq_driver tegra_cpufreq_driver = {
 	.exit		= tegra_cpu_exit,
 	.name		= "tegra",
 	.attr		= cpufreq_generic_attr,
+#ifdef CONFIG_PM
+	.suspend	= cpufreq_generic_suspend,
+#endif
 };
 
 static int __init tegra_cpufreq_init(void)
-- 
1.7.12.rc2.18.g61b472e

^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2013-12-02  5:52 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-12-02  5:52 [PATCH V4 0/6] cpufreq: suspend early/resume late: dpm_{suspend|resume}() Viresh Kumar
     [not found] ` <cover.1385962528.git.viresh.kumar-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2013-12-02  5:52   ` [PATCH V4 1/6] cpufreq: suspend governors from dpm_{suspend|resume}() Viresh Kumar
2013-12-02  5:52   ` [PATCH V4 4/6] cpufreq: exynos: Use cpufreq_generic_suspend() Viresh Kumar
2013-12-02  5:52   ` [PATCH V4 6/6] cpufreq: Tegra: " Viresh Kumar
2013-12-02  5:52 ` [PATCH V4 2/6] cpufreq: call driver's suspend/resume for each policy Viresh Kumar
2013-12-02  5:52 ` [PATCH V4 3/6] cpufreq: Implement cpufreq_generic_suspend() Viresh Kumar
2013-12-02  5:52 ` [PATCH V4 5/6] cpufreq: s5pv210: Use cpufreq_generic_suspend() Viresh Kumar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).