Merge branch 'for-linus' of master.kernel.org:/pub/scm/linux/kernel/git/cooloney...
[sfrench/cifs-2.6.git] / include / asm-mips / edac.h
1 #ifndef ASM_EDAC_H
2 #define ASM_EDAC_H
3
4 /* ECC atomic, DMA, SMP and interrupt safe scrub function */
5
6 static inline void atomic_scrub(void *va, u32 size)
7 {
8         unsigned long *virt_addr = va;
9         unsigned long temp;
10         u32 i;
11
12         for (i = 0; i < size / sizeof(unsigned long); i++, virt_addr++) {
13
14                 /*
15                  * Very carefully read and write to memory atomically
16                  * so we are interrupt, DMA and SMP safe.
17                  *
18                  * Intel: asm("lock; addl $0, %0"::"m"(*virt_addr));
19                  */
20
21                 __asm__ __volatile__ (
22                 "       .set    mips3                                   \n"
23                 "1:     ll      %0, %1          # atomic_add            \n"
24                 "       ll      %0, %1          # atomic_add            \n"
25                 "       addu    %0, $0                                  \n"
26                 "       sc      %0, %1                                  \n"
27                 "       beqz    %0, 1b                                  \n"
28                 "       .set    mips0                                   \n"
29                 : "=&r" (temp), "=m" (*virt_addr)
30                 : "m" (*virt_addr));
31
32         }
33 }
34
35 #endif