diff options
| -rw-r--r-- | arch/powerpc/platforms/85xx/smp.c | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c index 04160a4cc699..a15f582300d8 100644 --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c | |||
| @@ -46,6 +46,7 @@ smp_85xx_kick_cpu(int nr) | |||
| 46 | __iomem u32 *bptr_vaddr; | 46 | __iomem u32 *bptr_vaddr; |
| 47 | struct device_node *np; | 47 | struct device_node *np; |
| 48 | int n = 0; | 48 | int n = 0; |
| 49 | int ioremappable; | ||
| 49 | 50 | ||
| 50 | WARN_ON (nr < 0 || nr >= NR_CPUS); | 51 | WARN_ON (nr < 0 || nr >= NR_CPUS); |
| 51 | 52 | ||
| @@ -59,21 +60,37 @@ smp_85xx_kick_cpu(int nr) | |||
| 59 | return; | 60 | return; |
| 60 | } | 61 | } |
| 61 | 62 | ||
| 63 | /* | ||
| 64 | * A secondary core could be in a spinloop in the bootpage | ||
| 65 | * (0xfffff000), somewhere in highmem, or somewhere in lowmem. | ||
| 66 | * The bootpage and highmem can be accessed via ioremap(), but | ||
| 67 | * we need to directly access the spinloop if its in lowmem. | ||
| 68 | */ | ||
| 69 | ioremappable = *cpu_rel_addr > virt_to_phys(high_memory); | ||
| 70 | |||
| 62 | /* Map the spin table */ | 71 | /* Map the spin table */ |
| 63 | bptr_vaddr = ioremap(*cpu_rel_addr, SIZE_BOOT_ENTRY); | 72 | if (ioremappable) |
| 73 | bptr_vaddr = ioremap(*cpu_rel_addr, SIZE_BOOT_ENTRY); | ||
| 74 | else | ||
| 75 | bptr_vaddr = phys_to_virt(*cpu_rel_addr); | ||
| 64 | 76 | ||
| 65 | local_irq_save(flags); | 77 | local_irq_save(flags); |
| 66 | 78 | ||
| 67 | out_be32(bptr_vaddr + BOOT_ENTRY_PIR, nr); | 79 | out_be32(bptr_vaddr + BOOT_ENTRY_PIR, nr); |
| 68 | out_be32(bptr_vaddr + BOOT_ENTRY_ADDR_LOWER, __pa(__early_start)); | 80 | out_be32(bptr_vaddr + BOOT_ENTRY_ADDR_LOWER, __pa(__early_start)); |
| 69 | 81 | ||
| 82 | if (!ioremappable) | ||
| 83 | flush_dcache_range((ulong)bptr_vaddr, | ||
| 84 | (ulong)(bptr_vaddr + SIZE_BOOT_ENTRY)); | ||
| 85 | |||
| 70 | /* Wait a bit for the CPU to ack. */ | 86 | /* Wait a bit for the CPU to ack. */ |
| 71 | while ((__secondary_hold_acknowledge != nr) && (++n < 1000)) | 87 | while ((__secondary_hold_acknowledge != nr) && (++n < 1000)) |
| 72 | mdelay(1); | 88 | mdelay(1); |
| 73 | 89 | ||
| 74 | local_irq_restore(flags); | 90 | local_irq_restore(flags); |
| 75 | 91 | ||
| 76 | iounmap(bptr_vaddr); | 92 | if (ioremappable) |
| 93 | iounmap(bptr_vaddr); | ||
| 77 | 94 | ||
| 78 | pr_debug("waited %d msecs for CPU #%d.\n", n, nr); | 95 | pr_debug("waited %d msecs for CPU #%d.\n", n, nr); |
| 79 | } | 96 | } |
