aboutsummaryrefslogtreecommitdiff
path: root/arch/mips/mm
diff options
context:
space:
mode:
authorDavid Daney2012-11-15 13:58:59 -0800
committerRalf Baechle2012-12-13 18:15:26 +0100
commite1ced09797776dfd4a2a7b04b9ee7e97ab1e64be (patch)
tree473934ca424e0e10f235bcd9ae97781349af5495 /arch/mips/mm
parentabe105a4d8c5ee2aa2acef33c5d163e5d187598f (diff)
MIPS/EDAC: Improve OCTEON EDAC support.
Some initialization errors are reported with the existing OCTEON EDAC support patch. Also some parts have more than one memory controller. Fix the errors and add multiple controllers if present. Signed-off-by: David Daney <david.daney@cavium.com>
Diffstat (limited to 'arch/mips/mm')
-rw-r--r--arch/mips/mm/c-octeon.c39
1 files changed, 30 insertions, 9 deletions
diff --git a/arch/mips/mm/c-octeon.c b/arch/mips/mm/c-octeon.c
index 9f67553762d5..6ec04daf4231 100644
--- a/arch/mips/mm/c-octeon.c
+++ b/arch/mips/mm/c-octeon.c
@@ -286,10 +286,9 @@ void __cpuinit octeon_cache_init(void)
board_cache_error_setup = octeon_cache_error_setup;
}
-/**
+/*
* Handle a cache error exception
*/
-
static RAW_NOTIFIER_HEAD(co_cache_error_chain);
int register_co_cache_error_notifier(struct notifier_block *nb)
@@ -304,14 +303,39 @@ int unregister_co_cache_error_notifier(struct notifier_block *nb)
}
EXPORT_SYMBOL_GPL(unregister_co_cache_error_notifier);
-static inline int co_cache_error_call_notifiers(unsigned long val)
+static void co_cache_error_call_notifiers(unsigned long val)
{
- return raw_notifier_call_chain(&co_cache_error_chain, val, NULL);
+ int rv = raw_notifier_call_chain(&co_cache_error_chain, val, NULL);
+ if ((rv & ~NOTIFY_STOP_MASK) != NOTIFY_OK) {
+ u64 dcache_err;
+ unsigned long coreid = cvmx_get_core_num();
+ u64 icache_err = read_octeon_c0_icacheerr();
+
+ if (val) {
+ dcache_err = cache_err_dcache[coreid];
+ cache_err_dcache[coreid] = 0;
+ } else {
+ dcache_err = read_octeon_c0_dcacheerr();
+ }
+
+ pr_err("Core%lu: Cache error exception:\n", coreid);
+ pr_err("cp0_errorepc == %lx\n", read_c0_errorepc());
+ if (icache_err & 1) {
+ pr_err("CacheErr (Icache) == %llx\n",
+ (unsigned long long)icache_err);
+ write_octeon_c0_icacheerr(0);
+ }
+ if (dcache_err & 1) {
+ pr_err("CacheErr (Dcache) == %llx\n",
+ (unsigned long long)dcache_err);
+ }
+ }
}
-/**
+/*
* Called when the the exception is recoverable
*/
+
asmlinkage void cache_parity_error_octeon_recoverable(void)
{
co_cache_error_call_notifiers(0);
@@ -319,11 +343,8 @@ asmlinkage void cache_parity_error_octeon_recoverable(void)
/**
* Called when the the exception is not recoverable
- *
- * The issue not that the cache error exception itself was non-recoverable
- * but that due to nesting of exception may have lost some state so can't
- * continue.
*/
+
asmlinkage void cache_parity_error_octeon_non_recoverable(void)
{
co_cache_error_call_notifiers(1);