diff options
author | Jeremy Kerr <jk@ozlabs.org> | 2007-12-20 16:39:59 +0900 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2007-12-21 19:46:20 +1100 |
commit | d6ad39bc53521275d14fde86bfb94d9b2ddb7a08 (patch) | |
tree | 07dcc592b343395cb7fbfb3053aa21103fb94352 /arch/powerpc/platforms/cell/spu_base.c | |
parent | 8af30675c3e7b945bbaf6f57b724f246e56eb209 (diff) | |
download | blackbird-op-linux-d6ad39bc53521275d14fde86bfb94d9b2ddb7a08.tar.gz blackbird-op-linux-d6ad39bc53521275d14fde86bfb94d9b2ddb7a08.zip |
[POWERPC] spufs: rework class 0 and 1 interrupt handling
Based on original patches from
Arnd Bergmann <arnd.bergman@de.ibm.com>; and
Luke Browning <lukebr@linux.vnet.ibm.com>
Currently, spu contexts need to be loaded to the SPU in order to take
class 0 and class 1 exceptions.
This change makes the actual interrupt-handlers much simpler (ie,
set the exception information in the context save area), and defers the
handling code to the spufs_handle_class[01] functions, called from
spufs_run_spu.
This should improve the concurrency of the spu scheduling leading to
greater SPU utilization when SPUs are overcommited.
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/platforms/cell/spu_base.c')
-rw-r--r-- | arch/powerpc/platforms/cell/spu_base.c | 57 |
1 files changed, 7 insertions, 50 deletions
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c index a560277b3ad7..fb266ae32095 100644 --- a/arch/powerpc/platforms/cell/spu_base.c +++ b/arch/powerpc/platforms/cell/spu_base.c @@ -132,27 +132,6 @@ int spu_64k_pages_available(void) } EXPORT_SYMBOL_GPL(spu_64k_pages_available); -static int __spu_trap_invalid_dma(struct spu *spu) -{ - pr_debug("%s\n", __FUNCTION__); - spu->dma_callback(spu, SPE_EVENT_INVALID_DMA); - return 0; -} - -static int __spu_trap_dma_align(struct spu *spu) -{ - pr_debug("%s\n", __FUNCTION__); - spu->dma_callback(spu, SPE_EVENT_DMA_ALIGNMENT); - return 0; -} - -static int __spu_trap_error(struct spu *spu) -{ - pr_debug("%s\n", __FUNCTION__); - spu->dma_callback(spu, SPE_EVENT_SPE_ERROR); - return 0; -} - static void spu_restart_dma(struct spu *spu) { struct spu_priv2 __iomem *priv2 = spu->priv2; @@ -252,10 +231,12 @@ static int __spu_trap_data_map(struct spu *spu, unsigned long ea, u64 dsisr) return 1; } + spu->class_0_pending = 0; spu->dar = ea; spu->dsisr = dsisr; - mb(); + spu->stop_callback(spu); + return 0; } @@ -335,12 +316,13 @@ spu_irq_class_0(int irq, void *data) spu = data; + spin_lock(&spu->register_lock); mask = spu_int_mask_get(spu, 0); - stat = spu_int_stat_get(spu, 0); - stat &= mask; + stat = spu_int_stat_get(spu, 0) & mask; - spin_lock(&spu->register_lock); spu->class_0_pending |= stat; + spu->dsisr = spu_mfc_dsisr_get(spu); + spu->dar = spu_mfc_dar_get(spu); spin_unlock(&spu->register_lock); spu->stop_callback(spu); @@ -350,31 +332,6 @@ spu_irq_class_0(int irq, void *data) return IRQ_HANDLED; } -int -spu_irq_class_0_bottom(struct spu *spu) -{ - unsigned long flags; - unsigned long stat; - - spin_lock_irqsave(&spu->register_lock, flags); - stat = spu->class_0_pending; - spu->class_0_pending = 0; - - if (stat & CLASS0_DMA_ALIGNMENT_INTR) - __spu_trap_dma_align(spu); - - if (stat & CLASS0_INVALID_DMA_COMMAND_INTR) - __spu_trap_invalid_dma(spu); - - if (stat & CLASS0_SPU_ERROR_INTR) - __spu_trap_error(spu); - - spin_unlock_irqrestore(&spu->register_lock, flags); - - return (stat & CLASS0_INTR_MASK) ? -EIO : 0; -} -EXPORT_SYMBOL_GPL(spu_irq_class_0_bottom); - static irqreturn_t spu_irq_class_1(int irq, void *data) { |