aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/mm/c-octeon.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/mm/c-octeon.c')
-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)
286 board_cache_error_setup = octeon_cache_error_setup; 286 board_cache_error_setup = octeon_cache_error_setup;
287} 287}
288 288
289/** 289/*
290 * Handle a cache error exception 290 * Handle a cache error exception
291 */ 291 */
292
293static RAW_NOTIFIER_HEAD(co_cache_error_chain); 292static RAW_NOTIFIER_HEAD(co_cache_error_chain);
294 293
295int register_co_cache_error_notifier(struct notifier_block *nb) 294int register_co_cache_error_notifier(struct notifier_block *nb)
@@ -304,14 +303,39 @@ int unregister_co_cache_error_notifier(struct notifier_block *nb)
304} 303}
305EXPORT_SYMBOL_GPL(unregister_co_cache_error_notifier); 304EXPORT_SYMBOL_GPL(unregister_co_cache_error_notifier);
306 305
307static inline int co_cache_error_call_notifiers(unsigned long val) 306static void co_cache_error_call_notifiers(unsigned long val)
308{ 307{
309 return raw_notifier_call_chain(&co_cache_error_chain, val, NULL); 308 int rv = raw_notifier_call_chain(&co_cache_error_chain, val, NULL);
309 if ((rv & ~NOTIFY_STOP_MASK) != NOTIFY_OK) {
310 u64 dcache_err;
311 unsigned long coreid = cvmx_get_core_num();
312 u64 icache_err = read_octeon_c0_icacheerr();
313
314 if (val) {
315 dcache_err = cache_err_dcache[coreid];
316 cache_err_dcache[coreid] = 0;
317 } else {
318 dcache_err = read_octeon_c0_dcacheerr();
319 }
320
321 pr_err("Core%lu: Cache error exception:\n", coreid);
322 pr_err("cp0_errorepc == %lx\n", read_c0_errorepc());
323 if (icache_err & 1) {
324 pr_err("CacheErr (Icache) == %llx\n",
325 (unsigned long long)icache_err);
326 write_octeon_c0_icacheerr(0);
327 }
328 if (dcache_err & 1) {
329 pr_err("CacheErr (Dcache) == %llx\n",
330 (unsigned long long)dcache_err);
331 }
332 }
310} 333}
311 334
312/** 335/*
313 * Called when the the exception is recoverable 336 * Called when the the exception is recoverable
314 */ 337 */
338
315asmlinkage void cache_parity_error_octeon_recoverable(void) 339asmlinkage void cache_parity_error_octeon_recoverable(void)
316{ 340{
317 co_cache_error_call_notifiers(0); 341 co_cache_error_call_notifiers(0);
@@ -319,11 +343,8 @@ asmlinkage void cache_parity_error_octeon_recoverable(void)
319 343
320/** 344/**
321 * Called when the the exception is not recoverable 345 * Called when the the exception is not recoverable
322 *
323 * The issue not that the cache error exception itself was non-recoverable
324 * but that due to nesting of exception may have lost some state so can't
325 * continue.
326 */ 346 */
347
327asmlinkage void cache_parity_error_octeon_non_recoverable(void) 348asmlinkage void cache_parity_error_octeon_non_recoverable(void)
328{ 349{
329 co_cache_error_call_notifiers(1); 350 co_cache_error_call_notifiers(1);