~ubuntu-branches/ubuntu/precise/linux-lowlatency/precise

« back to all changes in this revision

Viewing changes to drivers/watchdog/intel_scu_watchdog.c

  • Committer: Package Import Robot
  • Author(s): Alessio Igor Bogani
  • Date: 2011-10-26 11:13:05 UTC
  • Revision ID: package-import@ubuntu.com-20111026111305-tz023xykf0i6eosh
Tags: upstream-3.2.0
ImportĀ upstreamĀ versionĀ 3.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *      Intel_SCU 0.2:  An Intel SCU IOH Based Watchdog Device
 
3
 *                      for Intel part #(s):
 
4
 *                              - AF82MP20 PCH
 
5
 *
 
6
 *      Copyright (C) 2009-2010 Intel Corporation. All rights reserved.
 
7
 *
 
8
 *      This program is free software; you can redistribute it and/or
 
9
 *      modify it under the terms of version 2 of the GNU General
 
10
 *      Public License as published by the Free Software Foundation.
 
11
 *
 
12
 *      This program is distributed in the hope that it will be
 
13
 *      useful, but WITHOUT ANY WARRANTY; without even the implied
 
14
 *      warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 
15
 *      PURPOSE.  See the GNU General Public License for more details.
 
16
 *      You should have received a copy of the GNU General Public
 
17
 *      License along with this program; if not, write to the Free
 
18
 *      Software Foundation, Inc., 59 Temple Place - Suite 330,
 
19
 *      Boston, MA  02111-1307, USA.
 
20
 *      The full GNU General Public License is included in this
 
21
 *      distribution in the file called COPYING.
 
22
 *
 
23
 */
 
24
 
 
25
#include <linux/compiler.h>
 
26
#include <linux/module.h>
 
27
#include <linux/kernel.h>
 
28
#include <linux/moduleparam.h>
 
29
#include <linux/types.h>
 
30
#include <linux/miscdevice.h>
 
31
#include <linux/watchdog.h>
 
32
#include <linux/fs.h>
 
33
#include <linux/notifier.h>
 
34
#include <linux/reboot.h>
 
35
#include <linux/init.h>
 
36
#include <linux/jiffies.h>
 
37
#include <linux/uaccess.h>
 
38
#include <linux/slab.h>
 
39
#include <linux/io.h>
 
40
#include <linux/interrupt.h>
 
41
#include <linux/delay.h>
 
42
#include <linux/sched.h>
 
43
#include <linux/signal.h>
 
44
#include <linux/sfi.h>
 
45
#include <asm/irq.h>
 
46
#include <linux/atomic.h>
 
47
#include <asm/intel_scu_ipc.h>
 
48
#include <asm/apb_timer.h>
 
49
#include <asm/mrst.h>
 
50
 
 
51
#include "intel_scu_watchdog.h"
 
52
 
 
53
/* Bounds number of times we will retry loading time count */
 
54
/* This retry is a work around for a silicon bug.          */
 
55
#define MAX_RETRY 16
 
56
 
 
57
#define IPC_SET_WATCHDOG_TIMER  0xF8
 
58
 
 
59
static int timer_margin = DEFAULT_SOFT_TO_HARD_MARGIN;
 
60
module_param(timer_margin, int, 0);
 
61
MODULE_PARM_DESC(timer_margin,
 
62
                "Watchdog timer margin"
 
63
                "Time between interrupt and resetting the system"
 
64
                "The range is from 1 to 160"
 
65
                "This is the time for all keep alives to arrive");
 
66
 
 
67
static int timer_set = DEFAULT_TIME;
 
68
module_param(timer_set, int, 0);
 
69
MODULE_PARM_DESC(timer_set,
 
70
                "Default Watchdog timer setting"
 
71
                "Complete cycle time"
 
72
                "The range is from 1 to 170"
 
73
                "This is the time for all keep alives to arrive");
 
74
 
 
75
/* After watchdog device is closed, check force_boot. If:
 
76
 * force_boot == 0, then force boot on next watchdog interrupt after close,
 
77
 * force_boot == 1, then force boot immediately when device is closed.
 
78
 */
 
79
static int force_boot;
 
80
module_param(force_boot, int, 0);
 
