Blame view

drivers/watchdog/alim7101_wdt.c 10.8 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
  /*
   *	ALi M7101 PMU Computer Watchdog Timer driver
   *
   *	Based on w83877f_wdt.c by Scott Jennings <linuxdrivers@oro.net>
   *	and the Cobalt kernel WDT timer driver by Tim Hockin
   *	                                      <thockin@cobaltnet.com>
   *
   *	(c)2002 Steve Hill <steve@navaho.co.uk>
   *
   *  This WDT driver is different from most other Linux WDT
   *  drivers in that the driver will ping the watchdog by itself,
   *  because this particular WDT has a very short timeout (1.6
   *  seconds) and it would be insane to count on any userspace
   *  daemon always getting scheduled within that time frame.
   *
   *  Additions:
   *   Aug 23, 2004 - Added use_gpio module parameter for use on revision a1d PMUs
   *                  found on very old cobalt hardware.
   *                  -- Mike Waychison <michael.waychison@sun.com>
   */
  
  #include <linux/module.h>
  #include <linux/moduleparam.h>
  #include <linux/types.h>
  #include <linux/timer.h>
  #include <linux/miscdevice.h>
  #include <linux/watchdog.h>
  #include <linux/ioport.h>
  #include <linux/notifier.h>
  #include <linux/reboot.h>
  #include <linux/init.h>
  #include <linux/fs.h>
  #include <linux/pci.h>
173d95bc2   Alan Cox   [WATCHDOG 03/57] ...
34
35
  #include <linux/io.h>
  #include <linux/uaccess.h>
089ab0791   Wim Van Sebroeck   [WATCHDOG] Clean-...
36

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
  #include <asm/system.h>
  
  #define OUR_NAME "alim7101_wdt"
  #define PFX OUR_NAME ": "
  
  #define WDT_ENABLE 0x9C
  #define WDT_DISABLE 0x8C
  
  #define ALI_7101_WDT    0x92
  #define ALI_7101_GPIO   0x7D
  #define ALI_7101_GPIO_O 0x7E
  #define ALI_WDT_ARM     0x01
  
  /*
   * We're going to use a 1 second timeout.
   * If we reset the watchdog every ~250ms we should be safe.  */
  
  #define WDT_INTERVAL (HZ/4+1)
  
  /*
   * We must not require too good response from the userspace daemon.
   * Here we require the userspace daemon to send us a heartbeat
   * char to /dev/watchdog every 30 seconds.
   */
  
  #define WATCHDOG_TIMEOUT 30            /* 30 sec default timeout */
173d95bc2   Alan Cox   [WATCHDOG 03/57] ...
63
64
  /* in seconds, will be multiplied by HZ to get seconds to wait for a ping */
  static int timeout = WATCHDOG_TIMEOUT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
65
  module_param(timeout, int, 0);
173d95bc2   Alan Cox   [WATCHDOG 03/57] ...
66
67
68
  MODULE_PARM_DESC(timeout,
  		"Watchdog timeout in seconds. (1<=timeout<=3600, default="
  				__MODULE_STRING(WATCHDOG_TIMEOUT) ")");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
69

173d95bc2   Alan Cox   [WATCHDOG 03/57] ...
70
  static int use_gpio; /* Use the pic (for a1d revision alim7101) */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
71
  module_param(use_gpio, int, 0);
173d95bc2   Alan Cox   [WATCHDOG 03/57] ...
72
73
  MODULE_PARM_DESC(use_gpio,
  		"Use the gpio watchdog (required by old cobalt boards).");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
74
75
  
  static void wdt_timer_ping(unsigned long);
