Linux Audio

Check our new training course

Loading...
v6.8
  1// SPDX-License-Identifier: GPL-2.0-or-later
  2/*
  3 *	Watchdog Timer Driver
  4 *	   for ITE IT87xx Environment Control - Low Pin Count Input / Output
  5 *
  6 *	(c) Copyright 2007  Oliver Schuster <olivers137@aol.com>
  7 *
  8 *	Based on softdog.c	by Alan Cox,
  9 *		 83977f_wdt.c	by Jose Goncalves,
 10 *		 it87.c		by Chris Gauthron, Jean Delvare
 11 *
 12 *	Data-sheets: Publicly available at the ITE website
 13 *		    http://www.ite.com.tw/
 14 *
 15 *	Support of the watchdog timers, which are available on
 16 *	IT8607, IT8613, IT8620, IT8622, IT8625, IT8628, IT8655, IT8659,
 17 *	IT8665, IT8686, IT8702, IT8712, IT8716, IT8718, IT8720, IT8721,
 18 *	IT8726,	IT8728, IT8772, IT8783, IT8784 and IT8786.
 
 
 
 
 
 
 
 
 
 
 
 
 
 19 */
 20
 21#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 22
 23#include <linux/init.h>
 24#include <linux/io.h>
 25#include <linux/kernel.h>
 26#include <linux/module.h>
 27#include <linux/moduleparam.h>
 28#include <linux/types.h>
 
 
 
 
 
 29#include <linux/watchdog.h>
 
 
 
 
 30
 
 
 31#define WATCHDOG_NAME		"IT87 WDT"
 
 
 32
 33/* Defaults for Module Parameter */
 
 
 34#define DEFAULT_TIMEOUT		60
 35#define DEFAULT_TESTMODE	0
 36#define DEFAULT_NOWAYOUT	WATCHDOG_NOWAYOUT
 37
 38/* IO Ports */
 39#define REG		0x2e
 40#define VAL		0x2f
 41
 42/* Logical device Numbers LDN */
 43#define GPIO		0x07
 
 
 44
 45/* Configuration Registers and Functions */
 46#define LDNREG		0x07
 47#define CHIPID		0x20
 48#define CHIPREV		0x22
 
 
 49
 50/* Chip Id numbers */
 51#define NO_DEV_ID	0xffff
 52#define IT8607_ID	0x8607
 53#define IT8613_ID	0x8613
 54#define IT8620_ID	0x8620
 55#define IT8622_ID	0x8622
 56#define IT8625_ID	0x8625
 57#define IT8628_ID	0x8628
 58#define IT8655_ID	0x8655
 59#define IT8659_ID	0x8659
 60#define IT8665_ID	0x8665
 61#define IT8686_ID	0x8686
 62#define IT8702_ID	0x8702
 63#define IT8705_ID	0x8705
 64#define IT8712_ID	0x8712
 65#define IT8716_ID	0x8716
 66#define IT8718_ID	0x8718
 67#define IT8720_ID	0x8720
 68#define IT8721_ID	0x8721
 69#define IT8726_ID	0x8726	/* the data sheet suggest wrongly 0x8716 */
 70#define IT8728_ID	0x8728
 71#define IT8772_ID	0x8772
 72#define IT8783_ID	0x8783
 73#define IT8784_ID	0x8784
 74#define IT8786_ID	0x8786
 75
 76/* GPIO Configuration Registers LDN=0x07 */
 77#define WDTCTRL		0x71
 78#define WDTCFG		0x72
 79#define WDTVALLSB	0x73
 80#define WDTVALMSB	0x74
 81
 
 
 
 
 
 
 
 
 82/* GPIO Bits WDTCFG */
 83#define WDT_TOV1	0x80
 84#define WDT_KRST	0x40
 85#define WDT_TOVE	0x20
 86#define WDT_PWROK	0x10 /* not in it8721 */
 87#define WDT_INT_MASK	0x0f
 88
 89static unsigned int max_units, chip_type;
 
 90
 91static unsigned int timeout = DEFAULT_TIMEOUT;
 92static int testmode = DEFAULT_TESTMODE;
 93static bool nowayout = DEFAULT_NOWAYOUT;
 94
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 95module_param(timeout, int, 0);
 96MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds, default="
 97		__MODULE_STRING(DEFAULT_TIMEOUT));
 98module_param(testmode, int, 0);
 99MODULE_PARM_DESC(testmode, "Watchdog test mode (1 = no reboot), default="
100		__MODULE_STRING(DEFAULT_TESTMODE));
101module_param(nowayout, bool, 0);
102MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started, default="
103		__MODULE_STRING(WATCHDOG_NOWAYOUT));
104
105/* Superio Chip */
106
107static inline int superio_enter(void)
108{
109	/*
110	 * Try to reserve REG and REG + 1 for exclusive access.
111	 */
112	if (!request_muxed_region(REG, 2, WATCHDOG_NAME))
113		return -EBUSY;
114
115	outb(0x87, REG);
116	outb(0x01, REG);
117	outb(0x55, REG);
118	outb(0x55, REG);
119	return 0;
120}
121
122static inline void superio_exit(void)
123{
124	outb(0x02, REG);
125	outb(0x02, VAL);
126	release_region(REG, 2);
127}
128
129static inline void superio_select(int ldn)
130{
131	outb(LDNREG, REG);
132	outb(ldn, VAL);
133}
134
135static inline int superio_inb(int reg)
136{
137	outb(reg, REG);
138	return inb(VAL);
139}
140
141static inline void superio_outb(int val, int reg)
142{
143	outb(reg, REG);
144	outb(val, VAL);
145}
146
147static inline int superio_inw(int reg)
148{
149	int val;
150
151	outb(reg++, REG);
152	val = inb(VAL) << 8;
153	outb(reg, REG);
154	val |= inb(VAL);
155	return val;
156}
157
 
 
 
 
 
 
 
 
158/* Internal function, should be called after superio_select(GPIO) */
159static void _wdt_update_timeout(unsigned int t)
160{
161	unsigned char cfg = WDT_KRST;
 
162
163	if (testmode)
164		cfg = 0;
165
166	if (t <= max_units)
167		cfg |= WDT_TOV1;
168	else
169		t /= 60;
170
171	if (chip_type != IT8721_ID)
172		cfg |= WDT_PWROK;
173
174	superio_outb(cfg, WDTCFG);
175	superio_outb(t, WDTVALLSB);
176	if (max_units > 255)
177		superio_outb(t >> 8, WDTVALMSB);
178}
179
180static int wdt_update_timeout(unsigned int t)
181{
182	int ret;
 
 
 
 
 
183
184	ret = superio_enter();
 
 
 
 
 
 
 
 
 
 
 
 
185	if (ret)
186		return ret;
187
188	superio_select(GPIO);
189	_wdt_update_timeout(t);
 
 
 
 
 
190	superio_exit();
191
192	return 0;
193}
194
195static int wdt_round_time(int t)
196{
197	t += 59;
198	t -= t % 60;
199	return t;
200}
201
202/* watchdog timer handling */
203
204static int wdt_start(struct watchdog_device *wdd)
205{
206	return wdt_update_timeout(wdd->timeout);
207}
 
 
208
209static int wdt_stop(struct watchdog_device *wdd)
210{
211	return wdt_update_timeout(0);
212}
213
214/**
215 *	wdt_set_timeout - set a new timeout value with watchdog ioctl
216 *	@t: timeout value in seconds
217 *
218 *	The hardware device has a 8 or 16 bit watchdog timer (depends on
219 *	chip version) that can be configured to count seconds or minutes.
220 *
221 *	Used within WDIOC_SETTIMEOUT watchdog device ioctl.
222 */
223
224static int wdt_set_timeout(struct watchdog_device *wdd, unsigned int t)
225{
226	int ret = 0;
 
227
228	if (t > max_units)
229		t = wdt_round_time(t);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
230
231	wdd->timeout = t;
 
 
 
 
 
 
 
 
 
 
 
232
233	if (watchdog_hw_running(wdd))
234		ret = wdt_update_timeout(t);
 
 
 
 
 
 
 
 
 
 
 
 
235
236	return ret;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
237}
238
239static const struct watchdog_info ident = {
240	.options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING,
241	.firmware_version = 1,
242	.identity = WATCHDOG_NAME,
243};
244
245static const struct watchdog_ops wdt_ops = {
246	.owner = THIS_MODULE,
247	.start = wdt_start,
248	.stop = wdt_stop,
249	.set_timeout = wdt_set_timeout,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
250};
251
252static struct watchdog_device wdt_dev = {
253	.info = &ident,
254	.ops = &wdt_ops,
255	.min_timeout = 1,
256};
257
258static int __init it87_wdt_init(void)
259{
 
 
260	u8  chip_rev;
261	u8 ctrl;
262	int rc;
 
263
264	rc = superio_enter();
265	if (rc)
266		return rc;
267
268	chip_type = superio_inw(CHIPID);
269	chip_rev  = superio_inb(CHIPREV) & 0x0f;
270	superio_exit();
271
272	switch (chip_type) {
273	case IT8702_ID:
274		max_units = 255;
275		break;
276	case IT8712_ID:
277		max_units = (chip_rev < 8) ? 255 : 65535;
278		break;
279	case IT8607_ID:
280	case IT8613_ID:
281	case IT8620_ID:
282	case IT8622_ID:
283	case IT8625_ID:
284	case IT8628_ID:
285	case IT8655_ID:
286	case IT8659_ID:
287	case IT8665_ID:
288	case IT8686_ID:
289	case IT8716_ID:
 
 
 
290	case IT8718_ID:
291	case IT8720_ID:
292	case IT8721_ID:
293	case IT8726_ID:
294	case IT8728_ID:
295	case IT8772_ID:
296	case IT8783_ID:
297	case IT8784_ID:
298	case IT8786_ID:
299		max_units = 65535;
 
300		break;
301	case IT8705_ID:
302		pr_err("Unsupported Chip found, Chip %04x Revision %02x\n",
303		       chip_type, chip_rev);
304		return -ENODEV;
305	case NO_DEV_ID:
306		pr_err("no device\n");
307		return -ENODEV;
308	default:
309		pr_err("Unknown Chip found, Chip %04x Revision %04x\n",
310		       chip_type, chip_rev);
311		return -ENODEV;
312	}
313
314	rc = superio_enter();
315	if (rc)
316		return rc;
317
318	superio_select(GPIO);
319	superio_outb(WDT_TOV1, WDTCFG);
 
320
321	switch (chip_type) {
322	case IT8784_ID:
323	case IT8786_ID:
324		ctrl = superio_inb(WDTCTRL);
325		ctrl &= 0x08;
326		superio_outb(ctrl, WDTCTRL);
327		break;
328	default:
329		superio_outb(0x00, WDTCTRL);
 
 
 
 
 
330	}
331
332	superio_exit();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
333
334	if (timeout < 1 || timeout > max_units * 60) {
335		timeout = DEFAULT_TIMEOUT;
336		pr_warn("Timeout value out of range, use default %d sec\n",
337			DEFAULT_TIMEOUT);
338	}
339
340	if (timeout > max_units)
341		timeout = wdt_round_time(timeout);
342
343	wdt_dev.timeout = timeout;
344	wdt_dev.max_timeout = max_units * 60;
 
 
 
345
346	watchdog_stop_on_reboot(&wdt_dev);
347	rc = watchdog_register_device(&wdt_dev);
348	if (rc) {
349		pr_err("Cannot register watchdog device (err=%d)\n", rc);
350		return rc;
 
 
 
 
 
 
 
 
 
 
 
 
351	}
352
353	pr_info("Chip IT%04x revision %d initialized. timeout=%d sec (nowayout=%d testmode=%d)\n",
354		chip_type, chip_rev, timeout, nowayout, testmode);
 
355
 
356	return 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
357}
358
359static void __exit it87_wdt_exit(void)
360{
361	watchdog_unregister_device(&wdt_dev);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
362}
363
364module_init(it87_wdt_init);
365module_exit(it87_wdt_exit);
366
367MODULE_AUTHOR("Oliver Schuster");
368MODULE_DESCRIPTION("Hardware Watchdog Device Driver for IT87xx EC-LPC I/O");
369MODULE_LICENSE("GPL");
v3.5.6
 
  1/*
  2 *	Watchdog Timer Driver
  3 *	   for ITE IT87xx Environment Control - Low Pin Count Input / Output
  4 *
  5 *	(c) Copyright 2007  Oliver Schuster <olivers137@aol.com>
  6 *
  7 *	Based on softdog.c	by Alan Cox,
  8 *		 83977f_wdt.c	by Jose Goncalves,
  9 *		 it87.c		by Chris Gauthron, Jean Delvare
 10 *
 11 *	Data-sheets: Publicly available at the ITE website
 12 *		    http://www.ite.com.tw/
 13 *
 14 *	Support of the watchdog timers, which are available on
 15 *	IT8702, IT8712, IT8716, IT8718, IT8720, IT8721, IT8726
 16 *	and IT8728.
 17 *
 18 *	This program is free software; you can redistribute it and/or
 19 *	modify it under the terms of the GNU General Public License
 20 *	as published by the Free Software Foundation; either version
 21 *	2 of the License, or (at your option) any later version.
 22 *
 23 *	This program is distributed in the hope that it will be useful,
 24 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
 25 *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 26 *	GNU General Public License for more details.
 27 *
 28 *	You should have received a copy of the GNU General Public License
 29 *	along with this program; if not, write to the Free Software
 30 *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 31 */
 32
 33#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 34
 
 
 
 35#include <linux/module.h>
 36#include <linux/moduleparam.h>
 37#include <linux/types.h>
 38#include <linux/kernel.h>
 39#include <linux/fs.h>
 40#include <linux/miscdevice.h>
 41#include <linux/init.h>
 42#include <linux/ioport.h>
 43#include <linux/watchdog.h>
 44#include <linux/notifier.h>
 45#include <linux/reboot.h>
 46#include <linux/uaccess.h>
 47#include <linux/io.h>
 48
 49
 50#define WATCHDOG_VERSION	"1.14"
 51#define WATCHDOG_NAME		"IT87 WDT"
 52#define DRIVER_VERSION		WATCHDOG_NAME " driver, v" WATCHDOG_VERSION "\n"
 53#define WD_MAGIC		'V'
 54
 55/* Defaults for Module Parameter */
 56#define DEFAULT_NOGAMEPORT	0
 57#define DEFAULT_EXCLUSIVE	1
 58#define DEFAULT_TIMEOUT		60
 59#define DEFAULT_TESTMODE	0
 60#define DEFAULT_NOWAYOUT	WATCHDOG_NOWAYOUT
 61
 62/* IO Ports */
 63#define REG		0x2e
 64#define VAL		0x2f
 65
 66/* Logical device Numbers LDN */
 67#define GPIO		0x07
 68#define GAMEPORT	0x09
 69#define CIR		0x0a
 70
 71/* Configuration Registers and Functions */
 72#define LDNREG		0x07
 73#define CHIPID		0x20
 74#define CHIPREV		0x22
 75#define ACTREG		0x30
 76#define BASEREG		0x60
 77
 78/* Chip Id numbers */
 79#define NO_DEV_ID	0xffff
 
 
 
 
 
 
 
 
 
 
 80#define IT8702_ID	0x8702
 81#define IT8705_ID	0x8705
 82#define IT8712_ID	0x8712
 83#define IT8716_ID	0x8716
 84#define IT8718_ID	0x8718
 85#define IT8720_ID	0x8720
 86#define IT8721_ID	0x8721
 87#define IT8726_ID	0x8726	/* the data sheet suggest wrongly 0x8716 */
 88#define IT8728_ID	0x8728
 
 
 
 
 89
 90/* GPIO Configuration Registers LDN=0x07 */
 91#define WDTCTRL		0x71
 92#define WDTCFG		0x72
 93#define WDTVALLSB	0x73
 94#define WDTVALMSB	0x74
 95
 96/* GPIO Bits WDTCTRL */
 97#define WDT_CIRINT	0x80
 98#define WDT_MOUSEINT	0x40
 99#define WDT_KYBINT	0x20