81
MODULE_PARM_DESC(force_boot,
 
82
                "A value of 1 means that the driver will reboot"
 
83
                "the system immediately if the /dev/watchdog device is closed"
 
84
                "A value of 0 means that when /dev/watchdog device is closed"
 
85
                "the watchdog timer will be refreshed for one more interval"
 
86
                "of length: timer_set. At the end of this interval, the"
 
87
                "watchdog timer will reset the system."
 
88
                );
 
89
 
 
90
/* there is only one device in the system now; this can be made into
 
91
 * an array in the future if we have more than one device */
 
92
 
 
93
static struct intel_scu_watchdog_dev watchdog_device;
 
94
 
 
95
/* Forces restart, if force_reboot is set */
 
96
static void watchdog_fire(void)
 
97
{
 
98
        if (force_boot) {
 
99
                printk(KERN_CRIT PFX "Initiating system reboot.\n");
 
100
                emergency_restart();
 
101
                printk(KERN_CRIT PFX "Reboot didn't ?????\n");
 
102
        }
 
103
 
 
104
        else {
 
105
                printk(KERN_CRIT PFX "Immediate Reboot Disabled\n");
 
106
                printk(KERN_CRIT PFX
 
107
                        "System will reset when watchdog timer times out!\n");
 
108
        }
 
109
}
 
110
 
 
111
static int check_timer_margin(int new_margin)
 
112
{
 
113
        if ((new_margin < MIN_TIME_CYCLE) ||
 
114
            (new_margin > MAX_TIME - timer_set)) {
 
115
                pr_debug("Watchdog timer: value of new_margin %d is out of the range %d to %d\n",
 
116
                          new_margin, MIN_TIME_CYCLE, MAX_TIME - timer_set);
 
117
                return -EINVAL;
 
118
        }
 
119
        return 0;
 
120
}
 
121
 
 
122
/*
 
123
 * IPC operations
 
124
 */
 
125
static int watchdog_set_ipc(int soft_threshold, int threshold)
 
126
{
 
127
        u32     *ipc_wbuf;
 
128
        u8       cbuf[16] = { '\0' };
 
129
        int      ipc_ret = 0;
 
130
 
 
131
        ipc_wbuf = (u32 *)&cbuf;
 
132
        ipc_wbuf[0] = soft_threshold;
 
133
        ipc_wbuf[1] = threshold;
 
134
 
 
135
        ipc_ret = intel_scu_ipc_command(
 
136
                        IPC_SET_WATCHDOG_TIMER,
 
137
                        0,
 
138
                        ipc_wbuf,
 
139
                        2,
 
140
                        NULL,
 
141
                        0);
 
142
 
 
143
        if (ipc_ret != 0)
 
144
                pr_err("Error setting SCU watchdog timer: %x\n", ipc_ret);
 
145
 
 
146
        return ipc_ret;
 
147
};
 
148
 
 
149
/*
 
150
 *      Intel_SCU operations
 
151
 */
 
152
 
 
153
/* timer interrupt handler */
 
154
static irqreturn_t watchdog_timer_interrupt(int irq, void *dev_id)
 
155
{
 
156
        int int_status;
 
157
        int_status = ioread32(watchdog_device.timer_interrupt_status_addr);
 
158
 
 
159
        pr_debug("Watchdog timer: irq, int_status: %x\n", int_status);
 
160
 
 
161
        if (int_status != 0)
 
162
                return IRQ_NONE;
 
163
 
 
164
        /* has the timer been started? If not, then this is spurious */
 
165
        if (watchdog_device.timer_started == 0) {
 
166
                pr_debug("Watchdog timer: spurious interrupt received\n");
 
167
                return IRQ_HANDLED;
 
168
        }
 
169
 
 
170
        /* temporarily disable the timer */
 
171
        iowrite32(0x00000002, watchdog_device.timer_control_addr);
 
172
 
 
173
        /* set the timer to the threshold */
 
174
        iowrite32(watchdog_device.threshold,
 
175
                  watchdog_device.timer_load_count_addr);
 
176
 
 
177
        /* allow the timer to run */
 
178
        iowrite32(0x00000003, watchdog_device.timer_control_addr);
 
179
 
 
180
        return IRQ_HANDLED;
 
181
}
 
182
 
 
183
static int intel_scu_keepalive(void)
 
