24 #include <linux/module.h>
28 #include <linux/kernel.h>
29 #include <linux/types.h>
30 #include <linux/watchdog.h>
37 #define DRIVER_NAME "ie6xx_wdt"
44 #define WDT_RELOAD 0x01
48 #define WDT_PRE_SEL 0x04
49 #define WDT_RESET_SEL 0x08
50 #define WDT_RESET_EN 0x10
51 #define WDT_TOUT_EN 0x20
57 #define WDT_ENABLE 0x02
58 #define WDT_TOUT_CNF 0x03
61 #define MAX_TIME (10 * 60)
62 #define DEFAULT_TIME 60
67 "Default Watchdog timer setting ("
69 "The range is from 1 to 600");
74 "Watchdog cannot be stopped once started (default="
77 static u8 resetmode = 0x10;
80 "Resetmode bits: 0x08 warm reset (cold reset otherwise), "
81 "0x10 reset enable, 0x20 disable toggle GPIO[4] (default=0x10)");
86 #ifdef CONFIG_DEBUG_FS
96 static void ie6xx_wdt_unlock_registers(
void)
98 outb(0x80, ie6xx_wdt_data.sch_wdtba +
RR0);
104 spin_lock(&ie6xx_wdt_data.unlock_sequence);
105 ie6xx_wdt_unlock_registers();
107 spin_unlock(&ie6xx_wdt_data.unlock_sequence);
111 static int ie6xx_wdt_set_timeout(
struct watchdog_device *wdd,
unsigned int t)
120 preload = (t *
clock) >> 15;
127 spin_lock(&ie6xx_wdt_data.unlock_sequence);
130 wdtcr = resetmode & 0x38;
131 outb(wdtcr, ie6xx_wdt_data.sch_wdtba +
WDTCR);
133 ie6xx_wdt_unlock_registers();
134 outl(0, ie6xx_wdt_data.sch_wdtba +
PV1);
136 ie6xx_wdt_unlock_registers();
137 outl(preload, ie6xx_wdt_data.sch_wdtba +
PV2);
139 ie6xx_wdt_unlock_registers();
142 spin_unlock(&ie6xx_wdt_data.unlock_sequence);
150 ie6xx_wdt_set_timeout(wdd, wdd->
timeout);
153 spin_lock(&ie6xx_wdt_data.unlock_sequence);
155 spin_unlock(&ie6xx_wdt_data.unlock_sequence);
166 spin_lock(&ie6xx_wdt_data.unlock_sequence);
167 outb(0, ie6xx_wdt_data.sch_wdtba +
WDTLR);
168 spin_unlock(&ie6xx_wdt_data.unlock_sequence);
174 .identity =
"Intel Atom E6xx Watchdog",
182 .start = ie6xx_wdt_start,
183 .stop = ie6xx_wdt_stop,
184 .ping = ie6xx_wdt_ping,
185 .set_timeout = ie6xx_wdt_set_timeout,
189 .info = &ie6xx_wdt_info,
190 .ops = &ie6xx_wdt_ops,
195 #ifdef CONFIG_DEBUG_FS
200 inl(ie6xx_wdt_data.sch_wdtba +
PV1));
202 inl(ie6xx_wdt_data.sch_wdtba +
PV2));
204 inw(ie6xx_wdt_data.sch_wdtba +
RR0));
206 inw(ie6xx_wdt_data.sch_wdtba +
WDTCR));
208 inl(ie6xx_wdt_data.sch_wdtba +
DCR));
210 inw(ie6xx_wdt_data.sch_wdtba +
WDTLR));
222 .
open = ie6xx_wdt_dbg_open,
228 static void __devinit ie6xx_wdt_debugfs_init(
void)
235 static void ie6xx_wdt_debugfs_exit(
void)
241 static void __devinit ie6xx_wdt_debugfs_init(
void)
245 static void ie6xx_wdt_debugfs_exit(
void)
261 dev_err(&pdev->
dev,
"Watchdog region 0x%llx already in use!\n",
266 ie6xx_wdt_data.sch_wdtba = res->
start;
267 dev_dbg(&pdev->
dev,
"WDT = 0x%X\n", ie6xx_wdt_data.sch_wdtba);
270 watchdog_set_nowayout(&ie6xx_wdt_dev, nowayout);
274 wdtlr =
inb(ie6xx_wdt_data.sch_wdtba +
WDTLR);
277 "Watchdog Timer is Locked (Reg=0x%x)\n", wdtlr);
279 ie6xx_wdt_debugfs_init();
284 "Watchdog timer: cannot register device (err =%d)\n",
286 goto misc_register_error;
292 ie6xx_wdt_debugfs_exit();
294 ie6xx_wdt_data.sch_wdtba = 0;
303 ie6xx_wdt_stop(
NULL);
305 ie6xx_wdt_debugfs_exit();
307 ie6xx_wdt_data.sch_wdtba = 0;
313 .probe = ie6xx_wdt_probe,
321 static int __init ie6xx_wdt_init(
void)
327 pr_err(
"Watchdog timer: value of timeout %d (dec) "
328 "is out of range from %d to %d (dec)\n",
336 static void __exit ie6xx_wdt_exit(
void)