Blame view
drivers/cpufreq/freq_table.c
6.02 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 3 4 |
/* * linux/drivers/cpufreq/freq_table.c * * Copyright (C) 2002 - 2003 Dominik Brodowski |
4f7436942 [CPUFREQ] clarify... |
5 6 7 8 9 |
* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * |
1da177e4c Linux-2.6.12-rc2 |
10 11 12 13 14 15 |
*/ #include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> #include <linux/cpufreq.h> |
1da177e4c Linux-2.6.12-rc2 |
16 17 18 19 20 21 22 23 24 |
/********************************************************************* * FREQUENCY TABLE HELPERS * *********************************************************************/ int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy, struct cpufreq_frequency_table *table) { unsigned int min_freq = ~0; unsigned int max_freq = 0; |
355eb3180 [CPUFREQ] Remove ... |
25 |
unsigned int i; |
1da177e4c Linux-2.6.12-rc2 |
26 |
|
97acec55d [CPUFREQ] checkpa... |
27 |
for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++) { |
1da177e4c Linux-2.6.12-rc2 |
28 29 |
unsigned int freq = table[i].frequency; if (freq == CPUFREQ_ENTRY_INVALID) { |
2d06d8c49 [CPUFREQ] use dyn... |
30 31 |
pr_debug("table entry %u is invalid, skipping ", i); |
1da177e4c Linux-2.6.12-rc2 |
32 33 34 |
continue; } |
2d06d8c49 [CPUFREQ] use dyn... |
35 36 |
pr_debug("table entry %u: %u kHz, %u index ", |
e08f5f5bb [CPUFREQ] Fix cod... |
37 |
i, freq, table[i].index); |
1da177e4c Linux-2.6.12-rc2 |
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
if (freq < min_freq) min_freq = freq; if (freq > max_freq) max_freq = freq; } policy->min = policy->cpuinfo.min_freq = min_freq; policy->max = policy->cpuinfo.max_freq = max_freq; if (policy->min == ~0) return -EINVAL; else return 0; } EXPORT_SYMBOL_GPL(cpufreq_frequency_table_cpuinfo); int cpufreq_frequency_table_verify(struct cpufreq_policy *policy, struct cpufreq_frequency_table *table) { unsigned int next_larger = ~0; |
5557976ca [CPUFREQ] Fix ano... |
59 |
unsigned int i; |
1da177e4c Linux-2.6.12-rc2 |
60 |
unsigned int count = 0; |
2d06d8c49 [CPUFREQ] use dyn... |
61 62 |
pr_debug("request for verification of policy (%u - %u kHz) for cpu %u ", |
e08f5f5bb [CPUFREQ] Fix cod... |
63 |
policy->min, policy->max, policy->cpu); |
1da177e4c Linux-2.6.12-rc2 |
64 65 66 |
if (!cpu_online(policy->cpu)) return -EINVAL; |
e08f5f5bb [CPUFREQ] Fix cod... |
67 68 |
cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, policy->cpuinfo.max_freq); |
1da177e4c Linux-2.6.12-rc2 |
69 |
|
97acec55d [CPUFREQ] checkpa... |
70 |
for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++) { |
1da177e4c Linux-2.6.12-rc2 |
71 72 73 74 75 76 77 78 79 80 81 |
unsigned int freq = table[i].frequency; if (freq == CPUFREQ_ENTRY_INVALID) continue; if ((freq >= policy->min) && (freq <= policy->max)) count++; else if ((next_larger > freq) && (freq > policy->max)) next_larger = freq; } if (!count) policy->max = next_larger; |
e08f5f5bb [CPUFREQ] Fix cod... |
82 83 |
cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, policy->cpuinfo.max_freq); |
1da177e4c Linux-2.6.12-rc2 |
84 |
|
2d06d8c49 [CPUFREQ] use dyn... |
85 86 |
pr_debug("verification lead to (%u - %u kHz) for cpu %u ", |
e08f5f5bb [CPUFREQ] Fix cod... |
87 |
policy->min, policy->max, policy->cpu); |
1da177e4c Linux-2.6.12-rc2 |
88 89 90 91 92 93 94 95 96 97 98 99 |
return 0; } EXPORT_SYMBOL_GPL(cpufreq_frequency_table_verify); int cpufreq_frequency_table_target(struct cpufreq_policy *policy, struct cpufreq_frequency_table *table, unsigned int target_freq, unsigned int relation, unsigned int *index) { |
484944a5b [CPUFREQ] Remove ... |
100 101 102 103 104 105 106 107 |
struct cpufreq_frequency_table optimal = { .index = ~0, .frequency = 0, }; struct cpufreq_frequency_table suboptimal = { .index = ~0, .frequency = 0, }; |
1da177e4c Linux-2.6.12-rc2 |
108 |
unsigned int i; |
2d06d8c49 [CPUFREQ] use dyn... |
109 110 |
pr_debug("request for target %u kHz (relation: %u) for cpu %u ", |
e08f5f5bb [CPUFREQ] Fix cod... |
111 |
target_freq, relation, policy->cpu); |
1da177e4c Linux-2.6.12-rc2 |
112 113 114 |
switch (relation) { case CPUFREQ_RELATION_H: |
1da177e4c Linux-2.6.12-rc2 |
115 116 117 118 |
suboptimal.frequency = ~0; break; case CPUFREQ_RELATION_L: optimal.frequency = ~0; |
1da177e4c Linux-2.6.12-rc2 |
119 120 121 122 123 |
break; } if (!cpu_online(policy->cpu)) return -EINVAL; |
97acec55d [CPUFREQ] checkpa... |
124 |
for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++) { |
1da177e4c Linux-2.6.12-rc2 |
125 126 127 128 129 |
unsigned int freq = table[i].frequency; if (freq == CPUFREQ_ENTRY_INVALID) continue; if ((freq < policy->min) || (freq > policy->max)) continue; |
97acec55d [CPUFREQ] checkpa... |
130 |
switch (relation) { |
1da177e4c Linux-2.6.12-rc2 |
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
case CPUFREQ_RELATION_H: if (freq <= target_freq) { if (freq >= optimal.frequency) { optimal.frequency = freq; optimal.index = i; } } else { if (freq <= suboptimal.frequency) { suboptimal.frequency = freq; suboptimal.index = i; } } break; case CPUFREQ_RELATION_L: if (freq >= target_freq) { if (freq <= optimal.frequency) { optimal.frequency = freq; optimal.index = i; } } else { if (freq >= suboptimal.frequency) { suboptimal.frequency = freq; suboptimal.index = i; } } break; } } if (optimal.index > i) { if (suboptimal.index > i) return -EINVAL; *index = suboptimal.index; } else *index = optimal.index; |
2d06d8c49 [CPUFREQ] use dyn... |
165 166 |
pr_debug("target is %u (%u kHz, %u) ", *index, table[*index].frequency, |
1da177e4c Linux-2.6.12-rc2 |
167 168 169 170 171 |
table[*index].index); return 0; } EXPORT_SYMBOL_GPL(cpufreq_frequency_table_target); |
f16250669 percpu: make perc... |
172 |
static DEFINE_PER_CPU(struct cpufreq_frequency_table *, cpufreq_show_table); |
1da177e4c Linux-2.6.12-rc2 |
173 |
/** |
e32d22f77 [CPUFREQ] fix inc... |
174 |
* show_available_freqs - show available frequencies for the specified CPU |
1da177e4c Linux-2.6.12-rc2 |
175 |
*/ |
97acec55d [CPUFREQ] checkpa... |
176 |
static ssize_t show_available_freqs(struct cpufreq_policy *policy, char *buf) |
1da177e4c Linux-2.6.12-rc2 |
177 178 179 180 181 |
{ unsigned int i = 0; unsigned int cpu = policy->cpu; ssize_t count = 0; struct cpufreq_frequency_table *table; |
f16250669 percpu: make perc... |
182 |
if (!per_cpu(cpufreq_show_table, cpu)) |
1da177e4c Linux-2.6.12-rc2 |
183 |
return -ENODEV; |
f16250669 percpu: make perc... |
184 |
table = per_cpu(cpufreq_show_table, cpu); |
1da177e4c Linux-2.6.12-rc2 |
185 |
|
97acec55d [CPUFREQ] checkpa... |
186 |
for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++) { |
1da177e4c Linux-2.6.12-rc2 |
187 188 189 190 191 192 193 194 195 196 197 198 |
if (table[i].frequency == CPUFREQ_ENTRY_INVALID) continue; count += sprintf(&buf[count], "%d ", table[i].frequency); } count += sprintf(&buf[count], " "); return count; } struct freq_attr cpufreq_freq_attr_scaling_available_freqs = { |
e08f5f5bb [CPUFREQ] Fix cod... |
199 200 |
.attr = { .name = "scaling_available_frequencies", .mode = 0444, |
e08f5f5bb [CPUFREQ] Fix cod... |
201 |
}, |
1da177e4c Linux-2.6.12-rc2 |
202 203 204 205 206 207 208 209 |
.show = show_available_freqs, }; EXPORT_SYMBOL_GPL(cpufreq_freq_attr_scaling_available_freqs); /* * if you use these, you must assure that the frequency table is valid * all the time between get_attr and put_attr! */ |
32ee8c3e4 [CPUFREQ] Lots of... |
210 |
void cpufreq_frequency_table_get_attr(struct cpufreq_frequency_table *table, |
1da177e4c Linux-2.6.12-rc2 |
211 212 |
unsigned int cpu) { |
2d06d8c49 [CPUFREQ] use dyn... |
213 214 |
pr_debug("setting show_table for cpu %u to %p ", cpu, table); |
f16250669 percpu: make perc... |
215 |
per_cpu(cpufreq_show_table, cpu) = table; |
1da177e4c Linux-2.6.12-rc2 |
216 217 218 219 220 |
} EXPORT_SYMBOL_GPL(cpufreq_frequency_table_get_attr); void cpufreq_frequency_table_put_attr(unsigned int cpu) { |
2d06d8c49 [CPUFREQ] use dyn... |
221 222 |
pr_debug("clearing show_table for cpu %u ", cpu); |
f16250669 percpu: make perc... |
223 |
per_cpu(cpufreq_show_table, cpu) = NULL; |
1da177e4c Linux-2.6.12-rc2 |
224 225 226 227 228 |
} EXPORT_SYMBOL_GPL(cpufreq_frequency_table_put_attr); struct cpufreq_frequency_table *cpufreq_frequency_get_table(unsigned int cpu) { |
f16250669 percpu: make perc... |
229 |
return per_cpu(cpufreq_show_table, cpu); |
1da177e4c Linux-2.6.12-rc2 |
230 231 |
} EXPORT_SYMBOL_GPL(cpufreq_frequency_get_table); |
97acec55d [CPUFREQ] checkpa... |
232 233 234 |
MODULE_AUTHOR("Dominik Brodowski <linux@brodo.de>"); MODULE_DESCRIPTION("CPUfreq frequency table helpers"); MODULE_LICENSE("GPL"); |