diff options
Diffstat (limited to 'arch/sparc/kernel/setup_64.c')
-rw-r--r-- | arch/sparc/kernel/setup_64.c | 32 |
1 files changed, 21 insertions, 11 deletions
diff --git a/arch/sparc/kernel/setup_64.c b/arch/sparc/kernel/setup_64.c index 26d114187e10..3e9daea1653d 100644 --- a/arch/sparc/kernel/setup_64.c +++ b/arch/sparc/kernel/setup_64.c | |||
@@ -275,24 +275,34 @@ void __init sun4v_patch(void) | |||
275 | static void __init popc_patch(void) | 275 | static void __init popc_patch(void) |
276 | { | 276 | { |
277 | struct popc_3insn_patch_entry *p3; | 277 | struct popc_3insn_patch_entry *p3; |
278 | struct popc_6insn_patch_entry *p6; | ||
278 | 279 | ||
279 | p3 = &__popc_3insn_patch; | 280 | p3 = &__popc_3insn_patch; |
280 | while (p3 < &__popc_3insn_patch_end) { | 281 | while (p3 < &__popc_3insn_patch_end) { |
281 | unsigned long addr = p3->addr; | 282 | unsigned long i, addr = p3->addr; |
282 | 283 | ||
283 | *(unsigned int *) (addr + 0) = p3->insns[0]; | 284 | for (i = 0; i < 3; i++) { |
284 | wmb(); | 285 | *(unsigned int *) (addr + (i * 4)) = p3->insns[i]; |
285 | __asm__ __volatile__("flush %0" : : "r" (addr + 0)); | 286 | wmb(); |
287 | __asm__ __volatile__("flush %0" | ||
288 | : : "r" (addr + (i * 4))); | ||
289 | } | ||
286 | 290 | ||
287 | *(unsigned int *) (addr + 4) = p3->insns[1]; | 291 | p3++; |
288 | wmb(); | 292 | } |
289 | __asm__ __volatile__("flush %0" : : "r" (addr + 4)); | ||
290 | 293 | ||
291 | *(unsigned int *) (addr + 8) = p3->insns[2]; | 294 | p6 = &__popc_6insn_patch; |
292 | wmb(); | 295 | while (p6 < &__popc_6insn_patch_end) { |
293 | __asm__ __volatile__("flush %0" : : "r" (addr + 4)); | 296 | unsigned long i, addr = p6->addr; |
294 | 297 | ||
295 | p3++; | 298 | for (i = 0; i < 6; i++) { |
299 | *(unsigned int *) (addr + (i * 4)) = p6->insns[i]; | ||
300 | wmb(); | ||
301 | __asm__ __volatile__("flush %0" | ||
302 | : : "r" (addr + (i * 4))); | ||
303 | } | ||
304 | |||
305 | p6++; | ||
296 | } | 306 | } |
297 | } | 307 | } |
298 | 308 | ||