Merge tag 'nds32-for-linux-5.2-rc3' of git://git.kernel.org/pub/scm/linux/kernel...
[sfrench/cifs-2.6.git] / arch / arm / include / asm / edac.h
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Copyright 2011 Calxeda, Inc.
4  * Based on PPC version Copyright 2007 MontaVista Software, Inc.
5  */
6 #ifndef ASM_EDAC_H
7 #define ASM_EDAC_H
8 /*
9  * ECC atomic, DMA, SMP and interrupt safe scrub function.
10  * Implements the per arch edac_atomic_scrub() that EDAC use for software
11  * ECC scrubbing.  It reads memory and then writes back the original
12  * value, allowing the hardware to detect and correct memory errors.
13  */
14
15 static inline void edac_atomic_scrub(void *va, u32 size)
16 {
17 #if __LINUX_ARM_ARCH__ >= 6
18         unsigned int *virt_addr = va;
19         unsigned int temp, temp2;
20         unsigned int i;
21
22         for (i = 0; i < size / sizeof(*virt_addr); i++, virt_addr++) {
23                 /* Very carefully read and write to memory atomically
24                  * so we are interrupt, DMA and SMP safe.
25                  */
26                 __asm__ __volatile__("\n"
27                         "1:     ldrex   %0, [%2]\n"
28                         "       strex   %1, %0, [%2]\n"
29                         "       teq     %1, #0\n"
30                         "       bne     1b\n"
31                         : "=&r"(temp), "=&r"(temp2)
32                         : "r"(virt_addr)
33                         : "cc");
34         }
35 #endif
36 }
37
38 #endif