Merge branch 'mv-merge'
[sfrench/cifs-2.6.git] / arch / powerpc / platforms / cell / spu_base.c
index d75ae03df68679e9bd05d9d97c5ef00d0b18d174..269dda4fd0b4ff23cb2657087cf6bd34adc09739 100644 (file)
@@ -32,7 +32,7 @@
 
 #include <asm/io.h>
 #include <asm/prom.h>
-#include <asm/semaphore.h>
+#include <linux/mutex.h>
 #include <asm/spu.h>
 #include <asm/mmu_context.h>
 
@@ -111,7 +111,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\n", __FUNCTION__);
+       pr_debug("%s, %lx, %lx\n", __FUNCTION__, dsisr, ea);
 
        /* Handle kernel space hash faults immediately.
           User hash faults need to be deferred to process context. */
@@ -168,7 +168,7 @@ static int __spu_trap_halt(struct spu *spu)
 static int __spu_trap_tag_group(struct spu *spu)
 {
        pr_debug("%s\n", __FUNCTION__);
-       /* wake_up(&spu->dma_wq); */
+       spu->mfc_callback(spu);
        return 0;
 }
 
@@ -242,6 +242,8 @@ spu_irq_class_1(int irq, void *data, struct pt_regs *regs)
                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 & 1) /* segment fault */
                __spu_trap_data_seg(spu, dar);
@@ -342,7 +344,7 @@ spu_free_irqs(struct spu *spu)
 }
 
 static LIST_HEAD(spu_list);
-static DECLARE_MUTEX(spu_mutex);
+static DEFINE_MUTEX(spu_mutex);
 
 static void spu_init_channels(struct spu *spu)
 {
@@ -382,7 +384,7 @@ struct spu *spu_alloc(void)
 {
        struct spu *spu;
 
-       down(&spu_mutex);
+       mutex_lock(&spu_mutex);
        if (!list_empty(&spu_list)) {
                spu = list_entry(spu_list.next, struct spu, list);
                list_del_init(&spu->list);
@@ -391,7 +393,7 @@ struct spu *spu_alloc(void)
                pr_debug("No SPU left\n");
                spu = NULL;
        }
-       up(&spu_mutex);
+       mutex_unlock(&spu_mutex);
 
        if (spu)
                spu_init_channels(spu);
@@ -402,9 +404,9 @@ EXPORT_SYMBOL_GPL(spu_alloc);
 
 void spu_free(struct spu *spu)
 {
-       down(&spu_mutex);
+       mutex_lock(&spu_mutex);
        list_add_tail(&spu->list, &spu_list);
-       up(&spu_mutex);
+       mutex_unlock(&spu_mutex);
 }
 EXPORT_SYMBOL_GPL(spu_free);
 
@@ -484,14 +486,13 @@ int spu_irq_class_1_bottom(struct spu *spu)
 
        ea = spu->dar;
        dsisr = spu->dsisr;
-       if (dsisr & MFC_DSISR_PTE_NOT_FOUND) {
+       if (dsisr & (MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED)) {
                access = (_PAGE_PRESENT | _PAGE_USER);
                access |= (dsisr & MFC_DSISR_ACCESS_PUT) ? _PAGE_RW : 0UL;
                if (hash_page(ea, access, 0x300) != 0)
                        error |= CLASS1_ENABLE_STORAGE_FAULT_INTR;
        }
-       if ((error & CLASS1_ENABLE_STORAGE_FAULT_INTR) ||
-           (dsisr & MFC_DSISR_ACCESS_DENIED)) {
+       if (error & CLASS1_ENABLE_STORAGE_FAULT_INTR) {
                if ((ret = spu_handle_mm_fault(spu)) != 0)
                        error |= CLASS1_ENABLE_STORAGE_FAULT_INTR;
                else
@@ -568,6 +569,11 @@ static int __init spu_map_device(struct spu *spu, struct device_node *spe)
        if (!spu->local_store)
                goto out;
 
+       prop = get_property(spe, "problem", NULL);
+       if (!prop)
+               goto out_unmap;
+       spu->problem_phys = *(unsigned long *)prop;
+
        spu->problem= map_spe_prop(spe, "problem");
        if (!spu->problem)
                goto out_unmap;
@@ -632,15 +638,16 @@ static int __init create_spu(struct device_node *spe)
        spu->ibox_callback = NULL;
        spu->wbox_callback = NULL;
        spu->stop_callback = NULL;
+       spu->mfc_callback = NULL;
 
-       down(&spu_mutex);
+       mutex_lock(&spu_mutex);
        spu->number = number++;
        ret = spu_request_irqs(spu);
        if (ret)
                goto out_unmap;
 
        list_add(&spu->list, &spu_list);
-       up(&spu_mutex);
+       mutex_unlock(&spu_mutex);
 
        pr_debug(KERN_DEBUG "Using SPE %s %02x %p %p %p %p %d\n",
                spu->name, spu->isrc, spu->local_store,
@@ -648,7 +655,7 @@ static int __init create_spu(struct device_node *spe)
        goto out;
 
 out_unmap:
-       up(&spu_mutex);
+       mutex_unlock(&spu_mutex);
        spu_unmap(spu);
 out_free:
        kfree(spu);
@@ -668,10 +675,10 @@ static void destroy_spu(struct spu *spu)
 static void cleanup_spu_base(void)
 {
        struct spu *spu, *tmp;
-       down(&spu_mutex);
+       mutex_lock(&spu_mutex);
        list_for_each_entry_safe(spu, tmp, &spu_list, list)
                destroy_spu(spu);
-       up(&spu_mutex);
+       mutex_unlock(&spu_mutex);
 }
 module_exit(cleanup_spu_base);