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