summaryrefslogtreecommitdiff
path: root/arch/powerpc/platforms/cell/spu_base.c
diff options
context:
space:
mode:
authorJeremy Kerr <jk@ozlabs.org>2007-12-20 16:39:59 +0900
committerPaul Mackerras <paulus@samba.org>2007-12-21 19:46:20 +1100
commitd6ad39bc53521275d14fde86bfb94d9b2ddb7a08 (patch)
tree07dcc592b343395cb7fbfb3053aa21103fb94352 /arch/powerpc/platforms/cell/spu_base.c
parent8af30675c3e7b945bbaf6f57b724f246e56eb209 (diff)
[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.c57
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)
{