linux-mips
[Top] [All Lists]

[PATCH v2] MIPS: Alchemy: fix wait function

To: Ralf Baechle <ralf@linux-mips.org>
Subject: [PATCH v2] MIPS: Alchemy: fix wait function
From: Manuel Lauss <manuel.lauss@gmail.com>
Date: Thu, 23 May 2013 15:28:36 +0200
Cc: Linux-MIPS <linux-mips@linux-mips.org>, Manuel Lauss <manuel.lauss@gmail.com>
Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer; bh=I4kCzT+ZNhM4RaxzbZTyb8QS6SKbwZye4fOqQ+iuEmE=; b=ICTfK77Ox2G6hTtZN453CNgZj6AB+mqQZKJSMjlfH5g7E/SsBA8+89D/jDfUu/9SaY j8ITd89vvKUBLlpYIgTpF4FYLO3z2HBEzhCtfP3a3cdUvSLoKgwwDLxMba4X5rfgaoWg D8CAUwo3c1ItjrBsRc8HfR/627jpkiQtPz45LegcMq9d5Ajndwg5Ws4Vvj6xD/vzvW8/ rW9/rGQvJ1CaGppTSej9QfoFLerpRLci/3vwsjGLh9NJB9NteqNLuwmJmOyGJtAM1HV7 ukhIrwVaJkFQRgLyzJbDRev6O346nyfSbiNhVX8aUTjoZ4sgD6kZfN3hh/JgD92RSosw /3MQ==
List-archive: <http://www.linux-mips.org/archives/linux-mips/>
List-help: <mailto:ecartis@linux-mips.org?Subject=help>
List-id: linux-mips <linux-mips.eddie.linux-mips.org>
List-owner: <mailto:ralf@linux-mips.org>
List-post: <mailto:linux-mips@linux-mips.org>
List-software: Ecartis version 1.0.0
List-subscribe: <mailto:ecartis@linux-mips.org?subject=subscribe%20linux-mips>
List-unsubscribe: <mailto:ecartis@linux-mips.org?subject=unsubscribe%20linux-mips>
Original-recipient: rfc822;linux-mips@linux-mips.org
Sender: linux-mips-bounce@linux-mips.org
Only an interrupt can wake the core from 'wait', enable interrupts
locally before executing 'wait'.

Signed-off-by: Manuel Lauss <manuel.lauss@gmail.com>
---
Ralf made me aware of the race in between enabling interrupts and
entering wait.  While this patch does not eliminate it, it shrinks it
to 1 instruction.  It's not perfect, but lets Alchemy boot until a
more sophisticated solution (like __r4k_wait) can be implemented
without having to duplicate the interrupt exception handler.

 arch/mips/kernel/idle.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/arch/mips/kernel/idle.c b/arch/mips/kernel/idle.c
index 3b09b88..1d37b4b 100644
--- a/arch/mips/kernel/idle.c
+++ b/arch/mips/kernel/idle.c
@@ -93,9 +93,9 @@ static void rm7k_wait_irqoff(void)
 }
 
 /*
- * The Au1xxx wait is available only if using 32khz counter or
- * external timer source, but specifically not CP0 Counter.
- * alchemy/common/time.c may override cpu_wait!
+ * Au1 'wait' is only useful when the 32kHz counter is used as timer,
+ * since coreclock (and the cp0 counter) stops upon executing it. Only an
+ * interrupt can wake it, so they must be enabled before entering idle modes.
  */
 static void au1k_wait(void)
 {
@@ -103,8 +103,10 @@ static void au1k_wait(void)
        "       .set    mips3                   \n"
        "       cache   0x14, 0(%0)             \n"
        "       cache   0x14, 32(%0)            \n"
+       "       mfc0    $8, $12                 \n"
+       "       ori     $8, $8, 1               \n"
        "       sync                            \n"
-       "       nop                             \n"
+       "       mtc0    $8, $12                 \n"     /* enable irqs */
        "       wait                            \n"
        "       nop                             \n"
        "       nop                             \n"
@@ -112,7 +114,6 @@ static void au1k_wait(void)
        "       nop                             \n"
        "       .set    mips0                   \n"
        : : "r" (au1k_wait));
-       local_irq_enable();
 }
 
 static int __initdata nowait;
-- 
1.8.2.1


<Prev in Thread] Current Thread [Next in Thread>
  • [PATCH v2] MIPS: Alchemy: fix wait function, Manuel Lauss <=