diff options
author | Brian Norris <briannorris@chromium.org> | 2017-04-04 15:32:05 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-04-12 06:41:16 -0400 |
commit | 26cbe162df3d0282e5108711663b8dcdafb1ad33 (patch) | |
tree | c8dd2fc66bb25fc646f349c6cae47b1b18829e28 /drivers/clocksource/arm_arch_timer.c | |
parent | d2f1000c3ae3ce285d99dae444f85baa53c1dfe6 (diff) |
clocksource/drivers/arm_arch_timer: Don't assume clock runs in suspend
[ Upstream commit d8ec7595a013237f82d965dcf981571aeb41855b ]
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: Brian Norris <briannorris@chromium.org>
Reviewed-by: Douglas Anderson <dianders@chromium.org>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Signed-off-by: Sasha Levin <alexander.levin@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/clocksource/arm_arch_timer.c')
-rw-r--r-- | drivers/clocksource/arm_arch_timer.c | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index 73c487da6d2a..a2503db7e533 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c | |||
@@ -81,6 +81,7 @@ static struct clock_event_device __percpu *arch_timer_evt; | |||
81 | static enum ppi_nr arch_timer_uses_ppi = VIRT_PPI; | 81 | static enum ppi_nr arch_timer_uses_ppi = VIRT_PPI; |
82 | static bool arch_timer_c3stop; | 82 | static bool arch_timer_c3stop; |
83 | static bool arch_timer_mem_use_virtual; | 83 | static bool arch_timer_mem_use_virtual; |
84 | static bool arch_counter_suspend_stop; | ||
84 | 85 | ||
85 | static bool evtstrm_enable = IS_ENABLED(CONFIG_ARM_ARCH_TIMER_EVTSTREAM); | 86 | static bool evtstrm_enable = IS_ENABLED(CONFIG_ARM_ARCH_TIMER_EVTSTREAM); |
86 | 87 | ||
@@ -576,7 +577,7 @@ static struct clocksource clocksource_counter = { | |||
576 | .rating = 400, | 577 | .rating = 400, |
577 | .read = arch_counter_read, | 578 | .read = arch_counter_read, |
578 | .mask = CLOCKSOURCE_MASK(56), | 579 | .mask = CLOCKSOURCE_MASK(56), |
579 | .flags = CLOCK_SOURCE_IS_CONTINUOUS | CLOCK_SOURCE_SUSPEND_NONSTOP, | 580 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, |
580 | }; | 581 | }; |
581 | 582 | ||
582 | static struct cyclecounter cyclecounter = { | 583 | static struct cyclecounter cyclecounter = { |
@@ -616,6 +617,8 @@ static void __init arch_counter_register(unsigned type) | |||
616 | arch_timer_read_counter = arch_counter_get_cntvct_mem; | 617 | arch_timer_read_counter = arch_counter_get_cntvct_mem; |
617 | } | 618 | } |
618 | 619 | ||
620 | if (!arch_counter_suspend_stop) | ||
621 | clocksource_counter.flags |= CLOCK_SOURCE_SUSPEND_NONSTOP; | ||
619 | start_count = arch_timer_read_counter(); | 622 | start_count = arch_timer_read_counter(); |
620 | clocksource_register_hz(&clocksource_counter, arch_timer_rate); | 623 | clocksource_register_hz(&clocksource_counter, arch_timer_rate); |
621 | cyclecounter.mult = clocksource_counter.mult; | 624 | cyclecounter.mult = clocksource_counter.mult; |
@@ -907,6 +910,10 @@ static int __init arch_timer_of_init(struct device_node *np) | |||
907 | of_property_read_bool(np, "arm,cpu-registers-not-fw-configured")) | 910 | of_property_read_bool(np, "arm,cpu-registers-not-fw-configured")) |
908 | arch_timer_uses_ppi = PHYS_SECURE_PPI; | 911 | arch_timer_uses_ppi = PHYS_SECURE_PPI; |
909 | 912 | ||
913 | /* On some systems, the counter stops ticking when in suspend. */ | ||
914 | arch_counter_suspend_stop = of_property_read_bool(np, | ||
915 | "arm,no-tick-in-suspend"); | ||
916 | |||
910 | return arch_timer_init(); | 917 | return arch_timer_init(); |
911 | } | 918 | } |
912 | CLOCKSOURCE_OF_DECLARE(armv7_arch_timer, "arm,armv7-timer", arch_timer_of_init); | 919 | CLOCKSOURCE_OF_DECLARE(armv7_arch_timer, "arm,armv7-timer", arch_timer_of_init); |