Merge branch 'cpufreq-macros' into pm-cpufreq

This commit is contained in:
Rafael J. Wysocki 2014-05-01 00:50:47 +02:00
commit 89d4f82aa5
23 changed files with 208 additions and 216 deletions

View File

@ -228,3 +228,22 @@ is the corresponding frequency table helper for the ->target
stage. Just pass the values to this function, and the unsigned int stage. Just pass the values to this function, and the unsigned int
index returns the number of the frequency table entry which contains index returns the number of the frequency table entry which contains
the frequency the CPU shall be set to. the frequency the CPU shall be set to.
The following macros can be used as iterators over cpufreq_frequency_table:
cpufreq_for_each_entry(pos, table) - iterates over all entries of frequency
table.
cpufreq-for_each_valid_entry(pos, table) - iterates over all entries,
excluding CPUFREQ_ENTRY_INVALID frequencies.
Use arguments "pos" - a cpufreq_frequency_table * as a loop cursor and
"table" - the cpufreq_frequency_table * you want to iterate over.
For example:
struct cpufreq_frequency_table *pos, *driver_freq_table;
cpufreq_for_each_entry(pos, driver_freq_table) {
/* Do something with pos */
pos->frequency = ...
}

View File

@ -1092,20 +1092,21 @@ int da850_register_cpufreq(char *async_clk)
static int da850_round_armrate(struct clk *clk, unsigned long rate) static int da850_round_armrate(struct clk *clk, unsigned long rate)
{ {
int i, ret = 0, diff; int ret = 0, diff;
unsigned int best = (unsigned int) -1; unsigned int best = (unsigned int) -1;
struct cpufreq_frequency_table *table = cpufreq_info.freq_table; struct cpufreq_frequency_table *table = cpufreq_info.freq_table;
struct cpufreq_frequency_table *pos;
rate /= 1000; /* convert to kHz */ rate /= 1000; /* convert to kHz */
for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) { cpufreq_for_each_entry(pos, table) {
diff = table[i].frequency - rate; diff = pos->frequency - rate;
if (diff < 0) if (diff < 0)
diff = -diff; diff = -diff;
if (diff < best) { if (diff < best) {
best = diff; best = diff;
ret = table[i].frequency; ret = pos->frequency;
} }
} }

View File

@ -91,9 +91,9 @@ EXPORT_SYMBOL(clk_put);
int clk_set_rate(struct clk *clk, unsigned long rate) int clk_set_rate(struct clk *clk, unsigned long rate)
{ {
struct cpufreq_frequency_table *pos;
int ret = 0; int ret = 0;
int regval; int regval;
int i;
if (likely(clk->ops && clk->ops->set_rate)) { if (likely(clk->ops && clk->ops->set_rate)) {
unsigned long flags; unsigned long flags;
@ -106,22 +106,16 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
if (unlikely(clk->flags & CLK_RATE_PROPAGATES)) if (unlikely(clk->flags & CLK_RATE_PROPAGATES))
propagate_rate(clk); propagate_rate(clk);
for (i = 0; loongson2_clockmod_table[i].frequency != CPUFREQ_TABLE_END; cpufreq_for_each_valid_entry(pos, loongson2_clockmod_table)
i++) { if (rate == pos->frequency)
if (loongson2_clockmod_table[i].frequency ==
CPUFREQ_ENTRY_INVALID)
continue;
if (rate == loongson2_clockmod_table[i].frequency)
break; break;
} if (rate != pos->frequency)
if (rate != loongson2_clockmod_table[i].frequency)
return -ENOTSUPP; return -ENOTSUPP;
clk->rate = rate; clk->rate = rate;
regval = LOONGSON_CHIPCFG0; regval = LOONGSON_CHIPCFG0;
regval = (regval & ~0x7) | regval = (regval & ~0x7) | (pos->driver_data - 1);
(loongson2_clockmod_table[i].driver_data - 1);
LOONGSON_CHIPCFG0 = regval; LOONGSON_CHIPCFG0 = regval;
return ret; return ret;

View File

@ -213,7 +213,7 @@ static unsigned extract_io(u32 value, struct acpi_cpufreq_data *data)
static unsigned extract_msr(u32 msr, struct acpi_cpufreq_data *data) static unsigned extract_msr(u32 msr, struct acpi_cpufreq_data *data)
{ {
int i; struct cpufreq_frequency_table *pos;
struct acpi_processor_performance *perf; struct acpi_processor_performance *perf;
if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD)
@ -223,10 +223,9 @@ static unsigned extract_msr(u32 msr, struct acpi_cpufreq_data *data)
perf = data->acpi_data; perf = data->acpi_data;
for (i = 0; data->freq_table[i].frequency != CPUFREQ_TABLE_END; i++) { cpufreq_for_each_entry(pos, data->freq_table)
if (msr == perf->states[data->freq_table[i].driver_data].status) if (msr == perf->states[pos->driver_data].status)
return data->freq_table[i].frequency; return pos->frequency;
}
return data->freq_table[0].frequency; return data->freq_table[0].frequency;
} }

View File

@ -226,22 +226,22 @@ static inline u32 get_table_count(struct cpufreq_frequency_table *table)
/* get the minimum frequency in the cpufreq_frequency_table */ /* get the minimum frequency in the cpufreq_frequency_table */
static inline u32 get_table_min(struct cpufreq_frequency_table *table) static inline u32 get_table_min(struct cpufreq_frequency_table *table)
{ {
int i; struct cpufreq_frequency_table *pos;
uint32_t min_freq = ~0; uint32_t min_freq = ~0;
for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++) cpufreq_for_each_entry(pos, table)
if (table[i].frequency < min_freq) if (pos->frequency < min_freq)
min_freq = table[i].frequency; min_freq = pos->frequency;
return min_freq; return min_freq;
} }
/* get the maximum frequency in the cpufreq_frequency_table */ /* get the maximum frequency in the cpufreq_frequency_table */
static inline u32 get_table_max(struct cpufreq_frequency_table *table) static inline u32 get_table_max(struct cpufreq_frequency_table *table)
{ {
int i; struct cpufreq_frequency_table *pos;
uint32_t max_freq = 0; uint32_t max_freq = 0;
for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++) cpufreq_for_each_entry(pos, table)
if (table[i].frequency > max_freq) if (pos->frequency > max_freq)
max_freq = table[i].frequency; max_freq = pos->frequency;
return max_freq; return max_freq;
} }

View File

@ -237,6 +237,17 @@ void cpufreq_cpu_put(struct cpufreq_policy *policy)
} }
EXPORT_SYMBOL_GPL(cpufreq_cpu_put); EXPORT_SYMBOL_GPL(cpufreq_cpu_put);
bool cpufreq_next_valid(struct cpufreq_frequency_table **pos)
{
while ((*pos)->frequency != CPUFREQ_TABLE_END)
if ((*pos)->frequency != CPUFREQ_ENTRY_INVALID)
return true;
else
(*pos)++;
return false;
}
EXPORT_SYMBOL_GPL(cpufreq_next_valid);
/********************************************************************* /*********************************************************************
* EXTERNALLY AFFECTING FREQUENCY CHANGES * * EXTERNALLY AFFECTING FREQUENCY CHANGES *
*********************************************************************/ *********************************************************************/

