| /* | 
 |  * 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 <linux/hardirq.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 (*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); |