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)
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);
}
}
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);
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);