From 028fda0a6c80c26f1d9f403b4490b9ddc74ffa3b Mon Sep 17 00:00:00 2001
From: Luke Browning <lukebrowning@us.ibm.com>
Date: Mon, 16 Jun 2008 10:42:38 +1000
Subject: [PATCH] powerpc/spufs: fix missed stop-and-signal event

There is a delay in the transition to the stopped state for class 2
interrupts. In some cases, the controlling thread detects the state of
the spu as running, and goes back to sleep resulting in a hung
application as the event is missed.

This change detects the stop condition and re-generates the wakeup event
after a context save.

Signed-off-by: Luke Browning <lukebrowning@us.ibm.com>
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
---
 arch/powerpc/platforms/cell/spufs/sched.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c
index cd725670b1b5..e929e70a84e3 100644
--- a/arch/powerpc/platforms/cell/spufs/sched.c
+++ b/arch/powerpc/platforms/cell/spufs/sched.c
@@ -407,6 +407,8 @@ static int has_affinity(struct spu_context *ctx)
  */
 static void spu_unbind_context(struct spu *spu, struct spu_context *ctx)
 {
+	u32 status;
+
 	spu_context_trace(spu_unbind_context__enter, ctx, spu);
 
 	spuctx_switch_state(ctx, SPU_UTIL_SYSTEM);
@@ -452,6 +454,9 @@ static void spu_unbind_context(struct spu *spu, struct spu_context *ctx)
 	/* This maps the underlying spu state to idle */
 	spuctx_switch_state(ctx, SPU_UTIL_IDLE_LOADED);
 	ctx->spu = NULL;
+
+	if (spu_stopped(ctx, &status))
+		wake_up_all(&ctx->stop_wq);
 }
 
 /**
-- 
2.20.1