From 6f62d14c9648fbd419675ab14b1d617806200eee Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Fri, 9 Dec 2011 17:58:35 +0100 Subject: [PATCH] --- yaml --- r: 279787 b: refs/heads/master c: 786a767465b12cb4c1a45421b12fbf6bff45b0ea h: refs/heads/master i: 279785: 1ba365f728ad34a3de2cef3e968f6038b7d8c9de 279783: 55ab82bd0ab73586fe50acad857b6419729e4825 v: v3 --- [refs] | 2 +- trunk/arch/arm/include/asm/edac.h | 48 +++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 trunk/arch/arm/include/asm/edac.h diff --git a/[refs] b/[refs] index 0b42ecb5382c..36b6879246f5 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 8878a539ff19a43cf3729e7562cd528f490246ae +refs/heads/master: 786a767465b12cb4c1a45421b12fbf6bff45b0ea diff --git a/trunk/arch/arm/include/asm/edac.h b/trunk/arch/arm/include/asm/edac.h new file mode 100644 index 000000000000..0df7a2c1fc3d --- /dev/null +++ b/trunk/arch/arm/include/asm/edac.h @@ -0,0 +1,48 @@ +/* + * Copyright 2011 Calxeda, Inc. + * Based on PPC version Copyright 2007 MontaVista Software, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ +#ifndef ASM_EDAC_H +#define ASM_EDAC_H +/* + * ECC atomic, DMA, SMP and interrupt safe scrub function. + * Implements the per arch atomic_scrub() that EDAC use for software + * ECC scrubbing. It reads memory and then writes back the original + * value, allowing the hardware to detect and correct memory errors. + */ +static inline void atomic_scrub(void *va, u32 size) +{ +#if __LINUX_ARM_ARCH__ >= 6 + unsigned int *virt_addr = va; + unsigned int temp, temp2; + unsigned int i; + + for (i = 0; i < size / sizeof(*virt_addr); i++, virt_addr++) { + /* Very carefully read and write to memory atomically + * so we are interrupt, DMA and SMP safe. + */ + __asm__ __volatile__("\n" + "1: ldrex %0, [%2]\n" + " strex %1, %0, [%2]\n" + " teq %1, #0\n" + " bne 1b\n" + : "=&r"(temp), "=&r"(temp2) + : "r"(virt_addr) + : "cc"); + } +#endif +} + +#endif