diff options
Diffstat (limited to 'drivers/cpufreq')
-rw-r--r-- | drivers/cpufreq/Kconfig.arm | 6 | ||||
-rw-r--r-- | drivers/cpufreq/acpi-cpufreq.c | 9 | ||||
-rw-r--r-- | drivers/cpufreq/arm_big_little.c | 16 | ||||
-rw-r--r-- | drivers/cpufreq/cpufreq.c | 11 | ||||
-rw-r--r-- | drivers/cpufreq/cpufreq_stats.c | 24 | ||||
-rw-r--r-- | drivers/cpufreq/dbx500-cpufreq.c | 8 | ||||
-rw-r--r-- | drivers/cpufreq/elanfreq.c | 9 | ||||
-rw-r--r-- | drivers/cpufreq/exynos-cpufreq.c | 11 | ||||
-rw-r--r-- | drivers/cpufreq/exynos5440-cpufreq.c | 30 | ||||
-rw-r--r-- | drivers/cpufreq/freq_table.c | 56 | ||||
-rw-r--r-- | drivers/cpufreq/intel_pstate.c | 34 | ||||
-rw-r--r-- | drivers/cpufreq/longhaul.c | 47 | ||||
-rw-r--r-- | drivers/cpufreq/loongson2_cpufreq.c | 4 | ||||
-rw-r--r-- | drivers/cpufreq/pasemi-cpufreq.c | 10 | ||||
-rw-r--r-- | drivers/cpufreq/powernow-k6.c | 37 | ||||
-rw-r--r-- | drivers/cpufreq/powernow-k7.c | 4 | ||||
-rw-r--r-- | drivers/cpufreq/powernv-cpufreq.c | 1 | ||||
-rw-r--r-- | drivers/cpufreq/ppc-corenet-cpufreq.c | 5 | ||||
-rw-r--r-- | drivers/cpufreq/ppc_cbe_cpufreq.c | 9 | ||||
-rw-r--r-- | drivers/cpufreq/s3c2416-cpufreq.c | 40 | ||||
-rw-r--r-- | drivers/cpufreq/s3c64xx-cpufreq.c | 15 | ||||
-rw-r--r-- | drivers/cpufreq/unicore2-cpufreq.c | 4 |
22 files changed, 189 insertions, 201 deletions
diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm index 0e9cce82844..580503513f0 100644 --- a/drivers/cpufreq/Kconfig.arm +++ b/drivers/cpufreq/Kconfig.arm @@ -92,11 +92,7 @@ config ARM_EXYNOS_CPU_FREQ_BOOST_SW config ARM_HIGHBANK_CPUFREQ tristate "Calxeda Highbank-based" - depends on ARCH_HIGHBANK - select GENERIC_CPUFREQ_CPU0 - select PM_OPP - select REGULATOR - + depends on ARCH_HIGHBANK && GENERIC_CPUFREQ_CPU0 && REGULATOR default m help This adds the CPUFreq driver for Calxeda Highbank SoC diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c index 000e4e0afd7..b0c18ed8d83 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 bad2ed317ba..1f4d4e31505 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 abda6609d3e..a517da996aa 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 ecaaebf969f..0cd9b4dcef9 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 412a78bb0c9..4bebc1b5db4 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 7f5d2a68c35..1c06e786c9b 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 f99cfe24e7b..9c132550d91 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 a6b8214d7b7..f33f25b483c 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 08e7bbcf6d7..8e518c68939 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/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index 099967302bf..eab8ccfe6be 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c @@ -37,6 +37,7 @@ #define BYT_RATIOS 0x66a #define BYT_VIDS 0x66b #define BYT_TURBO_RATIOS 0x66c +#define BYT_TURBO_VIDS 0x66d #define FRAC_BITS 6 @@ -70,8 +71,9 @@ struct pstate_data { }; struct vid_data { - int32_t min; - int32_t max; + int min; + int max; + int turbo; int32_t ratio; }; @@ -359,14 +361,14 @@ static int byt_get_min_pstate(void) { u64 value; rdmsrl(BYT_RATIOS, value); - return (value >> 8) & 0xFF; + return (value >> 8) & 0x3F; } static int byt_get_max_pstate(void) { u64 value; rdmsrl(BYT_RATIOS, value); - return (value >> 16) & 0xFF; + return (value >> 16) & 0x3F; } static int byt_get_turbo_pstate(void) @@ -393,6 +395,9 @@ static void byt_set_pstate(struct cpudata *cpudata, int pstate) vid_fp = clamp_t(int32_t, vid_fp, cpudata->vid.min, cpudata->vid.max); vid = fp_toint(vid_fp); + if (pstate > cpudata->pstate.max_pstate) + vid = cpudata->vid.turbo; + val |= vid; wrmsrl(MSR_IA32_PERF_CTL, val); @@ -402,13 +407,17 @@ static void byt_get_vid(struct cpudata *cpudata) { u64 value; + rdmsrl(BYT_VIDS, value); - cpudata->vid.min = int_tofp((value >> 8) & 0x7f); - cpudata->vid.max = int_tofp((value >> 16) & 0x7f); + cpudata->vid.min = int_tofp((value >> 8) & 0x3f); + cpudata->vid.max = int_tofp((value >> 16) & 0x3f); cpudata->vid.ratio = div_fp( cpudata->vid.max - cpudata->vid.min, int_tofp(cpudata->pstate.max_pstate - cpudata->pstate.min_pstate)); + + rdmsrl(BYT_TURBO_VIDS, value); + cpudata->vid.turbo = value & 0x7f; } @@ -545,12 +554,7 @@ static void intel_pstate_get_cpu_pstates(struct cpudata *cpu) if (pstate_funcs.get_vid) pstate_funcs.get_vid(cpu); - - /* - * goto max pstate so we don't slow up boot if we are built-in if we are - * a module we will take care of it during normal operation - */ - intel_pstate_set_pstate(cpu, cpu->pstate.max_pstate); + intel_pstate_set_pstate(cpu, cpu->pstate.min_pstate); } static inline void intel_pstate_calc_busy(struct cpudata *cpu, @@ -695,11 +699,6 @@ static int intel_pstate_init_cpu(unsigned int cpunum) cpu = all_cpu_data[cpunum]; intel_pstate_get_cpu_pstates(cpu); - if (!cpu->pstate.current_pstate) { - all_cpu_data[cpunum] = NULL; - kfree(cpu); - return -ENODATA; - } cpu->cpu = cpunum; @@ -710,7 +709,6 @@ static int intel_pstate_init_cpu(unsigned int cpunum) cpu->timer.expires = jiffies + HZ/100; intel_pstate_busy_pid_reset(cpu); intel_pstate_sample(cpu); - intel_pstate_set_pstate(cpu, cpu->pstate.max_pstate); add_timer_on(&cpu->timer, cpunum); diff --git a/drivers/cpufreq/longhaul.c b/drivers/cpufreq/longhaul.c index d00e5d1abd2..c913906a719 100644 --- a/drivers/cpufreq/longhaul.c +++ b/drivers/cpufreq/longhaul.c @@ -242,7 +242,7 @@ static void do_powersaver(int cx_address, unsigned int mults_index, * Sets a new clock ratio. */ -static void longhaul_setstate(struct cpufreq_policy *policy, +static int longhaul_setstate(struct cpufreq_policy *policy, unsigned int table_index) { unsigned int mults_index; @@ -258,10 +258,12 @@ static void longhaul_setstate(struct cpufreq_policy *policy, /* Safety precautions */ mult = mults[mults_index & 0x1f]; if (mult == -1) - return; + return -EINVAL; + speed = calc_speed(mult); if ((speed > highest_speed) || (speed < lowest_speed)) - return; + return -EINVAL; + /* Voltage transition before frequency transition? */ if (can_scale_voltage && longhaul_index < table_index) dir = 1; @@ -269,8 +271,6 @@ static void longhaul_setstate(struct cpufreq_policy *policy, freqs.old = calc_speed(longhaul_get_cpu_mult()); freqs.new = speed; - cpufreq_freq_transition_begin(policy, &freqs); - pr_debug("Setting to FSB:%dMHz Mult:%d.%dx (%s)\n", fsb, mult/10, mult%10, print_speed(speed/1000)); retry_loop: @@ -385,12 +385,14 @@ retry_loop: goto retry_loop; } } - /* Report true CPU frequency */ - cpufreq_freq_transition_end(policy, &freqs, 0); - if (!bm_timeout) + if (!bm_timeout) { printk(KERN_INFO PFX "Warning: Timeout while waiting for " "idle PCI bus.\n"); + return -EBUSY; + } + + return 0; } /* @@ -528,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; @@ -606,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; @@ -631,9 +632,10 @@ static int longhaul_target(struct cpufreq_policy *policy, unsigned int i; unsigned int dir = 0; u8 vid, current_vid; + int retval = 0; if (!can_scale_voltage) - longhaul_setstate(policy, table_index); + retval = longhaul_setstate(policy, table_index); else { /* On test system voltage transitions exceeding single * step up or down were turning motherboard off. Both @@ -648,7 +650,7 @@ static int longhaul_target(struct cpufreq_policy *policy, while (i != table_index) { vid = (longhaul_table[i].driver_data >> 8) & 0x1f; if (vid != current_vid) { - longhaul_setstate(policy, i); + retval = longhaul_setstate(policy, i); current_vid = vid; msleep(200); } @@ -657,10 +659,11 @@ static int longhaul_target(struct cpufreq_policy *policy, else i--; } - longhaul_setstate(policy, table_index); + retval = longhaul_setstate(policy, table_index); } + longhaul_index = table_index; - return 0; + return retval; } @@ -968,7 +971,15 @@ static void __exit longhaul_exit(void) for (i = 0; i < numscales; i++) { if (mults[i] == maxmult) { + struct cpufreq_freqs freqs; + + freqs.old = policy->cur; + freqs.new = longhaul_table[i].frequency; + freqs.flags = 0; + + cpufreq_freq_transition_begin(policy, &freqs); longhaul_setstate(policy, i); + cpufreq_freq_transition_end(policy, &freqs, 0); break; } } diff --git a/drivers/cpufreq/loongson2_cpufreq.c b/drivers/cpufreq/loongson2_cpufreq.c index f0bc31f5db2..d4add862194 100644 --- a/drivers/cpufreq/loongson2_cpufreq.c +++ b/drivers/cpufreq/loongson2_cpufreq.c @@ -62,7 +62,7 @@ static int loongson2_cpufreq_target(struct cpufreq_policy *policy, set_cpus_allowed_ptr(current, &cpus_allowed); /* setting the cpu frequency */ - clk_set_rate(policy->clk, freq); + clk_set_rate(policy->clk, freq * 1000); return 0; } @@ -92,7 +92,7 @@ static int loongson2_cpufreq_cpu_init(struct cpufreq_policy *policy) i++) loongson2_clockmod_table[i].frequency = (rate * i) / 8; - ret = clk_set_rate(cpuclk, rate); + ret = clk_set_rate(cpuclk, rate * 1000); if (ret) { clk_put(cpuclk); return ret; diff --git a/drivers/cpufreq/pasemi-cpufreq.c b/drivers/cpufreq/pasemi-cpufreq.c index 84c84b5f0f3..35dd4d7ffee 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 49f120e1bc7..c8012bc8691 100644 --- a/drivers/cpufreq/powernow-k6.c +++ b/drivers/cpufreq/powernow-k6.c @@ -138,27 +138,20 @@ static void powernow_k6_set_cpu_multiplier(unsigned int best_i) static int powernow_k6_target(struct cpufreq_policy *policy, unsigned int best_i) { - struct cpufreq_freqs freqs; if (clock_ratio[best_i].driver_data > max_multiplier) { printk(KERN_ERR PFX "invalid target frequency\n"); return -EINVAL; } - freqs.old = busfreq * powernow_k6_get_cpu_multiplier(); - freqs.new = busfreq * clock_ratio[best_i].driver_data; - - cpufreq_freq_transition_begin(policy, &freqs); - powernow_k6_set_cpu_multiplier(best_i); - cpufreq_freq_transition_end(policy, &freqs, 0); - return 0; } static int powernow_k6_cpu_init(struct cpufreq_policy *policy) { + struct cpufreq_frequency_table *pos; unsigned int i, f; unsigned khz; @@ -176,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; } @@ -209,12 +201,12 @@ have_busfreq: 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 */ @@ -227,9 +219,20 @@ have_busfreq: static int powernow_k6_cpu_exit(struct cpufreq_policy *policy) { unsigned int i; - for (i = 0; i < 8; i++) { - if (i == max_multiplier) + + for (i = 0; (clock_ratio[i].frequency != CPUFREQ_TABLE_END); i++) { + if (clock_ratio[i].driver_data == max_multiplier) { + struct cpufreq_freqs freqs; + + freqs.old = policy->cur; + freqs.new = clock_ratio[i].frequency; + freqs.flags = 0; + + cpufreq_freq_transition_begin(policy, &freqs); powernow_k6_target(policy, i); + cpufreq_freq_transition_end(policy, &freqs, 0); + break; + } } return 0; } diff --git a/drivers/cpufreq/powernow-k7.c b/drivers/cpufreq/powernow-k7.c index f911645c3f6..e61e224475a 100644 --- a/drivers/cpufreq/powernow-k7.c +++ b/drivers/cpufreq/powernow-k7.c @@ -269,8 +269,6 @@ static int powernow_target(struct cpufreq_policy *policy, unsigned int index) freqs.new = powernow_table[index].frequency; - cpufreq_freq_transition_begin(policy, &freqs); - /* Now do the magic poking into the MSRs. */ if (have_a0 == 1) /* A0 errata 5 */ @@ -290,8 +288,6 @@ static int powernow_target(struct cpufreq_policy *policy, unsigned int index) if (have_a0 == 1) local_irq_enable(); - cpufreq_freq_transition_end(policy, &freqs, 0); - return 0; } diff --git a/drivers/cpufreq/powernv-cpufreq.c b/drivers/cpufreq/powernv-cpufreq.c index 9edccc63245..af4968813e7 100644 --- a/drivers/cpufreq/powernv-cpufreq.c +++ b/drivers/cpufreq/powernv-cpufreq.c @@ -29,6 +29,7 @@ #include <asm/cputhreads.h> #include <asm/reg.h> +#include <asm/smp.h> /* Required for cpu_sibling_mask() in UP configs */ #define POWERNV_MAX_PSTATES 256 diff --git a/drivers/cpufreq/ppc-corenet-cpufreq.c b/drivers/cpufreq/ppc-corenet-cpufreq.c index b7e677be1df..0af618abeba 100644 --- a/drivers/cpufreq/ppc-corenet-cpufreq.c +++ b/drivers/cpufreq/ppc-corenet-cpufreq.c @@ -138,6 +138,7 @@ static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy) struct cpufreq_frequency_table *table; struct cpu_data *data; unsigned int cpu = policy->cpu; + u64 transition_latency_hz; np = of_get_cpu_node(cpu, NULL); if (!np) @@ -205,8 +206,10 @@ static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy) for_each_cpu(i, per_cpu(cpu_mask, cpu)) per_cpu(cpu_data, i) = data; + transition_latency_hz = 12ULL * NSEC_PER_SEC; policy->cpuinfo.transition_latency = - (12 * NSEC_PER_SEC) / fsl_get_sys_freq(); + do_div(transition_latency_hz, fsl_get_sys_freq()); + of_node_put(np); return 0; diff --git a/drivers/cpufreq/ppc_cbe_cpufreq.c b/drivers/cpufreq/ppc_cbe_cpufreq.c index 5be8a48dba7..5a4c5a639f6 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 4626f90559b..2fd53eaaec2 100644 --- a/drivers/cpufreq/s3c2416-cpufreq.c +++ b/drivers/cpufreq/s3c2416-cpufreq.c @@ -266,7 +266,7 @@ out: 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 ff7d3ecb85f..176e84cc399 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/cpufreq/unicore2-cpufreq.c b/drivers/cpufreq/unicore2-cpufreq.c index 8d045afa7fb..6f9dfa80563 100644 --- a/drivers/cpufreq/unicore2-cpufreq.c +++ b/drivers/cpufreq/unicore2-cpufreq.c @@ -60,9 +60,7 @@ static int __init ucv2_cpu_init(struct cpufreq_policy *policy) policy->max = policy->cpuinfo.max_freq = 1000000; policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; policy->clk = clk_get(NULL, "MAIN_CLK"); - if (IS_ERR(policy->clk)) - return PTR_ERR(policy->clk); - return 0; + return PTR_ERR_OR_ZERO(policy->clk); } static struct cpufreq_driver ucv2_driver = { |