aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/platforms/cell/spu_base.c78
1 files changed, 19 insertions, 59 deletions
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c
index 249a0af4cc99..db82f503ba2c 100644
--- a/arch/powerpc/platforms/cell/spu_base.c
+++ b/arch/powerpc/platforms/cell/spu_base.c
@@ -140,55 +140,7 @@ static int __spu_trap_data_map(struct spu *spu, unsigned long ea, u64 dsisr)
140 spu->dar = ea; 140 spu->dar = ea;
141 spu->dsisr = dsisr; 141 spu->dsisr = dsisr;
142 mb(); 142 mb();
143 if (spu->stop_callback) 143 spu->stop_callback(spu);
144 spu->stop_callback(spu);
145 return 0;
146}
147
148static int __spu_trap_mailbox(struct spu *spu)
149{
150 if (spu->ibox_callback)
151 spu->ibox_callback(spu);
152
153 /* atomically disable SPU mailbox interrupts */
154 spin_lock(&spu->register_lock);
155 spu_int_mask_and(spu, 2, ~0x1);
156 spin_unlock(&spu->register_lock);
157 return 0;
158}
159
160static int __spu_trap_stop(struct spu *spu)
161{
162 pr_debug("%s\n", __FUNCTION__);
163 if (spu->stop_callback)
164 spu->stop_callback(spu);
165 return 0;
166}
167
168static int __spu_trap_halt(struct spu *spu)
169{
170 pr_debug("%s\n", __FUNCTION__);
171 if (spu->stop_callback)
172 spu->stop_callback(spu);
173 return 0;
174}
175
176static int __spu_trap_tag_group(struct spu *spu)
177{
178 pr_debug("%s\n", __FUNCTION__);
179 spu->mfc_callback(spu);
180 return 0;
181}
182
183static int __spu_trap_spubox(struct spu *spu)
184{
185 if (spu->wbox_callback)
186 spu->wbox_callback(spu);
187
188 /* atomically disable SPU mailbox interrupts */
189 spin_lock(&spu->register_lock);
190 spu_int_mask_and(spu, 2, ~0x10);
191 spin_unlock(&spu->register_lock);
192 return 0; 144 return 0;
193} 145}
194 146
@@ -199,8 +151,7 @@ spu_irq_class_0(int irq, void *data, struct pt_regs *regs)
199 151
200 spu = data; 152 spu = data;
201 spu->class_0_pending = 1; 153 spu->class_0_pending = 1;
202 if (spu->stop_callback) 154 spu->stop_callback(spu);
203 spu->stop_callback(spu);
204 155
205 return IRQ_HANDLED; 156 return IRQ_HANDLED;
206} 157}
@@ -278,29 +229,38 @@ spu_irq_class_2(int irq, void *data, struct pt_regs *regs)
278 unsigned long mask; 229 unsigned long mask;
279 230
280 spu = data; 231 spu = data;
232 spin_lock(&spu->register_lock);
281 stat = spu_int_stat_get(spu, 2); 233 stat = spu_int_stat_get(spu, 2);
282 mask = spu_int_mask_get(spu, 2); 234 mask = spu_int_mask_get(spu, 2);
235 /* ignore interrupts we're not waiting for */
236 stat &= mask;
237 /*
238 * mailbox interrupts (0x1 and 0x10) are level triggered.
239 * mask them now before acknowledging.
240 */
241 if (stat & 0x11)
242 spu_int_mask_and(spu, 2, ~(stat & 0x11));
243 /* acknowledge all interrupts before the callbacks */
244 spu_int_stat_clear(spu, 2, stat);
245 spin_unlock(&spu->register_lock);
283 246
284 pr_debug("class 2 interrupt %d, %lx, %lx\n", irq, stat, mask); 247 pr_debug("class 2 interrupt %d, %lx, %lx\n", irq, stat, mask);
285 248
286 stat &= mask;
287
288 if (stat & 1) /* PPC core mailbox */ 249 if (stat & 1) /* PPC core mailbox */
289 __spu_trap_mailbox(spu); 250 spu->ibox_callback(spu);
290 251
291 if (stat & 2) /* SPU stop-and-signal */ 252 if (stat & 2) /* SPU stop-and-signal */
292 __spu_trap_stop(spu); 253 spu->stop_callback(spu);
293 254
294 if (stat & 4) /* SPU halted */ 255 if (stat & 4) /* SPU halted */
295 __spu_trap_halt(spu); 256 spu->stop_callback(spu);
296 257
297 if (stat & 8) /* DMA tag group complete */ 258 if (stat & 8) /* DMA tag group complete */
298 __spu_trap_tag_group(spu); 259 spu->mfc_callback(spu);
299 260
300 if (stat & 0x10) /* SPU mailbox threshold */ 261 if (stat & 0x10) /* SPU mailbox threshold */
301 __spu_trap_spubox(spu); 262 spu->wbox_callback(spu);
302 263
303 spu_int_stat_clear(spu, 2, stat);
304 return stat ? IRQ_HANDLED : IRQ_NONE; 264 return stat ? IRQ_HANDLED : IRQ_NONE;
305} 265}
306 266