Merge branch 'linux-2.6' into for-2.6.22
[sfrench/cifs-2.6.git] / include / asm-powerpc / edac.h
1 /*
2  * PPC EDAC common defs
3  *
4  * Author: Dave Jiang <djiang@mvista.com>
5  *
6  * 2007 (c) MontaVista Software, Inc. This file is licensed under
7  * the terms of the GNU General Public License version 2. This program
8  * is licensed "as is" without any warranty of any kind, whether express
9  * or implied.
10  */
11 #ifndef ASM_EDAC_H
12 #define ASM_EDAC_H
13 /*
14  * ECC atomic, DMA, SMP and interrupt safe scrub function.
15  * Implements the per arch atomic_scrub() that EDAC use for software
16  * ECC scrubbing.  It reads memory and then writes back the original
17  * value, allowing the hardware to detect and correct memory errors.
18  */
19 static __inline__ void atomic_scrub(void *va, u32 size)
20 {
21         unsigned int *virt_addr = va;
22         unsigned int temp;
23         unsigned int i;
24
25         for (i = 0; i < size / sizeof(*virt_addr); i++, virt_addr++) {
26                 /* Very carefully read and write to memory atomically
27                  * so we are interrupt, DMA and SMP safe.
28                  */
29                 __asm__ __volatile__ ("\n\
30                                 1:      lwarx   %0,0,%1\n\
31                                         stwcx.  %0,0,%1\n\
32                                         bne-    1b\n\
33                                         isync"
34                                         : "=&r"(temp)
35                                         : "r"(virt_addr)
36                                         : "cr0", "memory");
37         }
38 }
39
40 #endif