sh: mach-sdk7786: Handle baseboard NMI source selection.
authorPaul Mundt <lethal@linux-sh.org>
Fri, 17 Dec 2010 09:58:04 +0000 (18:58 +0900)
committerPaul Mundt <lethal@linux-sh.org>
Fri, 17 Dec 2010 09:58:04 +0000 (18:58 +0900)
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>
arch/sh/boards/mach-sdk7786/Makefile
arch/sh/boards/mach-sdk7786/nmi.c [new file with mode: 0644]
arch/sh/boards/mach-sdk7786/setup.c
arch/sh/include/mach-sdk7786/mach/fpga.h

index 23ff7d4ac491fc2e47cf334700e3133f01684b9c..8ae56e9560aca1d6bfebefb3ed0e4a9e35b95677 100644 (file)
@@ -1,4 +1,4 @@
-obj-y  := fpga.o irq.o setup.o
+obj-y  := fpga.o irq.o nmi.o setup.o
 
 obj-$(CONFIG_GENERIC_GPIO)     += gpio.o
 obj-$(CONFIG_HAVE_SRAM_POOL)   += sram.o
diff --git a/arch/sh/boards/mach-sdk7786/nmi.c b/arch/sh/boards/mach-sdk7786/nmi.c
new file mode 100644 (file)
index 0000000..edcfa1f
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * SDK7786 FPGA NMI Support.
+ *
+ * Copyright (C) 2010  Paul Mundt
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <mach/fpga.h>
+
+enum {
+       NMI_MODE_MANUAL,
+       NMI_MODE_AUX,
+       NMI_MODE_MASKED,
+       NMI_MODE_ANY,
+       NMI_MODE_UNKNOWN,
+};
+
+/*
+ * Default to the manual NMI switch.
+ */
+static unsigned int __initdata nmi_mode = NMI_MODE_ANY;
+
+static int __init nmi_mode_setup(char *str)
+{
+       if (!str)
+               return 0;
+
+       if (strcmp(str, "manual") == 0)
+               nmi_mode = NMI_MODE_MANUAL;
+       else if (strcmp(str, "aux") == 0)
+               nmi_mode = NMI_MODE_AUX;
+       else if (strcmp(str, "masked") == 0)
+               nmi_mode = NMI_MODE_MASKED;
+       else if (strcmp(str, "any") == 0)
+               nmi_mode = NMI_MODE_ANY;
+       else {
+               nmi_mode = NMI_MODE_UNKNOWN;
+               pr_warning("Unknown NMI mode %s\n", str);
+       }
+
+       printk("Set NMI mode to %d\n", nmi_mode);
+       return 0;
+}
+early_param("nmi_mode", nmi_mode_setup);
+
+void __init sdk7786_nmi_init(void)
+{
+       unsigned int source, mask, tmp;
+
+       switch (nmi_mode) {
+       case NMI_MODE_MANUAL:
+               source = NMISR_MAN_NMI;
+               mask = NMIMR_MAN_NMIM;
+               break;
+       case NMI_MODE_AUX:
+               source = NMISR_AUX_NMI;
+               mask = NMIMR_AUX_NMIM;
+               break;
+       case NMI_MODE_ANY:
+               source = NMISR_MAN_NMI | NMISR_AUX_NMI;
+               mask = NMIMR_MAN_NMIM | NMIMR_AUX_NMIM;
+               break;
+       case NMI_MODE_MASKED:
+       case NMI_MODE_UNKNOWN:
+       default:
+               source = mask = 0;
+               break;
+       }
+
+       /* Set the NMI source */
+       tmp = fpga_read_reg(NMISR);
+       tmp &= ~NMISR_MASK;
+       tmp |= source;
+       fpga_write_reg(tmp, NMISR);
+
+       /* And the IRQ masking */
+       fpga_write_reg(NMIMR_MASK ^ mask, NMIMR);
+}
index 7e0c4e3878e062dd292b591c9706a3ff3127fbd7..75e4ddbbec3e238c0c04caf91ab745e2552d7ef6 100644 (file)
@@ -237,6 +237,7 @@ static void __init sdk7786_setup(char **cmdline_p)
        pr_info("Renesas Technology Europe SDK7786 support:\n");
 
        sdk7786_fpga_init();
+       sdk7786_nmi_init();
 
        pr_info("\tPCB revision:\t%d\n", fpga_read_reg(PCBRR) & 0xf);
 
index 40f0c2d3690c5a3c6744f2bdff6c4eed8eb1c027..a9cdac469927ad6ee738a2ebf6bc66763c12babc 100644 (file)
 #define INTTESTR       0x040
 #define SYSSR          0x050
 #define NRGPR          0x060
+
 #define NMISR          0x070
+#define  NMISR_MAN_NMI BIT(0)
+#define  NMISR_AUX_NMI BIT(1)
+#define  NMISR_MASK    (NMISR_MAN_NMI | NMISR_AUX_NMI)
 
 #define NMIMR          0x080
 #define  NMIMR_MAN_NMIM        BIT(0)  /* Manual NMI mask */
 #define  NMIMR_AUX_NMIM        BIT(1)  /* Auxiliary NMI mask */
+#define  NMIMR_MASK    (NMIMR_MAN_NMIM | NMIMR_AUX_NMIM)
 
 #define INTBSR         0x090
 #define INTBMR         0x0a0
 extern void __iomem *sdk7786_fpga_base;
 extern void sdk7786_fpga_init(void);
 
+/* arch/sh/boards/mach-sdk7786/nmi.c */
+extern void sdk7786_nmi_init(void);
+
 #define SDK7786_FPGA_REGADDR(reg)      (sdk7786_fpga_base + (reg))
 
 /*