[POWERPC] spufs: reorganize spu_run_init
This cleans up spu_run_init so that it does all of the spu
initialization for spufs_run_spu. It initializes the spu context as
much as possible before it activates the spu and writes the runcntl
register.
Signed-off-by: Luke Browning <lukebr@linux.vnet.ibm.com>
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
diff --git a/arch/powerpc/platforms/cell/spufs/run.c b/arch/powerpc/platforms/cell/spufs/run.c
index 3b3de6c..652ae13 100644
--- a/arch/powerpc/platforms/cell/spufs/run.c
+++ b/arch/powerpc/platforms/cell/spufs/run.c
@@ -152,23 +152,41 @@
static int spu_run_init(struct spu_context *ctx, u32 *npc)
{
unsigned long runcntl;
+ int ret;
spuctx_switch_state(ctx, SPU_UTIL_SYSTEM);
if (ctx->flags & SPU_CREATE_ISOLATE) {
+ /*
+ * Force activation of spu. Isolated state assumes that
+ * special loader context is loaded and running on spu.
+ */
+ if (ctx->state == SPU_STATE_SAVED) {
+ spu_set_timeslice(ctx);
- if (!(ctx->ops->status_read(ctx) & SPU_STATUS_ISOLATED_STATE)) {
- int ret = spu_setup_isolated(ctx);
+ ret = spu_activate(ctx, 0);
if (ret)
return ret;
}
- /* if userspace has set the runcntrl register (eg, to issue an
- * isolated exit), we need to re-set it here */
+ if (!(ctx->ops->status_read(ctx) & SPU_STATUS_ISOLATED_STATE)) {
+ ret = spu_setup_isolated(ctx);
+ if (ret)
+ return ret;
+ }
+
+ /*
+ * If userspace has set the runcntrl register (eg, to
+ * issue an isolated exit), we need to re-set it here
+ */
runcntl = ctx->ops->runcntl_read(ctx) &
(SPU_RUNCNTL_RUNNABLE | SPU_RUNCNTL_ISOLATE);
if (runcntl == 0)
runcntl = SPU_RUNCNTL_RUNNABLE;
+
+ spuctx_switch_state(ctx, SPU_UTIL_USER);
+ ctx->ops->runcntl_write(ctx, runcntl);
+
} else {
unsigned long privcntl;
@@ -180,12 +198,18 @@
ctx->ops->npc_write(ctx, *npc);
ctx->ops->privcntl_write(ctx, privcntl);
+
+ if (ctx->state == SPU_STATE_SAVED) {
+ spu_set_timeslice(ctx);
+ ret = spu_activate(ctx, 0);
+ if (ret)
+ return ret;
+ }
+
+ spuctx_switch_state(ctx, SPU_UTIL_USER);
+ ctx->ops->runcntl_write(ctx, runcntl);
}
- ctx->ops->runcntl_write(ctx, runcntl);
-
- spuctx_switch_state(ctx, SPU_UTIL_USER);
-
return 0;
}
@@ -323,25 +347,8 @@
ctx->event_return = 0;
spu_acquire(ctx);
- if (ctx->state == SPU_STATE_SAVED) {
- __spu_update_sched_info(ctx);
- spu_set_timeslice(ctx);
- ret = spu_activate(ctx, 0);
- if (ret) {
- spu_release(ctx);
- goto out;
- }
- } else {
- /*
- * We have to update the scheduling priority under active_mutex
- * to protect against find_victim().
- *
- * No need to update the timeslice ASAP, it will get updated
- * once the current one has expired.
- */
- spu_update_sched_info(ctx);
- }
+ spu_update_sched_info(ctx);
ret = spu_run_init(ctx, npc);
if (ret) {