diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h index eaa5bbe3fa87..f95235abc841 100644 --- a/arch/arm64/include/asm/arch_timer.h +++ b/arch/arm64/include/asm/arch_timer.h @@ -148,8 +148,17 @@ static inline u64 arch_counter_get_cntpct(void) static inline u64 arch_counter_get_cntvct(void) { + u64 cval; isb(); - return arch_timer_reg_read_stable(cntvct_el0); +#if IS_ENABLED(CONFIG_MSM_TIMER_LEAP) +#define L32_BITS 0x00000000FFFFFFFF + do { + cval = arch_timer_reg_read_stable(cntvct_el0); + } while ((cval & L32_BITS) == L32_BITS); +#else + cval = arch_timer_reg_read_stable(cntvct_el0); +#endif + return cval; } static inline int arch_timer_arch_init(void) diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index cd6d3077d458..91cf85785782 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -331,6 +331,15 @@ config ARM_ARCH_TIMER_VCT_ACCESS This option enables support for reading the ARM architected timer's virtual counter in userspace. +config MSM_TIMER_LEAP + bool "ARCH TIMER counter rollover" + default n + depends on ARM_ARCH_TIMER && ARM64 + help + This option enables a check for least significant 32 bits of + counter rollover. On every counter read if least significant + 32 bits are set, reread counter. + config ARM_GLOBAL_TIMER bool "Support for the ARM global timer" if COMPILE_TEST select CLKSRC_OF if OF