184
{
 
185
 
 
186
        /* read eoi register - clears interrupt */
 
187
        ioread32(watchdog_device.timer_clear_interrupt_addr);
 
188
 
 
189
        /* temporarily disable the timer */
 
190
        iowrite32(0x00000002, watchdog_device.timer_control_addr);
 
191
 
 
192
        /* set the timer to the soft_threshold */
 
193
        iowrite32(watchdog_device.soft_threshold,
 
194
                  watchdog_device.timer_load_count_addr);
 
195
 
 
196
        /* allow the timer to run */
 
197
        iowrite32(0x00000003, watchdog_device.timer_control_addr);
 
198
 
 
199
        return 0;
 
200
}
 
201
 
 
202
static int intel_scu_stop(void)
 
203
{
 
204
        iowrite32(0, watchdog_device.timer_control_addr);
 
205
        return 0;
 
206
}
 
207
 
 
208
static int intel_scu_set_heartbeat(u32 t)
 
209
{
 
210
        int                      ipc_ret;
 
211
        int                      retry_count;
 
212
        u32                      soft_value;
 
213
        u32                      hw_pre_value;
 
214
        u32                      hw_value;
 
215
 
 
216
        watchdog_device.timer_set = t;
 
217
        watchdog_device.threshold =
 
218
                timer_margin * watchdog_device.timer_tbl_ptr->freq_hz;
 
219
        watchdog_device.soft_threshold =
 
220
                (watchdog_device.timer_set - timer_margin)
 
221
                * watchdog_device.timer_tbl_ptr->freq_hz;
 
222
 
 
223
        pr_debug("Watchdog timer: set_heartbeat: timer freq is %d\n",
 
224
                watchdog_device.timer_tbl_ptr->freq_hz);
 
225
        pr_debug("Watchdog timer: set_heartbeat: timer_set is %x (hex)\n",
 
226
                watchdog_device.timer_set);
 
227
        pr_debug("Watchdog timer: set_hearbeat: timer_margin is %x (hex)\n",
 
228
                timer_margin);
 
229
        pr_debug("Watchdog timer: set_heartbeat: threshold is %x (hex)\n",
 
230
                watchdog_device.threshold);
 
231
        pr_debug("Watchdog timer: set_heartbeat: soft_threshold is %x (hex)\n",
 
232
                watchdog_device.soft_threshold);
 
233
 
 
234
        /* Adjust thresholds by FREQ_ADJUSTMENT factor, to make the */
 
235
        /* watchdog timing come out right. */
 
236
        watchdog_device.threshold =
 
237
                watchdog_device.threshold / FREQ_ADJUSTMENT;
 
238
        watchdog_device.soft_threshold =
 
239
                watchdog_device.soft_threshold / FREQ_ADJUSTMENT;
 
240
 
 
241
        /* temporarily disable the timer */
 
242
        iowrite32(0x00000002, watchdog_device.timer_control_addr);
 
243
 
 
244
        /* send the threshold and soft_threshold via IPC to the processor */
 
245
        ipc_ret = watchdog_set_ipc(watchdog_device.soft_threshold,
 
246
                                   watchdog_device.threshold);
 
247
 
 
248
        if (ipc_ret != 0) {
 
249
                /* Make sure the watchdog timer is stopped */
 
250
                intel_scu_stop();
 
251
                return ipc_ret;
 
252
        }
 
253
 
 
254
        /* Soft Threshold set loop. Early versions of silicon did */
 
255
        /* not always set this count correctly.  This loop checks */
 
256
        /* the value and retries if it was not set correctly.     */
 
257
 
 
258
        retry_count = 0;
 
259
        soft_value = watchdog_device.soft_threshold & 0xFFFF0000;
 
260
        do {
 
261
 
 
262
                /* Make sure timer is stopped */
 
263
                intel_scu_stop();
 
264
 
 
265
                if (MAX_RETRY < retry_count++) {
 
266
                        /* Unable to set timer value */
 
267
                        pr_err("Watchdog timer: Unable to set timer\n");
 
268
                        return -ENODEV;
 
269
                }
 
270
 
 
271
                /* set the timer to the soft threshold */
 
272
                iowrite32(watchdog_device.soft_threshold,
 
273
                        watchdog_device.timer_load_count_addr);
 
274
 
 
275
                /* read count value before starting timer */
 
276
                hw_pre_value = ioread32(watchdog_device.timer_load_count_addr);
 
277
                hw_pre_value = hw_pre_value & 0xFFFF0000;
 
278
 
 
279
                /* Start the timer */
 
280
                iowrite32(0x00000003, watchdog_device.timer_control_addr);
 
281
 
 
282
                /* read the value the time loaded into its count reg */
 
283
                hw_value = ioread32(watchdog_device.timer_load_count_addr);
 
284
                hw_value = hw_value & 0xFFFF0000;
 
285
 
 
286
 
 
287
        } while (soft_value != hw_value);
 
288
 
 
289
        watchdog_device.timer_started = 1;
 
290
 
 
291
        return 0;
 
292
}
 
