[PATCH] ARM: mmp: fix timer_read delay

Doug Brown doug at schmorgal.com
Mon Sep 5 13:08:04 PDT 2022


The timer_read function was using an empty 100-iteration loop to wait
for the TMR_CVWR register to capture the latest timer counter value. The
delay wasn't long enough. This resulted in CPU idle time being extremely
underreported on the PXA168 with CONFIG_NO_HZ_IDLE=y.

Switch to the approach used in an older vendor kernel, which implements
the capture delay by reading TMR_CVWR a few times instead.

Fixes: 49cbe78637eb ("[ARM] pxa: add base support for Marvell's PXA168 processor line")
Signed-off-by: Doug Brown <doug at schmorgal.com>
---
 arch/arm/mach-mmp/time.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-mmp/time.c b/arch/arm/mach-mmp/time.c
index 41b2e8abc9e6..162603fdef0a 100644
--- a/arch/arm/mach-mmp/time.c
+++ b/arch/arm/mach-mmp/time.c
@@ -43,16 +43,18 @@
 static void __iomem *mmp_timer_base = TIMERS_VIRT_BASE;
 
 /*
- * FIXME: the timer needs some delay to stablize the counter capture
+ * Reads the timer through the CVWR register. Delay is required after
+ * requesting a read. We can't directly read the CR register due to
+ * metastability issues documented in the datasheet.
  */
 static inline uint32_t timer_read(void)
 {
-	int delay = 100;
+	int delay = 3;
 
 	__raw_writel(1, mmp_timer_base + TMR_CVWR(1));
 
 	while (delay--)
-		cpu_relax();
+		__raw_readl(mmp_timer_base + TMR_CVWR(1));
 
 	return __raw_readl(mmp_timer_base + TMR_CVWR(1));
 }
-- 
2.25.1




More information about the linux-arm-kernel mailing list