diff options
author | Dave Jones <davej@delerium.codemonkey.org.uk> | 2004-08-02 22:42:11 +0100 |
---|---|---|
committer | Dave Jones <davej@delerium.codemonkey.org.uk> | 2004-08-02 22:42:11 +0100 |
commit | dfd64ec8c405ebfcd440562552787c19ccd630a4 (patch) | |
tree | 63eaaf603c2bff3ad790a9b107e8d9b62b441f44 /drivers | |
parent | 81fd00e2e58911325c794b6f98d683ecb7db2b04 (diff) | |
parent | f9dfb7b589ec4827a47b74138aaadcaf38c6d75e (diff) | |
download | history-dfd64ec8c405ebfcd440562552787c19ccd630a4.tar.gz |
Merge
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/cpufreq/cpufreq.c | 167 | ||||
-rw-r--r-- | drivers/cpufreq/cpufreq_userspace.c | 10 |
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(¤t_policy[cpu], policy->min, CPUFREQ_RELATION_L); + else + __cpufreq_driver_target(¤t_policy[cpu], cpu_cur_freq[cpu], + CPUFREQ_RELATION_L); memcpy (¤t_policy[cpu], policy, sizeof(struct cpufreq_policy)); up(&userspace_sem); break; |