[CPUFREQ] Make cpufreq_conservative handle out-of-sync events properly

Make cpufreq_conservative handle out-of-sync events properly

Currently, the cpufreq_conservative governor doesn't get notified when the
actual frequency the cpu is running at differs from what cpufreq thought it
was. As a result the cpu may stay at the maximum frequency after a s2ram /
resume cycle even though the system is idle.

Signed-off-by: Elias Oltmanns <eo@nebensachen.de>
Signed-off-by: Dave Jones <davej@redhat.com>

authored by Elias Oltmanns and committed by Dave Jones a8d7c3bc c5829cd0

+30 -2
+30 -2
drivers/cpufreq/cpufreq_conservative.c
··· 116 return ret; 117 } 118 119 /************************** sysfs interface ************************/ 120 static ssize_t show_sampling_rate_max(struct cpufreq_policy *policy, char *buf) 121 { ··· 532 dbs_tuners_ins.sampling_rate = def_sampling_rate; 533 534 dbs_timer_init(); 535 } 536 537 mutex_unlock(&dbs_mutex); ··· 549 * Stop the timerschedule work, when this governor 550 * is used for first time 551 */ 552 - if (dbs_enable == 0) 553 dbs_timer_exit(); 554 - 555 mutex_unlock(&dbs_mutex); 556 557 break;
··· 116 return ret; 117 } 118 119 + /* keep track of frequency transitions */ 120 + static int 121 + dbs_cpufreq_notifier(struct notifier_block *nb, unsigned long val, 122 + void *data) 123 + { 124 + struct cpufreq_freqs *freq = data; 125 + struct cpu_dbs_info_s *this_dbs_info = &per_cpu(cpu_dbs_info, 126 + freq->cpu); 127 + 128 + if (!this_dbs_info->enable) 129 + return 0; 130 + 131 + this_dbs_info->requested_freq = freq->new; 132 + 133 + return 0; 134 + } 135 + 136 + static struct notifier_block dbs_cpufreq_notifier_block = { 137 + .notifier_call = dbs_cpufreq_notifier 138 + }; 139 + 140 /************************** sysfs interface ************************/ 141 static ssize_t show_sampling_rate_max(struct cpufreq_policy *policy, char *buf) 142 { ··· 511 dbs_tuners_ins.sampling_rate = def_sampling_rate; 512 513 dbs_timer_init(); 514 + cpufreq_register_notifier( 515 + &dbs_cpufreq_notifier_block, 516 + CPUFREQ_TRANSITION_NOTIFIER); 517 } 518 519 mutex_unlock(&dbs_mutex); ··· 525 * Stop the timerschedule work, when this governor 526 * is used for first time 527 */ 528 + if (dbs_enable == 0) { 529 dbs_timer_exit(); 530 + cpufreq_unregister_notifier( 531 + &dbs_cpufreq_notifier_block, 532 + CPUFREQ_TRANSITION_NOTIFIER); 533 + } 534 + 535 mutex_unlock(&dbs_mutex); 536 537 break;