aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/cell/spu_base.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/platforms/cell/spu_base.c')
-rw-r--r--arch/powerpc/platforms/cell/spu_base.c31
1 files changed, 22 insertions, 9 deletions
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c
index 6bab44b7716b..70c660121ec4 100644
--- a/arch/powerpc/platforms/cell/spu_base.c
+++ b/arch/powerpc/platforms/cell/spu_base.c
@@ -141,6 +141,10 @@ static void spu_restart_dma(struct spu *spu)
141 141
142 if (!test_bit(SPU_CONTEXT_SWITCH_PENDING, &spu->flags)) 142 if (!test_bit(SPU_CONTEXT_SWITCH_PENDING, &spu->flags))
143 out_be64(&priv2->mfc_control_RW, MFC_CNTL_RESTART_DMA_COMMAND); 143 out_be64(&priv2->mfc_control_RW, MFC_CNTL_RESTART_DMA_COMMAND);
144 else {
145 set_bit(SPU_CONTEXT_FAULT_PENDING, &spu->flags);
146 mb();
147 }
144} 148}
145 149
146static inline void spu_load_slb(struct spu *spu, int slbe, struct spu_slb *slb) 150static inline void spu_load_slb(struct spu *spu, int slbe, struct spu_slb *slb)
@@ -226,11 +230,13 @@ static int __spu_trap_data_map(struct spu *spu, unsigned long ea, u64 dsisr)
226 return 0; 230 return 0;
227 } 231 }
228 232
229 spu->class_0_pending = 0; 233 spu->class_1_dar = ea;
230 spu->dar = ea; 234 spu->class_1_dsisr = dsisr;
231 spu->dsisr = dsisr; 235
236 spu->stop_callback(spu, 1);
232 237
233 spu->stop_callback(spu); 238 spu->class_1_dar = 0;
239 spu->class_1_dsisr = 0;
234 240
235 return 0; 241 return 0;
236} 242}
@@ -318,11 +324,15 @@ spu_irq_class_0(int irq, void *data)
318 stat = spu_int_stat_get(spu, 0) & mask; 324 stat = spu_int_stat_get(spu, 0) & mask;
319 325
320 spu->class_0_pending |= stat; 326 spu->class_0_pending |= stat;
321 spu->dsisr = spu_mfc_dsisr_get(spu); 327 spu->class_0_dsisr = spu_mfc_dsisr_get(spu);
322 spu->dar = spu_mfc_dar_get(spu); 328 spu->class_0_dar = spu_mfc_dar_get(spu);
323 spin_unlock(&spu->register_lock); 329 spin_unlock(&spu->register_lock);
324 330
325 spu->stop_callback(spu); 331 spu->stop_callback(spu, 0);
332
333 spu->class_0_pending = 0;
334 spu->class_0_dsisr = 0;
335 spu->class_0_dar = 0;
326 336
327 spu_int_stat_clear(spu, 0, stat); 337 spu_int_stat_clear(spu, 0, stat);
328 338
@@ -363,6 +373,9 @@ spu_irq_class_1(int irq, void *data)
363 if (stat & CLASS1_LS_COMPARE_SUSPEND_ON_PUT_INTR) 373 if (stat & CLASS1_LS_COMPARE_SUSPEND_ON_PUT_INTR)
364 ; 374 ;
365 375
376 spu->class_1_dsisr = 0;
377 spu->class_1_dar = 0;
378
366 return stat ? IRQ_HANDLED : IRQ_NONE; 379 return stat ? IRQ_HANDLED : IRQ_NONE;
367} 380}
368 381
@@ -396,10 +409,10 @@ spu_irq_class_2(int irq, void *data)
396 spu->ibox_callback(spu); 409 spu->ibox_callback(spu);
397 410
398 if (stat & CLASS2_SPU_STOP_INTR) 411 if (stat & CLASS2_SPU_STOP_INTR)
399 spu->stop_callback(spu); 412 spu->stop_callback(spu, 2);
400 413
401 if (stat & CLASS2_SPU_HALT_INTR) 414 if (stat & CLASS2_SPU_HALT_INTR)
402 spu->stop_callback(spu); 415 spu->stop_callback(spu, 2);
403 416
404 if (stat & CLASS2_SPU_DMA_TAG_GROUP_COMPLETE_INTR) 417 if (stat & CLASS2_SPU_DMA_TAG_GROUP_COMPLETE_INTR)
405 spu->mfc_callback(spu); 418 spu->mfc_callback(spu);