[PATCH] for_each_possible_cpu: powerpc
[pandora-kernel.git] / arch / powerpc / platforms / cell / interrupt.c
index 9d41e07..978be1c 100644 (file)
@@ -63,7 +63,24 @@ static DEFINE_PER_CPU(struct iic, iic);
 
 void iic_local_enable(void)
 {
-       out_be64(&__get_cpu_var(iic).regs->prio, 0xff);
+       struct iic *iic = &__get_cpu_var(iic);
+       u64 tmp;
+
+       /*
+        * There seems to be a bug that is present in DD2.x CPUs
+        * and still only partially fixed in DD3.1.
+        * This bug causes a value written to the priority register
+        * not to make it there, resulting in a system hang unless we
+        * write it again.
+        * Masking with 0xf0 is done because the Cell BE does not
+        * implement the lower four bits of the interrupt priority,
+        * they always read back as zeroes, although future CPUs
+        * might implement different bits.
+        */
+       do {
+               out_be64(&iic->regs->prio, 0xff);
+               tmp = in_be64(&iic->regs->prio);
+       } while ((tmp & 0xf0) != 0xf0);
 }
 
 void iic_local_disable(void)
@@ -209,9 +226,7 @@ static int setup_iic_hardcoded(void)
                        regs += 0x20;
 
                printk(KERN_INFO "IIC for CPU %d at %lx\n", cpu, regs);
-               iic->regs = __ioremap(regs, sizeof(struct iic_regs),
-                                     _PAGE_NO_CACHE);
-
+               iic->regs = ioremap(regs, sizeof(struct iic_regs));
                iic->target_id = (nodeid << 4) + ((cpu & 1) ? 0xf : 0xe);
        }
 
@@ -252,14 +267,12 @@ static int setup_iic(void)
                }
 
                iic = &per_cpu(iic, np[0]);
-               iic->regs = __ioremap(regs[0], sizeof(struct iic_regs),
-                                     _PAGE_NO_CACHE);
+               iic->regs = ioremap(regs[0], sizeof(struct iic_regs));
                iic->target_id = ((np[0] & 2) << 3) + ((np[0] & 1) ? 0xf : 0xe);
                printk("IIC for CPU %d at %lx mapped to %p\n", np[0], regs[0], iic->regs);
 
                iic = &per_cpu(iic, np[1]);
-               iic->regs = __ioremap(regs[2], sizeof(struct iic_regs),
-                                     _PAGE_NO_CACHE);
+               iic->regs = ioremap(regs[2], sizeof(struct iic_regs));
                iic->target_id = ((np[1] & 2) << 3) + ((np[1] & 1) ? 0xf : 0xe);
                printk("IIC for CPU %d at %lx mapped to %p\n", np[1], regs[2], iic->regs);
 
@@ -351,7 +364,7 @@ void iic_init_IRQ(void)
                setup_iic_hardcoded();
 
        irq_offset = 0;
-       for_each_cpu(cpu) {
+       for_each_possible_cpu(cpu) {
                iic = &per_cpu(iic, cpu);
                if (iic->regs)
                        out_be64(&iic->regs->prio, 0xff);