1b7e04f8cSWim Van Sebroeck /* 2b7e04f8cSWim Van Sebroeck * intel TCO vendor specific watchdog driver support 3b7e04f8cSWim Van Sebroeck * 4b7e04f8cSWim Van Sebroeck * (c) Copyright 2006 Wim Van Sebroeck <wim@iguana.be>. 5b7e04f8cSWim Van Sebroeck * 6b7e04f8cSWim Van Sebroeck * This program is free software; you can redistribute it and/or 7b7e04f8cSWim Van Sebroeck * modify it under the terms of the GNU General Public License 8b7e04f8cSWim Van Sebroeck * as published by the Free Software Foundation; either version 9b7e04f8cSWim Van Sebroeck * 2 of the License, or (at your option) any later version. 10b7e04f8cSWim Van Sebroeck * 11b7e04f8cSWim Van Sebroeck * Neither Wim Van Sebroeck nor Iguana vzw. admit liability nor 12b7e04f8cSWim Van Sebroeck * provide warranty for any of this software. This material is 13b7e04f8cSWim Van Sebroeck * provided "AS-IS" and at no charge. 14b7e04f8cSWim Van Sebroeck */ 15b7e04f8cSWim Van Sebroeck 16b7e04f8cSWim Van Sebroeck /* 17b7e04f8cSWim Van Sebroeck * Includes, defines, variables, module parameters, ... 18b7e04f8cSWim Van Sebroeck */ 19b7e04f8cSWim Van Sebroeck 20b7e04f8cSWim Van Sebroeck /* Module and version information */ 21b7e04f8cSWim Van Sebroeck #define DRV_NAME "iTCO_vendor_support" 22b7e04f8cSWim Van Sebroeck #define DRV_VERSION "1.01" 23b7e04f8cSWim Van Sebroeck #define DRV_RELDATE "11-Nov-2006" 24b7e04f8cSWim Van Sebroeck #define PFX DRV_NAME ": " 25b7e04f8cSWim Van Sebroeck 26b7e04f8cSWim Van Sebroeck /* Includes */ 27b7e04f8cSWim Van Sebroeck #include <linux/module.h> /* For module specific items */ 28b7e04f8cSWim Van Sebroeck #include <linux/moduleparam.h> /* For new moduleparam's */ 29b7e04f8cSWim Van Sebroeck #include <linux/types.h> /* For standard types (like size_t) */ 30b7e04f8cSWim Van Sebroeck #include <linux/errno.h> /* For the -ENODEV/... values */ 31b7e04f8cSWim Van Sebroeck #include <linux/kernel.h> /* For printk/panic/... */ 32b7e04f8cSWim Van Sebroeck #include <linux/init.h> /* For __init/__exit/... */ 33b7e04f8cSWim Van Sebroeck #include <linux/ioport.h> /* For io-port access */ 34b7e04f8cSWim Van Sebroeck 350e6fa3fbSAlan Cox #include <linux/io.h> /* For inb/outb/... */ 360e6fa3fbSAlan Cox 370e6fa3fbSAlan Cox #include "iTCO_vendor.h" 38b7e04f8cSWim Van Sebroeck 39b7e04f8cSWim Van Sebroeck /* iTCO defines */ 40b7e04f8cSWim Van Sebroeck #define SMI_EN acpibase + 0x30 /* SMI Control and Enable Register */ 41b7e04f8cSWim Van Sebroeck #define TCOBASE acpibase + 0x60 /* TCO base address */ 42b7e04f8cSWim Van Sebroeck #define TCO1_STS TCOBASE + 0x04 /* TCO1 Status Register */ 43b7e04f8cSWim Van Sebroeck 44b7e04f8cSWim Van Sebroeck /* List of vendor support modes */ 450e6fa3fbSAlan Cox /* SuperMicro Pentium 3 Era 370SSE+-OEM1/P3TSSE */ 460e6fa3fbSAlan Cox #define SUPERMICRO_OLD_BOARD 1 470e6fa3fbSAlan Cox /* SuperMicro Pentium 4 / Xeon 4 / EMT64T Era Systems */ 480e6fa3fbSAlan Cox #define SUPERMICRO_NEW_BOARD 2 49b7e04f8cSWim Van Sebroeck 500e6fa3fbSAlan Cox static int vendorsupport; 51b7e04f8cSWim Van Sebroeck module_param(vendorsupport, int, 0); 52b7e04f8cSWim Van Sebroeck MODULE_PARM_DESC(vendorsupport, "iTCO vendor specific support mode, default=0 (none), 1=SuperMicro Pent3, 2=SuperMicro Pent4+"); 53b7e04f8cSWim Van Sebroeck 54b7e04f8cSWim Van Sebroeck /* 55b7e04f8cSWim Van Sebroeck * Vendor Specific Support 56b7e04f8cSWim Van Sebroeck */ 57b7e04f8cSWim Van Sebroeck 58b7e04f8cSWim Van Sebroeck /* 59b7e04f8cSWim Van Sebroeck * Vendor Support: 1 60b7e04f8cSWim Van Sebroeck * Board: Super Micro Computer Inc. 370SSE+-OEM1/P3TSSE 61b7e04f8cSWim Van Sebroeck * iTCO chipset: ICH2 62b7e04f8cSWim Van Sebroeck * 63b7e04f8cSWim Van Sebroeck * Code contributed by: R. Seretny <lkpatches@paypc.com> 64b7e04f8cSWim Van Sebroeck * Documentation obtained by R. Seretny from SuperMicro Technical Support 65b7e04f8cSWim Van Sebroeck * 66b7e04f8cSWim Van Sebroeck * To enable Watchdog function: 67b7e04f8cSWim Van Sebroeck * BIOS setup -> Power -> TCO Logic SMI Enable -> Within5Minutes 68b7e04f8cSWim Van Sebroeck * This setting enables SMI to clear the watchdog expired flag. 69b7e04f8cSWim Van Sebroeck * If BIOS or CPU fail which may cause SMI hang, then system will 70b7e04f8cSWim Van Sebroeck * reboot. When application starts to use watchdog function, 71b7e04f8cSWim Van Sebroeck * application has to take over the control from SMI. 72b7e04f8cSWim Van Sebroeck * 73b7e04f8cSWim Van Sebroeck * For P3TSSE, J36 jumper needs to be removed to enable the Watchdog 74b7e04f8cSWim Van Sebroeck * function. 75b7e04f8cSWim Van Sebroeck * 76b7e04f8cSWim Van Sebroeck * Note: The system will reboot when Expire Flag is set TWICE. 77b7e04f8cSWim Van Sebroeck * So, if the watchdog timer is 20 seconds, then the maximum hang 78b7e04f8cSWim Van Sebroeck * time is about 40 seconds, and the minimum hang time is about 79b7e04f8cSWim Van Sebroeck * 20.6 seconds. 80b7e04f8cSWim Van Sebroeck */ 81b7e04f8cSWim Van Sebroeck 82b7e04f8cSWim Van Sebroeck static void supermicro_old_pre_start(unsigned long acpibase) 83b7e04f8cSWim Van Sebroeck { 84b7e04f8cSWim Van Sebroeck unsigned long val32; 85b7e04f8cSWim Van Sebroeck 86b7e04f8cSWim Van Sebroeck val32 = inl(SMI_EN); 87b7e04f8cSWim Van Sebroeck val32 &= 0xffffdfff; /* Turn off SMI clearing watchdog */ 88b7e04f8cSWim Van Sebroeck outl(val32, SMI_EN); /* Needed to activate watchdog */ 89b7e04f8cSWim Van Sebroeck } 90b7e04f8cSWim Van Sebroeck 91b7e04f8cSWim Van Sebroeck static void supermicro_old_pre_stop(unsigned long acpibase) 92b7e04f8cSWim Van Sebroeck { 93b7e04f8cSWim Van Sebroeck unsigned long val32; 94b7e04f8cSWim Van Sebroeck 95b7e04f8cSWim Van Sebroeck val32 = inl(SMI_EN); 96b7e04f8cSWim Van Sebroeck val32 &= 0x00002000; /* Turn on SMI clearing watchdog */ 97b7e04f8cSWim Van Sebroeck outl(val32, SMI_EN); /* Needed to deactivate watchdog */ 98b7e04f8cSWim Van Sebroeck } 99b7e04f8cSWim Van Sebroeck 100b7e04f8cSWim Van Sebroeck static void supermicro_old_pre_keepalive(unsigned long acpibase) 101b7e04f8cSWim Van Sebroeck { 102b7e04f8cSWim Van Sebroeck /* Reload TCO Timer (done in iTCO_wdt_keepalive) + */ 103b7e04f8cSWim Van Sebroeck /* Clear "Expire Flag" (Bit 3 of TC01_STS register) */ 104b7e04f8cSWim Van Sebroeck outb(0x08, TCO1_STS); 105b7e04f8cSWim Van Sebroeck } 106b7e04f8cSWim Van Sebroeck 107b7e04f8cSWim Van Sebroeck /* 108b7e04f8cSWim Van Sebroeck * Vendor Support: 2 109b7e04f8cSWim Van Sebroeck * Board: Super Micro Computer Inc. P4SBx, P4DPx 110b7e04f8cSWim Van Sebroeck * iTCO chipset: ICH4 111b7e04f8cSWim Van Sebroeck * 112b7e04f8cSWim Van Sebroeck * Code contributed by: R. Seretny <lkpatches@paypc.com> 113b7e04f8cSWim Van Sebroeck * Documentation obtained by R. Seretny from SuperMicro Technical Support 114b7e04f8cSWim Van Sebroeck * 115b7e04f8cSWim Van Sebroeck * To enable Watchdog function: 116b7e04f8cSWim Van Sebroeck * 1. BIOS 117b7e04f8cSWim Van Sebroeck * For P4SBx: 118b7e04f8cSWim Van Sebroeck * BIOS setup -> Advanced -> Integrated Peripherals -> Watch Dog Feature 119b7e04f8cSWim Van Sebroeck * For P4DPx: 120b7e04f8cSWim Van Sebroeck * BIOS setup -> Advanced -> I/O Device Configuration -> Watch Dog 121b7e04f8cSWim Van Sebroeck * This setting enables or disables Watchdog function. When enabled, the 12296de0e25SJan Engelhardt * default watchdog timer is set to be 5 minutes (about 4m35s). It is 123b7e04f8cSWim Van Sebroeck * enough to load and run the OS. The application (service or driver) has 124b7e04f8cSWim Van Sebroeck * to take over the control once OS is running up and before watchdog 125b7e04f8cSWim Van Sebroeck * expires. 126b7e04f8cSWim Van Sebroeck * 127b7e04f8cSWim Van Sebroeck * 2. JUMPER 128b7e04f8cSWim Van Sebroeck * For P4SBx: JP39 129b7e04f8cSWim Van Sebroeck * For P4DPx: JP37 130b7e04f8cSWim Van Sebroeck * This jumper is used for safety. Closed is enabled. This jumper 131b7e04f8cSWim Van Sebroeck * prevents user enables watchdog in BIOS by accident. 132b7e04f8cSWim Van Sebroeck * 133b7e04f8cSWim Van Sebroeck * To enable Watch Dog function, both BIOS and JUMPER must be enabled. 134b7e04f8cSWim Van Sebroeck * 135b7e04f8cSWim Van Sebroeck * The documentation lists motherboards P4SBx and P4DPx series as of 136b7e04f8cSWim Van Sebroeck * 20-March-2002. However, this code works flawlessly with much newer 137b7e04f8cSWim Van Sebroeck * motherboards, such as my X6DHR-8G2 (SuperServer 6014H-82). 138b7e04f8cSWim Van Sebroeck * 139b7e04f8cSWim Van Sebroeck * The original iTCO driver as written does not actually reset the 140b7e04f8cSWim Van Sebroeck * watchdog timer on these machines, as a result they reboot after five 141b7e04f8cSWim Van Sebroeck * minutes. 142b7e04f8cSWim Van Sebroeck * 143b7e04f8cSWim Van Sebroeck * NOTE: You may leave the Watchdog function disabled in the SuperMicro 144b7e04f8cSWim Van Sebroeck * BIOS to avoid a "boot-race"... This driver will enable watchdog 145b7e04f8cSWim Van Sebroeck * functionality even if it's disabled in the BIOS once the /dev/watchdog 146b7e04f8cSWim Van Sebroeck * file is opened. 147b7e04f8cSWim Van Sebroeck */ 148b7e04f8cSWim Van Sebroeck 149b7e04f8cSWim Van Sebroeck /* I/O Port's */ 150b7e04f8cSWim Van Sebroeck #define SM_REGINDEX 0x2e /* SuperMicro ICH4+ Register Index */ 151b7e04f8cSWim Van Sebroeck #define SM_DATAIO 0x2f /* SuperMicro ICH4+ Register Data I/O */ 152b7e04f8cSWim Van Sebroeck 153b7e04f8cSWim Van Sebroeck /* Control Register's */ 154b7e04f8cSWim Van Sebroeck #define SM_CTLPAGESW 0x07 /* SuperMicro ICH4+ Control Page Switch */ 155b7e04f8cSWim Van Sebroeck #define SM_CTLPAGE 0x08 /* SuperMicro ICH4+ Control Page Num */ 156b7e04f8cSWim Van Sebroeck 157b7e04f8cSWim Van Sebroeck #define SM_WATCHENABLE 0x30 /* Watchdog enable: Bit 0: 0=off, 1=on */ 158b7e04f8cSWim Van Sebroeck 159b7e04f8cSWim Van Sebroeck #define SM_WATCHPAGE 0x87 /* Watchdog unlock control page */ 160b7e04f8cSWim Van Sebroeck 161b7e04f8cSWim Van Sebroeck #define SM_ENDWATCH 0xAA /* Watchdog lock control page */ 162b7e04f8cSWim Van Sebroeck 163b7e04f8cSWim Van Sebroeck #define SM_COUNTMODE 0xf5 /* Watchdog count mode select */ 164b7e04f8cSWim Van Sebroeck /* (Bit 3: 0 = seconds, 1 = minutes */ 165b7e04f8cSWim Van Sebroeck 166b7e04f8cSWim Van Sebroeck #define SM_WATCHTIMER 0xf6 /* 8-bits, Watchdog timer counter (RW) */ 167b7e04f8cSWim Van Sebroeck 168b7e04f8cSWim Van Sebroeck #define SM_RESETCONTROL 0xf7 /* Watchdog reset control */ 169b7e04f8cSWim Van Sebroeck /* Bit 6: timer is reset by kbd interrupt */ 170b7e04f8cSWim Van Sebroeck /* Bit 7: timer is reset by mouse interrupt */ 171b7e04f8cSWim Van Sebroeck 172b7e04f8cSWim Van Sebroeck static void supermicro_new_unlock_watchdog(void) 173b7e04f8cSWim Van Sebroeck { 1740e6fa3fbSAlan Cox /* Write 0x87 to port 0x2e twice */ 175b7e04f8cSWim Van Sebroeck outb(SM_WATCHPAGE, SM_REGINDEX); 1760e6fa3fbSAlan Cox outb(SM_WATCHPAGE, SM_REGINDEX); 1770e6fa3fbSAlan Cox /* Switch to watchdog control page */ 1780e6fa3fbSAlan Cox outb(SM_CTLPAGESW, SM_REGINDEX); 179b7e04f8cSWim Van Sebroeck outb(SM_CTLPAGE, SM_DATAIO); 180b7e04f8cSWim Van Sebroeck } 181b7e04f8cSWim Van Sebroeck 182b7e04f8cSWim Van Sebroeck static void supermicro_new_lock_watchdog(void) 183b7e04f8cSWim Van Sebroeck { 184b7e04f8cSWim Van Sebroeck outb(SM_ENDWATCH, SM_REGINDEX); 185b7e04f8cSWim Van Sebroeck } 186b7e04f8cSWim Van Sebroeck 187b7e04f8cSWim Van Sebroeck static void supermicro_new_pre_start(unsigned int heartbeat) 188b7e04f8cSWim Van Sebroeck { 189b7e04f8cSWim Van Sebroeck unsigned int val; 190b7e04f8cSWim Van Sebroeck 191b7e04f8cSWim Van Sebroeck supermicro_new_unlock_watchdog(); 192b7e04f8cSWim Van Sebroeck 193b7e04f8cSWim Van Sebroeck /* Watchdog timer setting needs to be in seconds*/ 194b7e04f8cSWim Van Sebroeck outb(SM_COUNTMODE, SM_REGINDEX); 195b7e04f8cSWim Van Sebroeck val = inb(SM_DATAIO); 196b7e04f8cSWim Van Sebroeck val &= 0xF7; 197b7e04f8cSWim Van Sebroeck outb(val, SM_DATAIO); 198b7e04f8cSWim Van Sebroeck 199b7e04f8cSWim Van Sebroeck /* Write heartbeat interval to WDOG */ 200b7e04f8cSWim Van Sebroeck outb(SM_WATCHTIMER, SM_REGINDEX); 201b7e04f8cSWim Van Sebroeck outb((heartbeat & 255), SM_DATAIO); 202b7e04f8cSWim Van Sebroeck 203b7e04f8cSWim Van Sebroeck /* Make sure keyboard/mouse interrupts don't interfere */ 204b7e04f8cSWim Van Sebroeck outb(SM_RESETCONTROL, SM_REGINDEX); 205b7e04f8cSWim Van Sebroeck val = inb(SM_DATAIO); 206b7e04f8cSWim Van Sebroeck val &= 0x3f; 207b7e04f8cSWim Van Sebroeck outb(val, SM_DATAIO); 208b7e04f8cSWim Van Sebroeck 209b7e04f8cSWim Van Sebroeck /* enable watchdog by setting bit 0 of Watchdog Enable to 1 */ 210b7e04f8cSWim Van Sebroeck outb(SM_WATCHENABLE, SM_REGINDEX); 211b7e04f8cSWim Van Sebroeck val = inb(SM_DATAIO); 212b7e04f8cSWim Van Sebroeck val |= 0x01; 213b7e04f8cSWim Van Sebroeck outb(val, SM_DATAIO); 214b7e04f8cSWim Van Sebroeck 215b7e04f8cSWim Van Sebroeck supermicro_new_lock_watchdog(); 216b7e04f8cSWim Van Sebroeck } 217b7e04f8cSWim Van Sebroeck 218b7e04f8cSWim Van Sebroeck static void supermicro_new_pre_stop(void) 219b7e04f8cSWim Van Sebroeck { 220b7e04f8cSWim Van Sebroeck unsigned int val; 221b7e04f8cSWim Van Sebroeck 222b7e04f8cSWim Van Sebroeck supermicro_new_unlock_watchdog(); 223b7e04f8cSWim Van Sebroeck 224b7e04f8cSWim Van Sebroeck /* disable watchdog by setting bit 0 of Watchdog Enable to 0 */ 225b7e04f8cSWim Van Sebroeck outb(SM_WATCHENABLE, SM_REGINDEX); 226b7e04f8cSWim Van Sebroeck val = inb(SM_DATAIO); 227b7e04f8cSWim Van Sebroeck val &= 0xFE; 228b7e04f8cSWim Van Sebroeck outb(val, SM_DATAIO); 229b7e04f8cSWim Van Sebroeck 230b7e04f8cSWim Van Sebroeck supermicro_new_lock_watchdog(); 231b7e04f8cSWim Van Sebroeck } 232b7e04f8cSWim Van Sebroeck 233b7e04f8cSWim Van Sebroeck static void supermicro_new_pre_set_heartbeat(unsigned int heartbeat) 234b7e04f8cSWim Van Sebroeck { 235b7e04f8cSWim Van Sebroeck supermicro_new_unlock_watchdog(); 236b7e04f8cSWim Van Sebroeck 237b7e04f8cSWim Van Sebroeck /* reset watchdog timeout to heartveat value */ 238b7e04f8cSWim Van Sebroeck outb(SM_WATCHTIMER, SM_REGINDEX); 239b7e04f8cSWim Van Sebroeck outb((heartbeat & 255), SM_DATAIO); 240b7e04f8cSWim Van Sebroeck 241b7e04f8cSWim Van Sebroeck supermicro_new_lock_watchdog(); 242b7e04f8cSWim Van Sebroeck } 243b7e04f8cSWim Van Sebroeck 244b7e04f8cSWim Van Sebroeck /* 245b7e04f8cSWim Van Sebroeck * Generic Support Functions 246b7e04f8cSWim Van Sebroeck */ 247b7e04f8cSWim Van Sebroeck 248b7e04f8cSWim Van Sebroeck void iTCO_vendor_pre_start(unsigned long acpibase, 249b7e04f8cSWim Van Sebroeck unsigned int heartbeat) 250b7e04f8cSWim Van Sebroeck { 251b7e04f8cSWim Van Sebroeck if (vendorsupport == SUPERMICRO_OLD_BOARD) 252b7e04f8cSWim Van Sebroeck supermicro_old_pre_start(acpibase); 253b7e04f8cSWim Van Sebroeck else if (vendorsupport == SUPERMICRO_NEW_BOARD) 254b7e04f8cSWim Van Sebroeck supermicro_new_pre_start(heartbeat); 255b7e04f8cSWim Van Sebroeck } 256b7e04f8cSWim Van Sebroeck EXPORT_SYMBOL(iTCO_vendor_pre_start); 257b7e04f8cSWim Van Sebroeck 258b7e04f8cSWim Van Sebroeck void iTCO_vendor_pre_stop(unsigned long acpibase) 259b7e04f8cSWim Van Sebroeck { 260b7e04f8cSWim Van Sebroeck if (vendorsupport == SUPERMICRO_OLD_BOARD) 261b7e04f8cSWim Van Sebroeck supermicro_old_pre_stop(acpibase); 262b7e04f8cSWim Van Sebroeck else if (vendorsupport == SUPERMICRO_NEW_BOARD) 263b7e04f8cSWim Van Sebroeck supermicro_new_pre_stop(); 264b7e04f8cSWim Van Sebroeck } 265b7e04f8cSWim Van Sebroeck EXPORT_SYMBOL(iTCO_vendor_pre_stop); 266b7e04f8cSWim Van Sebroeck 267b7e04f8cSWim Van Sebroeck void iTCO_vendor_pre_keepalive(unsigned long acpibase, unsigned int heartbeat) 268b7e04f8cSWim Van Sebroeck { 269b7e04f8cSWim Van Sebroeck if (vendorsupport == SUPERMICRO_OLD_BOARD) 270b7e04f8cSWim Van Sebroeck supermicro_old_pre_keepalive(acpibase); 271b7e04f8cSWim Van Sebroeck else if (vendorsupport == SUPERMICRO_NEW_BOARD) 272b7e04f8cSWim Van Sebroeck supermicro_new_pre_set_heartbeat(heartbeat); 273b7e04f8cSWim Van Sebroeck } 274b7e04f8cSWim Van Sebroeck EXPORT_SYMBOL(iTCO_vendor_pre_keepalive); 275b7e04f8cSWim Van Sebroeck 276b7e04f8cSWim Van Sebroeck void iTCO_vendor_pre_set_heartbeat(unsigned int heartbeat) 277b7e04f8cSWim Van Sebroeck { 278b7e04f8cSWim Van Sebroeck if (vendorsupport == SUPERMICRO_NEW_BOARD) 279b7e04f8cSWim Van Sebroeck supermicro_new_pre_set_heartbeat(heartbeat); 280b7e04f8cSWim Van Sebroeck } 281b7e04f8cSWim Van Sebroeck EXPORT_SYMBOL(iTCO_vendor_pre_set_heartbeat); 282b7e04f8cSWim Van Sebroeck 283b7e04f8cSWim Van Sebroeck int iTCO_vendor_check_noreboot_on(void) 284b7e04f8cSWim Van Sebroeck { 285b7e04f8cSWim Van Sebroeck switch (vendorsupport) { 286b7e04f8cSWim Van Sebroeck case SUPERMICRO_OLD_BOARD: 287b7e04f8cSWim Van Sebroeck return 0; 288b7e04f8cSWim Van Sebroeck default: 289b7e04f8cSWim Van Sebroeck return 1; 290b7e04f8cSWim Van Sebroeck } 291b7e04f8cSWim Van Sebroeck } 292b7e04f8cSWim Van Sebroeck EXPORT_SYMBOL(iTCO_vendor_check_noreboot_on); 293b7e04f8cSWim Van Sebroeck 294b7e04f8cSWim Van Sebroeck static int __init iTCO_vendor_init_module(void) 295b7e04f8cSWim Van Sebroeck { 296b7e04f8cSWim Van Sebroeck printk(KERN_INFO PFX "vendor-support=%d\n", vendorsupport); 297b7e04f8cSWim Van Sebroeck return 0; 298b7e04f8cSWim Van Sebroeck } 299b7e04f8cSWim Van Sebroeck 300b7e04f8cSWim Van Sebroeck static void __exit iTCO_vendor_exit_module(void) 301b7e04f8cSWim Van Sebroeck { 302b7e04f8cSWim Van Sebroeck printk(KERN_INFO PFX "Module Unloaded\n"); 303b7e04f8cSWim Van Sebroeck } 304b7e04f8cSWim Van Sebroeck 305b7e04f8cSWim Van Sebroeck module_init(iTCO_vendor_init_module); 306b7e04f8cSWim Van Sebroeck module_exit(iTCO_vendor_exit_module); 307b7e04f8cSWim Van Sebroeck 308b7e04f8cSWim Van Sebroeck MODULE_AUTHOR("Wim Van Sebroeck <wim@iguana.be>, R. Seretny <lkpatches@paypc.com>"); 309b7e04f8cSWim Van Sebroeck MODULE_DESCRIPTION("Intel TCO Vendor Specific WatchDog Timer Driver Support"); 310b7e04f8cSWim Van Sebroeck MODULE_VERSION(DRV_VERSION); 311b7e04f8cSWim Van Sebroeck MODULE_LICENSE("GPL"); 312b7e04f8cSWim Van Sebroeck 313