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