xref: /openbmc/linux/arch/sh/boards/mach-sdk7786/nmi.c (revision 76496f8f2e104b8bb08db09c063a6817d18829a6)
1*76496f8fSPaul Mundt /*
2*76496f8fSPaul Mundt  * SDK7786 FPGA NMI Support.
3*76496f8fSPaul Mundt  *
4*76496f8fSPaul Mundt  * Copyright (C) 2010  Paul Mundt
5*76496f8fSPaul Mundt  *
6*76496f8fSPaul Mundt  * This file is subject to the terms and conditions of the GNU General Public
7*76496f8fSPaul Mundt  * License.  See the file "COPYING" in the main directory of this archive
8*76496f8fSPaul Mundt  * for more details.
9*76496f8fSPaul Mundt  */
10*76496f8fSPaul Mundt #include <linux/init.h>
11*76496f8fSPaul Mundt #include <linux/kernel.h>
12*76496f8fSPaul Mundt #include <linux/string.h>
13*76496f8fSPaul Mundt #include <mach/fpga.h>
14*76496f8fSPaul Mundt 
15*76496f8fSPaul Mundt enum {
16*76496f8fSPaul Mundt 	NMI_MODE_MANUAL,
17*76496f8fSPaul Mundt 	NMI_MODE_AUX,
18*76496f8fSPaul Mundt 	NMI_MODE_MASKED,
19*76496f8fSPaul Mundt 	NMI_MODE_ANY,
20*76496f8fSPaul Mundt 	NMI_MODE_UNKNOWN,
21*76496f8fSPaul Mundt };
22*76496f8fSPaul Mundt 
23*76496f8fSPaul Mundt /*
24*76496f8fSPaul Mundt  * Default to the manual NMI switch.
25*76496f8fSPaul Mundt  */
26*76496f8fSPaul Mundt static unsigned int __initdata nmi_mode = NMI_MODE_ANY;
27*76496f8fSPaul Mundt 
28*76496f8fSPaul Mundt static int __init nmi_mode_setup(char *str)
29*76496f8fSPaul Mundt {
30*76496f8fSPaul Mundt 	if (!str)
31*76496f8fSPaul Mundt 		return 0;
32*76496f8fSPaul Mundt 
33*76496f8fSPaul Mundt 	if (strcmp(str, "manual") == 0)
34*76496f8fSPaul Mundt 		nmi_mode = NMI_MODE_MANUAL;
35*76496f8fSPaul Mundt 	else if (strcmp(str, "aux") == 0)
36*76496f8fSPaul Mundt 		nmi_mode = NMI_MODE_AUX;
37*76496f8fSPaul Mundt 	else if (strcmp(str, "masked") == 0)
38*76496f8fSPaul Mundt 		nmi_mode = NMI_MODE_MASKED;
39*76496f8fSPaul Mundt 	else if (strcmp(str, "any") == 0)
40*76496f8fSPaul Mundt 		nmi_mode = NMI_MODE_ANY;
41*76496f8fSPaul Mundt 	else {
42*76496f8fSPaul Mundt 		nmi_mode = NMI_MODE_UNKNOWN;
43*76496f8fSPaul Mundt 		pr_warning("Unknown NMI mode %s\n", str);
44*76496f8fSPaul Mundt 	}
45*76496f8fSPaul Mundt 
46*76496f8fSPaul Mundt 	printk("Set NMI mode to %d\n", nmi_mode);
47*76496f8fSPaul Mundt 	return 0;
48*76496f8fSPaul Mundt }
49*76496f8fSPaul Mundt early_param("nmi_mode", nmi_mode_setup);
50*76496f8fSPaul Mundt 
51*76496f8fSPaul Mundt void __init sdk7786_nmi_init(void)
52*76496f8fSPaul Mundt {
53*76496f8fSPaul Mundt 	unsigned int source, mask, tmp;
54*76496f8fSPaul Mundt 
55*76496f8fSPaul Mundt 	switch (nmi_mode) {
56*76496f8fSPaul Mundt 	case NMI_MODE_MANUAL:
57*76496f8fSPaul Mundt 		source = NMISR_MAN_NMI;
58*76496f8fSPaul Mundt 		mask = NMIMR_MAN_NMIM;
59*76496f8fSPaul Mundt 		break;
60*76496f8fSPaul Mundt 	case NMI_MODE_AUX:
61*76496f8fSPaul Mundt 		source = NMISR_AUX_NMI;
62*76496f8fSPaul Mundt 		mask = NMIMR_AUX_NMIM;
63*76496f8fSPaul Mundt 		break;
64*76496f8fSPaul Mundt 	case NMI_MODE_ANY:
65*76496f8fSPaul Mundt 		source = NMISR_MAN_NMI | NMISR_AUX_NMI;
66*76496f8fSPaul Mundt 		mask = NMIMR_MAN_NMIM | NMIMR_AUX_NMIM;
67*76496f8fSPaul Mundt 		break;
68*76496f8fSPaul Mundt 	case NMI_MODE_MASKED:
69*76496f8fSPaul Mundt 	case NMI_MODE_UNKNOWN:
70*76496f8fSPaul Mundt 	default:
71*76496f8fSPaul Mundt 		source = mask = 0;
72*76496f8fSPaul Mundt 		break;
73*76496f8fSPaul Mundt 	}
74*76496f8fSPaul Mundt 
75*76496f8fSPaul Mundt 	/* Set the NMI source */
76*76496f8fSPaul Mundt 	tmp = fpga_read_reg(NMISR);
77*76496f8fSPaul Mundt 	tmp &= ~NMISR_MASK;
78*76496f8fSPaul Mundt 	tmp |= source;
79*76496f8fSPaul Mundt 	fpga_write_reg(tmp, NMISR);
80*76496f8fSPaul Mundt 
81*76496f8fSPaul Mundt 	/* And the IRQ masking */
82*76496f8fSPaul Mundt 	fpga_write_reg(NMIMR_MASK ^ mask, NMIMR);
83*76496f8fSPaul Mundt }
84