293
 
 
294
/*
 
295
 * /dev/watchdog handling
 
296
 */
 
297
 
 
298
static int intel_scu_open(struct inode *inode, struct file *file)
 
299
{
 
300
 
 
301
        /* Set flag to indicate that watchdog device is open */
 
302
        if (test_and_set_bit(0, &watchdog_device.driver_open))
 
303
                return -EBUSY;
 
304
 
 
305
        /* Check for reopen of driver. Reopens are not allowed */
 
306
        if (watchdog_device.driver_closed)
 
307
                return -EPERM;
 
308
 
 
309
        return nonseekable_open(inode, file);
 
310
}
 
311
 
 
312
static int intel_scu_release(struct inode *inode, struct file *file)
 
313
{
 
314
        /*
 
315
         * This watchdog should not be closed, after the timer
 
316
         * is started with the WDIPC_SETTIMEOUT ioctl
 
317
         * If force_boot is set watchdog_fire() will cause an
 
318
         * immediate reset. If force_boot is not set, the watchdog
 
319
         * timer is refreshed for one more interval. At the end
 
320
         * of that interval, the watchdog timer will reset the system.
 
321
         */
 
322
 
 
323
        if (!test_and_clear_bit(0, &watchdog_device.driver_open)) {
 
324
                pr_debug("Watchdog timer: intel_scu_release, without open\n");
 
325
                return -ENOTTY;
 
326
        }
 
327
 
 
328
        if (!watchdog_device.timer_started) {
 
329
                /* Just close, since timer has not been started */
 
330
                pr_debug("Watchdog timer: closed, without starting timer\n");
 
331
                return 0;
 
332
        }
 
333
 
 
334
        printk(KERN_CRIT PFX
 
335
               "Unexpected close of /dev/watchdog!\n");
 
336
 
 
337
        /* Since the timer was started, prevent future reopens */
 
338
        watchdog_device.driver_closed = 1;
 
339
 
 
340
        /* Refresh the timer for one more interval */
 
341
        intel_scu_keepalive();
 
342
 
 
343
        /* Reboot system (if force_boot is set) */
 
344
        watchdog_fire();
 
345
 
 
346
        /* We should only reach this point if force_boot is not set */
 
347
        return 0;
 
348
}
 
349
 
 
350
static ssize_t intel_scu_write(struct file *file,
 
351
                              char const *data,
 
352
                              size_t len,
 
353
                              loff_t *ppos)
 
354
{
 
355
 
 
356
        if (watchdog_device.timer_started)
 
357
                /* Watchdog already started, keep it alive */
 
358
                intel_scu_keepalive();
 
359
        else
 
360
                /* Start watchdog with timer value set by init */
 
361
                intel_scu_set_heartbeat(watchdog_device.timer_set);
 
362
 
 
363
        return len;
 
364
}
 
365
 
 
366
static long intel_scu_ioctl(struct file *file,
 
367
                           unsigned int cmd,
 
368
                           unsigned long arg)
 
