Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6f3d90e5 authored by Will Deacon's avatar Will Deacon Committed by Russell King
Browse files

ARM: 7685/1: delay: use private ticks_per_jiffy field for timer-based delay ops



Commit 70264367 ("ARM: 7653/2: do not scale loops_per_jiffy when
using a constant delay clock") fixed a problem with our timer-based
delay loop, where loops_per_jiffy is scaled by cpufreq yet used directly
by the timer delay ops.

This patch fixes the problem in a more elegant way by keeping a private
ticks_per_jiffy field in the delay ops, independent of loops_per_jiffy
and therefore not subject to scaling. The loop-based delay continues to
use loops_per_jiffy directly, as it should.

Acked-by: default avatarNicolas Pitre <nico@linaro.org>
Signed-off-by: default avatarWill Deacon <will.deacon@arm.com>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 93dc6887
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -24,7 +24,7 @@ extern struct arm_delay_ops {
	void (*delay)(unsigned long);
	void (*const_udelay)(unsigned long);
	void (*udelay)(unsigned long);
	bool const_clock;
	unsigned long ticks_per_jiffy;
} arm_delay_ops;

#define __delay(n)		arm_delay_ops.delay(n)
+0 −3
Original line number Diff line number Diff line
@@ -673,9 +673,6 @@ static int cpufreq_callback(struct notifier_block *nb,
	if (freq->flags & CPUFREQ_CONST_LOOPS)
		return NOTIFY_OK;

	if (arm_delay_ops.const_clock)
		return NOTIFY_OK;

	if (!per_cpu(l_p_j_ref, cpu)) {
		per_cpu(l_p_j_ref, cpu) =
			per_cpu(cpu_data, cpu).loops_per_jiffy;
+5 −3
Original line number Diff line number Diff line
@@ -58,7 +58,7 @@ static void __timer_delay(unsigned long cycles)
static void __timer_const_udelay(unsigned long xloops)
{
	unsigned long long loops = xloops;
	loops *= loops_per_jiffy;
	loops *= arm_delay_ops.ticks_per_jiffy;
	__timer_delay(loops >> UDELAY_SHIFT);
}

@@ -73,11 +73,13 @@ void __init register_current_timer_delay(const struct delay_timer *timer)
		pr_info("Switching to timer-based delay loop\n");
		delay_timer			= timer;
		lpj_fine			= timer->freq / HZ;
		loops_per_jiffy			= lpj_fine;

		/* cpufreq may scale loops_per_jiffy, so keep a private copy */
		arm_delay_ops.ticks_per_jiffy	= lpj_fine;
		arm_delay_ops.delay		= __timer_delay;
		arm_delay_ops.const_udelay	= __timer_const_udelay;
		arm_delay_ops.udelay		= __timer_udelay;
		arm_delay_ops.const_clock	= true;

		delay_calibrated		= true;
	} else {
		pr_info("Ignoring duplicate/late registration of read_current_timer delay\n");