From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752330AbcBOQh5 (ORCPT ); Mon, 15 Feb 2016 11:37:57 -0500 Received: from smtprelay4.synopsys.com ([198.182.47.9]:53207 "EHLO smtprelay.synopsys.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751377AbcBOQh4 (ORCPT ); Mon, 15 Feb 2016 11:37:56 -0500 From: Alexey Brodkin To: linux-snps-arc@lists.infradead.org Cc: linux-kernel@vger.kernel.org, Alexey Brodkin , Vineet Gupta Subject: [PATCH] arc: make sure __delay() never gets executed with 0 loops Date: Mon, 15 Feb 2016 19:37:47 +0300 Message-Id: <1455554267-23886-1-git-send-email-abrodkin@synopsys.com> X-Mailer: git-send-email 2.4.3 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Current implementation of __delay() function uses so-called zero-delay loops. And the only condition to exit that loop is LP_COUNT (loop count register) = 1 (but not 0 as it might be easily imagined). So if our calculation of "loops" gives 0 (and that is pretty possible given result of multiplication being >> 32) then zero-delay loop mechanism starts with LP_COUNT=0 and it ends up decrementing LP_COUNT while staying in the loop effectively producing close to infinite delay instead of very short one. I bumped into it with AXS101 + external DDR controller and caches disabled. In that case I've got very small loops_per_jiffy=0xf00: ------------------------>8-------------------- Calibrating delay loop... 0.77 BogoMIPS (lpj=3862) ------------------------>8-------------------- And on console output delays were way too long. Signed-off-by: Alexey Brodkin Cc: Vineet Gupta Please enter the commit message for your changes. Lines starting --- arch/arc/include/asm/delay.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arc/include/asm/delay.h b/arch/arc/include/asm/delay.h index 08e7e2a..1a7a1dc 100644 --- a/arch/arc/include/asm/delay.h +++ b/arch/arc/include/asm/delay.h @@ -57,7 +57,8 @@ static inline void __udelay(unsigned long usecs) */ loops = ((u64) usecs * 4295 * HZ * loops_per_jiffy) >> 32; - __delay(loops); + if (loops) + __delay(loops); } #define udelay(n) (__builtin_constant_p(n) ? ((n) > 20000 ? __bad_udelay() \ -- 2.4.3