]> err.no Git - linux-2.6/blobdiff - arch/powerpc/platforms/cell/spu_base.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris...
[linux-2.6] / arch / powerpc / platforms / cell / spu_base.c
index fb266ae320954ed2e344e2786e526dd24d5b0347..6bab44b7716b2d525bff0720c0c6a0f436a55acb 100644 (file)
@@ -81,9 +81,12 @@ struct spu_slb {
 void spu_invalidate_slbs(struct spu *spu)
 {
        struct spu_priv2 __iomem *priv2 = spu->priv2;
+       unsigned long flags;
 
+       spin_lock_irqsave(&spu->register_lock, flags);
        if (spu_mfc_sr1_get(spu) & MFC_STATE1_RELOCATE_MASK)
                out_be64(&priv2->slb_invalidate_all_W, 0UL);
+       spin_unlock_irqrestore(&spu->register_lock, flags);
 }
 EXPORT_SYMBOL_GPL(spu_invalidate_slbs);
 
@@ -148,7 +151,11 @@ static inline void spu_load_slb(struct spu *spu, int slbe, struct spu_slb *slb)
                        __func__, slbe, slb->vsid, slb->esid);
 
        out_be64(&priv2->slb_index_W, slbe);
+       /* set invalid before writing vsid */
+       out_be64(&priv2->slb_esid_RW, 0);
+       /* now it's safe to write the vsid */
        out_be64(&priv2->slb_vsid_RW, slb->vsid);
+       /* setting the new esid makes the entry valid again */
        out_be64(&priv2->slb_esid_RW, slb->esid);
 }
 
@@ -158,15 +165,8 @@ static int __spu_trap_data_seg(struct spu *spu, unsigned long ea)
        struct spu_slb slb;
        int psize;
 
-       pr_debug("%s\n", __FUNCTION__);
+       pr_debug("%s\n", __func__);
 
-       if (test_bit(SPU_CONTEXT_SWITCH_ACTIVE, &spu->flags)) {
-               /* SLBs are pre-loaded for context switch, so
-                * we should never get here!
-                */
-               printk("%s: invalid access during switch!\n", __func__);
-               return 1;
-       }
        slb.esid = (ea & ESID_MASK) | SLB_ESID_V;
 
        switch(REGION_ID(ea)) {
@@ -215,7 +215,7 @@ static int __spu_trap_data_seg(struct spu *spu, unsigned long ea)
 extern int hash_page(unsigned long ea, unsigned long access, unsigned long trap); //XXX
 static int __spu_trap_data_map(struct spu *spu, unsigned long ea, u64 dsisr)
 {
-       pr_debug("%s, %lx, %lx\n", __FUNCTION__, dsisr, ea);
+       pr_debug("%s, %lx, %lx\n", __func__, dsisr, ea);
 
        /* Handle kernel space hash faults immediately.
           User hash faults need to be deferred to process context. */
@@ -226,11 +226,6 @@ static int __spu_trap_data_map(struct spu *spu, unsigned long ea, u64 dsisr)
                return 0;
        }
 
-       if (test_bit(SPU_CONTEXT_SWITCH_ACTIVE, &spu->flags)) {
-               printk("%s: invalid access during switch!\n", __func__);
-               return 1;
-       }
-
        spu->class_0_pending = 0;
        spu->dar = ea;
        spu->dsisr = dsisr;
@@ -302,9 +297,11 @@ void spu_setup_kernel_slbs(struct spu *spu, struct spu_lscsa *lscsa,
                nr_slbs++;
        }
 
+       spin_lock_irq(&spu->register_lock);
        /* Add the set of SLBs */
        for (i = 0; i < nr_slbs; i++)
                spu_load_slb(spu, i, &slbs[i]);
+       spin_unlock_irq(&spu->register_lock);
 }
 EXPORT_SYMBOL_GPL(spu_setup_kernel_slbs);
 
@@ -349,13 +346,14 @@ spu_irq_class_1(int irq, void *data)
        if (stat & CLASS1_STORAGE_FAULT_INTR)
                spu_mfc_dsisr_set(spu, 0ul);
        spu_int_stat_clear(spu, 1, stat);
-       spin_unlock(&spu->register_lock);
-       pr_debug("%s: %lx %lx %lx %lx\n", __FUNCTION__, mask, stat,
-                       dar, dsisr);
 
        if (stat & CLASS1_SEGMENT_FAULT_INTR)
                __spu_trap_data_seg(spu, dar);
 
+       spin_unlock(&spu->register_lock);
+       pr_debug("%s: %lx %lx %lx %lx\n", __func__, mask, stat,
+                       dar, dsisr);
+
        if (stat & CLASS1_STORAGE_FAULT_INTR)
                __spu_trap_data_map(spu, dar, dsisr);
 
@@ -511,7 +509,7 @@ static int spu_shutdown(struct sys_device *sysdev)
 }
 
 static struct sysdev_class spu_sysdev_class = {
-       set_kset_name("spu"),
+       .name = "spu",
        .shutdown = spu_shutdown,
 };
 
@@ -728,7 +726,7 @@ static int __init init_spu_base(void)
 
        if (ret < 0) {
                printk(KERN_WARNING "%s: Error initializing spus\n",
-                       __FUNCTION__);
+                       __func__);
                goto out_unregister_sysdev_class;
        }