82eb7c505   Jiri Slaby   [WATCHDOG] timers...
76
  static DEFINE_TIMER(timer, wdt_timer_ping, 0, 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
77
78
79
80
  static unsigned long next_heartbeat;
  static unsigned long wdt_is_open;
  static char wdt_expect_close;
  static struct pci_dev *alim7101_pmu;
4bfdf3783   Andrey Panin   [PATCH] consolida...
81
  static int nowayout = WATCHDOG_NOWAYOUT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
82
  module_param(nowayout, int, 0);
173d95bc2   Alan Cox   [WATCHDOG 03/57] ...
83
84
85
  MODULE_PARM_DESC(nowayout,
  		"Watchdog cannot be stopped once started (default="
  				__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
86
87
88
89
90
91
92
93
94
95
  
  /*
   *	Whack the dog
   */
  
  static void wdt_timer_ping(unsigned long data)
  {
  	/* If we got a heartbeat pulse within the WDT_US_INTERVAL
  	 * we agree to ping the WDT
  	 */
173d95bc2   Alan Cox   [WATCHDOG 03/57] ...
96
  	char tmp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
97

173d95bc2   Alan Cox   [WATCHDOG 03/57] ...
98
  	if (time_before(jiffies, next_heartbeat)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
99
100
  		/* Ping the WDT (this is actually a disarm/arm sequence) */
  		pci_read_config_byte(alim7101_pmu, 0x92, &tmp);
173d95bc2   Alan Cox   [WATCHDOG 03/57] ...
101
102
103
104
  		pci_write_config_byte(alim7101_pmu,
  					ALI_7101_WDT, (tmp & ~ALI_WDT_ARM));
  		pci_write_config_byte(alim7101_pmu,
  					ALI_7101_WDT, (tmp | ALI_WDT_ARM));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
105
  		if (use_gpio) {
173d95bc2   Alan Cox   [WATCHDOG 03/57] ...
106
107
108
109
110
111
  			pci_read_config_byte(alim7101_pmu,
  					ALI_7101_GPIO_O, &tmp);
  			pci_write_config_byte(alim7101_pmu,
  					ALI_7101_GPIO_O, tmp | 0x20);
  			pci_write_config_byte(alim7101_pmu,
  					ALI_7101_GPIO_O, tmp & ~0x20);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
112
113
  		}
  	} else {
173d95bc2   Alan Cox   [WATCHDOG 03/57] ...
114
115
116
  		printk(KERN_WARNING PFX
  			"Heartbeat lost! Will not ping the watchdog
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
117
118
  	}
  	/* Re-set the timer interval */
82eb7c505   Jiri Slaby   [WATCHDOG] timers...
119
  	mod_timer(&timer, jiffies + WDT_INTERVAL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
120
121
122
123
124
125
126
127
  }
  
  /*
   * Utility routines
   */
  
  static void wdt_change(int writeval)
  {
7944d3a5a   Wim Van Sebroeck   [WATCHDOG] more c...
128
  	char tmp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
129
130
131
  
  	pci_read_config_byte(alim7101_pmu, ALI_7101_WDT, &tmp);
  	if (writeval == WDT_ENABLE) {
173d95bc2   Alan Cox   [WATCHDOG 03/57] ...
132
133
  		pci_write_config_byte(alim7101_pmu,
  					ALI_7101_WDT, (tmp | ALI_WDT_ARM));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
134
  		if (use_gpio) {
173d95bc2   Alan Cox   [WATCHDOG 03/57] ...
135
136
137
138
  			pci_read_config_byte(alim7101_pmu,
  					ALI_7101_GPIO_O, &tmp);
  			pci_write_config_byte(alim7101_pmu,
  					ALI_7101_GPIO_O, tmp & ~0x20);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
139
140
141
  		}
  
  	} else {
173d95bc2   Alan Cox   [WATCHDOG 03/57] ...
142
143
  		pci_write_config_byte(alim7101_pmu,
  					ALI_7101_WDT, (tmp & ~ALI_WDT_ARM));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
144
  		if (use_gpio) {
173d95bc2   Alan Cox   [WATCHDOG 03/57] ...
145
146
147
148
  			pci_read_config_byte(alim7101_pmu,
  					ALI_7101_GPIO_O, &tmp);
  			pci_write_config_byte(alim7101_pmu,
  					ALI_7101_GPIO_O, tmp | 0x20);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
149
150
151
152
153
154
155
156
157
158
159
160
161
162
  		}
  	}
  }
  
  static void wdt_startup(void)
  {
  	next_heartbeat = jiffies + (timeout * HZ);
  
  	/* We must enable before we kick off the timer in case the timer
  	   occurs as we ping it */
  
  	wdt_change(WDT_ENABLE);
  
  	/* Start the timer */
82eb7c505   Jiri Slaby   [WATCHDOG] timers...
163
  	mod_timer(&timer, jiffies + WDT_INTERVAL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
  
  	printk(KERN_INFO PFX "Watchdog timer is now enabled.
  ");
  }
  
  static void wdt_turnoff(void)
  {
  	/* Stop the timer */
  	del_timer_sync(&timer);
  	wdt_change(WDT_DISABLE);
  	printk(KERN_INFO PFX "Watchdog timer is now disabled...
  ");
  }
  
  static void wdt_keepalive(void)
  {
  	/* user land ping */
  	next_heartbeat = jiffies + (timeout * HZ);
  }
  
  /*
   * /dev/watchdog handling
   */
173d95bc2   Alan Cox   [WATCHDOG 03/57] ...
187
188
  static ssize_t fop_write(struct file *file, const char __user *buf,
  						size_t count, loff_t *ppos)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
189
190
  {
  	/* See if we got the magic character 'V' and reload the timer */
173d95bc2   Alan Cox   [WATCHDOG 03/57] ...
191
  	if (count) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
192
193
194
195
196
197
198
199
200
201
  		if (!nowayout) {
  			size_t ofs;
  
  			/* note: just in case someone wrote the magic character
  			 * five months ago... */
  			wdt_expect_close = 0;
  
  			/* now scan */
  			for (ofs = 0; ofs != count; ofs++) {
  				char c;
7944d3a5a   Wim Van Sebroeck   [WATCHDOG] more c...
202
  				if (get_user(c, buf + ofs))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
203
204
205
206
207
208
209
210
211
212
  					return -EFAULT;
  				if (c == 'V')
  					wdt_expect_close = 42;
  			}
  		}
  		/* someone wrote to us, we should restart timer */
  		wdt_keepalive();
  	}
  	return count;
  }
173d95bc2   Alan Cox   [WATCHDOG 03/57] ...
213
  static int fop_open(struct inode *inode, struct file *file)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
214
215
  {
  	/* Just in case we're already talking to someone... */
173d95bc2   Alan Cox   [WATCHDOG 03/57] ...
216
  	if (test_and_set_bit(0, &wdt_is_open))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
217
218
219
220
221
  		return -EBUSY;
  	/* Good, fire up the show */
  	wdt_startup();
  	return nonseekable_open(inode, file);
  }
173d95bc2   Alan Cox   [WATCHDOG 03/57] ...
222
  static int fop_close(struct inode *inode, struct file *file)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
223
  {
173d95bc2   Alan Cox   [WATCHDOG 03/57] ...
224
  	if (wdt_expect_close == 42)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
225
226
227
  		wdt_turnoff();
  	else {
  		/* wim: shouldn't there be a: del_timer(&timer); */
173d95bc2   Alan Cox   [WATCHDOG 03/57] ...
228
229
230
  		printk(KERN_CRIT PFX
  		  "device file closed unexpectedly. Will not stop the WDT!
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
231
232
233
234
235
  	}
  	clear_bit(0, &wdt_is_open);
  	wdt_expect_close = 0;
  	return 0;
  }
173d95bc2   Alan Cox   [WATCHDOG 03/57] ...
236
  static long fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
237
238
239
  {
  	void __user *argp = (void __user *)arg;
  	int __user *p = argp;
42747d712   Wim Van Sebroeck   [WATCHDOG] watchd...
240
  	static const struct watchdog_info ident = {
173d95bc2   Alan Cox   [WATCHDOG 03/57] ...
241
242
  		.options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT
  							| WDIOF_MAGICCLOSE,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
243
244
245
  		.firmware_version = 1,
  		.identity = "ALiM7101",
  	};
173d95bc2   Alan Cox   [WATCHDOG 03/57] ...
246
247
248
249
250
251
  	switch (cmd) {
  	case WDIOC_GETSUPPORT:
  		return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
  	case WDIOC_GETSTATUS:
  	case WDIOC_GETBOOTSTATUS:
  		return put_user(0, p);
173d95bc2   Alan Cox   [WATCHDOG 03/57] ...
252
  	case WDIOC_SETOPTIONS:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
253
  	{
173d95bc2   Alan Cox   [WATCHDOG 03/57] ...
254
  		int new_options, retval = -EINVAL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
255

173d95bc2   Alan Cox   [WATCHDOG 03/57] ...
256
257
258
259
260
  		if (get_user(new_options, p))
  			return -EFAULT;
  		if (new_options & WDIOS_DISABLECARD) {
  			wdt_turnoff();
  			retval = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
261
  		}
173d95bc2   Alan Cox   [WATCHDOG 03/57] ...
262
263
264
  		if (new_options & WDIOS_ENABLECARD) {
  			wdt_startup();
  			retval = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
265
  		}
173d95bc2   Alan Cox   [WATCHDOG 03/57] ...
266
267
  		return retval;
  	}
0c06090c9   Wim Van Sebroeck   [WATCHDOG] Coding...
268
269
270
  	case WDIOC_KEEPALIVE:
  		wdt_keepalive();
  		return 0;
173d95bc2   Alan Cox   [WATCHDOG 03/57] ...
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
  	case WDIOC_SETTIMEOUT:
  	{
  		int new_timeout;
  
  		if (get_user(new_timeout, p))
  			return -EFAULT;
  		/* arbitrary upper limit */
  		if (new_timeout < 1 || new_timeout > 3600)
  			return -EINVAL;
  		timeout = new_timeout;
  		wdt_keepalive();
  		/* Fall through */
  	}
  	case WDIOC_GETTIMEOUT:
  		return put_user(timeout, p);
  	default:
  		return -ENOTTY;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
288
289
  	}
  }
62322d255   Arjan van de Ven   [PATCH] make more...
290
  static const struct file_operations wdt_fops = {
173d95bc2   Alan Cox   [WATCHDOG 03/57] ...
291
292
293
294
295
296
  	.owner		=	THIS_MODULE,
  	.llseek		=	no_llseek,
  	.write		=	fop_write,
  	.open		=	fop_open,
  	.release	=	fop_close,
  	.unlocked_ioctl	=	fop_ioctl,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
297
298
299
  };
  
  static struct miscdevice wdt_miscdev = {
173d95bc2   Alan Cox   [WATCHDOG 03/57] ...
300
301
302
  	.minor	=	WATCHDOG_MINOR,
  	.name	=	"watchdog",
  	.fops	=	&wdt_fops,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
303
304
305
306
307
  };
  
  /*
   *	Notifier for system down
   */
173d95bc2   Alan Cox   [WATCHDOG 03/57] ...
308
309
  static int wdt_notify_sys(struct notifier_block *this,
  					unsigned long code, void *unused)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
310
  {
173d95bc2   Alan Cox   [WATCHDOG 03/57] ...
311
  	if (code == SYS_DOWN || code == SYS_HALT)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
312
  		wdt_turnoff();
173d95bc2   Alan Cox   [WATCHDOG 03/57] ...
313
  	if (code == SYS_RESTART) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
314
  		/*
173d95bc2   Alan Cox   [WATCHDOG 03/57] ...
315
316
317
  		 * Cobalt devices have no way of rebooting themselves other
  		 * than getting the watchdog to pull reset, so we restart the
  		 * watchdog on reboot with no heartbeat
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
318
319
  		 */
  		wdt_change(WDT_ENABLE);
a77dba7e4   Wim Van Sebroeck   [WATCHDOG] Some m...
320
321
322
  		printk(KERN_INFO PFX "Watchdog timer is now enabled "
  			"with no heartbeat - should reboot in ~1 second.
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
323
324
325
326
327
328
329
330
  	}
  	return NOTIFY_DONE;
  }
  
  /*
   *	The WDT needs to learn about soft shutdowns in order to
   *	turn the timebomb registers off.
   */
173d95bc2   Alan Cox   [WATCHDOG 03/57] ...
331
  static struct notifier_block wdt_notifier = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
332
333
334
335
336
337
338
339
340
  	.notifier_call = wdt_notify_sys,
  };
  
  static void __exit alim7101_wdt_unload(void)
  {
  	wdt_turnoff();
  	/* Deregister */
  	misc_deregister(&wdt_miscdev);
  	unregister_reboot_notifier(&wdt_notifier);
02be2ee9e   Jiri Slaby   [WATCHDOG] alim r...
341
  	pci_dev_put(alim7101_pmu);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
342
343
344
345
346
347
348
349
350
351
  }
  
  static int __init alim7101_wdt_init(void)
  {
  	int rc = -EBUSY;
  	struct pci_dev *ali1543_south;
  	char tmp;
  
  	printk(KERN_INFO PFX "Steve Hill <steve@navaho.co.uk>.
  ");
02be2ee9e   Jiri Slaby   [WATCHDOG] alim r...
352
353
  	alim7101_pmu = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101,
  		NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
354
  	if (!alim7101_pmu) {
143a2e54b   Wim Van Sebroeck   [WATCHDOG] More c...
355
356
357
  		printk(KERN_INFO PFX
  			"ALi M7101 PMU not present - WDT not set
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
358
359
360
361
362
  		return -EBUSY;
  	}
  
  	/* Set the WDT in the PMU to 1 second */
  	pci_write_config_byte(alim7101_pmu, ALI_7101_WDT, 0x02);
02be2ee9e   Jiri Slaby   [WATCHDOG] alim r...
363
364
  	ali1543_south = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533,
  		NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
365
  	if (!ali1543_south) {
173d95bc2   Alan Cox   [WATCHDOG 03/57] ...
366
367
368
  		printk(KERN_INFO PFX
  			"ALi 1543 South-Bridge not present - WDT not set
  ");
02be2ee9e   Jiri Slaby   [WATCHDOG] alim r...
369
  		goto err_out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
370
371
  	}
  	pci_read_config_byte(ali1543_south, 0x5e, &tmp);
02be2ee9e   Jiri Slaby   [WATCHDOG] alim r...
372
  	pci_dev_put(ali1543_south);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
373
374
  	if ((tmp & 0x1e) == 0x00) {
  		if (!use_gpio) {
a77dba7e4   Wim Van Sebroeck   [WATCHDOG] Some m...
375
376
377
378
379
  			printk(KERN_INFO PFX
  				"Detected old alim7101 revision 'a1d'.  "
  				"If this is a cobalt board, set the 'use_gpio' "
  				"module parameter.
  ");
02be2ee9e   Jiri Slaby   [WATCHDOG] alim r...
380
  			goto err_out;
173d95bc2   Alan Cox   [WATCHDOG 03/57] ...
381
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
382
383
  		nowayout = 1;
  	} else if ((tmp & 0x1e) != 0x12 && (tmp & 0x1e) != 0x00) {
a77dba7e4   Wim Van Sebroeck   [WATCHDOG] Some m...
384
385
386
387
  		printk(KERN_INFO PFX
  			"ALi 1543 South-Bridge does not have the correct "
  			"revision number (???1001?) - WDT not set
  ");
02be2ee9e   Jiri Slaby   [WATCHDOG] alim r...
388
  		goto err_out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
389
  	}
173d95bc2   Alan Cox   [WATCHDOG 03/57] ...
390
391
  	if (timeout < 1 || timeout > 3600) {
  		/* arbitrary upper limit */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
392
  		timeout = WATCHDOG_TIMEOUT;
173d95bc2   Alan Cox   [WATCHDOG 03/57] ...
393
394
395
396
  		printk(KERN_INFO PFX
  			"timeout value must be 1 <= x <= 3600, using %d
  ",
  								timeout);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
397
  	}
c6cb13aea   Wim Van Sebroeck   [WATCHDOG] misc_r...
398
  	rc = register_reboot_notifier(&wdt_notifier);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
399
  	if (rc) {
173d95bc2   Alan Cox   [WATCHDOG 03/57] ...
400
401
402
  		printk(KERN_ERR PFX
  			"cannot register reboot notifier (err=%d)
  ", rc);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
403
404
  		goto err_out;
  	}
c6cb13aea   Wim Van Sebroeck   [WATCHDOG] misc_r...
405
  	rc = misc_register(&wdt_miscdev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
406
  	if (rc) {
143a2e54b   Wim Van Sebroeck   [WATCHDOG] More c...
407
408
409
  		printk(KERN_ERR PFX
  			"cannot register miscdev on minor=%d (err=%d)
  ",
c6cb13aea   Wim Van Sebroeck   [WATCHDOG] misc_r...
410
411
  			wdt_miscdev.minor, rc);
  		goto err_out_reboot;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
412
  	}
173d95bc2   Alan Cox   [WATCHDOG 03/57] ...
413
  	if (nowayout)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
414
  		__module_get(THIS_MODULE);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
415

a77dba7e4   Wim Van Sebroeck   [WATCHDOG] Some m...
416
417
418
  	printk(KERN_INFO PFX "WDT driver for ALi M7101 initialised. "
  					"timeout=%d sec (nowayout=%d)
  ",
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
419
420
  		timeout, nowayout);
  	return 0;
c6cb13aea   Wim Van Sebroeck   [WATCHDOG] misc_r...
421
422
  err_out_reboot:
  	unregister_reboot_notifier(&wdt_notifier);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
423
  err_out:
02be2ee9e   Jiri Slaby   [WATCHDOG] alim r...
424
  	pci_dev_put(alim7101_pmu);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
425
426
427
428
429
  	return rc;
  }
  
  module_init(alim7101_wdt_init);
  module_exit(alim7101_wdt_unload);
4562f5394   Wim Van Sebroeck   watchdog: convert...
430
  static DEFINE_PCI_DEVICE_TABLE(alim7101_pci_tbl) __used = {
29d73aab3   Jiri Slaby   [PATCH] Char: use...
431
432
  	{ PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533) },
  	{ PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101) },
5cacb9f8b   Ben Collins   [alim7101] Add pc...
433
434
435
436
  	{ }
  };
  
  MODULE_DEVICE_TABLE(pci, alim7101_pci_tbl);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
437
438
439
440
  MODULE_AUTHOR("Steve Hill");
  MODULE_DESCRIPTION("ALi M7101 PMU Computer Watchdog Timer driver");
  MODULE_LICENSE("GPL");
  MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);