aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDave Jones <davej@delerium.codemonkey.org.uk>2004-08-02 22:42:11 +0100
committerDave Jones <davej@delerium.codemonkey.org.uk>2004-08-02 22:42:11 +0100
commitdfd64ec8c405ebfcd440562552787c19ccd630a4 (patch)
tree63eaaf603c2bff3ad790a9b107e8d9b62b441f44 /drivers
parent81fd00e2e58911325c794b6f98d683ecb7db2b04 (diff)
parentf9dfb7b589ec4827a47b74138aaadcaf38c6d75e (diff)
downloadhistory-dfd64ec8c405ebfcd440562552787c19ccd630a4.tar.gz
Merge
Diffstat (limited to 'drivers')
-rw-r--r--drivers/cpufreq/cpufreq.c167
-rw-r--r--drivers/cpufreq/cpufreq_userspace.c10
2 files changed, 94 insertions, 83 deletions
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index a7fa79f5b867fc..6e739f99853ce5 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -100,6 +100,86 @@ static void cpufreq_cpu_put(struct cpufreq_policy *data)
}
/*********************************************************************
+ * EXTERNALLY AFFECTING FREQUENCY CHANGES *
+ *********************************************************************/
+
+/**
+ * adjust_jiffies - adjust the system "loops_per_jiffy"
+ *
+ * This function alters the system "loops_per_jiffy" for the clock
+ * speed change. Note that loops_per_jiffy cannot be updated on SMP
+ * systems as each CPU might be scaled differently. So, use the arch
+ * per-CPU loops_per_jiffy value wherever possible.
+ */
+#ifndef CONFIG_SMP
+static unsigned long l_p_j_ref;
+static unsigned int l_p_j_ref_freq;
+
+static inline void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
+{
+ if (ci->flags & CPUFREQ_CONST_LOOPS)
+ return;
+
+ if (!l_p_j_ref_freq) {
+ l_p_j_ref = loops_per_jiffy;
+ l_p_j_ref_freq = ci->old;
+ }
+ if ((val == CPUFREQ_PRECHANGE && ci->old < ci->new) ||
+ (val == CPUFREQ_POSTCHANGE && ci->old > ci->new) ||
+ (val == CPUFREQ_RESUMECHANGE))
+ loops_per_jiffy = cpufreq_scale(l_p_j_ref, l_p_j_ref_freq, ci->new);
+}
+#else
+static inline void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci) { return; }
+#endif
+
+
+/**
+ * cpufreq_notify_transition - call notifier chain and adjust_jiffies on frequency transition
+ *
+ * This function calls the transition notifiers and the "adjust_jiffies" function. It is called
+ * twice on all CPU frequency changes that have external effects.
+ */
+void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state)
+{
+ BUG_ON(irqs_disabled());
+
+ freqs->flags = cpufreq_driver->flags;
+
+ down_read(&cpufreq_notifier_rwsem);
+ switch (state) {
+ case CPUFREQ_PRECHANGE:
+ /* detect if the driver reported a value as "old frequency" which
+ * is not equal to what the cpufreq core thinks is "old frequency".
+ */
+ if (!(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) {
+ if ((likely(cpufreq_cpu_data[freqs->cpu]->cur)) &&
+ (unlikely(freqs->old != cpufreq_cpu_data[freqs->cpu]->cur)))
+ {
+ if (cpufreq_driver->flags & CPUFREQ_PANIC_OUTOFSYNC)
+ panic("CPU Frequency is out of sync.");
+
+ printk(KERN_WARNING "Warning: CPU frequency is %u, "
+ "cpufreq assumed %u kHz.\n", freqs->old, cpufreq_cpu_data[freqs->cpu]->cur);
+ freqs->old = cpufreq_cpu_data[freqs->cpu]->cur;
+ }
+ }
+ notifier_call_chain(&cpufreq_transition_notifier_list, CPUFREQ_PRECHANGE, freqs);
+ adjust_jiffies(CPUFREQ_PRECHANGE, freqs);
+ break;
+ case CPUFREQ_POSTCHANGE:
+ adjust_jiffies(CPUFREQ_POSTCHANGE, freqs);
+ notifier_call_chain(&cpufreq_transition_notifier_list, CPUFREQ_POSTCHANGE, freqs);
+ cpufreq_cpu_data[freqs->cpu]->cur = freqs->new;
+ break;
+ }
+ up_read(&cpufreq_notifier_rwsem);
+}
+EXPORT_SYMBOL_GPL(cpufreq_notify_transition);
+
+
+
+/*********************************************************************
* SYSFS INTERFACE *
*********************************************************************/
@@ -617,8 +697,8 @@ static int cpufreq_resume(struct sys_device * sysdev)
if (cpufreq_driver->flags & CPUFREQ_PANIC_RESUME_OUTOFSYNC)
panic("CPU Frequency is out of sync.");
- printk(KERN_WARNING "Warning: CPU frequency out of sync: cpufreq and timing"
- "core thinks of %u, is %u kHz.\n", cpu_policy->cur, cur_freq);
+ printk(KERN_WARNING "Warning: CPU frequency is %u, "
+ "cpufreq assumed %u kHz.\n", cur_freq, cpu_policy->cur);
freqs.cpu = cpu;
freqs.old = cpu_policy->cur;
@@ -626,6 +706,8 @@ static int cpufreq_resume(struct sys_device * sysdev)
notifier_call_chain(&cpufreq_transition_notifier_list, CPUFREQ_RESUMECHANGE, &freqs);
adjust_jiffies(CPUFREQ_RESUMECHANGE, &freqs);
+
+ cpu_policy->cur = cur_freq;
}
}
@@ -1006,87 +1088,6 @@ EXPORT_SYMBOL(cpufreq_update_policy);
/*********************************************************************
- * EXTERNALLY AFFECTING FREQUENCY CHANGES *
- *********************************************************************/
-
-/**
- * adjust_jiffies - adjust the system "loops_per_jiffy"
- *
- * This function alters the system "loops_per_jiffy" for the clock
- * speed change. Note that loops_per_jiffy cannot be updated on SMP
- * systems as each CPU might be scaled differently. So, use the arch
- * per-CPU loops_per_jiffy value wherever possible.
- */
-#ifndef CONFIG_SMP
-static unsigned long l_p_j_ref;
-static unsigned int l_p_j_ref_freq;
-
-static inline void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
-{
- if (ci->flags & CPUFREQ_CONST_LOOPS)
- return;
-
- if (!l_p_j_ref_freq) {
- l_p_j_ref = loops_per_jiffy;
- l_p_j_ref_freq = ci->old;
- }
- if ((val == CPUFREQ_PRECHANGE && ci->old < ci->new) ||
- (val == CPUFREQ_POSTCHANGE && ci->old > ci->new) ||
- (val == CPUFREQ_RESUMECHANGE))
- loops_per_jiffy = cpufreq_scale(l_p_j_ref, l_p_j_ref_freq, ci->new);
-}
-#else
-static inline void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci) { return; }
-#endif
-
-
-/**
- * cpufreq_notify_transition - call notifier chain and adjust_jiffies on frequency transition
- *
- * This function calls the transition notifiers and the "adjust_jiffies" function. It is called
- * twice on all CPU frequency changes that have external effects.
- */
-void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state)
-{
- BUG_ON(irqs_disabled());
-
- freqs->flags = cpufreq_driver->flags;
-
- down_read(&cpufreq_notifier_rwsem);
- switch (state) {
- case CPUFREQ_PRECHANGE:
- /* detect if the driver reported a value as "old frequency" which
- * is not equal to what the cpufreq core thinks is "old frequency".
- */
- if (!(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) {
- if ((likely(cpufreq_cpu_data[freqs->cpu]->cur)) &&
- (unlikely(freqs->old != cpufreq_cpu_data[freqs->cpu]->cur)))
- {
- if (cpufreq_driver->flags & CPUFREQ_PANIC_OUTOFSYNC)
- panic("CPU Frequency is out of sync.");
-
- printk(KERN_WARNING "Warning: CPU frequency out of sync: "
- "cpufreq and timing core thinks of %u, is %u kHz.\n",
- cpufreq_cpu_data[freqs->cpu]->cur, freqs->old);
- freqs->old = cpufreq_cpu_data[freqs->cpu]->cur;
- }
- }
- notifier_call_chain(&cpufreq_transition_notifier_list, CPUFREQ_PRECHANGE, freqs);
- adjust_jiffies(CPUFREQ_PRECHANGE, freqs);
- break;
- case CPUFREQ_POSTCHANGE:
- adjust_jiffies(CPUFREQ_POSTCHANGE, freqs);
- notifier_call_chain(&cpufreq_transition_notifier_list, CPUFREQ_POSTCHANGE, freqs);
- cpufreq_cpu_data[freqs->cpu]->cur = freqs->new;
- break;
- }
- up_read(&cpufreq_notifier_rwsem);
-}
-EXPORT_SYMBOL_GPL(cpufreq_notify_transition);
-
-
-
-/*********************************************************************
* REGISTER / UNREGISTER CPUFREQ DRIVER *
*********************************************************************/
diff --git a/drivers/cpufreq/cpufreq_userspace.c b/drivers/cpufreq/cpufreq_userspace.c
index 5102144709559f..6a27a2567991a6 100644
--- a/drivers/cpufreq/cpufreq_userspace.c
+++ b/drivers/cpufreq/cpufreq_userspace.c
@@ -82,6 +82,13 @@ userspace_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
{
struct cpufreq_freqs *freq = data;
+ /* Don't update cur_freq if CPU is managed and we're
+ * waking up: else we won't remember what frequency
+ * we need to set the CPU to.
+ */
+ if (cpu_is_managed[freq->cpu] && (val == CPUFREQ_RESUMECHANGE))
+ return 0;
+
cpu_cur_freq[freq->cpu] = freq->new;
return 0;
@@ -522,6 +529,9 @@ static int cpufreq_governor_userspace(struct cpufreq_policy *policy,
else if (policy->min > cpu_cur_freq[cpu])
__cpufreq_driver_target(&current_policy[cpu], policy->min,
CPUFREQ_RELATION_L);
+ else
+ __cpufreq_driver_target(&current_policy[cpu], cpu_cur_freq[cpu],
+ CPUFREQ_RELATION_L);
memcpy (&current_policy[cpu], policy, sizeof(struct cpufreq_policy));
up(&userspace_sem);
break;