369
{
 
370
        void __user *argp = (void __user *)arg;
 
371
        u32 __user *p = argp;
 
372
        u32 new_margin;
 
373
 
 
374
 
 
375
        static const struct watchdog_info ident = {
 
376
                .options =          WDIOF_SETTIMEOUT
 
377
                                    | WDIOF_KEEPALIVEPING,
 
378
                .firmware_version = 0,  /* @todo Get from SCU via
 
379
                                                 ipc_get_scu_fw_version()? */
 
380
                .identity =         "Intel_SCU IOH Watchdog"  /* len < 32 */
 
381
        };
 
382
 
 
383
        switch (cmd) {
 
384
        case WDIOC_GETSUPPORT:
 
385
                return copy_to_user(argp,
 
386
                                    &ident,
 
387
                                    sizeof(ident)) ? -EFAULT : 0;
 
388
        case WDIOC_GETSTATUS:
 
389
        case WDIOC_GETBOOTSTATUS:
 
390
                return put_user(0, p);
 
391
        case WDIOC_KEEPALIVE:
 
392
                intel_scu_keepalive();
 
393
 
 
394
                return 0;
 
395
        case WDIOC_SETTIMEOUT:
 
396
                if (get_user(new_margin, p))
 
397
                        return -EFAULT;
 
398
 
 
399
                if (check_timer_margin(new_margin))
 
400
                        return -EINVAL;
 
401
 
 
402
                if (intel_scu_set_heartbeat(new_margin))
 
403
                        return -EINVAL;
 
404
                return 0;
 
405
        case WDIOC_GETTIMEOUT:
 
406
                return put_user(watchdog_device.soft_threshold, p);
 
407
 
 
408
        default:
 
409
                return -ENOTTY;
 
410
        }
 
411
}
 
412
 
 
413
/*
 
414
 *      Notifier for system down
 
415
 */
 
416
static int intel_scu_notify_sys(struct notifier_block *this,
 
417
                               unsigned long code,
 
418
                               void *another_unused)
 
419
{
 
420
        if (code == SYS_DOWN || code == SYS_HALT)
 
421
                /* Turn off the watchdog timer. */
 
422
                intel_scu_stop();
 
423
        return NOTIFY_DONE;
 
424
}
 
425
 
 
426
/*
 
427
 *      Kernel Interfaces
 
428
 */
 
429
static const struct file_operations intel_scu_fops = {
 
430
        .owner          = THIS_MODULE,
 
431
        .llseek         = no_llseek,
 
432
        .write          = intel_scu_write,
 
433
        .unlocked_ioctl = intel_scu_ioctl,
 
434
        .open           = intel_scu_open,
 
435
        .release        = intel_scu_release,
 
436
};
 
437
 
 
438
static int __init intel_scu_watchdog_init(void)
 
