Skip to content
Commit 32b66d78 authored by James Morse's avatar James Morse
Browse files

clocksource/drivers/arm_arch_timer: Save/restore the enabled bits over idle



When a CPU enters low power mode using PSCI's CPU_SUSPEND, the 'pm'
notify chain is triggered. The arch-timer uses this to save/restore
the event stream configuration and the traps in CNTKCTL_EL1. It doesn't
save/restore the timer counter match or control register. The control
register is where the enable bit for the interrupt lives. Interrupts are
(re-)enabled when set_next_event is called, which happens when the timer
interrupt fires.

When CPUs return via the cold path with the MMU off, all the system
registers will have been reset. On Juno the timer configuration registers
reset value has the enabled bit clear.

The existing code depends on the timer interrupt fire-ing and being
latched by the interrupt controller - before the CPU powers up and
resets the timer control register. Linux takes the timer interrupt
after returning from idle, and re-configures the timer.

This is a problem when the timer interrupt wasn't the reason the CPU
woke from idle. The timer interrupt has been disabled when the CPU
got reset, and the timer interrupt is not pending in the interrupt
controller because that wasn't the reason the CPU woke from idle.
The result is all the CPUs sitting in the idle thread.

Add helpers to save/restore the counter value and the control register.
In most cases this will cause the timer interrupt to become pending
again, as its level triggered this is harmless.

Fixes: 346e7480 ("drivers: clocksource: add CPU PM notifier for ARM architected timer")
Signed-off-by: James Morse's avatarJames Morse <james.morse@arm.com>
----
Discovered when implementing this in kvmtool (PSCI in user-space) with
idle-states that return immediately.
parent 58ec9598
Loading
Loading
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment