Skip to content

Commit

Permalink
Merge branch 'cpufreq-macros' into pm-cpufreq
Browse files Browse the repository at this point in the history
  • Loading branch information
Rafael J. Wysocki committed Apr 30, 2014
2 parents 6712d29 + 4229e1c commit 89d4f82
Show file tree
Hide file tree
Showing 23 changed files with 208 additions and 216 deletions.
19 changes: 19 additions & 0 deletions Documentation/cpu-freq/cpu-drivers.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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 = ...
}
9 changes: 5 additions & 4 deletions arch/arm/mach-davinci/da850.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}

Expand Down
16 changes: 5 additions & 11 deletions arch/mips/loongson/lemote-2f/clock.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down
9 changes: 4 additions & 5 deletions drivers/cpufreq/acpi-cpufreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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;
}

Expand Down
16 changes: 8 additions & 8 deletions drivers/cpufreq/arm_big_little.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
11 changes: 11 additions & 0 deletions drivers/cpufreq/cpufreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 *
*********************************************************************/
Expand Down
24 changes: 8 additions & 16 deletions drivers/cpufreq/cpufreq_stats.c
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand All @@ -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);

Expand All @@ -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);
Expand Down
8 changes: 3 additions & 5 deletions drivers/cpufreq/dbx500-cpufreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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);
}
Expand Down
9 changes: 4 additions & 5 deletions drivers/cpufreq/elanfreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) ||
Expand All @@ -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;
Expand Down
11 changes: 5 additions & 6 deletions drivers/cpufreq/exynos-cpufreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
30 changes: 15 additions & 15 deletions drivers/cpufreq/exynos5440-cpufreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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();
Expand All @@ -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);

Expand All @@ -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",
Expand All @@ -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);
}

Expand Down
Loading

0 comments on commit 89d4f82

Please sign in to comment.