2 * linux/drivers/cpufreq/freq_table.c
4 * Copyright (C) 2002 - 2003 Dominik Brodowski
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
12 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
14 #include <linux/cpufreq.h>
15 #include <linux/module.h>
17 /*********************************************************************
18 * FREQUENCY TABLE HELPERS *
19 *********************************************************************/
21 int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy
*policy
,
22 struct cpufreq_frequency_table
*table
)
24 unsigned int min_freq
= ~0;
25 unsigned int max_freq
= 0;
28 for (i
= 0; (table
[i
].frequency
!= CPUFREQ_TABLE_END
); i
++) {
29 unsigned int freq
= table
[i
].frequency
;
30 if (freq
== CPUFREQ_ENTRY_INVALID
) {
31 pr_debug("table entry %u is invalid, skipping\n", i
);
35 if (!cpufreq_boost_enabled()
36 && (table
[i
].flags
& CPUFREQ_BOOST_FREQ
))
39 pr_debug("table entry %u: %u kHz\n", i
, freq
);
46 policy
->min
= policy
->cpuinfo
.min_freq
= min_freq
;
47 policy
->max
= policy
->cpuinfo
.max_freq
= max_freq
;
49 if (policy
->min
== ~0)
54 EXPORT_SYMBOL_GPL(cpufreq_frequency_table_cpuinfo
);
57 int cpufreq_frequency_table_verify(struct cpufreq_policy
*policy
,
58 struct cpufreq_frequency_table
*table
)
60 unsigned int next_larger
= ~0, freq
, i
= 0;
63 pr_debug("request for verification of policy (%u - %u kHz) for cpu %u\n",
64 policy
->min
, policy
->max
, policy
->cpu
);
66 cpufreq_verify_within_cpu_limits(policy
);
68 for (; freq
= table
[i
].frequency
, freq
!= CPUFREQ_TABLE_END
; i
++) {
69 if (freq
== CPUFREQ_ENTRY_INVALID
)
71 if ((freq
>= policy
->min
) && (freq
<= policy
->max
)) {
76 if ((next_larger
> freq
) && (freq
> policy
->max
))
81 policy
->max
= next_larger
;
82 cpufreq_verify_within_cpu_limits(policy
);
85 pr_debug("verification lead to (%u - %u kHz) for cpu %u\n",
86 policy
->min
, policy
->max
, policy
->cpu
);
90 EXPORT_SYMBOL_GPL(cpufreq_frequency_table_verify
);
93 * Generic routine to verify policy & frequency table, requires driver to set
94 * policy->freq_table prior to it.
96 int cpufreq_generic_frequency_table_verify(struct cpufreq_policy
*policy
)
98 struct cpufreq_frequency_table
*table
=
99 cpufreq_frequency_get_table(policy
->cpu
);
103 return cpufreq_frequency_table_verify(policy
, table
);
105 EXPORT_SYMBOL_GPL(cpufreq_generic_frequency_table_verify
);
107 int cpufreq_frequency_table_target(struct cpufreq_policy
*policy
,
108 struct cpufreq_frequency_table
*table
,
109 unsigned int target_freq
,
110 unsigned int relation
,
113 struct cpufreq_frequency_table optimal
= {
117 struct cpufreq_frequency_table suboptimal
= {
123 pr_debug("request for target %u kHz (relation: %u) for cpu %u\n",
124 target_freq
, relation
, policy
->cpu
);
127 case CPUFREQ_RELATION_H
:
128 suboptimal
.frequency
= ~0;
130 case CPUFREQ_RELATION_L
:
131 optimal
.frequency
= ~0;
135 for (i
= 0; (table
[i
].frequency
!= CPUFREQ_TABLE_END
); i
++) {
136 unsigned int freq
= table
[i
].frequency
;
137 if (freq
== CPUFREQ_ENTRY_INVALID
)
139 if ((freq
< policy
->min
) || (freq
> policy
->max
))
142 case CPUFREQ_RELATION_H
:
143 if (freq
<= target_freq
) {
144 if (freq
>= optimal
.frequency
) {
145 optimal
.frequency
= freq
;
146 optimal
.driver_data
= i
;
149 if (freq
<= suboptimal
.frequency
) {
150 suboptimal
.frequency
= freq
;
151 suboptimal
.driver_data
= i
;
155 case CPUFREQ_RELATION_L
:
156 if (freq
>= target_freq
) {
157 if (freq
<= optimal
.frequency
) {
158 optimal
.frequency
= freq
;
159 optimal
.driver_data
= i
;
162 if (freq
>= suboptimal
.frequency
) {
163 suboptimal
.frequency
= freq
;
164 suboptimal
.driver_data
= i
;
170 if (optimal
.driver_data
> i
) {
171 if (suboptimal
.driver_data
> i
)
173 *index
= suboptimal
.driver_data
;
175 *index
= optimal
.driver_data
;
177 pr_debug("target index is %u, freq is:%u kHz\n", *index
,
178 table
[*index
].frequency
);
182 EXPORT_SYMBOL_GPL(cpufreq_frequency_table_target
);
184 int cpufreq_frequency_table_get_index(struct cpufreq_policy
*policy
,
187 struct cpufreq_frequency_table
*table
;
190 table
= cpufreq_frequency_get_table(policy
->cpu
);
191 if (unlikely(!table
)) {
192 pr_debug("%s: Unable to find frequency table\n", __func__
);
196 for (i
= 0; table
[i
].frequency
!= CPUFREQ_TABLE_END
; i
++) {
197 if (table
[i
].frequency
== freq
)
203 EXPORT_SYMBOL_GPL(cpufreq_frequency_table_get_index
);
206 * show_available_freqs - show available frequencies for the specified CPU
208 static ssize_t
show_available_freqs(struct cpufreq_policy
*policy
, char *buf
,
213 struct cpufreq_frequency_table
*table
= policy
->freq_table
;
218 for (i
= 0; (table
[i
].frequency
!= CPUFREQ_TABLE_END
); i
++) {
219 if (table
[i
].frequency
== CPUFREQ_ENTRY_INVALID
)
222 * show_boost = true and driver_data = BOOST freq
223 * display BOOST freqs
225 * show_boost = false and driver_data = BOOST freq
226 * show_boost = true and driver_data != BOOST freq
227 * continue - do not display anything
229 * show_boost = false and driver_data != BOOST freq
230 * display NON BOOST freqs
232 if (show_boost
^ (table
[i
].flags
& CPUFREQ_BOOST_FREQ
))
235 count
+= sprintf(&buf
[count
], "%d ", table
[i
].frequency
);
237 count
+= sprintf(&buf
[count
], "\n");
243 #define cpufreq_attr_available_freq(_name) \
244 struct freq_attr cpufreq_freq_attr_##_name##_freqs = \
245 __ATTR_RO(_name##_frequencies)
248 * show_scaling_available_frequencies - show available normal frequencies for
251 static ssize_t
scaling_available_frequencies_show(struct cpufreq_policy
*policy
,
254 return show_available_freqs(policy
, buf
, false);
256 cpufreq_attr_available_freq(scaling_available
);
257 EXPORT_SYMBOL_GPL(cpufreq_freq_attr_scaling_available_freqs
);
260 * show_available_boost_freqs - show available boost frequencies for
263 static ssize_t
scaling_boost_frequencies_show(struct cpufreq_policy
*policy
,
266 return show_available_freqs(policy
, buf
, true);
268 cpufreq_attr_available_freq(scaling_boost
);
269 EXPORT_SYMBOL_GPL(cpufreq_freq_attr_scaling_boost_freqs
);
271 struct freq_attr
*cpufreq_generic_attr
[] = {
272 &cpufreq_freq_attr_scaling_available_freqs
,
273 #ifdef CONFIG_CPU_FREQ_BOOST_SW
274 &cpufreq_freq_attr_scaling_boost_freqs
,
278 EXPORT_SYMBOL_GPL(cpufreq_generic_attr
);
280 int cpufreq_table_validate_and_show(struct cpufreq_policy
*policy
,
281 struct cpufreq_frequency_table
*table
)
283 int ret
= cpufreq_frequency_table_cpuinfo(policy
, table
);
286 policy
->freq_table
= table
;
290 EXPORT_SYMBOL_GPL(cpufreq_table_validate_and_show
);
292 struct cpufreq_policy
*cpufreq_cpu_get_raw(unsigned int cpu
);
294 struct cpufreq_frequency_table
*cpufreq_frequency_get_table(unsigned int cpu
)
296 struct cpufreq_policy
*policy
= cpufreq_cpu_get_raw(cpu
);
297 return policy
? policy
->freq_table
: NULL
;
299 EXPORT_SYMBOL_GPL(cpufreq_frequency_get_table
);
301 MODULE_AUTHOR("Dominik Brodowski <linux@brodo.de>");
302 MODULE_DESCRIPTION("CPUfreq frequency table helpers");
303 MODULE_LICENSE("GPL");