mirror of
https://github.com/FEX-Emu/linux.git
synced 2024-12-17 14:30:00 +00:00
ARM: 7212/1: smp_twd: reconfigure clockevents after cpufreq change
This break-out from Colin Cross' cpufreq-aware TWD patch will handle the case when our localtimer's clock changes with the cpu clock. A cpufreq transtion notifier will be registered only if the platform has supplied a specified clock to the TWD. After a cpufreq transition, update the clockevent's frequency by fetching the new clock rate from the clock framework and reprogram the next clock event. The necessary changes in the clockevents framework was done by Thomas Gleixner in kernel v3.0. ChangeLog v1->v2: - Replace IS_ERR_OR_NULL() with IS_ERR() in twd_clk check. - Update code to use the already existing per-cpu array of TWD clockevents instead of adding cruft. [Broke out, ifdef:ed CPUfreq stuff for non-cpufreq configs] [Rebased to newer TWD base with per-CPU clock array] Signed-off-by: Colin Cross <ccross@android.com> Acked-by: Thomas Gleixner <tglx@linutronix.de> Acked-by: Rob Herring <rob.herring@calxeda.com> Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
This commit is contained in:
parent
5def51b0f8
commit
4fd7f9b128
@ -11,6 +11,7 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/cpufreq.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/err.h>
|
||||
@ -92,6 +93,52 @@ void twd_timer_stop(struct clock_event_device *clk)
|
||||
disable_percpu_irq(clk->irq);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CPU_FREQ
|
||||
|
||||
/*
|
||||
* Updates clockevent frequency when the cpu frequency changes.
|
||||
* Called on the cpu that is changing frequency with interrupts disabled.
|
||||
*/
|
||||
static void twd_update_frequency(void *data)
|
||||
{
|
||||
twd_timer_rate = clk_get_rate(twd_clk);
|
||||
|
||||
clockevents_update_freq(*__this_cpu_ptr(twd_evt), twd_timer_rate);
|
||||
}
|
||||
|
||||
static int twd_cpufreq_transition(struct notifier_block *nb,
|
||||
unsigned long state, void *data)
|
||||
{
|
||||
struct cpufreq_freqs *freqs = data;
|
||||
|
||||
/*
|
||||
* The twd clock events must be reprogrammed to account for the new
|
||||
* frequency. The timer is local to a cpu, so cross-call to the
|
||||
* changing cpu.
|
||||
*/
|
||||
if (state == CPUFREQ_POSTCHANGE || state == CPUFREQ_RESUMECHANGE)
|
||||
smp_call_function_single(freqs->cpu, twd_update_frequency,
|
||||
NULL, 1);
|
||||
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
static struct notifier_block twd_cpufreq_nb = {
|
||||
.notifier_call = twd_cpufreq_transition,
|
||||
};
|
||||
|
||||
static int twd_cpufreq_init(void)
|
||||
{
|
||||
if (!IS_ERR(twd_clk))
|
||||
return cpufreq_register_notifier(&twd_cpufreq_nb,
|
||||
CPUFREQ_TRANSITION_NOTIFIER);
|
||||
|
||||
return 0;
|
||||
}
|
||||
core_initcall(twd_cpufreq_init);
|
||||
|
||||
#endif
|
||||
|
||||
static void __cpuinit twd_calibrate_rate(void)
|
||||
{
|
||||
unsigned long count;
|
||||
|
Loading…
Reference in New Issue
Block a user