View File

@ -182,11 +182,11 @@ static void cpufreq_stats_free_table(unsigned int cpu)
static int __cpufreq_stats_create_table(struct cpufreq_policy *policy) static int __cpufreq_stats_create_table(struct cpufreq_policy *policy)
{ {
unsigned int i, j, count = 0, ret = 0; unsigned int i, count = 0, ret = 0;
struct cpufreq_stats *stat; struct cpufreq_stats *stat;
unsigned int alloc_size; unsigned int alloc_size;
unsigned int cpu = policy->cpu; unsigned int cpu = policy->cpu;
struct cpufreq_frequency_table *table; struct cpufreq_frequency_table *pos, *table;
table = cpufreq_frequency_get_table(cpu); table = cpufreq_frequency_get_table(cpu);
if (unlikely(!table)) if (unlikely(!table))
@ -205,12 +205,8 @@ static int __cpufreq_stats_create_table(struct cpufreq_policy *policy)
stat->cpu = cpu; stat->cpu = cpu;
per_cpu(cpufreq_stats_table, cpu) = stat; per_cpu(cpufreq_stats_table, cpu) = stat;
for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) { cpufreq_for_each_valid_entry(pos, table)
unsigned int freq = table[i].frequency;
if (freq == CPUFREQ_ENTRY_INVALID)
continue;
count++; count++;
}
alloc_size = count * sizeof(int) + count * sizeof(u64); alloc_size = count * sizeof(int) + count * sizeof(u64);
@ -228,15 +224,11 @@ static int __cpufreq_stats_create_table(struct cpufreq_policy *policy)
#ifdef CONFIG_CPU_FREQ_STAT_DETAILS #ifdef CONFIG_CPU_FREQ_STAT_DETAILS
stat->trans_table = stat->freq_table + count; stat->trans_table = stat->freq_table + count;
#endif #endif
j = 0; i = 0;
for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) { cpufreq_for_each_valid_entry(pos, table)
unsigned int freq = table[i].frequency; if (freq_table_get_index(stat, pos->frequency) == -1)
if (freq == CPUFREQ_ENTRY_INVALID) stat->freq_table[i++] = pos->frequency;
continue; stat->state_num = i;
if (freq_table_get_index(stat, freq) == -1)
stat->freq_table[j++] = freq;
}
stat->state_num = j;
spin_lock(&cpufreq_stats_lock); spin_lock(&cpufreq_stats_lock);
stat->last_time = get_jiffies_64(); stat->last_time = get_jiffies_64();
stat->last_index = freq_table_get_index(stat, policy->cur); stat->last_index = freq_table_get_index(stat, policy->cur);

View File