100#define WDT_GAMEPORT	0x10 /* not in it8718, it8720, it8721, it8728 */
101#define WDT_FORCE	0x02
102#define WDT_ZERO	0x01
103
104/* GPIO Bits WDTCFG */
105#define WDT_TOV1	0x80
106#define WDT_KRST	0x40
107#define WDT_TOVE	0x20
108#define WDT_PWROK	0x10 /* not in it8721 */
109#define WDT_INT_MASK	0x0f
110
111/* CIR Configuration Register LDN=0x0a */
112#define CIR_ILS		0x70
113
114/* The default Base address is not always available, we use this */
115#define CIR_BASE	0x0208
 
116
117/* CIR Controller */
118#define CIR_DR(b)	(b)
119#define CIR_IER(b)	(b + 1)
120#define CIR_RCR(b)	(b + 2)
121#define CIR_TCR1(b)	(b + 3)
122#define CIR_TCR2(b)	(b + 4)
123#define CIR_TSR(b)	(b + 5)
124#define CIR_RSR(b)	(b + 6)
125#define CIR_BDLR(b)	(b + 5)
126#define CIR_BDHR(b)	(b + 6)
127#define CIR_IIR(b)	(b + 7)
128
129/* Default Base address of Game port */
130#define GP_BASE_DEFAULT	0x0201
131
132/* wdt_status */
133#define WDTS_TIMER_RUN	0
134#define WDTS_DEV_OPEN	1
135#define WDTS_KEEPALIVE	2
136#define WDTS_LOCKED	3
137#define WDTS_USE_GP	4
138#define WDTS_EXPECTED	5
139
140static	unsigned int base, gpact, ciract, max_units, chip_type;
141static	unsigned long wdt_status;
142
143static	int nogameport = DEFAULT_NOGAMEPORT;
144static	int exclusive  = DEFAULT_EXCLUSIVE;
145static	int timeout    = DEFAULT_TIMEOUT;
146static	int testmode   = DEFAULT_TESTMODE;
147static	bool nowayout   = DEFAULT_NOWAYOUT;
148
149module_param(nogameport, int, 0);
150MODULE_PARM_DESC(nogameport, "Forbid the activation of game port, default="
151		__MODULE_STRING(DEFAULT_NOGAMEPORT));
152module_param(exclusive, int, 0);
153MODULE_PARM_DESC(exclusive, "Watchdog exclusive device open, default="
154		__MODULE_STRING(DEFAULT_EXCLUSIVE));
155module_param(timeout, int, 0);
156MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds, default="
157		__MODULE_STRING(DEFAULT_TIMEOUT));
158module_param(testmode, int, 0);
159MODULE_PARM_DESC(testmode, "Watchdog test mode (1 = no reboot), default="
160		__MODULE_STRING(DEFAULT_TESTMODE));
161module_param(nowayout, bool, 0);
162MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started, default="
163		__MODULE_STRING(WATCHDOG_NOWAYOUT));
164
165/* Superio Chip */
166
167static inline int superio_enter(void)
168{
169	/*
170	 * Try to reserve REG and REG + 1 for exclusive access.
171	 */
172	if (!request_muxed_region(REG, 2, WATCHDOG_NAME))
173		return -EBUSY;
174
175	outb(0x87, REG);
176	outb(0x01, REG);
177	outb(0x55, REG);
178	outb(0x55, REG);
179	return 0;
180}
181
182static inline void superio_exit(void)
183{
184	outb(0x02, REG);
185	outb(0x02, VAL);
186	release_region(REG, 2);
187}
188
189static inline void superio_select(int ldn)
190{
191	outb(LDNREG, REG);
192	outb(ldn, VAL);
193}
194
195static inline int superio_inb(int reg)
196{
197	outb(reg, REG);
198	return inb(VAL);
199}
200
201static inline void superio_outb(int val, int reg)
202{
203	outb(reg, REG);
204	outb(val, VAL);
205}
206
207static inline int superio_inw(int reg)
208{
209	int val;
 
210	outb(reg++, REG);
211	val = inb(VAL) << 8;
212	outb(reg, REG);
213	val |= inb(VAL);
214	return val;
215}
216
217static inline void superio_outw(int val, int reg)
218{
219	outb(reg++, REG);
220	outb(val >> 8, VAL);
221	outb(reg, REG);
222	outb(val, VAL);
223}
224
225/* Internal function, should be called after superio_select(GPIO) */
226static void wdt_update_timeout(void)
227{
228	unsigned char cfg = WDT_KRST;
229	int tm = timeout;
230
231	if (testmode)
232		cfg = 0;
233
234	if (tm <= max_units)
235		cfg |= WDT_TOV1;
236	else
237		tm /= 60;
238
239	if (chip_type != IT8721_ID)
240		cfg |= WDT_PWROK;
241
242	superio_outb(cfg, WDTCFG);
243	superio_outb(tm, WDTVALLSB);
244	if (max_units > 255)
245		superio_outb(tm>>8, WDTVALMSB);
246}
247
248static int wdt_round_time(int t)
249{
250	t += 59;
251	t -= t % 60;
252	return t;
253}
254
255/* watchdog timer handling */
256
257static void wdt_keepalive(void)
258{
259	if (test_bit(WDTS_USE_GP, &wdt_status))
260		inb(base);
261	else
262		/* The timer reloads with around 5 msec delay */
263		outb(0x55, CIR_DR(base));
264	set_bit(WDTS_KEEPALIVE, &wdt_status);
265}
266
267static int wdt_start(void)
268{
269	int ret = superio_enter();
270	if (ret)
271		return ret;
272
273	superio_select(GPIO);
274	if (test_bit(WDTS_USE_GP, &wdt_status))
275		superio_outb(WDT_GAMEPORT, WDTCTRL);
276	else
277		superio_outb(WDT_CIRINT, WDTCTRL);
278	wdt_update_timeout();
279
280	superio_exit();
281
282	return 0;
283}
284
285static int wdt_stop(void)
286{
287	int ret = superio_enter();
288	if (ret)
289		return ret;
 
 
 
290
291	superio_select(GPIO);
292	superio_outb(0x00, WDTCTRL);
293	superio_outb(WDT_TOV1, WDTCFG);
294	superio_outb(0x00, WDTVALLSB);
295	if (max_units > 255)
296		superio_outb(0x00, WDTVALMSB);
297
298	superio_exit();
299	return 0;
 
300}
301
302/**
303 *	wdt_set_timeout - set a new timeout value with watchdog ioctl
304 *	@t: timeout value in seconds
305 *
306 *	The hardware device has a 8 or 16 bit watchdog timer (depends on
307 *	chip version) that can be configured to count seconds or minutes.
308 *
309 *	Used within WDIOC_SETTIMEOUT watchdog device ioctl.
310 */
311
312static int wdt_set_timeout(int t)
313{
314	if (t < 1 || t > max_units * 60)
315		return -EINVAL;
316
317	if (t > max_units)
318		timeout = wdt_round_time(t);
319	else
320		timeout = t;
321
322	if (test_bit(WDTS_TIMER_RUN, &wdt_status)) {
323		int ret = superio_enter();
324		if (ret)
325			return ret;
326
327		superio_select(GPIO);
328		wdt_update_timeout();
329		superio_exit();
330	}
331	return 0;
332}
333
334/**
335 *	wdt_get_status - determines the status supported by watchdog ioctl
336 *	@status: status returned to user space
337 *
338 *	The status bit of the device does not allow to distinguish
339 *	between a regular system reset and a watchdog forced reset.
340 *	But, in test mode it is useful, so it is supported through
341 *	WDIOC_GETSTATUS watchdog ioctl. Additionally the driver
342 *	reports the keepalive signal and the acception of the magic.
343 *
344 *	Used within WDIOC_GETSTATUS watchdog device ioctl.
345 */
346
347static int wdt_get_status(int *status)
348{
349	*status = 0;
350	if (testmode) {
351		int ret = superio_enter();
352		if (ret)
353			return ret;
354
355		superio_select(GPIO);
356		if (superio_inb(WDTCTRL) & WDT_ZERO) {
357			superio_outb(0x00, WDTCTRL);
358			clear_bit(WDTS_TIMER_RUN, &wdt_status);
359			*status |= WDIOF_CARDRESET;
360		}
361
362		superio_exit();
363	}
364	if (test_and_clear_bit(WDTS_KEEPALIVE, &wdt_status))
365		*status |= WDIOF_KEEPALIVEPING;
366	if (test_bit(WDTS_EXPECTED, &wdt_status))
367		*status |= WDIOF_MAGICCLOSE;
368	return 0;
369}
370
371/* /dev/watchdog handling */
372
373/**
374 *	wdt_open - watchdog file_operations .open
375 *	@inode: inode of the device
376 *	@file: file handle to the device
377 *
378 *	The watchdog timer starts by opening the device.
379 *
380 *	Used within the file operation of the watchdog device.
381 */
382
383static int wdt_open(struct inode *inode, struct file *file)
384{
385	if (exclusive && test_and_set_bit(WDTS_DEV_OPEN, &wdt_status))
386		return -EBUSY;
387	if (!test_and_set_bit(WDTS_TIMER_RUN, &wdt_status)) {
388		int ret;
389		if (nowayout && !test_and_set_bit(WDTS_LOCKED, &wdt_status))
390			__module_get(THIS_MODULE);
391
392		ret = wdt_start();
393		if (ret) {
394			clear_bit(WDTS_LOCKED, &wdt_status);
395			clear_bit(WDTS_TIMER_RUN, &wdt_status);
396			clear_bit(WDTS_DEV_OPEN, &wdt_status);
397			return ret;
398		}
399	}
400	return nonseekable_open(inode, file);
401}
402
403/**
404 *	wdt_release - watchdog file_operations .release
405 *	@inode: inode of the device
406 *	@file: file handle to the device
407 *
408 *	Closing the watchdog device either stops the watchdog timer
409 *	or in the case, that nowayout is set or the magic character
410 *	wasn't written, a critical warning about an running watchdog
411 *	timer is given.
412 *
413 *	Used within the file operation of the watchdog device.
414 */
415
416static int wdt_release(struct inode *inode, struct file *file)
417{
418	if (test_bit(WDTS_TIMER_RUN, &wdt_status)) {
419		if (test_and_clear_bit(WDTS_EXPECTED, &wdt_status)) {
420			int ret = wdt_stop();
421			if (ret) {
422				/*
423				 * Stop failed. Just keep the watchdog alive
424				 * and hope nothing bad happens.
425				 */
426				set_bit(WDTS_EXPECTED, &wdt_status);
427				wdt_keepalive();
428				return ret;
429			}
430			clear_bit(WDTS_TIMER_RUN, &wdt_status);
431		} else {
432			wdt_keepalive();
433			pr_crit("unexpected close, not stopping watchdog!\n");
434		}
435	}
436	clear_bit(WDTS_DEV_OPEN, &wdt_status);
437	return 0;
438}
439
440/**
441 *	wdt_write - watchdog file_operations .write
442 *	@file: file handle to the watchdog
443 *	@buf: buffer to write
444 *	@count: count of bytes
445 *	@ppos: pointer to the position to write. No seeks allowed
446 *
447 *	A write to a watchdog device is defined as a keepalive signal. Any
448 *	write of data will do, as we don't define content meaning.
449 *
450 *	Used within the file operation of the watchdog device.
451 */
452
453static ssize_t wdt_write(struct file *file, const char __user *buf,
454			    size_t count, loff_t *ppos)
455{
456	if (count) {
457		clear_bit(WDTS_EXPECTED, &wdt_status);
458		wdt_keepalive();
459	}
460	if (!nowayout) {
461		size_t ofs;
462
463	/* note: just in case someone wrote the magic character long ago */
464		for (ofs = 0; ofs != count; ofs++) {
465			char c;
466			if (get_user(c, buf + ofs))
467				return -EFAULT;
468			if (c == WD_MAGIC)
469				set_bit(WDTS_EXPECTED, &wdt_status);
470		}
471	}
472	return count;
473}
474
475static const struct watchdog_info ident = {
476	.options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING,
477	.firmware_version =	1,
478	.identity = WATCHDOG_NAME,
479};
480
481/**
482 *	wdt_ioctl - watchdog file_operations .unlocked_ioctl
483 *	@file: file handle to the device
484 *	@cmd: watchdog command
485 *	@arg: argument pointer
486 *
487 *	The watchdog API defines a common set of functions for all watchdogs
488 *	according to their available features.
489 *
490 *	Used within the file operation of the watchdog device.
491 */
492
493static long wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
494{
495	int rc = 0, status, new_options, new_timeout;
496	union {
497		struct watchdog_info __user *ident;
498		int __user *i;
499	} uarg;
500
501	uarg.i = (int __user *)arg;
502
503	switch (cmd) {
504	case WDIOC_GETSUPPORT:
505		return copy_to_user(uarg.ident,
506				    &ident, sizeof(ident)) ? -EFAULT : 0;
507
508	case WDIOC_GETSTATUS:
509		rc = wdt_get_status(&status);
510		if (rc)
511			return rc;
512		return put_user(status, uarg.i);
513
514	case WDIOC_GETBOOTSTATUS:
515		return put_user(0, uarg.i);
516
517	case WDIOC_KEEPALIVE:
518		wdt_keepalive();
519		return 0;
520
521	case WDIOC_SETOPTIONS:
522		if (get_user(new_options, uarg.i))
523			return -EFAULT;
524
525		switch (new_options) {
526		case WDIOS_DISABLECARD:
527			if (test_bit(WDTS_TIMER_RUN, &wdt_status)) {
528				rc = wdt_stop();
529				if (rc)
530					return rc;
531			}
532			clear_bit(WDTS_TIMER_RUN, &wdt_status);
533			return 0;
534
535		case WDIOS_ENABLECARD:
536			if (!test_and_set_bit(WDTS_TIMER_RUN, &wdt_status)) {
537				rc = wdt_start();
538				if (rc) {
539					clear_bit(WDTS_TIMER_RUN, &wdt_status);
540					return rc;
541				}
542			}
543			return 0;
544
545		default:
546			return -EFAULT;
547		}
548
549	case WDIOC_SETTIMEOUT:
550		if (get_user(new_timeout, uarg.i))
551			return -EFAULT;
552		rc = wdt_set_timeout(new_timeout);
553	case WDIOC_GETTIMEOUT:
554		if (put_user(timeout, uarg.i))
555			return -EFAULT;
556		return rc;
557
558	default:
559		return -ENOTTY;
560	}
561}
562
563static int wdt_notify_sys(struct notifier_block *this, unsigned long code,
564	void *unused)
565{
566	if (code == SYS_DOWN || code == SYS_HALT)
567		wdt_stop();
568	return NOTIFY_DONE;
569}
570
571static const struct file_operations wdt_fops = {
572	.owner		= THIS_MODULE,
573	.llseek		= no_llseek,
574	.write		= wdt_write,
575	.unlocked_ioctl	= wdt_ioctl,
576	.open		= wdt_open,
577	.release	= wdt_release,
578};
579
580static struct miscdevice wdt_miscdev = {
581	.minor		= WATCHDOG_MINOR,
582	.name		= "watchdog",
583	.fops		= &wdt_fops,
584};
585
586static struct notifier_block wdt_notifier = {
587	.notifier_call = wdt_notify_sys,
 
 
588};
589
590static int __init it87_wdt_init(void)
591{
592	int rc = 0;
593	int try_gameport = !nogameport;
594	u8  chip_rev;
595	int gp_rreq_fail = 0;
596
597	wdt_status = 0;
598
599	rc = superio_enter();
600	if (rc)
601		return rc;
602
603	chip_type = superio_inw(CHIPID);
604	chip_rev  = superio_inb(CHIPREV) & 0x0f;
605	superio_exit();
606
607	switch (chip_type) {
608	case IT8702_ID:
609		max_units = 255;
610		break;
611	case IT8712_ID:
612		max_units = (chip_rev < 8) ? 255 : 65535;
613		break;
 
 
 
 
 
 
 
 
 
 
614	case IT8716_ID:
615	case IT8726_ID:
616		max_units = 65535;
617		break;
618	case IT8718_ID:
619	case IT8720_ID:
620	case IT8721_ID:
 
621	case IT8728_ID:
 
 
 
 
622		max_units = 65535;
623		try_gameport = 0;
624		break;
625	case IT8705_ID:
626		pr_err("Unsupported Chip found, Chip %04x Revision %02x\n",
627		       chip_type, chip_rev);
628		return -ENODEV;
629	case NO_DEV_ID:
630		pr_err("no device\n");
631		return -ENODEV;
632	default:
633		pr_err("Unknown Chip found, Chip %04x Revision %04x\n",
634		       chip_type, chip_rev);
635		return -ENODEV;
636	}
637
638	rc = superio_enter();
639	if (rc)
640		return rc;
641
642	superio_select(GPIO);
643	superio_outb(WDT_TOV1, WDTCFG);
644	superio_outb(0x00, WDTCTRL);
645
646	/* First try to get Gameport support */
647	if (try_gameport) {
648		superio_select(GAMEPORT);
649		base = superio_inw(BASEREG);
650		if (!base) {
651			base = GP_BASE_DEFAULT;
652			superio_outw(base, BASEREG);
653		}
654		gpact = superio_inb(ACTREG);
655		superio_outb(0x01, ACTREG);
656		if (request_region(base, 1, WATCHDOG_NAME))
657			set_bit(WDTS_USE_GP, &wdt_status);
658		else
659			gp_rreq_fail = 1;
660	}
661
662	/* If we haven't Gameport support, try to get CIR support */
663	if (!test_bit(WDTS_USE_GP, &wdt_status)) {
664		if (!request_region(CIR_BASE, 8, WATCHDOG_NAME)) {
665			if (gp_rreq_fail)
666				pr_err("I/O Address 0x%04x and 0x%04x already in use\n",
667				       base, CIR_BASE);
668			else
669				pr_err("I/O Address 0x%04x already in use\n",
670				       CIR_BASE);
671			rc = -EIO;
672			goto err_out;
673		}
674		base = CIR_BASE;
675
676		superio_select(CIR);
677		superio_outw(base, BASEREG);
678		superio_outb(0x00, CIR_ILS);
679		ciract = superio_inb(ACTREG);
680		superio_outb(0x01, ACTREG);
681		if (gp_rreq_fail) {
682			superio_select(GAMEPORT);
683			superio_outb(gpact, ACTREG);
684		}
685	}
686
687	if (timeout < 1 || timeout > max_units * 60) {
688		timeout = DEFAULT_TIMEOUT;
689		pr_warn("Timeout value out of range, use default %d sec\n",
690			DEFAULT_TIMEOUT);
691	}
692
693	if (timeout > max_units)
694		timeout = wdt_round_time(timeout);
695
696	rc = register_reboot_notifier(&wdt_notifier);
697	if (rc) {
698		pr_err("Cannot register reboot notifier (err=%d)\n", rc);
699		goto err_out_region;
700	}
701
702	rc = misc_register(&wdt_miscdev);
 
703	if (rc) {
704		pr_err("Cannot register miscdev on minor=%d (err=%d)\n",
705		       wdt_miscdev.minor, rc);
706		goto err_out_reboot;
707	}
708
709	/* Initialize CIR to use it as keepalive source */
710	if (!test_bit(WDTS_USE_GP, &wdt_status)) {
711		outb(0x00, CIR_RCR(base));
712		outb(0xc0, CIR_TCR1(base));
713		outb(0x5c, CIR_TCR2(base));
714		outb(0x10, CIR_IER(base));
715		outb(0x00, CIR_BDHR(base));
716		outb(0x01, CIR_BDLR(base));
717		outb(0x09, CIR_IER(base));
718	}
719
720	pr_info("Chip IT%04x revision %d initialized. timeout=%d sec (nowayout=%d testmode=%d exclusive=%d nogameport=%d)\n",
721		chip_type, chip_rev, timeout,
722		nowayout, testmode, exclusive, nogameport);
723
724	superio_exit();
725	return 0;
726
727err_out_reboot:
728	unregister_reboot_notifier(&wdt_notifier);
729err_out_region:
730	release_region(base, test_bit(WDTS_USE_GP, &wdt_status) ? 1 : 8);
731	if (!test_bit(WDTS_USE_GP, &wdt_status)) {
732		superio_select(CIR);
733		superio_outb(ciract, ACTREG);
734	}
735err_out:
736	if (try_gameport) {
737		superio_select(GAMEPORT);
738		superio_outb(gpact, ACTREG);
739	}
740
741	superio_exit();
742	return rc;
743}
744
745static void __exit it87_wdt_exit(void)
746{
747	if (superio_enter() == 0) {
748		superio_select(GPIO);
749		superio_outb(0x00, WDTCTRL);
750		superio_outb(0x00, WDTCFG);
751		superio_outb(0x00, WDTVALLSB);
752		if (max_units > 255)
753			superio_outb(0x00, WDTVALMSB);
754		if (test_bit(WDTS_USE_GP, &wdt_status)) {
755			superio_select(GAMEPORT);
756			superio_outb(gpact, ACTREG);
757		} else {
758			superio_select(CIR);
759			superio_outb(ciract, ACTREG);
760		}
761		superio_exit();
762	}
763
764	misc_deregister(&wdt_miscdev);
765	unregister_reboot_notifier(&wdt_notifier);
766	release_region(base, test_bit(WDTS_USE_GP, &wdt_status) ? 1 : 8);
767}
768
769module_init(it87_wdt_init);
770module_exit(it87_wdt_exit);
771
772MODULE_AUTHOR("Oliver Schuster");
773MODULE_DESCRIPTION("Hardware Watchdog Device Driver for IT87xx EC-LPC I/O");
774MODULE_LICENSE("GPL");
775MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);