From: Jeremy Kerr Date: Thu, 24 Apr 2008 08:15:40 +0000 (+1000) Subject: [POWERPC] spufs: fix post-stopped update of MFC_CNTL register X-Git-Tag: v2.6.26-rc2~16^2~17 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=55d7cd74d44e7e0597f95db25c12f3e6c5e7916f;p=linux-2.6 [POWERPC] spufs: fix post-stopped update of MFC_CNTL register We currently have two issues with the MFC save code: * save_mfc_decr doesn't handle a transition of 1 -> 0 of the Ds bit * The Q bit may be stale in the CSA This change fixes the first issue by clearing the relevant bits from the MFC_CNTL value in the CSA before or-ing in the updated status. Also, we add the Q bit to the updated status. Signed-off-by: Jeremy Kerr --- diff --git a/arch/powerpc/platforms/cell/spufs/switch.c b/arch/powerpc/platforms/cell/spufs/switch.c index 4131784216..53361d0c07 100644 --- a/arch/powerpc/platforms/cell/spufs/switch.c +++ b/arch/powerpc/platforms/cell/spufs/switch.c @@ -250,16 +250,21 @@ static inline void save_spu_status(struct spu_state *csa, struct spu *spu) } } -static inline void save_mfc_decr(struct spu_state *csa, struct spu *spu) +static inline void save_mfc_stopped_status(struct spu_state *csa, + struct spu *spu) { struct spu_priv2 __iomem *priv2 = spu->priv2; + const u64 mask = MFC_CNTL_DECREMENTER_RUNNING | + MFC_CNTL_DMA_QUEUES_EMPTY; /* Save, Step 12: * Read MFC_CNTL[Ds]. Update saved copy of * CSA.MFC_CNTL[Ds]. + * + * update: do the same with MFC_CNTL[Q]. */ - csa->priv2.mfc_control_RW |= - in_be64(&priv2->mfc_control_RW) & MFC_CNTL_DECREMENTER_RUNNING; + csa->priv2.mfc_control_RW &= ~mask; + csa->priv2.mfc_control_RW |= in_be64(&priv2->mfc_control_RW) & mask; } static inline void halt_mfc_decr(struct spu_state *csa, struct spu *spu) @@ -1791,7 +1796,7 @@ static int quiece_spu(struct spu_state *prev, struct spu *spu) save_spu_runcntl(prev, spu); /* Step 9. */ save_mfc_sr1(prev, spu); /* Step 10. */ save_spu_status(prev, spu); /* Step 11. */ - save_mfc_decr(prev, spu); /* Step 12. */ + save_mfc_stopped_status(prev, spu); /* Step 12. */ halt_mfc_decr(prev, spu); /* Step 13. */ save_timebase(prev, spu); /* Step 14. */ remove_other_spu_access(prev, spu); /* Step 15. */