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 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; 40*6d80f20cSKefeng 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 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