@ -45,7 +45,7 @@ static struct cpufreq_driver dbx500_cpufreq_driver = {
static int dbx500_cpufreq_probe(struct platform_device *pdev) static int dbx500_cpufreq_probe(struct platform_device *pdev)
{ {
int i = 0; struct cpufreq_frequency_table *pos;
freq_table = dev_get_platdata(&pdev->dev); freq_table = dev_get_platdata(&pdev->dev);
if (!freq_table) { if (!freq_table) {
@ -60,10 +60,8 @@ static int dbx500_cpufreq_probe(struct platform_device *pdev)
} }
pr_info("dbx500-cpufreq: Available frequencies:\n"); pr_info("dbx500-cpufreq: Available frequencies:\n");
while (freq_table[i].frequency != CPUFREQ_TABLE_END) { cpufreq_for_each_entry(pos, freq_table)
pr_info(" %d Mhz\n", freq_table[i].frequency/1000); pr_info(" %d Mhz\n", pos->frequency / 1000);
i++;
}
return cpufreq_register_driver(&dbx500_cpufreq_driver); return cpufreq_register_driver(&dbx500_cpufreq_driver);
} }

View File

@ -147,7 +147,7 @@ static int elanfreq_target(struct cpufreq_policy *policy,
static int elanfreq_cpu_init(struct cpufreq_policy *policy) static int elanfreq_cpu_init(struct cpufreq_policy *policy)
{ {
struct cpuinfo_x86 *c = &cpu_data(0); struct cpuinfo_x86 *c = &cpu_data(0);
unsigned int i; struct cpufreq_frequency_table *pos;
/* capability check */ /* capability check */
if ((c->x86_vendor != X86_VENDOR_AMD) || if ((c->x86_vendor != X86_VENDOR_AMD) ||
@ -159,10 +159,9 @@ static int elanfreq_cpu_init(struct cpufreq_policy *policy)
max_freq = elanfreq_get_cpu_frequency(0); max_freq = elanfreq_get_cpu_frequency(0);
/* table init */ /* table init */
for (i = 0; (elanfreq_table[i].frequency != CPUFREQ_TABLE_END); i++) { cpufreq_for_each_entry(pos, elanfreq_table)
if (elanfreq_table[i].frequency > max_freq) if (pos->frequency > max_freq)
elanfreq_table[i].frequency = CPUFREQ_ENTRY_INVALID; pos->frequency = CPUFREQ_ENTRY_INVALID;
}
/* cpuinfo and default policy values */ /* cpuinfo and default policy values */
policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;

View File

@ -29,17 +29,16 @@ static unsigned int locking_frequency;
static int exynos_cpufreq_get_index(unsigned int freq) static int exynos_cpufreq_get_index(unsigned int freq)
{ {
struct cpufreq_frequency_table *freq_table = exynos_info->freq_table; struct cpufreq_frequency_table *freq_table = exynos_info->freq_table;
int index; struct cpufreq_frequency_table *pos;
for (index = 0; cpufreq_for_each_entry(pos, freq_table)
freq_table[index].frequency != CPUFREQ_TABLE_END; index++) if (pos->frequency == freq)
if (freq_table[index].frequency == freq)
break; break;
if (freq_table[index].frequency == CPUFREQ_TABLE_END) if (pos->frequency == CPUFREQ_TABLE_END)
return -EINVAL; return -EINVAL;
return index; return pos - freq_table;
} }
static int exynos_cpufreq_scale(unsigned int target_freq) static int exynos_cpufreq_scale(unsigned int target_freq)

View File

@ -114,25 +114,23 @@ static struct cpufreq_freqs freqs;
static int init_div_table(void) static int init_div_table(void)
{ {
struct cpufreq_frequency_table *freq_tbl = dvfs_info->freq_table; struct cpufreq_frequency_table *pos, *freq_tbl = dvfs_info->freq_table;
unsigned int tmp, clk_div, ema_div, freq, volt_id; unsigned int tmp, clk_div, ema_div, freq, volt_id;
int i = 0;
struct dev_pm_opp *opp; struct dev_pm_opp *opp;
rcu_read_lock(); rcu_read_lock();
for (i = 0; freq_tbl[i].frequency != CPUFREQ_TABLE_END; i++) { cpufreq_for_each_entry(pos, freq_tbl) {
opp = dev_pm_opp_find_freq_exact(dvfs_info->dev, opp = dev_pm_opp_find_freq_exact(dvfs_info->dev,
freq_tbl[i].frequency * 1000, true); pos->frequency * 1000, true);
if (IS_ERR(opp)) { if (IS_ERR(opp)) {
rcu_read_unlock(); rcu_read_unlock();
dev_err(dvfs_info->dev, dev_err(dvfs_info->dev,
"failed to find valid OPP for %u KHZ\n", "failed to find valid OPP for %u KHZ\n",
freq_tbl[i].frequency); pos->frequency);
return PTR_ERR(opp); return PTR_ERR(opp);
} }
freq = freq_tbl[i].frequency / 1000; /* In MHZ */ freq = pos->frequency / 1000; /* In MHZ */
clk_div = ((freq / CPU_DIV_FREQ_MAX) & P0_7_CPUCLKDEV_MASK) clk_div = ((freq / CPU_DIV_FREQ_MAX) & P0_7_CPUCLKDEV_MASK)
<< P0_7_CPUCLKDEV_SHIFT; << P0_7_CPUCLKDEV_SHIFT;
clk_div |= ((freq / CPU_ATB_FREQ_MAX) & P0_7_ATBCLKDEV_MASK) clk_div |= ((freq / CPU_ATB_FREQ_MAX) & P0_7_ATBCLKDEV_MASK)
@ -157,7 +155,8 @@ static int init_div_table(void)
tmp = (clk_div | ema_div | (volt_id << P0_7_VDD_SHIFT) tmp = (clk_div | ema_div | (volt_id << P0_7_VDD_SHIFT)
| ((freq / FREQ_UNIT) << P0_7_FREQ_SHIFT)); | ((freq / FREQ_UNIT) << P0_7_FREQ_SHIFT));
__raw_writel(tmp, dvfs_info->base + XMU_PMU_P0_7 + 4 * i); __raw_writel(tmp, dvfs_info->base + XMU_PMU_P0_7 + 4 *
(pos - freq_tbl));
} }
rcu_read_unlock(); rcu_read_unlock();
@ -166,8 +165,9 @@ static int init_div_table(void)
static void exynos_enable_dvfs(unsigned int cur_frequency) static void exynos_enable_dvfs(unsigned int cur_frequency)
{ {
unsigned int tmp, i, cpu; unsigned int tmp, cpu;
struct cpufreq_frequency_table *freq_table = dvfs_info->freq_table; struct cpufreq_frequency_table *freq_table = dvfs_info->freq_table;
struct cpufreq_frequency_table *pos;
/* Disable DVFS */ /* Disable DVFS */
__raw_writel(0, dvfs_info->base + XMU_DVFS_CTRL); __raw_writel(0, dvfs_info->base + XMU_DVFS_CTRL);
@ -182,15 +182,15 @@ static void exynos_enable_dvfs(unsigned int cur_frequency)
__raw_writel(tmp, dvfs_info->base + XMU_PMUIRQEN); __raw_writel(tmp, dvfs_info->base + XMU_PMUIRQEN);
/* Set initial performance index */ /* Set initial performance index */
for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) cpufreq_for_each_entry(pos, freq_table)
if (freq_table[i].frequency == cur_frequency) if (pos->frequency == cur_frequency)
break; break;
if (freq_table[i].frequency == CPUFREQ_TABLE_END) { if (pos->frequency == CPUFREQ_TABLE_END) {
dev_crit(dvfs_info->dev, "Boot up frequency not supported\n"); dev_crit(dvfs_info->dev, "Boot up frequency not supported\n");
/* Assign the highest frequency */ /* Assign the highest frequency */
i = 0; pos = freq_table;
cur_frequency = freq_table[i].frequency; cur_frequency = pos->frequency;
} }
dev_info(dvfs_info->dev, "Setting dvfs initial frequency = %uKHZ", dev_info(dvfs_info->dev, "Setting dvfs initial frequency = %uKHZ",
@ -199,7 +199,7 @@ static void exynos_enable_dvfs(unsigned int cur_frequency)
for (cpu = 0; cpu < CONFIG_NR_CPUS; cpu++) { for (cpu = 0; cpu < CONFIG_NR_CPUS; cpu++) {
tmp = __raw_readl(dvfs_info->base + XMU_C0_3_PSTATE + cpu * 4); tmp = __raw_readl(dvfs_info->base + XMU_C0_3_PSTATE + cpu * 4);
tmp &= ~(P_VALUE_MASK << C0_3_PSTATE_NEW_SHIFT); tmp &= ~(P_VALUE_MASK << C0_3_PSTATE_NEW_SHIFT);
tmp |= (i << C0_3_PSTATE_NEW_SHIFT); tmp |= ((pos - freq_table) << C0_3_PSTATE_NEW_SHIFT);
__raw_writel(tmp, dvfs_info->base + XMU_C0_3_PSTATE + cpu * 4); __raw_writel(tmp, dvfs_info->base + XMU_C0_3_PSTATE + cpu * 4);
} }

View File

@ -21,22 +21,19 @@
int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy, int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy,
struct cpufreq_frequency_table *table) struct cpufreq_frequency_table *table)
{ {
struct cpufreq_frequency_table *pos;
unsigned int min_freq = ~0; unsigned int min_freq = ~0;
unsigned int max_freq = 0; unsigned int max_freq = 0;
unsigned int i; unsigned int freq;
for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++) { cpufreq_for_each_valid_entry(pos, table) {
unsigned int freq = table[i].frequency; freq = pos->frequency;
if (freq == CPUFREQ_ENTRY_INVALID) {
pr_debug("table entry %u is invalid, skipping\n", i);
continue;
}
if (!cpufreq_boost_enabled() if (!cpufreq_boost_enabled()
&& (table[i].flags & CPUFREQ_BOOST_FREQ)) && (pos->flags & CPUFREQ_BOOST_FREQ))
continue; continue;
pr_debug("table entry %u: %u kHz\n", i, freq); pr_debug("table entry %u: %u kHz\n", (int)(pos - table), freq);
if (freq < min_freq) if (freq < min_freq)
min_freq = freq; min_freq = freq;
if (freq > max_freq) if (freq > max_freq)
@ -57,7 +54,8 @@ EXPORT_SYMBOL_GPL(cpufreq_frequency_table_cpuinfo);
int cpufreq_frequency_table_verify(struct cpufreq_policy *policy, int cpufreq_frequency_table_verify(struct cpufreq_policy *policy,
struct cpufreq_frequency_table *table) struct cpufreq_frequency_table *table)
{ {
unsigned int next_larger = ~0, freq, i = 0; struct cpufreq_frequency_table *pos;
unsigned int freq, next_larger = ~0;
bool found = false; bool found = false;
pr_debug("request for verification of policy (%u - %u kHz) for cpu %u\n", pr_debug("request for verification of policy (%u - %u kHz) for cpu %u\n",
@ -65,9 +63,9 @@ int cpufreq_frequency_table_verify(struct cpufreq_policy *policy,
cpufreq_verify_within_cpu_limits(policy); cpufreq_verify_within_cpu_limits(policy);
for (; freq = table[i].frequency, freq != CPUFREQ_TABLE_END; i++) { cpufreq_for_each_valid_entry(pos, table) {
if (freq == CPUFREQ_ENTRY_INVALID) freq = pos->frequency;
continue;
if ((freq >= policy->min) && (freq <= policy->max)) { if ((freq >= policy->min) && (freq <= policy->max)) {
found = true; found = true;
break; break;
@ -118,7 +116,8 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
.driver_data = ~0, .driver_data = ~0,
.frequency = 0, .frequency = 0,
}; };
unsigned int i; struct cpufreq_frequency_table *pos;
unsigned int freq, i = 0;
pr_debug("request for target %u kHz (relation: %u) for cpu %u\n", pr_debug("request for target %u kHz (relation: %u) for cpu %u\n",
target_freq, relation, policy->cpu); target_freq, relation, policy->cpu);
@ -132,10 +131,10 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
break; break;
} }
for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++) { cpufreq_for_each_valid_entry(pos, table) {
unsigned int freq = table[i].frequency; freq = pos->frequency;
if (freq == CPUFREQ_ENTRY_INVALID)
continue; i = pos - table;
if ((freq < policy->min) || (freq > policy->max)) if ((freq < policy->min) || (freq > policy->max))
continue; continue;
switch (relation) { switch (relation) {
@ -184,8 +183,7 @@ EXPORT_SYMBOL_GPL(cpufreq_frequency_table_target);
int cpufreq_frequency_table_get_index(struct cpufreq_policy *policy, int cpufreq_frequency_table_get_index(struct cpufreq_policy *policy,
unsigned int freq) unsigned int freq)
{ {
struct cpufreq_frequency_table *table; struct cpufreq_frequency_table *pos, *table;
int i;
table = cpufreq_frequency_get_table(policy->cpu); table = cpufreq_frequency_get_table(policy->cpu);
if (unlikely(!table)) { if (unlikely(!table)) {
@ -193,10 +191,9 @@ int cpufreq_frequency_table_get_index(struct cpufreq_policy *policy,
return -ENOENT; return -ENOENT;
} }
for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) { cpufreq_for_each_valid_entry(pos, table)
if (table[i].frequency == freq) if (pos->frequency == freq)
return i; return pos - table;
}
return -EINVAL; return -EINVAL;
} }
@ -208,16 +205,13 @@ EXPORT_SYMBOL_GPL(cpufreq_frequency_table_get_index);
static ssize_t show_available_freqs(struct cpufreq_policy *policy, char *buf, static ssize_t show_available_freqs(struct cpufreq_policy *policy, char *buf,
bool show_boost) bool show_boost)
{ {
unsigned int i = 0;
ssize_t count = 0; ssize_t count = 0;
struct cpufreq_frequency_table *table = policy->freq_table; struct cpufreq_frequency_table *pos, *table = policy->freq_table;
if (!table) if (!table)
return -ENODEV; return -ENODEV;
for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++) { cpufreq_for_each_valid_entry(pos, table) {
if (table[i].frequency == CPUFREQ_ENTRY_INVALID)
continue;
/* /*
* show_boost = true and driver_data = BOOST freq * show_boost = true and driver_data = BOOST freq
* display BOOST freqs * display BOOST freqs
@ -229,10 +223,10 @@ static ssize_t show_available_freqs(struct cpufreq_policy *policy, char *buf,
* show_boost = false and driver_data != BOOST freq * show_boost = false and driver_data != BOOST freq
* display NON BOOST freqs * display NON BOOST freqs
*/ */
if (show_boost ^ (table[i].flags & CPUFREQ_BOOST_FREQ)) if (show_boost ^ (pos->flags & CPUFREQ_BOOST_FREQ))
continue; continue;
count += sprintf(&buf[count], "%d ", table[i].frequency); count += sprintf(&buf[count], "%d ", pos->frequency);
} }
count += sprintf(&buf[count], "\n"); count += sprintf(&buf[count], "\n");

View File

@ -530,6 +530,7 @@ static int longhaul_get_ranges(void)
static void longhaul_setup_voltagescaling(void) static void longhaul_setup_voltagescaling(void)
{ {
struct cpufreq_frequency_table *freq_pos;
union msr_longhaul longhaul; union msr_longhaul longhaul;
struct mV_pos minvid, maxvid, vid; struct mV_pos minvid, maxvid, vid;
unsigned int j, speed, pos, kHz_step, numvscales; unsigned int j, speed, pos, kHz_step, numvscales;
@ -608,18 +609,16 @@ static void longhaul_setup_voltagescaling(void)
/* Calculate kHz for one voltage step */ /* Calculate kHz for one voltage step */
kHz_step = (highest_speed - min_vid_speed) / numvscales; kHz_step = (highest_speed - min_vid_speed) / numvscales;
j = 0; cpufreq_for_each_entry(freq_pos, longhaul_table) {
while (longhaul_table[j].frequency != CPUFREQ_TABLE_END) { speed = freq_pos->frequency;
speed = longhaul_table[j].frequency;
if (speed > min_vid_speed) if (speed > min_vid_speed)
pos = (speed - min_vid_speed) / kHz_step + minvid.pos; pos = (speed - min_vid_speed) / kHz_step + minvid.pos;
else else
pos = minvid.pos; pos = minvid.pos;
longhaul_table[j].driver_data |= mV_vrm_table[pos] << 8; freq_pos->driver_data |= mV_vrm_table[pos] << 8;
vid = vrm_mV_table[mV_vrm_table[pos]]; vid = vrm_mV_table[mV_vrm_table[pos]];
printk(KERN_INFO PFX "f: %d kHz, index: %d, vid: %d mV\n", printk(KERN_INFO PFX "f: %d kHz, index: %d, vid: %d mV\n",
speed, j, vid.mV); speed, (int)(freq_pos - longhaul_table), vid.mV);
j++;
} }
can_scale_voltage = 1; can_scale_voltage = 1;

View File

@ -136,9 +136,10 @@ void restore_astate(int cpu)
static int pas_cpufreq_cpu_init(struct cpufreq_policy *policy) static int pas_cpufreq_cpu_init(struct cpufreq_policy *policy)
{ {
struct cpufreq_frequency_table *pos;
const u32 *max_freqp; const u32 *max_freqp;
u32 max_freq; u32 max_freq;
int i, cur_astate; int cur_astate;
struct resource res; struct resource res;
struct device_node *cpu, *dn; struct device_node *cpu, *dn;
int err = -ENODEV; int err = -ENODEV;
@ -197,10 +198,9 @@ static int pas_cpufreq_cpu_init(struct cpufreq_policy *policy)
pr_debug("initializing frequency table\n"); pr_debug("initializing frequency table\n");
/* initialize frequency table */ /* initialize frequency table */
for (i=0; pas_freqs[i].frequency!=CPUFREQ_TABLE_END; i++) { cpufreq_for_each_entry(pos, pas_freqs) {
pas_freqs[i].frequency = pos->frequency = get_astate_freq(pos->driver_data) * 100000;
get_astate_freq(pas_freqs[i].driver_data) * 100000; pr_debug("%d: %d\n", (int)(pos - pas_freqs), pos->frequency);
pr_debug("%d: %d\n", i, pas_freqs[i].frequency);
} }
cur_astate = get_cur_astate(policy->cpu); cur_astate = get_cur_astate(policy->cpu);

View File

@ -151,6 +151,7 @@ static int powernow_k6_target(struct cpufreq_policy *policy,
static int powernow_k6_cpu_init(struct cpufreq_policy *policy) static int powernow_k6_cpu_init(struct cpufreq_policy *policy)
{ {
struct cpufreq_frequency_table *pos;
unsigned int i, f; unsigned int i, f;
unsigned khz; unsigned khz;
@ -168,12 +169,11 @@ static int powernow_k6_cpu_init(struct cpufreq_policy *policy)
} }
} }
if (param_max_multiplier) { if (param_max_multiplier) {
for (i = 0; (clock_ratio[i].frequency != CPUFREQ_TABLE_END); i++) { cpufreq_for_each_entry(pos, clock_ratio)
if (clock_ratio[i].driver_data == param_max_multiplier) { if (pos->driver_data == param_max_multiplier) {
max_multiplier = param_max_multiplier; max_multiplier = param_max_multiplier;
goto have_max_multiplier; goto have_max_multiplier;
} }
}
printk(KERN_ERR "powernow-k6: invalid max_multiplier parameter, valid parameters 20, 30, 35, 40, 45, 50, 55, 60\n"); printk(KERN_ERR "powernow-k6: invalid max_multiplier parameter, valid parameters 20, 30, 35, 40, 45, 50, 55, 60\n");
return -EINVAL; return -EINVAL;
} }
@ -201,12 +201,12 @@ have_busfreq:
param_busfreq = busfreq * 10; param_busfreq = busfreq * 10;
/* table init */ /* table init */
for (i = 0; (clock_ratio[i].frequency != CPUFREQ_TABLE_END); i++) { cpufreq_for_each_entry(pos, clock_ratio) {
f = clock_ratio[i].driver_data; f = pos->driver_data;
if (f > max_multiplier) if (f > max_multiplier)
clock_ratio[i].frequency = CPUFREQ_ENTRY_INVALID; pos->frequency = CPUFREQ_ENTRY_INVALID;
else else
clock_ratio[i].frequency = busfreq * f; pos->frequency = busfreq * f;
} }
/* cpuinfo and default policy values */ /* cpuinfo and default policy values */

View File

@ -67,9 +67,10 @@ static int set_pmode(unsigned int cpu, unsigned int slow_mode)
static int cbe_cpufreq_cpu_init(struct cpufreq_policy *policy) static int cbe_cpufreq_cpu_init(struct cpufreq_policy *policy)
{ {
struct cpufreq_frequency_table *pos;
const u32 *max_freqp; const u32 *max_freqp;
u32 max_freq; u32 max_freq;
int i, cur_pmode; int cur_pmode;
struct device_node *cpu; struct device_node *cpu;
cpu = of_get_cpu_node(policy->cpu, NULL); cpu = of_get_cpu_node(policy->cpu, NULL);
@ -102,9 +103,9 @@ static int cbe_cpufreq_cpu_init(struct cpufreq_policy *policy)
pr_debug("initializing frequency table\n"); pr_debug("initializing frequency table\n");
/* initialize frequency table */ /* initialize frequency table */
for (i=0; cbe_freqs[i].frequency!=CPUFREQ_TABLE_END; i++) { cpufreq_for_each_entry(pos, cbe_freqs) {
cbe_freqs[i].frequency = max_freq / cbe_freqs[i].driver_data; pos->frequency = max_freq / pos->driver_data;
pr_debug("%d: %d\n", i, cbe_freqs[i].frequency); pr_debug("%d: %d\n", (int)(pos - cbe_freqs), pos->frequency);
} }
/* if DEBUG is enabled set_pmode() measures the latency /* if DEBUG is enabled set_pmode() measures the latency

View File

@ -266,7 +266,7 @@ out:
static void __init s3c2416_cpufreq_cfg_regulator(struct s3c2416_data *s3c_freq) static void __init s3c2416_cpufreq_cfg_regulator(struct s3c2416_data *s3c_freq)
{ {
int count, v, i, found; int count, v, i, found;
struct cpufreq_frequency_table *freq; struct cpufreq_frequency_table *pos;
struct s3c2416_dvfs *dvfs; struct s3c2416_dvfs *dvfs;
count = regulator_count_voltages(s3c_freq->vddarm); count = regulator_count_voltages(s3c_freq->vddarm);
@ -275,12 +275,11 @@ static void __init s3c2416_cpufreq_cfg_regulator(struct s3c2416_data *s3c_freq)
return; return;
} }
freq = s3c_freq->freq_table; if (!count)
while (count > 0 && freq->frequency != CPUFREQ_TABLE_END) { goto out;
if (freq->frequency == CPUFREQ_ENTRY_INVALID)
continue;
dvfs = &s3c2416_dvfs_table[freq->driver_data]; cpufreq_for_each_valid_entry(pos, s3c_freq->freq_table) {
dvfs = &s3c2416_dvfs_table[pos->driver_data];
found = 0; found = 0;
/* Check only the min-voltage, more is always ok on S3C2416 */ /* Check only the min-voltage, more is always ok on S3C2416 */
@ -292,13 +291,12 @@ static void __init s3c2416_cpufreq_cfg_regulator(struct s3c2416_data *s3c_freq)
if (!found) { if (!found) {
pr_debug("cpufreq: %dkHz unsupported by regulator\n", pr_debug("cpufreq: %dkHz unsupported by regulator\n",
freq->frequency); pos->frequency);
freq->frequency = CPUFREQ_ENTRY_INVALID; pos->frequency = CPUFREQ_ENTRY_INVALID;
} }
freq++;
} }
out:
/* Guessed */ /* Guessed */
s3c_freq->regulator_latency = 1 * 1000 * 1000; s3c_freq->regulator_latency = 1 * 1000 * 1000;
} }
@ -338,7 +336,7 @@ static struct notifier_block s3c2416_cpufreq_reboot_notifier = {
static int __init s3c2416_cpufreq_driver_init(struct cpufreq_policy *policy) static int __init s3c2416_cpufreq_driver_init(struct cpufreq_policy *policy)
{ {
struct s3c2416_data *s3c_freq = &s3c2416_cpufreq; struct s3c2416_data *s3c_freq = &s3c2416_cpufreq;
struct cpufreq_frequency_table *freq; struct cpufreq_frequency_table *pos;
struct clk *msysclk; struct clk *msysclk;
unsigned long rate; unsigned long rate;
int ret; int ret;
@ -427,31 +425,27 @@ static int __init s3c2416_cpufreq_driver_init(struct cpufreq_policy *policy)
s3c_freq->regulator_latency = 0; s3c_freq->regulator_latency = 0;
#endif #endif
freq = s3c_freq->freq_table; cpufreq_for_each_entry(pos, s3c_freq->freq_table) {
while (freq->frequency != CPUFREQ_TABLE_END) {
/* special handling for dvs mode */ /* special handling for dvs mode */
if (freq->driver_data == 0) { if (pos->driver_data == 0) {
if (!s3c_freq->hclk) { if (!s3c_freq->hclk) {
pr_debug("cpufreq: %dkHz unsupported as it would need unavailable dvs mode\n", pr_debug("cpufreq: %dkHz unsupported as it would need unavailable dvs mode\n",
freq->frequency); pos->frequency);
freq->frequency = CPUFREQ_ENTRY_INVALID; pos->frequency = CPUFREQ_ENTRY_INVALID;
} else { } else {
freq++;
continue; continue;
} }
} }
/* Check for frequencies we can generate */ /* Check for frequencies we can generate */
rate = clk_round_rate(s3c_freq->armdiv, rate = clk_round_rate(s3c_freq->armdiv,
freq->frequency * 1000); pos->frequency * 1000);
rate /= 1000; rate /= 1000;
if (rate != freq->frequency) { if (rate != pos->frequency) {
pr_debug("cpufreq: %dkHz unsupported by clock (clk_round_rate return %lu)\n", pr_debug("cpufreq: %dkHz unsupported by clock (clk_round_rate return %lu)\n",
freq->frequency, rate); pos->frequency, rate);
freq->frequency = CPUFREQ_ENTRY_INVALID; pos->frequency = CPUFREQ_ENTRY_INVALID;
} }
freq++;
} }
/* Datasheet says PLL stabalisation time must be at least 300us, /* Datasheet says PLL stabalisation time must be at least 300us,

View File

@ -118,11 +118,10 @@ static void __init s3c64xx_cpufreq_config_regulator(void)
pr_err("Unable to check supported voltages\n"); pr_err("Unable to check supported voltages\n");
} }
freq = s3c64xx_freq_table; if (!count)
while (count > 0 && freq->frequency != CPUFREQ_TABLE_END) { goto out;
if (freq->frequency == CPUFREQ_ENTRY_INVALID)
continue;
cpufreq_for_each_valid_entry(freq, s3c64xx_freq_table) {
dvfs = &s3c64xx_dvfs_table[freq->driver_data]; dvfs = &s3c64xx_dvfs_table[freq->driver_data];
found = 0; found = 0;
@ -137,10 +136,9 @@ static void __init s3c64xx_cpufreq_config_regulator(void)
freq->frequency); freq->frequency);
freq->frequency = CPUFREQ_ENTRY_INVALID; freq->frequency = CPUFREQ_ENTRY_INVALID;
} }
freq++;
} }
out:
/* Guess based on having to do an I2C/SPI write; in future we /* Guess based on having to do an I2C/SPI write; in future we
* will be able to query the regulator performance here. */ * will be able to query the regulator performance here. */
regulator_latency = 1 * 1000 * 1000; regulator_latency = 1 * 1000 * 1000;
@ -179,8 +177,7 @@ static int s3c64xx_cpufreq_driver_init(struct cpufreq_policy *policy)
} }
#endif #endif
freq = s3c64xx_freq_table; cpufreq_for_each_entry(freq, s3c64xx_freq_table) {
while (freq->frequency != CPUFREQ_TABLE_END) {
unsigned long r; unsigned long r;
/* Check for frequencies we can generate */ /* Check for frequencies we can generate */
@ -196,8 +193,6 @@ static int s3c64xx_cpufreq_driver_init(struct cpufreq_policy *policy)
* frequency is the maximum we can support. */ * frequency is the maximum we can support. */
if (!vddarm && freq->frequency > clk_get_rate(policy->clk) / 1000) if (!vddarm && freq->frequency > clk_get_rate(policy->clk) / 1000)
freq->frequency = CPUFREQ_ENTRY_INVALID; freq->frequency = CPUFREQ_ENTRY_INVALID;
freq++;
} }
/* Datasheet says PLL stabalisation time (if we were to use /* Datasheet says PLL stabalisation time (if we were to use

View File

@ -1734,18 +1734,17 @@ static struct cpufreq_frequency_table db8500_cpufreq_table[] = {
static long round_armss_rate(unsigned long rate) static long round_armss_rate(unsigned long rate)
{ {
struct cpufreq_frequency_table *pos;
long freq = 0; long freq = 0;
int i = 0;
/* cpufreq table frequencies is in KHz. */ /* cpufreq table frequencies is in KHz. */
rate = rate / 1000; rate = rate / 1000;
/* Find the corresponding arm opp from the cpufreq table. */ /* Find the corresponding arm opp from the cpufreq table. */
while (db8500_cpufreq_table[i].frequency != CPUFREQ_TABLE_END) { cpufreq_for_each_entry(pos, db8500_cpufreq_table) {
freq = db8500_cpufreq_table[i].frequency; freq = pos->frequency;
if (freq == rate) if (freq == rate)
break; break;
i++;
} }
/* Return the last valid value, even if a match was not found. */ /* Return the last valid value, even if a match was not found. */
@ -1886,23 +1885,21 @@ static void set_clock_rate(u8 clock, unsigned long rate)
static int set_armss_rate(unsigned long rate) static int set_armss_rate(unsigned long rate)
{ {
int i = 0; struct cpufreq_frequency_table *pos;
/* cpufreq table frequencies is in KHz. */ /* cpufreq table frequencies is in KHz. */
rate = rate / 1000; rate = rate / 1000;
/* Find the corresponding arm opp from the cpufreq table. */ /* Find the corresponding arm opp from the cpufreq table. */
while (db8500_cpufreq_table[i].frequency != CPUFREQ_TABLE_END) { cpufreq_for_each_entry(pos, db8500_cpufreq_table)
if (db8500_cpufreq_table[i].frequency == rate) if (pos->frequency == rate)
break; break;
i++;
}
if (db8500_cpufreq_table[i].frequency != rate) if (pos->frequency != rate)
return -EINVAL; return -EINVAL;
/* Set the new arm opp. */ /* Set the new arm opp. */
return db8500_prcmu_set_arm_opp(db8500_cpufreq_table[i].driver_data); return db8500_prcmu_set_arm_opp(pos->driver_data);
} }
static int set_plldsi_rate(unsigned long rate) static int set_plldsi_rate(unsigned long rate)

View File

@ -217,21 +217,17 @@ crc_init_out:
static u32 sh_sir_find_sclk(struct clk *irda_clk) static u32 sh_sir_find_sclk(struct clk *irda_clk)
{ {
struct cpufreq_frequency_table *freq_table = irda_clk->freq_table; struct cpufreq_frequency_table *freq_table = irda_clk->freq_table;
struct cpufreq_frequency_table *pos;
struct clk *pclk = clk_get(NULL, "peripheral_clk"); struct clk *pclk = clk_get(NULL, "peripheral_clk");
u32 limit, min = 0xffffffff, tmp; u32 limit, min = 0xffffffff, tmp;
int i, index = 0; int index = 0;
limit = clk_get_rate(pclk); limit = clk_get_rate(pclk);
clk_put(pclk); clk_put(pclk);
/* IrDA can not set over peripheral_clk */ /* IrDA can not set over peripheral_clk */
for (i = 0; cpufreq_for_each_valid_entry(pos, freq_table) {
freq_table[i].frequency != CPUFREQ_TABLE_END; u32 freq = pos->frequency;
i++) {
u32 freq = freq_table[i].frequency;
if (freq == CPUFREQ_ENTRY_INVALID)
continue;
/* IrDA should not over peripheral_clk */ /* IrDA should not over peripheral_clk */
if (freq > limit) if (freq > limit)
@ -240,7 +236,7 @@ static u32 sh_sir_find_sclk(struct clk *irda_clk)
tmp = freq % SCLK_BASE; tmp = freq % SCLK_BASE;
if (tmp < min) { if (tmp < min) {
min = tmp; min = tmp;
index = i; index = pos - freq_table;
} }
} }

View File

@ -196,17 +196,11 @@ int clk_rate_table_find(struct clk *clk,
struct cpufreq_frequency_table *freq_table, struct cpufreq_frequency_table *freq_table,
unsigned long rate) unsigned long rate)
{ {
int i; struct cpufreq_frequency_table *pos;
for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) { cpufreq_for_each_valid_entry(pos, freq_table)
unsigned long freq = freq_table[i].frequency; if (pos->frequency == rate)
return pos - freq_table;
if (freq == CPUFREQ_ENTRY_INVALID)
continue;
if (freq == rate)
return i;
}
return -ENOENT; return -ENOENT;
} }
@ -575,11 +569,7 @@ long clk_round_parent(struct clk *clk, unsigned long target,
return abs(target - *best_freq); return abs(target - *best_freq);
} }
for (freq = parent->freq_table; freq->frequency != CPUFREQ_TABLE_END; cpufreq_for_each_valid_entry(freq, parent->freq_table) {
freq++) {
if (freq->frequency == CPUFREQ_ENTRY_INVALID)
continue;
if (unlikely(freq->frequency / target <= div_min - 1)) { if (unlikely(freq->frequency / target <= div_min - 1)) {
unsigned long freq_max; unsigned long freq_max;

View File

@ -144,11 +144,11 @@ static int get_property(unsigned int cpu, unsigned long input,
unsigned int *output, unsigned int *output,
enum cpufreq_cooling_property property) enum cpufreq_cooling_property property)
{ {
int i, j; int i;
unsigned long max_level = 0, level = 0; unsigned long max_level = 0, level = 0;
unsigned int freq = CPUFREQ_ENTRY_INVALID; unsigned int freq = CPUFREQ_ENTRY_INVALID;
int descend = -1; int descend = -1;
struct cpufreq_frequency_table *table = struct cpufreq_frequency_table *pos, *table =
cpufreq_frequency_get_table(cpu); cpufreq_frequency_get_table(cpu);
if (!output) if (!output)
@ -157,20 +157,16 @@ static int get_property(unsigned int cpu, unsigned long input,
if (!table) if (!table)
return -EINVAL; return -EINVAL;
for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) { cpufreq_for_each_valid_entry(pos, table) {
/* ignore invalid entries */
if (table[i].frequency == CPUFREQ_ENTRY_INVALID)
continue;
/* ignore duplicate entry */ /* ignore duplicate entry */
if (freq == table[i].frequency) if (freq == pos->frequency)
continue; continue;
/* get the frequency order */ /* get the frequency order */
if (freq != CPUFREQ_ENTRY_INVALID && descend == -1) if (freq != CPUFREQ_ENTRY_INVALID && descend == -1)
descend = !!(freq > table[i].frequency); descend = freq > pos->frequency;
freq = table[i].frequency; freq = pos->frequency;
max_level++; max_level++;
} }
@ -190,29 +186,26 @@ static int get_property(unsigned int cpu, unsigned long input,
if (property == GET_FREQ) if (property == GET_FREQ)
level = descend ? input : (max_level - input); level = descend ? input : (max_level - input);
for (i = 0, j = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) { i = 0;
/* ignore invalid entry */ cpufreq_for_each_valid_entry(pos, table) {
if (table[i].frequency == CPUFREQ_ENTRY_INVALID)
continue;
/* ignore duplicate entry */ /* ignore duplicate entry */
if (freq == table[i].frequency) if (freq == pos->frequency)
continue; continue;
/* now we have a valid frequency entry */ /* now we have a valid frequency entry */
freq = table[i].frequency; freq = pos->frequency;
if (property == GET_LEVEL && (unsigned int)input == freq) { if (property == GET_LEVEL && (unsigned int)input == freq) {
/* get level by frequency */ /* get level by frequency */
*output = descend ? j : (max_level - j); *output = descend ? i : (max_level - i);
return 0; return 0;
} }
if (property == GET_FREQ && level == j) { if (property == GET_FREQ && level == i) {
/* get frequency by level */ /* get frequency by level */
*output = freq; *output = freq;
return 0; return 0;
} }
j++; i++;
} }
return -EINVAL; return -EINVAL;

View File

@ -468,6 +468,27 @@ struct cpufreq_frequency_table {
* order */ * order */
}; };
bool cpufreq_next_valid(struct cpufreq_frequency_table **pos);
/*
* cpufreq_for_each_entry - iterate over a cpufreq_frequency_table
* @pos: the cpufreq_frequency_table * to use as a loop cursor.
* @table: the cpufreq_frequency_table * to iterate over.
*/
#define cpufreq_for_each_entry(pos, table) \
for (pos = table; pos->frequency != CPUFREQ_TABLE_END; pos++)
/*
* cpufreq_for_each_valid_entry - iterate over a cpufreq_frequency_table
* excluding CPUFREQ_ENTRY_INVALID frequencies.
* @pos: the cpufreq_frequency_table * to use as a loop cursor.
* @table: the cpufreq_frequency_table * to iterate over.
*/
#define cpufreq_for_each_valid_entry(pos, table) \
for (pos = table; cpufreq_next_valid(&pos); pos++)
int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy, int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy,
struct cpufreq_frequency_table *table); struct cpufreq_frequency_table *table);