Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

PM / devfreq: Don't adjust to user limits in governors

Several governors use the user space limits df->min/max_freq to adjust
the target frequency. This is not necessary, since update_devfreq()
already takes care of this. Instead the governor can request the available
min/max frequency by setting the target frequency to DEVFREQ_MIN/MAX_FREQ
and let update_devfreq() take care of any adjustments.

Signed-off-by: Matthias Kaehlcke <mka@chromium.org>
Reviewed-by: Brian Norris <briannorris@chromium.org>
Reviewed-by: Chanwoo Choi <cw00.choi@samsung.com>
Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>

authored by

Matthias Kaehlcke and committed by
MyungJoo Ham
6ff66e2a df5cf4a3

+12 -26
+3
drivers/devfreq/governor.h
··· 25 25 #define DEVFREQ_GOV_SUSPEND 0x4 26 26 #define DEVFREQ_GOV_RESUME 0x5 27 27 28 + #define DEVFREQ_MIN_FREQ 0 29 + #define DEVFREQ_MAX_FREQ ULONG_MAX 30 + 28 31 /** 29 32 * struct devfreq_governor - Devfreq policy governor 30 33 * @node: list node - contains registered devfreq governors
+1 -4
drivers/devfreq/governor_performance.c
··· 20 20 * target callback should be able to get floor value as 21 21 * said in devfreq.h 22 22 */ 23 - if (!df->max_freq) 24 - *freq = UINT_MAX; 25 - else 26 - *freq = df->max_freq; 23 + *freq = DEVFREQ_MAX_FREQ; 27 24 return 0; 28 25 } 29 26
+1 -1
drivers/devfreq/governor_powersave.c
··· 20 20 * target callback should be able to get ceiling value as 21 21 * said in devfreq.h 22 22 */ 23 - *freq = df->min_freq; 23 + *freq = DEVFREQ_MIN_FREQ; 24 24 return 0; 25 25 } 26 26
+3 -9
drivers/devfreq/governor_simpleondemand.c
··· 27 27 unsigned int dfso_upthreshold = DFSO_UPTHRESHOLD; 28 28 unsigned int dfso_downdifferential = DFSO_DOWNDIFFERENCTIAL; 29 29 struct devfreq_simple_ondemand_data *data = df->data; 30 - unsigned long max = (df->max_freq) ? df->max_freq : UINT_MAX; 31 30 32 31 err = devfreq_update_stats(df); 33 32 if (err) ··· 46 47 47 48 /* Assume MAX if it is going to be divided by zero */ 48 49 if (stat->total_time == 0) { 49 - *freq = max; 50 + *freq = DEVFREQ_MAX_FREQ; 50 51 return 0; 51 52 } 52 53 ··· 59 60 /* Set MAX if it's busy enough */ 60 61 if (stat->busy_time * 100 > 61 62 stat->total_time * dfso_upthreshold) { 62 - *freq = max; 63 + *freq = DEVFREQ_MAX_FREQ; 63 64 return 0; 64 65 } 65 66 66 67 /* Set MAX if we do not know the initial frequency */ 67 68 if (stat->current_frequency == 0) { 68 - *freq = max; 69 + *freq = DEVFREQ_MAX_FREQ; 69 70 return 0; 70 71 } 71 72 ··· 83 84 b *= 100; 84 85 b = div_u64(b, (dfso_upthreshold - dfso_downdifferential / 2)); 85 86 *freq = (unsigned long) b; 86 - 87 - if (df->min_freq && *freq < df->min_freq) 88 - *freq = df->min_freq; 89 - if (df->max_freq && *freq > df->max_freq) 90 - *freq = df->max_freq; 91 87 92 88 return 0; 93 89 }
+4 -12
drivers/devfreq/governor_userspace.c
··· 26 26 { 27 27 struct userspace_data *data = df->data; 28 28 29 - if (data->valid) { 30 - unsigned long adjusted_freq = data->user_frequency; 31 - 32 - if (df->max_freq && adjusted_freq > df->max_freq) 33 - adjusted_freq = df->max_freq; 34 - 35 - if (df->min_freq && adjusted_freq < df->min_freq) 36 - adjusted_freq = df->min_freq; 37 - 38 - *freq = adjusted_freq; 39 - } else { 29 + if (data->valid) 30 + *freq = data->user_frequency; 31 + else 40 32 *freq = df->previous_freq; /* No user freq specified yet */ 41 - } 33 + 42 34 return 0; 43 35 } 44 36