diff options
Diffstat (limited to 'arch/powerpc/platforms/cell/spufs/run.c')
-rw-r--r-- | arch/powerpc/platforms/cell/spufs/run.c | 55 |
1 files changed, 31 insertions, 24 deletions
diff --git a/arch/powerpc/platforms/cell/spufs/run.c b/arch/powerpc/platforms/cell/spufs/run.c index 3b3de6c7ee5..652ae1366dc 100644 --- a/arch/powerpc/platforms/cell/spufs/run.c +++ b/arch/powerpc/platforms/cell/spufs/run.c @@ -152,23 +152,41 @@ out: 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); + + ret = spu_activate(ctx, 0); + if (ret) + return ret; + } if (!(ctx->ops->status_read(ctx) & SPU_STATUS_ISOLATED_STATE)) { - int ret = spu_setup_isolated(ctx); + 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 */ + /* + * 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,11 +198,17 @@ static int spu_run_init(struct spu_context *ctx, u32 *npc) ctx->ops->npc_write(ctx, *npc); ctx->ops->privcntl_write(ctx, privcntl); - } - ctx->ops->runcntl_write(ctx, runcntl); + 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); + spuctx_switch_state(ctx, SPU_UTIL_USER); + ctx->ops->runcntl_write(ctx, runcntl); + } return 0; } @@ -323,25 +347,8 @@ long spufs_run_spu(struct spu_context *ctx, u32 *npc, u32 *event) 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) { |