Skip to content

Commit

Permalink
cpufreq: Notify all policy->cpus in cpufreq_notify_transition()
Browse files Browse the repository at this point in the history
policy->cpus contains all online cpus that have single shared clock line. And
their frequencies are always updated together.

Many SMP system's cpufreq drivers take care of this in individual drivers but
the best place for this code is in cpufreq core.

This patch modifies cpufreq_notify_transition() to notify frequency change for
all cpus in policy->cpus and hence updates all users of this API.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Acked-by: Stephen Warren <swarren@nvidia.com>
Tested-by: Stephen Warren <swarren@nvidia.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
  • Loading branch information
vireshk authored and rafaeljw committed Apr 2, 2013
1 parent fd143b4 commit b43a7ff
Show file tree
Hide file tree
Showing 51 changed files with 238 additions and 340 deletions.
5 changes: 2 additions & 3 deletions arch/arm/mach-davinci/cpufreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,6 @@ static int davinci_target(struct cpufreq_policy *policy,

freqs.old = davinci_getspeed(0);
freqs.new = clk_round_rate(armclk, target_freq * 1000) / 1000;
freqs.cpu = 0;

if (freqs.old == freqs.new)
return ret;
Expand All @@ -102,7 +101,7 @@ static int davinci_target(struct cpufreq_policy *policy,
if (ret)
return -EINVAL;

cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);

/* if moving to higher frequency, up the voltage beforehand */
if (pdata->set_voltage && freqs.new > freqs.old) {
Expand All @@ -126,7 +125,7 @@ static int davinci_target(struct cpufreq_policy *policy,
pdata->set_voltage(idx);

out:
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);

return ret;
}
Expand Down
5 changes: 2 additions & 3 deletions arch/arm/mach-imx/cpufreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,13 +87,12 @@ static int mxc_set_target(struct cpufreq_policy *policy,

freqs.old = clk_get_rate(cpu_clk) / 1000;
freqs.new = freq_Hz / 1000;
freqs.cpu = 0;
freqs.flags = 0;
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);

ret = set_cpu_freq(freq_Hz);

cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);

return ret;
}
Expand Down
6 changes: 2 additions & 4 deletions arch/arm/mach-integrator/cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,14 +123,12 @@ static int integrator_set_target(struct cpufreq_policy *policy,
vco = icst_hz_to_vco(&cclk_params, target_freq * 1000);
freqs.new = icst_hz(&cclk_params, vco) / 1000;

freqs.cpu = policy->cpu;

if (freqs.old == freqs.new) {
set_cpus_allowed(current, cpus_allowed);
return 0;
}

cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);

cm_osc = __raw_readl(CM_OSC);

Expand All @@ -151,7 +149,7 @@ static int integrator_set_target(struct cpufreq_policy *policy,
*/
set_cpus_allowed(current, cpus_allowed);

cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);

