diff --git a/Documentation/cpu-freq/cpu-drivers.txt b/Documentation/cpu-freq/cpu-drivers.txt index 48da5fdcb9f11b5671859a63e61ce2c9f40bab03..b045fe54986a077792c80e4ad2563b2e38118a86 100644 --- a/Documentation/cpu-freq/cpu-drivers.txt +++ b/Documentation/cpu-freq/cpu-drivers.txt @@ -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 index returns the number of the frequency table entry which contains 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 = ... + } diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index 85399c98f84a7f30657ecc57beb267d404593560..45ce065e7170f802483ebef099621f20e12772e7 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c @@ -1092,20 +1092,21 @@ int da850_register_cpufreq(char *async_clk) 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; struct cpufreq_frequency_table *table = cpufreq_info.freq_table; + struct cpufreq_frequency_table *pos; rate /= 1000; /* convert to kHz */ - for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) { - diff = table[i].frequency - rate; + cpufreq_for_each_entry(pos, table) { + diff = pos->frequency - rate; if (diff < 0) diff = -diff; if (diff < best) { best = diff; - ret = table[i].frequency; + ret = pos->frequency; } } diff --git a/arch/mips/loongson/lemote-2f/clock.c b/arch/mips/loongson/lemote-2f/clock.c index e1f427f4f5f3fed4985bb370054421d7d2f91cdc..1eed38e28b1e19f95584f64e84c66145b2ff9638 100644 --- a/arch/mips/loongson/lemote-2f/clock.c +++ b/arch/mips/loongson/lemote-2f/clock.c @@ -91,9 +91,9 @@ EXPORT_SYMBOL(clk_put); int clk_set_rate(struct clk *clk, unsigned long rate) { + struct cpufreq_frequency_table *pos; int ret = 0; int regval; - int i; if (likely(clk->ops && clk->ops->set_rate)) { unsigned long flags; @@ -106,22 +106,16 @@ int clk_set_rate(struct clk *clk, unsigned long rate) if (unlikely(clk->flags & CLK_RATE_PROPAGATES)) propagate_rate(clk); - for (i = 0; loongson2_clockmod_table[i].frequency != CPUFREQ_TABLE_END; - i++) { - if (loongson2_clockmod_table[i].frequency == - CPUFREQ_ENTRY_INVALID) - continue; - if (rate == loongson2_clockmod_table[i].frequency) + cpufreq_for_each_valid_entry(pos, loongson2_clockmod_table) + if (rate == pos->frequency) break; - } - if (rate != loongson2_clockmod_table[i].frequency) + if (rate != pos->frequency) return -ENOTSUPP; clk->rate = rate; regval = LOONGSON_CHIPCFG0; - regval = (regval & ~0x7) | - (loongson2_clockmod_table[i].driver_data - 1); + regval = (regval & ~0x7) | (pos->driver_data - 1); LOONGSON_CHIPCFG0 = regval; return ret; diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c index 000e4e0afd7e672abaac488d3096ae199f68a301..b0c18ed8d83f707d000213e458dba613e4ffaf96 100644 --- a/drivers/cpufreq/acpi-cpufreq.c +++ b/drivers/cpufreq/acpi-cpufreq.c @@ -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) { - int i; + struct cpufreq_frequency_table *pos; struct acpi_processor_performance *perf; 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; - for (i = 0; data->freq_table[i].frequency != CPUFREQ_TABLE_END; i++) { - if (msr == perf->states[data->freq_table[i].driver_data].status) - return data->freq_table[i].frequency; - } + cpufreq_for_each_entry(pos, data->freq_table) + if (msr == perf->states[pos->driver_data].status) + return pos->frequency; return data->freq_table[0].frequency; } diff --git a/drivers/cpufreq/arm_big_little.c b/drivers/cpufreq/arm_big_little.c index bad2ed317ba294462212bc00cc3cc94132e0aeb2..1f4d4e31505746db9e2cc5565710d4180349245b 100644 --- a/drivers/cpufreq/arm_big_little.c +++ b/drivers/cpufreq/arm_big_little.c @@ -226,22 +226,22 @@ static inline u32 get_table_count(struct cpufreq_frequency_table *table) /* get the minimum frequency in the cpufreq_frequency_table */ static inline u32 get_table_min(struct cpufreq_frequency_table *table) { - int i; + struct cpufreq_frequency_table *pos; uint32_t min_freq = ~0; - for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++) - if (table[i].frequency < min_freq) - min_freq = table[i].frequency; + cpufreq_for_each_entry(pos, table) + if (pos->frequency < min_freq) + min_freq = pos->frequency; return min_freq; } /* get the maximum frequency in the cpufreq_frequency_table */ static inline u32 get_table_max(struct cpufreq_frequency_table *table) { - int i; + struct cpufreq_frequency_table *pos; uint32_t max_freq = 0; - for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++) - if (table[i].frequency > max_freq) - max_freq = table[i].frequency; + cpufreq_for_each_entry(pos, table) + if (pos->frequency > max_freq) + max_freq = pos->frequency; return max_freq; } diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index abda6609d3e79f670c7143a01bbec53078e8bce1..a517da996aaffb229632c52bef7e17239729a641 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -237,6 +237,17 @@ void cpufreq_cpu_put(struct cpufreq_policy *policy) } 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 * *********************************************************************/ diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c index ecaaebf969fc4e5427464dfce53d0bb321e3c39b..0cd9b4dcef997d4814c5d2570092b46d26b4e143 100644 --- a/drivers/cpufreq/cpufreq_stats.c +++ b/drivers/cpufreq/cpufreq_stats.c @@ -182,11 +182,11 @@ static void cpufreq_stats_free_table(unsigned int cpu) 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; unsigned int alloc_size; unsigned int cpu = policy->cpu; - struct cpufreq_frequency_table *table; + struct cpufreq_frequency_table *pos, *table; table = cpufreq_frequency_get_table(cpu); if (unlikely(!table)) @@ -205,12 +205,8 @@ static int __cpufreq_stats_create_table(struct cpufreq_policy *policy) stat->cpu = cpu; per_cpu(cpufreq_stats_table, cpu) = stat; - for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) { - unsigned int freq = table[i].frequency; - if (freq == CPUFREQ_ENTRY_INVALID) - continue; + cpufreq_for_each_valid_entry(pos, table) count++; - } 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 stat->trans_table = stat->freq_table + count; #endif - j = 0; - for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) { - unsigned int freq = table[i].frequency; - if (freq == CPUFREQ_ENTRY_INVALID) - continue; - if (freq_table_get_index(stat, freq) == -1) - stat->freq_table[j++] = freq; - } - stat->state_num = j; + i = 0; + cpufreq_for_each_valid_entry(pos, table) + if (freq_table_get_index(stat, pos->frequency) == -1) + stat->freq_table[i++] = pos->frequency; + stat->state_num = i; spin_lock(&cpufreq_stats_lock); stat->last_time = get_jiffies_64(); stat->last_index = freq_table_get_index(stat, policy->cur); diff --git a/drivers/cpufreq/dbx500-cpufreq.c b/drivers/cpufreq/dbx500-cpufreq.c index 412a78bb0c9410b3fe592227d6b9b03e534616b7..4bebc1b5db48f389aa546083ea6ec68d80edfa67 100644 --- a/drivers/cpufreq/dbx500-cpufreq.c +++ b/drivers/cpufreq/dbx500-cpufreq.c @@ -45,7 +45,7 @@ static struct cpufreq_driver dbx500_cpufreq_driver = { static int dbx500_cpufreq_probe(struct platform_device *pdev) { - int i = 0; + struct cpufreq_frequency_table *pos; freq_table = dev_get_platdata(&pdev->dev); if (!freq_table) { @@ -60,10 +60,8 @@ static int dbx500_cpufreq_probe(struct platform_device *pdev) } pr_info("dbx500-cpufreq: Available frequencies:\n"); - while (freq_table[i].frequency != CPUFREQ_TABLE_END) { - pr_info(" %d Mhz\n", freq_table[i].frequency/1000); - i++; - } + cpufreq_for_each_entry(pos, freq_table) + pr_info(" %d Mhz\n", pos->frequency / 1000); return cpufreq_register_driver(&dbx500_cpufreq_driver); } diff --git a/drivers/cpufreq/elanfreq.c b/drivers/cpufreq/elanfreq.c index 7f5d2a68c3532880b37646ff0761bb73911e00e5..1c06e786c9baa53f587579ab932701e0a51d5a3f 100644 --- a/drivers/cpufreq/elanfreq.c +++ b/drivers/cpufreq/elanfreq.c @@ -147,7 +147,7 @@ static int elanfreq_target(struct cpufreq_policy *policy, static int elanfreq_cpu_init(struct cpufreq_policy *policy) { struct cpuinfo_x86 *c = &cpu_data(0); - unsigned int i; + struct cpufreq_frequency_table *pos; /* capability check */ 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); /* table init */ - for (i = 0; (elanfreq_table[i].frequency != CPUFREQ_TABLE_END); i++) { - if (elanfreq_table[i].frequency > max_freq) - elanfreq_table[i].frequency = CPUFREQ_ENTRY_INVALID; - } + cpufreq_for_each_entry(pos, elanfreq_table) + if (pos->frequency > max_freq) + pos->frequency = CPUFREQ_ENTRY_INVALID; /* cpuinfo and default policy values */ policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; diff --git a/drivers/cpufreq/exynos-cpufreq.c b/drivers/cpufreq/exynos-cpufreq.c index f99cfe24e7bca6489dcbf592372a38d1d019f4f1..9c132550d9106f1dbe13227db7aa39f604def58b 100644 --- a/drivers/cpufreq/exynos-cpufreq.c +++ b/drivers/cpufreq/exynos-cpufreq.c @@ -29,17 +29,16 @@ static unsigned int locking_frequency; static int exynos_cpufreq_get_index(unsigned int freq) { struct cpufreq_frequency_table *freq_table = exynos_info->freq_table; - int index; + struct cpufreq_frequency_table *pos; - for (index = 0; - freq_table[index].frequency != CPUFREQ_TABLE_END; index++) - if (freq_table[index].frequency == freq) + cpufreq_for_each_entry(pos, freq_table) + if (pos->frequency == freq) break; - if (freq_table[index].frequency == CPUFREQ_TABLE_END) + if (pos->frequency == CPUFREQ_TABLE_END) return -EINVAL; - return index; + return pos - freq_table; } static int exynos_cpufreq_scale(unsigned int target_freq) diff --git a/drivers/cpufreq/exynos5440-cpufreq.c b/drivers/cpufreq/exynos5440-cpufreq.c index a6b8214d7b7712bb7d877d68d71e476e7bde26dc..f33f25b483ca6ce0ac87cfda264ba0f1a1eff8d6 100644 --- a/drivers/cpufreq/exynos5440-cpufreq.c +++ b/drivers/cpufreq/exynos5440-cpufreq.c @@ -114,25 +114,23 @@ static struct cpufreq_freqs freqs; 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; - int i = 0; struct dev_pm_opp *opp; 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, - freq_tbl[i].frequency * 1000, true); + pos->frequency * 1000, true); if (IS_ERR(opp)) { rcu_read_unlock(); dev_err(dvfs_info->dev, "failed to find valid OPP for %u KHZ\n", - freq_tbl[i].frequency); + pos->frequency); 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) << P0_7_CPUCLKDEV_SHIFT; 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) | ((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(); @@ -166,8 +165,9 @@ static int init_div_table(void) 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 *pos; /* Disable DVFS */ __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); /* Set initial performance index */ - for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) - if (freq_table[i].frequency == cur_frequency) + cpufreq_for_each_entry(pos, freq_table) + if (pos->frequency == cur_frequency) 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"); /* Assign the highest frequency */ - i = 0; - cur_frequency = freq_table[i].frequency; + pos = freq_table; + cur_frequency = pos->frequency; } 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++) { tmp = __raw_readl(dvfs_info->base + XMU_C0_3_PSTATE + cpu * 4); 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); } diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c index 08e7bbcf6d7362d633311132e8b9fe21433360a0..8e518c6893935135e0bfff4d7c7b8735bd0fefa1 100644 --- a/drivers/cpufreq/freq_table.c +++ b/drivers/cpufreq/freq_table.c @@ -21,22 +21,19 @@ int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy, struct cpufreq_frequency_table *table) { + struct cpufreq_frequency_table *pos; unsigned int min_freq = ~0; unsigned int max_freq = 0; - unsigned int i; + unsigned int freq; - for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++) { - unsigned int freq = table[i].frequency; - if (freq == CPUFREQ_ENTRY_INVALID) { - pr_debug("table entry %u is invalid, skipping\n", i); + cpufreq_for_each_valid_entry(pos, table) { + freq = pos->frequency; - continue; - } if (!cpufreq_boost_enabled() - && (table[i].flags & CPUFREQ_BOOST_FREQ)) + && (pos->flags & CPUFREQ_BOOST_FREQ)) 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) min_freq = 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, 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; 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); - for (; freq = table[i].frequency, freq != CPUFREQ_TABLE_END; i++) { - if (freq == CPUFREQ_ENTRY_INVALID) - continue; + cpufreq_for_each_valid_entry(pos, table) { + freq = pos->frequency; + if ((freq >= policy->min) && (freq <= policy->max)) { found = true; break; @@ -118,7 +116,8 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy, .driver_data = ~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", target_freq, relation, policy->cpu); @@ -132,10 +131,10 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy, break; } - for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++) { - unsigned int freq = table[i].frequency; - if (freq == CPUFREQ_ENTRY_INVALID) - continue; + cpufreq_for_each_valid_entry(pos, table) { + freq = pos->frequency; + + i = pos - table; if ((freq < policy->min) || (freq > policy->max)) continue; switch (relation) { @@ -184,8 +183,7 @@ EXPORT_SYMBOL_GPL(cpufreq_frequency_table_target); int cpufreq_frequency_table_get_index(struct cpufreq_policy *policy, unsigned int freq) { - struct cpufreq_frequency_table *table; - int i; + struct cpufreq_frequency_table *pos, *table; table = cpufreq_frequency_get_table(policy->cpu); if (unlikely(!table)) { @@ -193,10 +191,9 @@ int cpufreq_frequency_table_get_index(struct cpufreq_policy *policy, return -ENOENT; } - for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) { - if (table[i].frequency == freq) - return i; - } + cpufreq_for_each_valid_entry(pos, table) + if (pos->frequency == freq) + return pos - table; 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, bool show_boost) { - unsigned int i = 0; ssize_t count = 0; - struct cpufreq_frequency_table *table = policy->freq_table; + struct cpufreq_frequency_table *pos, *table = policy->freq_table; if (!table) return -ENODEV; - for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++) { - if (table[i].frequency == CPUFREQ_ENTRY_INVALID) - continue; + cpufreq_for_each_valid_entry(pos, table) { /* * show_boost = true and driver_data = BOOST freq * 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 * display NON BOOST freqs */ - if (show_boost ^ (table[i].flags & CPUFREQ_BOOST_FREQ)) + if (show_boost ^ (pos->flags & CPUFREQ_BOOST_FREQ)) continue; - count += sprintf(&buf[count], "%d ", table[i].frequency); + count += sprintf(&buf[count], "%d ", pos->frequency); } count += sprintf(&buf[count], "\n"); diff --git a/drivers/cpufreq/longhaul.c b/drivers/cpufreq/longhaul.c index 5c4369b5d834d93f05095cf6052848ec2d2ddec4..c913906a719ee0f9b44598593b4900c201395596 100644 --- a/drivers/cpufreq/longhaul.c +++ b/drivers/cpufreq/longhaul.c @@ -530,6 +530,7 @@ static int longhaul_get_ranges(void) static void longhaul_setup_voltagescaling(void) { + struct cpufreq_frequency_table *freq_pos; union msr_longhaul longhaul; struct mV_pos minvid, maxvid, vid; unsigned int j, speed, pos, kHz_step, numvscales; @@ -608,18 +609,16 @@ static void longhaul_setup_voltagescaling(void) /* Calculate kHz for one voltage step */ kHz_step = (highest_speed - min_vid_speed) / numvscales; - j = 0; - while (longhaul_table[j].frequency != CPUFREQ_TABLE_END) { - speed = longhaul_table[j].frequency; + cpufreq_for_each_entry(freq_pos, longhaul_table) { + speed = freq_pos->frequency; if (speed > min_vid_speed) pos = (speed - min_vid_speed) / kHz_step + minvid.pos; else 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]]; printk(KERN_INFO PFX "f: %d kHz, index: %d, vid: %d mV\n", - speed, j, vid.mV); - j++; + speed, (int)(freq_pos - longhaul_table), vid.mV); } can_scale_voltage = 1; diff --git a/drivers/cpufreq/pasemi-cpufreq.c b/drivers/cpufreq/pasemi-cpufreq.c index 84c84b5f0f3a426d70738730b8715defc18bec20..35dd4d7ffee0824be3bd1bb0ce55eca7074a8da4 100644 --- a/drivers/cpufreq/pasemi-cpufreq.c +++ b/drivers/cpufreq/pasemi-cpufreq.c @@ -136,9 +136,10 @@ void restore_astate(int cpu) static int pas_cpufreq_cpu_init(struct cpufreq_policy *policy) { + struct cpufreq_frequency_table *pos; const u32 *max_freqp; u32 max_freq; - int i, cur_astate; + int cur_astate; struct resource res; struct device_node *cpu, *dn; int err = -ENODEV; @@ -197,10 +198,9 @@ static int pas_cpufreq_cpu_init(struct cpufreq_policy *policy) pr_debug("initializing frequency table\n"); /* initialize frequency table */ - for (i=0; pas_freqs[i].frequency!=CPUFREQ_TABLE_END; i++) { - pas_freqs[i].frequency = - get_astate_freq(pas_freqs[i].driver_data) * 100000; - pr_debug("%d: %d\n", i, pas_freqs[i].frequency); + cpufreq_for_each_entry(pos, pas_freqs) { + pos->frequency = get_astate_freq(pos->driver_data) * 100000; + pr_debug("%d: %d\n", (int)(pos - pas_freqs), pos->frequency); } cur_astate = get_cur_astate(policy->cpu); diff --git a/drivers/cpufreq/powernow-k6.c b/drivers/cpufreq/powernow-k6.c index 78904e6ca4a020d53a60f4139711441a069ad447..c8012bc869107206ad1fd7024ab86a76a406890e 100644 --- a/drivers/cpufreq/powernow-k6.c +++ b/drivers/cpufreq/powernow-k6.c @@ -151,6 +151,7 @@ static int powernow_k6_target(struct cpufreq_policy *policy, static int powernow_k6_cpu_init(struct cpufreq_policy *policy) { + struct cpufreq_frequency_table *pos; unsigned int i, f; unsigned khz; @@ -168,12 +169,11 @@ static int powernow_k6_cpu_init(struct cpufreq_policy *policy) } } if (param_max_multiplier) { - for (i = 0; (clock_ratio[i].frequency != CPUFREQ_TABLE_END); i++) { - if (clock_ratio[i].driver_data == param_max_multiplier) { + cpufreq_for_each_entry(pos, clock_ratio) + if (pos->driver_data == param_max_multiplier) { max_multiplier = param_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"); return -EINVAL; } @@ -201,12 +201,12 @@ static int powernow_k6_cpu_init(struct cpufreq_policy *policy) param_busfreq = busfreq * 10; /* table init */ - for (i = 0; (clock_ratio[i].frequency != CPUFREQ_TABLE_END); i++) { - f = clock_ratio[i].driver_data; + cpufreq_for_each_entry(pos, clock_ratio) { + f = pos->driver_data; if (f > max_multiplier) - clock_ratio[i].frequency = CPUFREQ_ENTRY_INVALID; + pos->frequency = CPUFREQ_ENTRY_INVALID; else - clock_ratio[i].frequency = busfreq * f; + pos->frequency = busfreq * f; } /* cpuinfo and default policy values */ diff --git a/drivers/cpufreq/ppc_cbe_cpufreq.c b/drivers/cpufreq/ppc_cbe_cpufreq.c index 5be8a48dba74fdca1d3d8b33ac02c93229b792c6..5a4c5a639f618f01074c5d1c73afa9b0e48352c3 100644 --- a/drivers/cpufreq/ppc_cbe_cpufreq.c +++ b/drivers/cpufreq/ppc_cbe_cpufreq.c @@ -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) { + struct cpufreq_frequency_table *pos; const u32 *max_freqp; u32 max_freq; - int i, cur_pmode; + int cur_pmode; struct device_node *cpu; 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"); /* initialize frequency table */ - for (i=0; cbe_freqs[i].frequency!=CPUFREQ_TABLE_END; i++) { - cbe_freqs[i].frequency = max_freq / cbe_freqs[i].driver_data; - pr_debug("%d: %d\n", i, cbe_freqs[i].frequency); + cpufreq_for_each_entry(pos, cbe_freqs) { + pos->frequency = max_freq / pos->driver_data; + pr_debug("%d: %d\n", (int)(pos - cbe_freqs), pos->frequency); } /* if DEBUG is enabled set_pmode() measures the latency diff --git a/drivers/cpufreq/s3c2416-cpufreq.c b/drivers/cpufreq/s3c2416-cpufreq.c index 4626f90559b55167869b86aa6c0349cb45d29d46..2fd53eaaec20bf30ef00d6a19226fba13670501a 100644 --- a/drivers/cpufreq/s3c2416-cpufreq.c +++ b/drivers/cpufreq/s3c2416-cpufreq.c @@ -266,7 +266,7 @@ static int s3c2416_cpufreq_set_target(struct cpufreq_policy *policy, static void __init s3c2416_cpufreq_cfg_regulator(struct s3c2416_data *s3c_freq) { int count, v, i, found; - struct cpufreq_frequency_table *freq; + struct cpufreq_frequency_table *pos; struct s3c2416_dvfs *dvfs; count = regulator_count_voltages(s3c_freq->vddarm); @@ -275,12 +275,11 @@ static void __init s3c2416_cpufreq_cfg_regulator(struct s3c2416_data *s3c_freq) return; } - freq = s3c_freq->freq_table; - while (count > 0 && freq->frequency != CPUFREQ_TABLE_END) { - if (freq->frequency == CPUFREQ_ENTRY_INVALID) - continue; + if (!count) + goto out; - 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; /* 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) { pr_debug("cpufreq: %dkHz unsupported by regulator\n", - freq->frequency); - freq->frequency = CPUFREQ_ENTRY_INVALID; + pos->frequency); + pos->frequency = CPUFREQ_ENTRY_INVALID; } - - freq++; } +out: /* Guessed */ 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) { struct s3c2416_data *s3c_freq = &s3c2416_cpufreq; - struct cpufreq_frequency_table *freq; + struct cpufreq_frequency_table *pos; struct clk *msysclk; unsigned long rate; int ret; @@ -427,31 +425,27 @@ static int __init s3c2416_cpufreq_driver_init(struct cpufreq_policy *policy) s3c_freq->regulator_latency = 0; #endif - freq = s3c_freq->freq_table; - while (freq->frequency != CPUFREQ_TABLE_END) { + cpufreq_for_each_entry(pos, s3c_freq->freq_table) { /* special handling for dvs mode */ - if (freq->driver_data == 0) { + if (pos->driver_data == 0) { if (!s3c_freq->hclk) { pr_debug("cpufreq: %dkHz unsupported as it would need unavailable dvs mode\n", - freq->frequency); - freq->frequency = CPUFREQ_ENTRY_INVALID; + pos->frequency); + pos->frequency = CPUFREQ_ENTRY_INVALID; } else { - freq++; continue; } } /* Check for frequencies we can generate */ rate = clk_round_rate(s3c_freq->armdiv, - freq->frequency * 1000); + pos->frequency * 1000); rate /= 1000; - if (rate != freq->frequency) { + if (rate != pos->frequency) { pr_debug("cpufreq: %dkHz unsupported by clock (clk_round_rate return %lu)\n", - freq->frequency, rate); - freq->frequency = CPUFREQ_ENTRY_INVALID; + pos->frequency, rate); + pos->frequency = CPUFREQ_ENTRY_INVALID; } - - freq++; } /* Datasheet says PLL stabalisation time must be at least 300us, diff --git a/drivers/cpufreq/s3c64xx-cpufreq.c b/drivers/cpufreq/s3c64xx-cpufreq.c index ff7d3ecb85f0f3c45430423942dc79a03f8837a6..176e84cc3991994871d6eee9a1b8927a3bdf95fa 100644 --- a/drivers/cpufreq/s3c64xx-cpufreq.c +++ b/drivers/cpufreq/s3c64xx-cpufreq.c @@ -118,11 +118,10 @@ static void __init s3c64xx_cpufreq_config_regulator(void) pr_err("Unable to check supported voltages\n"); } - freq = s3c64xx_freq_table; - while (count > 0 && freq->frequency != CPUFREQ_TABLE_END) { - if (freq->frequency == CPUFREQ_ENTRY_INVALID) - continue; + if (!count) + goto out; + cpufreq_for_each_valid_entry(freq, s3c64xx_freq_table) { dvfs = &s3c64xx_dvfs_table[freq->driver_data]; found = 0; @@ -137,10 +136,9 @@ static void __init s3c64xx_cpufreq_config_regulator(void) freq->frequency); freq->frequency = CPUFREQ_ENTRY_INVALID; } - - freq++; } +out: /* Guess based on having to do an I2C/SPI write; in future we * will be able to query the regulator performance here. */ regulator_latency = 1 * 1000 * 1000; @@ -179,8 +177,7 @@ static int s3c64xx_cpufreq_driver_init(struct cpufreq_policy *policy) } #endif - freq = s3c64xx_freq_table; - while (freq->frequency != CPUFREQ_TABLE_END) { + cpufreq_for_each_entry(freq, s3c64xx_freq_table) { unsigned long r; /* 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. */ if (!vddarm && freq->frequency > clk_get_rate(policy->clk) / 1000) freq->frequency = CPUFREQ_ENTRY_INVALID; - - freq++; } /* Datasheet says PLL stabalisation time (if we were to use diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c index 7694e0700d340329c5696c4ccba0417f9f93486f..b11fdd63eecdaa68b58cdefd9af1204c2bf69887 100644 --- a/drivers/mfd/db8500-prcmu.c +++ b/drivers/mfd/db8500-prcmu.c @@ -1734,18 +1734,17 @@ static struct cpufreq_frequency_table db8500_cpufreq_table[] = { static long round_armss_rate(unsigned long rate) { + struct cpufreq_frequency_table *pos; long freq = 0; - int i = 0; /* cpufreq table frequencies is in KHz. */ rate = rate / 1000; /* Find the corresponding arm opp from the cpufreq table. */ - while (db8500_cpufreq_table[i].frequency != CPUFREQ_TABLE_END) { - freq = db8500_cpufreq_table[i].frequency; + cpufreq_for_each_entry(pos, db8500_cpufreq_table) { + freq = pos->frequency; if (freq == rate) break; - i++; } /* 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) { - int i = 0; + struct cpufreq_frequency_table *pos; /* cpufreq table frequencies is in KHz. */ rate = rate / 1000; /* Find the corresponding arm opp from the cpufreq table. */ - while (db8500_cpufreq_table[i].frequency != CPUFREQ_TABLE_END) { - if (db8500_cpufreq_table[i].frequency == rate) + cpufreq_for_each_entry(pos, db8500_cpufreq_table) + if (pos->frequency == rate) break; - i++; - } - if (db8500_cpufreq_table[i].frequency != rate) + if (pos->frequency != rate) return -EINVAL; /* 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) diff --git a/drivers/net/irda/sh_sir.c b/drivers/net/irda/sh_sir.c index cadf52e224645f1f5f06f588447686015bf67e3a..e3fe9a286136a92a09708727295f42ef4b1254aa 100644 --- a/drivers/net/irda/sh_sir.c +++ b/drivers/net/irda/sh_sir.c @@ -217,21 +217,17 @@ static int sh_sir_crc_init(struct sh_sir_self *self) static u32 sh_sir_find_sclk(struct clk *irda_clk) { struct cpufreq_frequency_table *freq_table = irda_clk->freq_table; + struct cpufreq_frequency_table *pos; struct clk *pclk = clk_get(NULL, "peripheral_clk"); u32 limit, min = 0xffffffff, tmp; - int i, index = 0; + int index = 0; limit = clk_get_rate(pclk); clk_put(pclk); /* IrDA can not set over peripheral_clk */ - for (i = 0; - freq_table[i].frequency != CPUFREQ_TABLE_END; - i++) { - u32 freq = freq_table[i].frequency; - - if (freq == CPUFREQ_ENTRY_INVALID) - continue; + cpufreq_for_each_valid_entry(pos, freq_table) { + u32 freq = pos->frequency; /* IrDA should not over peripheral_clk */ if (freq > limit) @@ -240,7 +236,7 @@ static u32 sh_sir_find_sclk(struct clk *irda_clk) tmp = freq % SCLK_BASE; if (tmp < min) { min = tmp; - index = i; + index = pos - freq_table; } } diff --git a/drivers/sh/clk/core.c b/drivers/sh/clk/core.c index 74727851820df42e5b6471a0799357ad66e850e1..be56b22ca941a0ccb005429a0bc920e953a63b24 100644 --- a/drivers/sh/clk/core.c +++ b/drivers/sh/clk/core.c @@ -196,17 +196,11 @@ int clk_rate_table_find(struct clk *clk, struct cpufreq_frequency_table *freq_table, unsigned long rate) { - int i; - - for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) { - unsigned long freq = freq_table[i].frequency; + struct cpufreq_frequency_table *pos; - if (freq == CPUFREQ_ENTRY_INVALID) - continue; - - if (freq == rate) - return i; - } + cpufreq_for_each_valid_entry(pos, freq_table) + if (pos->frequency == rate) + return pos - freq_table; return -ENOENT; } @@ -575,11 +569,7 @@ long clk_round_parent(struct clk *clk, unsigned long target, return abs(target - *best_freq); } - for (freq = parent->freq_table; freq->frequency != CPUFREQ_TABLE_END; - freq++) { - if (freq->frequency == CPUFREQ_ENTRY_INVALID) - continue; - + cpufreq_for_each_valid_entry(freq, parent->freq_table) { if (unlikely(freq->frequency / target <= div_min - 1)) { unsigned long freq_max; diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c index 4246262c4bd249f5ee0d3cec5f3712d1fdd9bbc6..84a75f89bf74d07786989cd643b1cf327224c2ff 100644 --- a/drivers/thermal/cpu_cooling.c +++ b/drivers/thermal/cpu_cooling.c @@ -144,11 +144,11 @@ static int get_property(unsigned int cpu, unsigned long input, unsigned int *output, enum cpufreq_cooling_property property) { - int i, j; + int i; unsigned long max_level = 0, level = 0; unsigned int freq = CPUFREQ_ENTRY_INVALID; int descend = -1; - struct cpufreq_frequency_table *table = + struct cpufreq_frequency_table *pos, *table = cpufreq_frequency_get_table(cpu); if (!output) @@ -157,20 +157,16 @@ static int get_property(unsigned int cpu, unsigned long input, if (!table) return -EINVAL; - for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) { - /* ignore invalid entries */ - if (table[i].frequency == CPUFREQ_ENTRY_INVALID) - continue; - + cpufreq_for_each_valid_entry(pos, table) { /* ignore duplicate entry */ - if (freq == table[i].frequency) + if (freq == pos->frequency) continue; /* get the frequency order */ 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++; } @@ -190,29 +186,26 @@ static int get_property(unsigned int cpu, unsigned long input, if (property == GET_FREQ) level = descend ? input : (max_level - input); - for (i = 0, j = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) { - /* ignore invalid entry */ - if (table[i].frequency == CPUFREQ_ENTRY_INVALID) - continue; - + i = 0; + cpufreq_for_each_valid_entry(pos, table) { /* ignore duplicate entry */ - if (freq == table[i].frequency) + if (freq == pos->frequency) continue; /* now we have a valid frequency entry */ - freq = table[i].frequency; + freq = pos->frequency; if (property == GET_LEVEL && (unsigned int)input == freq) { /* get level by frequency */ - *output = descend ? j : (max_level - j); + *output = descend ? i : (max_level - i); return 0; } - if (property == GET_FREQ && level == j) { + if (property == GET_FREQ && level == i) { /* get frequency by level */ *output = freq; return 0; } - j++; + i++; } return -EINVAL; diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 5ae5100c1f2457ec9573870f2b90875031255a02..77a5fa191502fdf96528a3eccbf57f79cf3d9f6d 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -468,6 +468,27 @@ struct cpufreq_frequency_table { * 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, struct cpufreq_frequency_table *table);