Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

sh: mach-sdk7786: Handle baseboard NMI source selection.

The on-board NMI switch is routed through and mangled by the FPGA prior
to its delivery to the NMI pin, so add some glue for the various
configuration options. The default is to unmask it and enable all input
sources.

Signed-off-by: Paul Mundt <lethal@linux-sh.org>

+93 -1
+1 -1
arch/sh/boards/mach-sdk7786/Makefile
··· 1 - obj-y := fpga.o irq.o setup.o 1 + obj-y := fpga.o irq.o nmi.o setup.o 2 2 3 3 obj-$(CONFIG_GENERIC_GPIO) += gpio.o 4 4 obj-$(CONFIG_HAVE_SRAM_POOL) += sram.o
+83
arch/sh/boards/mach-sdk7786/nmi.c
··· 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 + 15 + enum { 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 + */ 26 + static unsigned int __initdata nmi_mode = NMI_MODE_ANY; 27 + 28 + static 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 + } 49 + early_param("nmi_mode", nmi_mode_setup); 50 + 51 + void __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 + }
+1
arch/sh/boards/mach-sdk7786/setup.c
··· 237 237 pr_info("Renesas Technology Europe SDK7786 support:\n"); 238 238 239 239 sdk7786_fpga_init(); 240 + sdk7786_nmi_init(); 240 241 241 242 pr_info("\tPCB revision:\t%d\n", fpga_read_reg(PCBRR) & 0xf); 242 243
+8
arch/sh/include/mach-sdk7786/mach/fpga.h
··· 14 14 #define INTTESTR 0x040 15 15 #define SYSSR 0x050 16 16 #define NRGPR 0x060 17 + 17 18 #define NMISR 0x070 19 + #define NMISR_MAN_NMI BIT(0) 20 + #define NMISR_AUX_NMI BIT(1) 21 + #define NMISR_MASK (NMISR_MAN_NMI | NMISR_AUX_NMI) 18 22 19 23 #define NMIMR 0x080 20 24 #define NMIMR_MAN_NMIM BIT(0) /* Manual NMI mask */ 21 25 #define NMIMR_AUX_NMIM BIT(1) /* Auxiliary NMI mask */ 26 + #define NMIMR_MASK (NMIMR_MAN_NMIM | NMIMR_AUX_NMIM) 22 27 23 28 #define INTBSR 0x090 24 29 #define INTBMR 0x0a0 ··· 130 125 /* arch/sh/boards/mach-sdk7786/fpga.c */ 131 126 extern void __iomem *sdk7786_fpga_base; 132 127 extern void sdk7786_fpga_init(void); 128 + 129 + /* arch/sh/boards/mach-sdk7786/nmi.c */ 130 + extern void sdk7786_nmi_init(void); 133 131 134 132 #define SDK7786_FPGA_REGADDR(reg) (sdk7786_fpga_base + (reg)) 135 133