return 0;
}
Expand Down
5 changes: 2 additions & 3 deletions arch/arm/mach-pxa/cpufreq-pxa2xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,6 @@ static int pxa_set_target(struct cpufreq_policy *policy,
new_freq_mem = pxa_freq_settings[idx].membus;
freqs.old = policy->cur;
freqs.new = new_freq_cpu;
freqs.cpu = policy->cpu;

if (freq_debug)
pr_debug("Changing CPU frequency to %d Mhz, (SDRAM %d Mhz)\n",
Expand All @@ -327,7 +326,7 @@ static int pxa_set_target(struct cpufreq_policy *policy,
* you should add a notify client with any platform specific
* Vcc changing capability
*/
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);

/* Calculate the next MDREFR. If we're slowing down the SDRAM clock
* we need to preset the smaller DRI before the change. If we're
Expand Down Expand Up @@ -382,7 +381,7 @@ static int pxa_set_target(struct cpufreq_policy *policy,
* you should add a notify client with any platform specific
* SDRAM refresh timer adjustments
*/
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);

/*
* Even if voltage setting fails, we don't report it, as the frequency
Expand Down
5 changes: 2 additions & 3 deletions arch/arm/mach-pxa/cpufreq-pxa3xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,6 @@ static int pxa3xx_cpufreq_set(struct cpufreq_policy *policy,

freqs.old = policy->cur;
freqs.new = next->cpufreq_mhz * 1000;
freqs.cpu = policy->cpu;

pr_debug("CPU frequency from %d MHz to %d MHz%s\n",
freqs.old / 1000, freqs.new / 1000,
Expand All @@ -193,14 +192,14 @@ static int pxa3xx_cpufreq_set(struct cpufreq_policy *policy,
if (freqs.old == target_freq)
return 0;

cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);

local_irq_save(flags);
__update_core_freq(next);
__update_bus_freq(next);
local_irq_restore(flags);

cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);

return 0;
}
Expand Down
8 changes: 2 additions & 6 deletions arch/arm/mach-s3c24xx/cpufreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,6 @@ static int s3c_cpufreq_settarget(struct cpufreq_policy *policy,
freqs.old = cpu_cur.freq;
freqs.new = cpu_new.freq;

freqs.freqs.cpu = 0;
freqs.freqs.old = cpu_cur.freq.armclk / 1000;
freqs.freqs.new = cpu_new.freq.armclk / 1000;

Expand All @@ -218,9 +217,7 @@ static int s3c_cpufreq_settarget(struct cpufreq_policy *policy,
s3c_cpufreq_updateclk(clk_pclk, cpu_new.freq.pclk);

/* start the frequency change */

if (policy)
cpufreq_notify_transition(&freqs.freqs, CPUFREQ_PRECHANGE);
cpufreq_notify_transition(policy, &freqs.freqs, CPUFREQ_PRECHANGE);

/* If hclk is staying the same, then we do not need to
* re-write the IO or the refresh timings whilst we are changing
Expand Down Expand Up @@ -264,8 +261,7 @@ static int s3c_cpufreq_settarget(struct cpufreq_policy *policy,
local_irq_restore(flags);

/* notify everyone we've done this */
if (policy)
cpufreq_notify_transition(&freqs.freqs, CPUFREQ_POSTCHANGE);
cpufreq_notify_transition(policy, &freqs.freqs, CPUFREQ_POSTCHANGE);

s3c_freq_dbg("%s: finished\n", __func__);
return 0;
Expand Down
5 changes: 2 additions & 3 deletions arch/arm/mach-sa1100/cpu-sa1100.c
Original file line number Diff line number Diff line change
Expand Up @@ -201,9 +201,8 @@ static int sa1100_target(struct cpufreq_policy *policy,

freqs.old = cur;
freqs.new = sa11x0_ppcr_to_freq(new_ppcr);
freqs.cpu = 0;

cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);

if (freqs.new > cur)
sa1100_update_dram_timings(cur, freqs.new);
Expand All @@ -213,7 +212,7 @@ static int sa1100_target(struct cpufreq_policy *policy,
if (freqs.new < cur)
sa1100_update_dram_timings(cur, freqs.new);

cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);

return 0;
}
Expand Down
5 changes: 2 additions & 3 deletions arch/arm/mach-sa1100/cpu-sa1110.c
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,6 @@ static int sa1110_target(struct cpufreq_policy *policy,

freqs.old = sa11x0_getspeed(0);
freqs.new = sa11x0_ppcr_to_freq(ppcr);
freqs.cpu = 0;

sdram_calculate_timing(&sd, freqs.new, sdram);

Expand All @@ -279,7 +278,7 @@ static int sa1110_target(struct cpufreq_policy *policy,
sd.mdcas[2] = 0xaaaaaaaa;
#endif

cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);

/*
* The clock could be going away for some time. Set the SDRAMs
Expand Down Expand Up @@ -327,7 +326,7 @@ static int sa1110_target(struct cpufreq_policy *policy,
*/
sdram_update_refresh(freqs.new, sdram);

cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);

return 0;
}
Expand Down
15 changes: 8 additions & 7 deletions arch/arm/mach-tegra/cpu-tegra.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,8 @@ static int tegra_cpu_clk_set_rate(unsigned long rate)
return ret;
}

static int tegra_update_cpu_speed(unsigned long rate)
static int tegra_update_cpu_speed(struct cpufreq_policy *policy,
unsigned long rate)
{
int ret = 0;
struct cpufreq_freqs freqs;
Expand All @@ -128,8 +129,7 @@ static int tegra_update_cpu_speed(unsigned long rate)
else
clk_set_rate(emc_clk, 100000000); /* emc 50Mhz */

for_each_online_cpu(freqs.cpu)
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);

#ifdef CONFIG_CPU_FREQ_DEBUG
printk(KERN_DEBUG "cpufreq-tegra: transition: %u --> %u\n",
Expand All @@ -143,8 +143,7 @@ static int tegra_update_cpu_speed(unsigned long rate)
return ret;
}

for_each_online_cpu(freqs.cpu)
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);

