83 lines
		
	
	
	
		
			1.7 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			83 lines
		
	
	
	
		
			1.7 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
|   | /*
 | ||
|  |  * Copyright (C) 2007 Atmel Corporation | ||
|  |  * | ||
|  |  * This program is free software; you can redistribute it and/or modify | ||
|  |  * it under the terms of the GNU General Public License version 2 as | ||
|  |  * published by the Free Software Foundation. | ||
|  |  */ | ||
|  | #include <linux/delay.h>
 | ||
|  | #include <linux/kdebug.h>
 | ||
|  | #include <linux/notifier.h>
 | ||
|  | #include <linux/sched.h>
 | ||
|  | 
 | ||
|  | #include <asm/irq.h>
 | ||
|  | 
 | ||
|  | enum nmi_action { | ||
|  | 	NMI_SHOW_STATE	= 1 << 0, | ||
|  | 	NMI_SHOW_REGS	= 1 << 1, | ||
|  | 	NMI_DIE		= 1 << 2, | ||
|  | 	NMI_DEBOUNCE	= 1 << 3, | ||
|  | }; | ||
|  | 
 | ||
|  | static unsigned long nmi_actions; | ||
|  | 
 | ||
|  | static int nmi_debug_notify(struct notifier_block *self, | ||
|  | 		unsigned long val, void *data) | ||
|  | { | ||
|  | 	struct die_args *args = data; | ||
|  | 
 | ||
|  | 	if (likely(val != DIE_NMI)) | ||
|  | 		return NOTIFY_DONE; | ||
|  | 
 | ||
|  | 	if (nmi_actions & NMI_SHOW_STATE) | ||
|  | 		show_state(); | ||
|  | 	if (nmi_actions & NMI_SHOW_REGS) | ||
|  | 		show_regs(args->regs); | ||
|  | 	if (nmi_actions & NMI_DEBOUNCE) | ||
|  | 		mdelay(10); | ||
|  | 	if (nmi_actions & NMI_DIE) | ||
|  | 		return NOTIFY_BAD; | ||
|  | 
 | ||
|  | 	return NOTIFY_OK; | ||
|  | } | ||
|  | 
 | ||
|  | static struct notifier_block nmi_debug_nb = { | ||
|  | 	.notifier_call = nmi_debug_notify, | ||
|  | }; | ||
|  | 
 | ||
|  | static int __init nmi_debug_setup(char *str) | ||
|  | { | ||
|  | 	char *p, *sep; | ||
|  | 
 | ||
|  | 	register_die_notifier(&nmi_debug_nb); | ||
|  | 	if (nmi_enable()) { | ||
|  | 		printk(KERN_WARNING "Unable to enable NMI.\n"); | ||
|  | 		return 0; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	if (*str != '=') | ||
|  | 		return 0; | ||
|  | 
 | ||
|  | 	for (p = str + 1; *p; p = sep + 1) { | ||
|  | 		sep = strchr(p, ','); | ||
|  | 		if (sep) | ||
|  | 			*sep = 0; | ||
|  | 		if (strcmp(p, "state") == 0) | ||
|  | 			nmi_actions |= NMI_SHOW_STATE; | ||
|  | 		else if (strcmp(p, "regs") == 0) | ||
|  | 			nmi_actions |= NMI_SHOW_REGS; | ||
|  | 		else if (strcmp(p, "debounce") == 0) | ||
|  | 			nmi_actions |= NMI_DEBOUNCE; | ||
|  | 		else if (strcmp(p, "die") == 0) | ||
|  | 			nmi_actions |= NMI_DIE; | ||
|  | 		else | ||
|  | 			printk(KERN_WARNING "NMI: Unrecognized action `%s'\n", | ||
|  | 				p); | ||
|  | 		if (!sep) | ||
|  | 			break; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	return 0; | ||
|  | } | ||
|  | __setup("nmi_debug", nmi_debug_setup); |