.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0+ |
---|
1 | 2 | /* |
---|
2 | 3 | * intel TCO vendor specific watchdog driver support |
---|
3 | 4 | * |
---|
4 | 5 | * (c) Copyright 2006-2009 Wim Van Sebroeck <wim@iguana.be>. |
---|
5 | | - * |
---|
6 | | - * This program is free software; you can redistribute it and/or |
---|
7 | | - * modify it under the terms of the GNU General Public License |
---|
8 | | - * as published by the Free Software Foundation; either version |
---|
9 | | - * 2 of the License, or (at your option) any later version. |
---|
10 | 6 | * |
---|
11 | 7 | * Neither Wim Van Sebroeck nor Iguana vzw. admit liability nor |
---|
12 | 8 | * provide warranty for any of this software. This material is |
---|
.. | .. |
---|
38 | 34 | /* List of vendor support modes */ |
---|
39 | 35 | /* SuperMicro Pentium 3 Era 370SSE+-OEM1/P3TSSE */ |
---|
40 | 36 | #define SUPERMICRO_OLD_BOARD 1 |
---|
41 | | -/* SuperMicro Pentium 4 / Xeon 4 / EMT64T Era Systems */ |
---|
| 37 | +/* SuperMicro Pentium 4 / Xeon 4 / EMT64T Era Systems - no longer supported */ |
---|
42 | 38 | #define SUPERMICRO_NEW_BOARD 2 |
---|
43 | 39 | /* Broken BIOS */ |
---|
44 | 40 | #define BROKEN_BIOS 911 |
---|
45 | 41 | |
---|
46 | | -static int vendorsupport; |
---|
47 | | -module_param(vendorsupport, int, 0); |
---|
| 42 | +int iTCO_vendorsupport; |
---|
| 43 | +EXPORT_SYMBOL(iTCO_vendorsupport); |
---|
| 44 | + |
---|
| 45 | +module_param_named(vendorsupport, iTCO_vendorsupport, int, 0); |
---|
48 | 46 | MODULE_PARM_DESC(vendorsupport, "iTCO vendor specific support mode, default=" |
---|
49 | | - "0 (none), 1=SuperMicro Pent3, 2=SuperMicro Pent4+, " |
---|
50 | | - "911=Broken SMI BIOS"); |
---|
| 47 | + "0 (none), 1=SuperMicro Pent3, 911=Broken SMI BIOS"); |
---|
51 | 48 | |
---|
52 | 49 | /* |
---|
53 | 50 | * Vendor Specific Support |
---|
.. | .. |
---|
95 | 92 | val32 = inl(smires->start); |
---|
96 | 93 | val32 |= 0x00002000; /* Turn on SMI clearing watchdog */ |
---|
97 | 94 | outl(val32, smires->start); /* Needed to deactivate watchdog */ |
---|
98 | | -} |
---|
99 | | - |
---|
100 | | -/* |
---|
101 | | - * Vendor Support: 2 |
---|
102 | | - * Board: Super Micro Computer Inc. P4SBx, P4DPx |
---|
103 | | - * iTCO chipset: ICH4 |
---|
104 | | - * |
---|
105 | | - * Code contributed by: R. Seretny <lkpatches@paypc.com> |
---|
106 | | - * Documentation obtained by R. Seretny from SuperMicro Technical Support |
---|
107 | | - * |
---|
108 | | - * To enable Watchdog function: |
---|
109 | | - * 1. BIOS |
---|
110 | | - * For P4SBx: |
---|
111 | | - * BIOS setup -> Advanced -> Integrated Peripherals -> Watch Dog Feature |
---|
112 | | - * For P4DPx: |
---|
113 | | - * BIOS setup -> Advanced -> I/O Device Configuration -> Watch Dog |
---|
114 | | - * This setting enables or disables Watchdog function. When enabled, the |
---|
115 | | - * default watchdog timer is set to be 5 minutes (about 4m35s). It is |
---|
116 | | - * enough to load and run the OS. The application (service or driver) has |
---|
117 | | - * to take over the control once OS is running up and before watchdog |
---|
118 | | - * expires. |
---|
119 | | - * |
---|
120 | | - * 2. JUMPER |
---|
121 | | - * For P4SBx: JP39 |
---|
122 | | - * For P4DPx: JP37 |
---|
123 | | - * This jumper is used for safety. Closed is enabled. This jumper |
---|
124 | | - * prevents user enables watchdog in BIOS by accident. |
---|
125 | | - * |
---|
126 | | - * To enable Watch Dog function, both BIOS and JUMPER must be enabled. |
---|
127 | | - * |
---|
128 | | - * The documentation lists motherboards P4SBx and P4DPx series as of |
---|
129 | | - * 20-March-2002. However, this code works flawlessly with much newer |
---|
130 | | - * motherboards, such as my X6DHR-8G2 (SuperServer 6014H-82). |
---|
131 | | - * |
---|
132 | | - * The original iTCO driver as written does not actually reset the |
---|
133 | | - * watchdog timer on these machines, as a result they reboot after five |
---|
134 | | - * minutes. |
---|
135 | | - * |
---|
136 | | - * NOTE: You may leave the Watchdog function disabled in the SuperMicro |
---|
137 | | - * BIOS to avoid a "boot-race"... This driver will enable watchdog |
---|
138 | | - * functionality even if it's disabled in the BIOS once the /dev/watchdog |
---|
139 | | - * file is opened. |
---|
140 | | - */ |
---|
141 | | - |
---|
142 | | -/* I/O Port's */ |
---|
143 | | -#define SM_REGINDEX 0x2e /* SuperMicro ICH4+ Register Index */ |
---|
144 | | -#define SM_DATAIO 0x2f /* SuperMicro ICH4+ Register Data I/O */ |
---|
145 | | - |
---|
146 | | -/* Control Register's */ |
---|
147 | | -#define SM_CTLPAGESW 0x07 /* SuperMicro ICH4+ Control Page Switch */ |
---|
148 | | -#define SM_CTLPAGE 0x08 /* SuperMicro ICH4+ Control Page Num */ |
---|
149 | | - |
---|
150 | | -#define SM_WATCHENABLE 0x30 /* Watchdog enable: Bit 0: 0=off, 1=on */ |
---|
151 | | - |
---|
152 | | -#define SM_WATCHPAGE 0x87 /* Watchdog unlock control page */ |
---|
153 | | - |
---|
154 | | -#define SM_ENDWATCH 0xAA /* Watchdog lock control page */ |
---|
155 | | - |
---|
156 | | -#define SM_COUNTMODE 0xf5 /* Watchdog count mode select */ |
---|
157 | | - /* (Bit 3: 0 = seconds, 1 = minutes */ |
---|
158 | | - |
---|
159 | | -#define SM_WATCHTIMER 0xf6 /* 8-bits, Watchdog timer counter (RW) */ |
---|
160 | | - |
---|
161 | | -#define SM_RESETCONTROL 0xf7 /* Watchdog reset control */ |
---|
162 | | - /* Bit 6: timer is reset by kbd interrupt */ |
---|
163 | | - /* Bit 7: timer is reset by mouse interrupt */ |
---|
164 | | - |
---|
165 | | -static void supermicro_new_unlock_watchdog(void) |
---|
166 | | -{ |
---|
167 | | - /* Write 0x87 to port 0x2e twice */ |
---|
168 | | - outb(SM_WATCHPAGE, SM_REGINDEX); |
---|
169 | | - outb(SM_WATCHPAGE, SM_REGINDEX); |
---|
170 | | - /* Switch to watchdog control page */ |
---|
171 | | - outb(SM_CTLPAGESW, SM_REGINDEX); |
---|
172 | | - outb(SM_CTLPAGE, SM_DATAIO); |
---|
173 | | -} |
---|
174 | | - |
---|
175 | | -static void supermicro_new_lock_watchdog(void) |
---|
176 | | -{ |
---|
177 | | - outb(SM_ENDWATCH, SM_REGINDEX); |
---|
178 | | -} |
---|
179 | | - |
---|
180 | | -static void supermicro_new_pre_start(unsigned int heartbeat) |
---|
181 | | -{ |
---|
182 | | - unsigned int val; |
---|
183 | | - |
---|
184 | | - supermicro_new_unlock_watchdog(); |
---|
185 | | - |
---|
186 | | - /* Watchdog timer setting needs to be in seconds*/ |
---|
187 | | - outb(SM_COUNTMODE, SM_REGINDEX); |
---|
188 | | - val = inb(SM_DATAIO); |
---|
189 | | - val &= 0xF7; |
---|
190 | | - outb(val, SM_DATAIO); |
---|
191 | | - |
---|
192 | | - /* Write heartbeat interval to WDOG */ |
---|
193 | | - outb(SM_WATCHTIMER, SM_REGINDEX); |
---|
194 | | - outb((heartbeat & 255), SM_DATAIO); |
---|
195 | | - |
---|
196 | | - /* Make sure keyboard/mouse interrupts don't interfere */ |
---|
197 | | - outb(SM_RESETCONTROL, SM_REGINDEX); |
---|
198 | | - val = inb(SM_DATAIO); |
---|
199 | | - val &= 0x3f; |
---|
200 | | - outb(val, SM_DATAIO); |
---|
201 | | - |
---|
202 | | - /* enable watchdog by setting bit 0 of Watchdog Enable to 1 */ |
---|
203 | | - outb(SM_WATCHENABLE, SM_REGINDEX); |
---|
204 | | - val = inb(SM_DATAIO); |
---|
205 | | - val |= 0x01; |
---|
206 | | - outb(val, SM_DATAIO); |
---|
207 | | - |
---|
208 | | - supermicro_new_lock_watchdog(); |
---|
209 | | -} |
---|
210 | | - |
---|
211 | | -static void supermicro_new_pre_stop(void) |
---|
212 | | -{ |
---|
213 | | - unsigned int val; |
---|
214 | | - |
---|
215 | | - supermicro_new_unlock_watchdog(); |
---|
216 | | - |
---|
217 | | - /* disable watchdog by setting bit 0 of Watchdog Enable to 0 */ |
---|
218 | | - outb(SM_WATCHENABLE, SM_REGINDEX); |
---|
219 | | - val = inb(SM_DATAIO); |
---|
220 | | - val &= 0xFE; |
---|
221 | | - outb(val, SM_DATAIO); |
---|
222 | | - |
---|
223 | | - supermicro_new_lock_watchdog(); |
---|
224 | | -} |
---|
225 | | - |
---|
226 | | -static void supermicro_new_pre_set_heartbeat(unsigned int heartbeat) |
---|
227 | | -{ |
---|
228 | | - supermicro_new_unlock_watchdog(); |
---|
229 | | - |
---|
230 | | - /* reset watchdog timeout to heartveat value */ |
---|
231 | | - outb(SM_WATCHTIMER, SM_REGINDEX); |
---|
232 | | - outb((heartbeat & 255), SM_DATAIO); |
---|
233 | | - |
---|
234 | | - supermicro_new_lock_watchdog(); |
---|
235 | 95 | } |
---|
236 | 96 | |
---|
237 | 97 | /* |
---|
.. | .. |
---|
294 | 154 | void iTCO_vendor_pre_start(struct resource *smires, |
---|
295 | 155 | unsigned int heartbeat) |
---|
296 | 156 | { |
---|
297 | | - switch (vendorsupport) { |
---|
| 157 | + switch (iTCO_vendorsupport) { |
---|
298 | 158 | case SUPERMICRO_OLD_BOARD: |
---|
299 | 159 | supermicro_old_pre_start(smires); |
---|
300 | | - break; |
---|
301 | | - case SUPERMICRO_NEW_BOARD: |
---|
302 | | - supermicro_new_pre_start(heartbeat); |
---|
303 | 160 | break; |
---|
304 | 161 | case BROKEN_BIOS: |
---|
305 | 162 | broken_bios_start(smires); |
---|
.. | .. |
---|
310 | 167 | |
---|
311 | 168 | void iTCO_vendor_pre_stop(struct resource *smires) |
---|
312 | 169 | { |
---|
313 | | - switch (vendorsupport) { |
---|
| 170 | + switch (iTCO_vendorsupport) { |
---|
314 | 171 | case SUPERMICRO_OLD_BOARD: |
---|
315 | 172 | supermicro_old_pre_stop(smires); |
---|
316 | | - break; |
---|
317 | | - case SUPERMICRO_NEW_BOARD: |
---|
318 | | - supermicro_new_pre_stop(); |
---|
319 | 173 | break; |
---|
320 | 174 | case BROKEN_BIOS: |
---|
321 | 175 | broken_bios_stop(smires); |
---|
.. | .. |
---|
324 | 178 | } |
---|
325 | 179 | EXPORT_SYMBOL(iTCO_vendor_pre_stop); |
---|
326 | 180 | |
---|
327 | | -void iTCO_vendor_pre_keepalive(struct resource *smires, unsigned int heartbeat) |
---|
328 | | -{ |
---|
329 | | - if (vendorsupport == SUPERMICRO_NEW_BOARD) |
---|
330 | | - supermicro_new_pre_set_heartbeat(heartbeat); |
---|
331 | | -} |
---|
332 | | -EXPORT_SYMBOL(iTCO_vendor_pre_keepalive); |
---|
333 | | - |
---|
334 | | -void iTCO_vendor_pre_set_heartbeat(unsigned int heartbeat) |
---|
335 | | -{ |
---|
336 | | - if (vendorsupport == SUPERMICRO_NEW_BOARD) |
---|
337 | | - supermicro_new_pre_set_heartbeat(heartbeat); |
---|
338 | | -} |
---|
339 | | -EXPORT_SYMBOL(iTCO_vendor_pre_set_heartbeat); |
---|
340 | | - |
---|
341 | 181 | int iTCO_vendor_check_noreboot_on(void) |
---|
342 | 182 | { |
---|
343 | | - switch (vendorsupport) { |
---|
| 183 | + switch (iTCO_vendorsupport) { |
---|
344 | 184 | case SUPERMICRO_OLD_BOARD: |
---|
345 | 185 | return 0; |
---|
346 | 186 | default: |
---|
.. | .. |
---|
351 | 191 | |
---|
352 | 192 | static int __init iTCO_vendor_init_module(void) |
---|
353 | 193 | { |
---|
354 | | - pr_info("vendor-support=%d\n", vendorsupport); |
---|
| 194 | + if (iTCO_vendorsupport == SUPERMICRO_NEW_BOARD) { |
---|
| 195 | + pr_warn("Option vendorsupport=%d is no longer supported, " |
---|
| 196 | + "please use the w83627hf_wdt driver instead\n", |
---|
| 197 | + SUPERMICRO_NEW_BOARD); |
---|
| 198 | + return -EINVAL; |
---|
| 199 | + } |
---|
| 200 | + pr_info("vendor-support=%d\n", iTCO_vendorsupport); |
---|
355 | 201 | return 0; |
---|
356 | 202 | } |
---|
357 | 203 | |
---|
.. | .. |
---|
368 | 214 | MODULE_DESCRIPTION("Intel TCO Vendor Specific WatchDog Timer Driver Support"); |
---|
369 | 215 | MODULE_VERSION(DRV_VERSION); |
---|
370 | 216 | MODULE_LICENSE("GPL"); |
---|
371 | | - |
---|