return 0;
}
Expand Down Expand Up @@ -181,7 +180,7 @@ static int tegra_target(struct cpufreq_policy *policy,

target_cpu_speed[policy->cpu] = freq;

ret = tegra_update_cpu_speed(tegra_cpu_highest_speed());
ret = tegra_update_cpu_speed(policy, tegra_cpu_highest_speed());

out:
mutex_unlock(&tegra_cpu_lock);
Expand All @@ -193,10 +192,12 @@ static int tegra_pm_notify(struct notifier_block *nb, unsigned long event,
{
mutex_lock(&tegra_cpu_lock);
if (event == PM_SUSPEND_PREPARE) {
struct cpufreq_policy *policy = cpufreq_cpu_get(0);
is_suspended = true;
pr_info("Tegra cpufreq suspend: setting frequency to %d kHz\n",
freq_table[0].frequency);
tegra_update_cpu_speed(freq_table[0].frequency);
tegra_update_cpu_speed(policy, freq_table[0].frequency);
cpufreq_cpu_put(policy);
} else if (event == PM_POST_SUSPEND) {
is_suspended = false;
}
Expand Down
5 changes: 2 additions & 3 deletions arch/avr32/mach-at32ap/cpufreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,23 +61,22 @@ static int at32_set_target(struct cpufreq_policy *policy,

freqs.old = at32_get_speed(0);
freqs.new = (freq + 500) / 1000;
freqs.cpu = 0;
freqs.flags = 0;

if (!ref_freq) {
ref_freq = freqs.old;
loops_per_jiffy_ref = boot_cpu_data.loops_per_jiffy;
}

cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
if (freqs.old < freqs.new)
boot_cpu_data.loops_per_jiffy = cpufreq_scale(
loops_per_jiffy_ref, ref_freq, freqs.new);
clk_set_rate(cpuclk, freq);
if (freqs.new < freqs.old)
boot_cpu_data.loops_per_jiffy = cpufreq_scale(
loops_per_jiffy_ref, ref_freq, freqs.new);
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);

pr_debug("cpufreq: set frequency %lu Hz\n", freq);

Expand Down
79 changes: 34 additions & 45 deletions arch/blackfin/mach-common/cpufreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,13 +127,13 @@ unsigned long cpu_set_cclk(int cpu, unsigned long new)
}
#endif

static int bfin_target(struct cpufreq_policy *poli,
static int bfin_target(struct cpufreq_policy *policy,
unsigned int target_freq, unsigned int relation)
{
#ifndef CONFIG_BF60x
unsigned int plldiv;
#endif
unsigned int index, cpu;
unsigned int index;
unsigned long cclk_hz;
struct cpufreq_freqs freqs;
static unsigned long lpj_ref;
Expand All @@ -144,59 +144,48 @@ static int bfin_target(struct cpufreq_policy *poli,
cycles_t cycles;
#endif

for_each_online_cpu(cpu) {
struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
if (cpufreq_frequency_table_target(policy, bfin_freq_table, target_freq,
relation, &index))
return -EINVAL;

if (!policy)
continue;
cclk_hz = bfin_freq_table[index].frequency;

if (cpufreq_frequency_table_target(policy, bfin_freq_table,
target_freq, relation, &index))
return -EINVAL;
freqs.old = bfin_getfreq_khz(0);
freqs.new = cclk_hz;

cclk_hz = bfin_freq_table[index].frequency;
pr_debug("cpufreq: changing cclk to %lu; target = %u, oldfreq = %u\n",
cclk_hz, target_freq, freqs.old);

freqs.old = bfin_getfreq_khz(0);
freqs.new = cclk_hz;
freqs.cpu = cpu;

pr_debug("cpufreq: changing cclk to %lu; target = %u, oldfreq = %u\n",
cclk_hz, target_freq, freqs.old);

cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
if (cpu == CPUFREQ_CPU) {
cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
#ifndef CONFIG_BF60x
plldiv = (bfin_read_PLL_DIV() & SSEL) |
dpm_state_table[index].csel;
bfin_write_PLL_DIV(plldiv);
plldiv = (bfin_read_PLL_DIV() & SSEL) | dpm_state_table[index].csel;
bfin_write_PLL_DIV(plldiv);
#else
ret = cpu_set_cclk(cpu, freqs.new * 1000);
if (ret != 0) {
WARN_ONCE(ret, "cpufreq set freq failed %d\n", ret);
break;
}
ret = cpu_set_cclk(policy->cpu, freqs.new * 1000);
if (ret != 0) {
WARN_ONCE(ret, "cpufreq set freq failed %d\n", ret);
return ret;
}
#endif
on_each_cpu(bfin_adjust_core_timer, &index, 1);
on_each_cpu(bfin_adjust_core_timer, &index, 1);
#if defined(CONFIG_CYCLES_CLOCKSOURCE)
cycles = get_cycles();
SSYNC();
cycles += 10; /* ~10 cycles we lose after get_cycles() */
__bfin_cycles_off +=
(cycles << __bfin_cycles_mod) - (cycles << index);
__bfin_cycles_mod = index;
cycles = get_cycles();
SSYNC();
cycles += 10; /* ~10 cycles we lose after get_cycles() */
__bfin_cycles_off += (cycles << __bfin_cycles_mod) - (cycles << index);
__bfin_cycles_mod = index;
#endif
if (!lpj_ref_freq) {
lpj_ref = loops_per_jiffy;
lpj_ref_freq = freqs.old;
}
if (freqs.new != freqs.old) {
loops_per_jiffy = cpufreq_scale(lpj_ref,
lpj_ref_freq, freqs.new);
}
}
/* TODO: just test case for cycles clock source, remove later */
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
if (!lpj_ref_freq) {
lpj_ref = loops_per_jiffy;
lpj_ref_freq = freqs.old;
}
if (freqs.new != freqs.old) {
loops_per_jiffy = cpufreq_scale(lpj_ref,
lpj_ref_freq, freqs.new);
}

/* TODO: just test case for cycles clock source, remove later */
cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);

pr_debug("cpufreq: done\n");
return ret;
Expand Down
Loading

0 comments on commit b43a7ff

Please sign in to comment.