xref: /openbmc/linux/arch/sh/boards/mach-sdk7786/nmi.c (revision 6d80f20c)
1aaf9128aSKuninori Morimoto // SPDX-License-Identifier: GPL-2.0
276496f8fSPaul Mundt /*
376496f8fSPaul Mundt  * SDK7786 FPGA NMI Support.
476496f8fSPaul Mundt  *
576496f8fSPaul Mundt  * Copyright (C) 2010  Paul Mundt
676496f8fSPaul Mundt  */
776496f8fSPaul Mundt #include <linux/init.h>
876496f8fSPaul Mundt #include <linux/kernel.h>
976496f8fSPaul Mundt #include <linux/string.h>
1076496f8fSPaul Mundt #include <mach/fpga.h>
1176496f8fSPaul Mundt 
1276496f8fSPaul Mundt enum {
1376496f8fSPaul Mundt 	NMI_MODE_MANUAL,
1476496f8fSPaul Mundt 	NMI_MODE_AUX,
1576496f8fSPaul Mundt 	NMI_MODE_MASKED,
1676496f8fSPaul Mundt 	NMI_MODE_ANY,
1776496f8fSPaul Mundt 	NMI_MODE_UNKNOWN,
1876496f8fSPaul Mundt };
1976496f8fSPaul Mundt 
2076496f8fSPaul Mundt /*
2176496f8fSPaul Mundt  * Default to the manual NMI switch.
2276496f8fSPaul Mundt  */
2376496f8fSPaul Mundt static unsigned int __initdata nmi_mode = NMI_MODE_ANY;
2476496f8fSPaul Mundt 
nmi_mode_setup(char * str)2576496f8fSPaul Mundt static int __init nmi_mode_setup(char *str)
2676496f8fSPaul Mundt {
2776496f8fSPaul Mundt 	if (!str)
2876496f8fSPaul Mundt 		return 0;
2976496f8fSPaul Mundt 
3076496f8fSPaul Mundt 	if (strcmp(str, "manual") == 0)
3176496f8fSPaul Mundt 		nmi_mode = NMI_MODE_MANUAL;
3276496f8fSPaul Mundt 	else if (strcmp(str, "aux") == 0)
3376496f8fSPaul Mundt 		nmi_mode = NMI_MODE_AUX;
3476496f8fSPaul Mundt 	else if (strcmp(str, "masked") == 0)
3576496f8fSPaul Mundt 		nmi_mode = NMI_MODE_MASKED;
3676496f8fSPaul Mundt 	else if (strcmp(str, "any") == 0)
3776496f8fSPaul Mundt 		nmi_mode = NMI_MODE_ANY;
3876496f8fSPaul Mundt 	else {
3976496f8fSPaul Mundt 		nmi_mode = NMI_MODE_UNKNOWN;
406d80f20cSKefeng Wang 		pr_warn("Unknown NMI mode %s\n", str);
4176496f8fSPaul Mundt 	}
4276496f8fSPaul Mundt 
4376496f8fSPaul Mundt 	printk("Set NMI mode to %d\n", nmi_mode);
4476496f8fSPaul Mundt 	return 0;
4576496f8fSPaul Mundt }
4676496f8fSPaul Mundt early_param("nmi_mode", nmi_mode_setup);
4776496f8fSPaul Mundt 
sdk7786_nmi_init(void)4876496f8fSPaul Mundt void __init sdk7786_nmi_init(void)
4976496f8fSPaul Mundt {
5076496f8fSPaul Mundt 	unsigned int source, mask, tmp;
5176496f8fSPaul Mundt 
5276496f8fSPaul Mundt 	switch (nmi_mode) {
5376496f8fSPaul Mundt 	case NMI_MODE_MANUAL:
5476496f8fSPaul Mundt 		source = NMISR_MAN_NMI;
5576496f8fSPaul Mundt 		mask = NMIMR_MAN_NMIM;
5676496f8fSPaul Mundt 		break;
5776496f8fSPaul Mundt 	case NMI_MODE_AUX:
5876496f8fSPaul Mundt 		source = NMISR_AUX_NMI;
5976496f8fSPaul Mundt 		mask = NMIMR_AUX_NMIM;
6076496f8fSPaul Mundt 		break;
6176496f8fSPaul Mundt 	case NMI_MODE_ANY:
6276496f8fSPaul Mundt 		source = NMISR_MAN_NMI | NMISR_AUX_NMI;
6376496f8fSPaul Mundt 		mask = NMIMR_MAN_NMIM | NMIMR_AUX_NMIM;
6476496f8fSPaul Mundt 		break;
6576496f8fSPaul Mundt 	case NMI_MODE_MASKED:
6676496f8fSPaul Mundt 	case NMI_MODE_UNKNOWN:
6776496f8fSPaul Mundt 	default:
6876496f8fSPaul Mundt 		source = mask = 0;
6976496f8fSPaul Mundt 		break;
7076496f8fSPaul Mundt 	}
7176496f8fSPaul Mundt 
7276496f8fSPaul Mundt 	/* Set the NMI source */
7376496f8fSPaul Mundt 	tmp = fpga_read_reg(NMISR);
7476496f8fSPaul Mundt 	tmp &= ~NMISR_MASK;
7576496f8fSPaul Mundt 	tmp |= source;
7676496f8fSPaul Mundt 	fpga_write_reg(tmp, NMISR);
7776496f8fSPaul Mundt 
7876496f8fSPaul Mundt 	/* And the IRQ masking */
7976496f8fSPaul Mundt 	fpga_write_reg(NMIMR_MASK ^ mask, NMIMR);
8076496f8fSPaul Mundt }
81