439
{
 
440
        int ret;
 
441
        u32 __iomem *tmp_addr;
 
442
 
 
443
        /*
 
444
         * We don't really need to check this as the SFI timer get will fail
 
445
         * but if we do so we can exit with a clearer reason and no noise.
 
446
         *
 
447
         * If it isn't an intel MID device then it doesn't have this watchdog
 
448
         */
 
449
        if (!mrst_identify_cpu())
 
450
                return -ENODEV;
 
451
 
 
452
        /* Check boot parameters to verify that their initial values */
 
453
        /* are in range. */
 
454
        /* Check value of timer_set boot parameter */
 
455
        if ((timer_set < MIN_TIME_CYCLE) ||
 
456
            (timer_set > MAX_TIME - MIN_TIME_CYCLE)) {
 
457
                pr_err("Watchdog timer: value of timer_set %x (hex) "
 
458
                  "is out of range from %x to %x (hex)\n",
 
459
                  timer_set, MIN_TIME_CYCLE, MAX_TIME - MIN_TIME_CYCLE);
 
460
                return -EINVAL;
 
461
        }
 
462
 
 
463
        /* Check value of timer_margin boot parameter */
 
464
        if (check_timer_margin(timer_margin))
 
465
                return -EINVAL;
 
466
 
 
467
        watchdog_device.timer_tbl_ptr = sfi_get_mtmr(sfi_mtimer_num-1);
 
468
 
 
469
        if (watchdog_device.timer_tbl_ptr == NULL) {
 
470
                pr_debug("Watchdog timer - Intel SCU watchdog: timer is not available\n");
 
471
                return -ENODEV;
 
472
        }
 
473
        /* make sure the timer exists */
 
474
        if (watchdog_device.timer_tbl_ptr->phys_addr == 0) {
 
475
                pr_debug("Watchdog timer - Intel SCU watchdog - timer %d does not have valid physical memory\n",
 
476
                                                                sfi_mtimer_num);
 
477
                return -ENODEV;
 
478
        }
 
479
 
 
480
        if (watchdog_device.timer_tbl_ptr->irq == 0) {
 
481
                pr_debug("Watchdog timer: timer %d invalid irq\n",
 
482
                                                        sfi_mtimer_num);
 
483
                return -ENODEV;
 
484
        }
 
485
 
 
486
        tmp_addr = ioremap_nocache(watchdog_device.timer_tbl_ptr->phys_addr,
 
487
                        20);
 
488
 
 
489
        if (tmp_addr == NULL) {
 
490
                pr_debug("Watchdog timer: timer unable to ioremap\n");
 
491
                return -ENOMEM;
 
492
        }
 
493
 
 
494
        watchdog_device.timer_load_count_addr = tmp_addr++;
 
495
        watchdog_device.timer_current_value_addr = tmp_addr++;
 
496
        watchdog_device.timer_control_addr = tmp_addr++;
 
497
        watchdog_device.timer_clear_interrupt_addr = tmp_addr++;
 
498
        watchdog_device.timer_interrupt_status_addr = tmp_addr++;
 
499
 
 
500
        /* Set the default time values in device structure */
 
501
 
 
502
        watchdog_device.timer_set = timer_set;
 
503
        watchdog_device.threshold =
 
504
                timer_margin * watchdog_device.timer_tbl_ptr->freq_hz;
 
505
        watchdog_device.soft_threshold =
 
506
                (watchdog_device.timer_set - timer_margin)
 
507
                * watchdog_device.timer_tbl_ptr->freq_hz;
 
508
 
 
509
 
 
510
        watchdog_device.intel_scu_notifier.notifier_call =
 
511
                intel_scu_notify_sys;
 
512
 
 
513
        ret = register_reboot_notifier(&watchdog_device.intel_scu_notifier);
 
514
        if (ret) {
 
515
                pr_err("Watchdog timer: cannot register notifier %d)\n", ret);
 
516
                goto register_reboot_error;
 
517
        }
 
518
 
 
519
        watchdog_device.miscdev.minor = WATCHDOG_MINOR;
 
520
        watchdog_device.miscdev.name = "watchdog";
 
521
        watchdog_device.miscdev.fops = &intel_scu_fops;
 
522
 
 
523
        ret = misc_register(&watchdog_device.miscdev);
 
524
        if (ret) {
 
525
                pr_err("Watchdog timer: cannot register miscdev %d err =%d\n",
 
526
                                                        WATCHDOG_MINOR, ret);
 
527
                goto misc_register_error;
 
528
        }
 
529
 
 
530
        ret = request_irq((unsigned int)watchdog_device.timer_tbl_ptr->irq,
 
531
                watchdog_timer_interrupt,
 
532
                IRQF_SHARED, "watchdog",
 
533
                &watchdog_device.timer_load_count_addr);
 
534
        if (ret) {
 
535
                pr_err("Watchdog timer: error requesting irq %d\n", ret);
 
536
                goto request_irq_error;
 
537
        }
 
538
        /* Make sure timer is disabled before returning */
 
539
        intel_scu_stop();
 
540
        return 0;
 
541
 
 
542
/* error cleanup */
 
543
 
 
544
request_irq_error:
 
545
        misc_deregister(&watchdog_device.miscdev);
 
546
misc_register_error:
 
547
        unregister_reboot_notifier(&watchdog_device.intel_scu_notifier);
 
548
register_reboot_error:
 
549
        intel_scu_stop();
 
550
        iounmap(watchdog_device.timer_load_count_addr);
 
551
        return ret;
 
552
}
 
553
 
 
554
static void __exit intel_scu_watchdog_exit(void)
 
555
{
 
556
 
 
557
        misc_deregister(&watchdog_device.miscdev);
 
558
        unregister_reboot_notifier(&watchdog_device.intel_scu_notifier);
 
559
        /* disable the timer */
 
560
        iowrite32(0x00000002, watchdog_device.timer_control_addr);
 
561
        iounmap(watchdog_device.timer_load_count_addr);
 
562
}
 
563
 
 
564
late_initcall(intel_scu_watchdog_init);
 
565
module_exit(intel_scu_watchdog_exit);
 
566
 
 
567
MODULE_AUTHOR("Intel Corporation");
 
568
MODULE_DESCRIPTION("Intel SCU Watchdog Device Driver");
 
569
MODULE_LICENSE("GPL");
 
570
MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
 
571
MODULE_VERSION(WDT_VER);