1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * SDK7786 FPGA NMI Support. |
4 | * |
5 | * Copyright (C) 2010 Paul Mundt |
6 | */ |
7 | #include <linux/init.h> |
8 | #include <linux/kernel.h> |
9 | #include <linux/string.h> |
10 | #include <mach/fpga.h> |
11 | |
12 | enum { |
13 | NMI_MODE_MANUAL, |
14 | NMI_MODE_AUX, |
15 | NMI_MODE_MASKED, |
16 | NMI_MODE_ANY, |
17 | NMI_MODE_UNKNOWN, |
18 | }; |
19 | |
20 | /* |
21 | * Default to the manual NMI switch. |
22 | */ |
23 | static unsigned int __initdata nmi_mode = NMI_MODE_ANY; |
24 | |
25 | static int __init nmi_mode_setup(char *str) |
26 | { |
27 | if (!str) |
28 | return 0; |
29 | |
30 | if (strcmp(str, "manual" ) == 0) |
31 | nmi_mode = NMI_MODE_MANUAL; |
32 | else if (strcmp(str, "aux" ) == 0) |
33 | nmi_mode = NMI_MODE_AUX; |
34 | else if (strcmp(str, "masked" ) == 0) |
35 | nmi_mode = NMI_MODE_MASKED; |
36 | else if (strcmp(str, "any" ) == 0) |
37 | nmi_mode = NMI_MODE_ANY; |
38 | else { |
39 | nmi_mode = NMI_MODE_UNKNOWN; |
40 | pr_warn("Unknown NMI mode %s\n" , str); |
41 | } |
42 | |
43 | printk("Set NMI mode to %d\n" , nmi_mode); |
44 | return 0; |
45 | } |
46 | early_param("nmi_mode" , nmi_mode_setup); |
47 | |
48 | void __init sdk7786_nmi_init(void) |
49 | { |
50 | unsigned int source, mask, tmp; |
51 | |
52 | switch (nmi_mode) { |
53 | case NMI_MODE_MANUAL: |
54 | source = NMISR_MAN_NMI; |
55 | mask = NMIMR_MAN_NMIM; |
56 | break; |
57 | case NMI_MODE_AUX: |
58 | source = NMISR_AUX_NMI; |
59 | mask = NMIMR_AUX_NMIM; |
60 | break; |
61 | case NMI_MODE_ANY: |
62 | source = NMISR_MAN_NMI | NMISR_AUX_NMI; |
63 | mask = NMIMR_MAN_NMIM | NMIMR_AUX_NMIM; |
64 | break; |
65 | case NMI_MODE_MASKED: |
66 | case NMI_MODE_UNKNOWN: |
67 | default: |
68 | source = mask = 0; |
69 | break; |
70 | } |
71 | |
72 | /* Set the NMI source */ |
73 | tmp = fpga_read_reg(NMISR); |
74 | tmp &= ~NMISR_MASK; |
75 | tmp |= source; |
76 | fpga_write_reg(tmp, NMISR); |
77 | |
78 | /* And the IRQ masking */ |
79 | fpga_write_reg(NMIMR_MASK ^ mask, NMIMR); |
80 | } |
81 | |