Linux MIPS Architecture development
 help / color / mirror / Atom feed
* [PATCH v3] MIPS: Alchemy: fix wait function
@ 2013-06-08 20:15 Manuel Lauss
  2013-06-10 15:53 ` Ralf Baechle
  2013-06-10 17:17 ` Maciej W. Rozycki
  0 siblings, 2 replies; 3+ messages in thread
From: Manuel Lauss @ 2013-06-08 20:15 UTC (permalink / raw)
  To: Linux-MIPS; +Cc: Ralf Baechle, Maciej W. Rozycki, Manuel Lauss

Only an interrupt can wake the core from 'wait', enable interrupts
locally before executing 'wait'.

Signed-off-by: Manuel Lauss <manuel.lauss@gmail.com>
---
v3: add constraint for additional register used, as per Maciej's feedback
v2: enable interrupts immediately before executing 'wait', to minimize chance
    of interrupts occurring.


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

diff --git a/arch/mips/kernel/idle.c b/arch/mips/kernel/idle.c
index 3b09b88..0c655de 100644
--- a/arch/mips/kernel/idle.c
+++ b/arch/mips/kernel/idle.c
@@ -93,26 +93,27 @@ 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)
 {
+	unsigned long c0status = read_c0_status() | 1;	/* irqs on */
+
 	__asm__(
 	"	.set	mips3			\n"
 	"	cache	0x14, 0(%0)		\n"
 	"	cache	0x14, 32(%0)		\n"
 	"	sync				\n"
-	"	nop				\n"
+	"	mtc0	%1, $12			\n" /* wr c0status */
 	"	wait				\n"
 	"	nop				\n"
 	"	nop				\n"
 	"	nop				\n"
 	"	nop				\n"
 	"	.set	mips0			\n"
-	: : "r" (au1k_wait));
-	local_irq_enable();
+	: : "r" (au1k_wait), "r" (c0status));
 }
 
 static int __initdata nowait;
-- 
1.8.2.1

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH v3] MIPS: Alchemy: fix wait function
  2013-06-08 20:15 [PATCH v3] MIPS: Alchemy: fix wait function Manuel Lauss
@ 2013-06-10 15:53 ` Ralf Baechle
  2013-06-10 17:17 ` Maciej W. Rozycki
  1 sibling, 0 replies; 3+ messages in thread
From: Ralf Baechle @ 2013-06-10 15:53 UTC (permalink / raw)
  To: Manuel Lauss; +Cc: Linux-MIPS, Maciej W. Rozycki

On Sat, Jun 08, 2013 at 10:15:41PM +0200, Manuel Lauss wrote:

> Only an interrupt can wake the core from 'wait', enable interrupts
> locally before executing 'wait'.
> 
> Signed-off-by: Manuel Lauss <manuel.lauss@gmail.com>
> ---
> v3: add constraint for additional register used, as per Maciej's feedback
> v2: enable interrupts immediately before executing 'wait', to minimize chance
>     of interrupts occurring.

Applied, primarily because time is running away and it's more important to
get Alchemy back to at least limping along happily ...

  Ralf

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH v3] MIPS: Alchemy: fix wait function
  2013-06-08 20:15 [PATCH v3] MIPS: Alchemy: fix wait function Manuel Lauss
  2013-06-10 15:53 ` Ralf Baechle
@ 2013-06-10 17:17 ` Maciej W. Rozycki
  1 sibling, 0 replies; 3+ messages in thread
From: Maciej W. Rozycki @ 2013-06-10 17:17 UTC (permalink / raw)
  To: Manuel Lauss; +Cc: Linux-MIPS, Ralf Baechle

On Sat, 8 Jun 2013, Manuel Lauss wrote:

> diff --git a/arch/mips/kernel/idle.c b/arch/mips/kernel/idle.c
> index 3b09b88..0c655de 100644
> --- a/arch/mips/kernel/idle.c
> +++ b/arch/mips/kernel/idle.c
> @@ -93,26 +93,27 @@ 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)
>  {
> +	unsigned long c0status = read_c0_status() | 1;	/* irqs on */
> +
>  	__asm__(
>  	"	.set	mips3			\n"
>  	"	cache	0x14, 0(%0)		\n"
>  	"	cache	0x14, 32(%0)		\n"
>  	"	sync				\n"
> -	"	nop				\n"
> +	"	mtc0	%1, $12			\n" /* wr c0status */
>  	"	wait				\n"
>  	"	nop				\n"
>  	"	nop				\n"
>  	"	nop				\n"
>  	"	nop				\n"
>  	"	.set	mips0			\n"
> -	: : "r" (au1k_wait));
> -	local_irq_enable();
> +	: : "r" (au1k_wait), "r" (c0status));
>  }
>  
>  static int __initdata nowait;

 Not exacly what I had in mind, but this looks good to me too. :)

Acked-by: Maciej W. Rozycki <macro@linux-mips.org>

  Maciej

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2013-06-10 17:17 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-06-08 20:15 [PATCH v3] MIPS: Alchemy: fix wait function Manuel Lauss
2013-06-10 15:53 ` Ralf Baechle
2013-06-10 17:17 ` Maciej W. Rozycki

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox