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

Commit d8ec7595 authored by Brian Norris's avatar Brian Norris Committed by Daniel Lezcano
Browse files

clocksource/drivers/arm_arch_timer: Don't assume clock runs in suspend



The ARM specifies that the system counter "must be implemented in an
always-on power domain," and so we try to use the counter as a source of
timekeeping across suspend/resume. Unfortunately, some SoCs (e.g.,
Rockchip's RK3399) do not keep the counter ticking properly when
switched from their high-power clock to the lower-power clock used in
system suspend. Support this quirk by adding a new device tree property.

Signed-off-by: default avatarBrian Norris <briannorris@chromium.org>
Reviewed-by: default avatarDouglas Anderson <dianders@chromium.org>
Acked-by: default avatarMarc Zyngier <marc.zyngier@arm.com>
Signed-off-by: default avatarDaniel Lezcano <daniel.lezcano@linaro.org>
parent baa73d9e
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -38,6 +38,11 @@ to deliver its interrupts via SPIs.
  architecturally-defined reset values. Only supported for 32-bit
  systems which follow the ARMv7 architected reset values.

- arm,no-tick-in-suspend : The main counter does not tick when the system is in
  low-power system suspend on some SoCs. This behavior does not match the
  Architecture Reference Manual's specification that the system counter "must
  be implemented in an always-on power domain."


Example:

+8 −1
Original line number Diff line number Diff line
@@ -81,6 +81,7 @@ static struct clock_event_device __percpu *arch_timer_evt;
static enum ppi_nr arch_timer_uses_ppi = VIRT_PPI;
static bool arch_timer_c3stop;
static bool arch_timer_mem_use_virtual;
static bool arch_counter_suspend_stop;

static bool evtstrm_enable = IS_ENABLED(CONFIG_ARM_ARCH_TIMER_EVTSTREAM);

@@ -576,7 +577,7 @@ static struct clocksource clocksource_counter = {
	.rating	= 400,
	.read	= arch_counter_read,
	.mask	= CLOCKSOURCE_MASK(56),
	.flags	= CLOCK_SOURCE_IS_CONTINUOUS | CLOCK_SOURCE_SUSPEND_NONSTOP,
	.flags	= CLOCK_SOURCE_IS_CONTINUOUS,
};

static struct cyclecounter cyclecounter = {
@@ -616,6 +617,8 @@ static void __init arch_counter_register(unsigned type)
		arch_timer_read_counter = arch_counter_get_cntvct_mem;
	}

	if (!arch_counter_suspend_stop)
		clocksource_counter.flags |= CLOCK_SOURCE_SUSPEND_NONSTOP;
	start_count = arch_timer_read_counter();
	clocksource_register_hz(&clocksource_counter, arch_timer_rate);
	cyclecounter.mult = clocksource_counter.mult;
@@ -907,6 +910,10 @@ static int __init arch_timer_of_init(struct device_node *np)
	    of_property_read_bool(np, "arm,cpu-registers-not-fw-configured"))
		arch_timer_uses_ppi = PHYS_SECURE_PPI;

	/* On some systems, the counter stops ticking when in suspend. */
	arch_counter_suspend_stop = of_property_read_bool(np,
							 "arm,no-tick-in-suspend");

	return arch_timer_init();
}
CLOCKSOURCE_OF_DECLARE(armv7_arch_timer, "arm,armv7-timer", arch_timer_of_init);