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