176496f8fSPaul Mundt /* 276496f8fSPaul Mundt * SDK7786 FPGA NMI Support. 376496f8fSPaul Mundt * 476496f8fSPaul Mundt * Copyright (C) 2010 Paul Mundt 576496f8fSPaul Mundt * 676496f8fSPaul Mundt * This file is subject to the terms and conditions of the GNU General Public 776496f8fSPaul Mundt * License. See the file "COPYING" in the main directory of this archive 876496f8fSPaul Mundt * for more details. 976496f8fSPaul Mundt */ 1076496f8fSPaul Mundt #include <linux/init.h> 1176496f8fSPaul Mundt #include <linux/kernel.h> 1276496f8fSPaul Mundt #include <linux/string.h> 1376496f8fSPaul Mundt #include <mach/fpga.h> 1476496f8fSPaul Mundt 1576496f8fSPaul Mundt enum { 1676496f8fSPaul Mundt NMI_MODE_MANUAL, 1776496f8fSPaul Mundt NMI_MODE_AUX, 1876496f8fSPaul Mundt NMI_MODE_MASKED, 1976496f8fSPaul Mundt NMI_MODE_ANY, 2076496f8fSPaul Mundt NMI_MODE_UNKNOWN, 2176496f8fSPaul Mundt }; 2276496f8fSPaul Mundt 2376496f8fSPaul Mundt /* 2476496f8fSPaul Mundt * Default to the manual NMI switch. 2576496f8fSPaul Mundt */ 2676496f8fSPaul Mundt static unsigned int __initdata nmi_mode = NMI_MODE_ANY; 2776496f8fSPaul Mundt 2876496f8fSPaul Mundt static int __init nmi_mode_setup(char *str) 2976496f8fSPaul Mundt { 3076496f8fSPaul Mundt if (!str) 3176496f8fSPaul Mundt return 0; 3276496f8fSPaul Mundt 3376496f8fSPaul Mundt if (strcmp(str, "manual") == 0) 3476496f8fSPaul Mundt nmi_mode = NMI_MODE_MANUAL; 3576496f8fSPaul Mundt else if (strcmp(str, "aux") == 0) 3676496f8fSPaul Mundt nmi_mode = NMI_MODE_AUX; 3776496f8fSPaul Mundt else if (strcmp(str, "masked") == 0) 3876496f8fSPaul Mundt nmi_mode = NMI_MODE_MASKED; 3976496f8fSPaul Mundt else if (strcmp(str, "any") == 0) 4076496f8fSPaul Mundt nmi_mode = NMI_MODE_ANY; 4176496f8fSPaul Mundt else { 4276496f8fSPaul Mundt nmi_mode = NMI_MODE_UNKNOWN; 4376496f8fSPaul Mundt pr_warning("Unknown NMI mode %s\n", str); 4476496f8fSPaul Mundt } 4576496f8fSPaul Mundt 4676496f8fSPaul Mundt printk("Set NMI mode to %d\n", nmi_mode); 4776496f8fSPaul Mundt return 0; 4876496f8fSPaul Mundt } 4976496f8fSPaul Mundt early_param("nmi_mode", nmi_mode_setup); 5076496f8fSPaul Mundt 5176496f8fSPaul Mundt void __init sdk7786_nmi_init(void) 5276496f8fSPaul Mundt { 5376496f8fSPaul Mundt unsigned int source, mask, tmp; 5476496f8fSPaul Mundt 5576496f8fSPaul Mundt switch (nmi_mode) { 5676496f8fSPaul Mundt case NMI_MODE_MANUAL: 5776496f8fSPaul Mundt source = NMISR_MAN_NMI; 5876496f8fSPaul Mundt mask = NMIMR_MAN_NMIM; 5976496f8fSPaul Mundt break; 6076496f8fSPaul Mundt case NMI_MODE_AUX: 6176496f8fSPaul Mundt source = NMISR_AUX_NMI; 6276496f8fSPaul Mundt mask = NMIMR_AUX_NMIM; 6376496f8fSPaul Mundt break; 6476496f8fSPaul Mundt case NMI_MODE_ANY: 6576496f8fSPaul Mundt source = NMISR_MAN_NMI | NMISR_AUX_NMI; 6676496f8fSPaul Mundt mask = NMIMR_MAN_NMIM | NMIMR_AUX_NMIM; 6776496f8fSPaul Mundt break; 6876496f8fSPaul Mundt case NMI_MODE_MASKED: 6976496f8fSPaul Mundt case NMI_MODE_UNKNOWN: 7076496f8fSPaul Mundt default: 7176496f8fSPaul Mundt source = mask = 0; 7276496f8fSPaul Mundt break; 7376496f8fSPaul Mundt } 7476496f8fSPaul Mundt 7576496f8fSPaul Mundt /* Set the NMI source */ 7676496f8fSPaul Mundt tmp = fpga_read_reg(NMISR); 7776496f8fSPaul Mundt tmp &= ~NMISR_MASK; 7876496f8fSPaul Mundt tmp |= source; 7976496f8fSPaul Mundt fpga_write_reg(tmp, NMISR); 8076496f8fSPaul Mundt 8176496f8fSPaul Mundt /* And the IRQ masking */ 8276496f8fSPaul Mundt fpga_write_reg(NMIMR_MASK ^ mask, NMIMR); 8376496f8fSPaul Mundt } 84