13 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
16 #include <linux/kernel.h>
17 #include <linux/module.h>
18 #include <linux/pci.h>
21 #include <linux/watchdog.h>
36 #define TOPAZ_ASR_REG_OFFSET 4
37 #define TOPAZ_ASR_TOGGLE 0x40
38 #define TOPAZ_ASR_DISABLE 0x80
41 #define PEARL_BASE 0xe04
42 #define PEARL_WRITE 0xe06
43 #define PEARL_READ 0xe07
45 #define PEARL_ASR_DISABLE_MASK 0x80
46 #define PEARL_ASR_TOGGLE_MASK 0x40
49 #define JASPER_ASR_REG_OFFSET 0x38
51 #define JASPER_ASR_DISABLE_MASK 0x01
52 #define JASPER_ASR_TOGGLE_MASK 0x02
54 #define JUNIPER_BASE_ADDRESS 0x54b
55 #define JUNIPER_ASR_DISABLE_MASK 0x01
56 #define JUNIPER_ASR_TOGGLE_MASK 0x02
58 #define SPRUCE_BASE_ADDRESS 0x118e
59 #define SPRUCE_ASR_DISABLE_MASK 0x01
60 #define SPRUCE_ASR_TOGGLE_MASK 0x02
65 static unsigned long asr_is_open;
66 static char asr_expect_close;
68 static unsigned int asr_type, asr_base, asr_length;
69 static unsigned int asr_read_addr, asr_write_addr;
70 static unsigned char asr_toggle_mask, asr_disable_mask;
73 static void __asr_toggle(
void)
77 reg =
inb(asr_read_addr);
79 outb(reg & ~asr_toggle_mask, asr_write_addr);
80 reg =
inb(asr_read_addr);
82 outb(reg | asr_toggle_mask, asr_write_addr);
83 reg =
inb(asr_read_addr);
85 outb(reg & ~asr_toggle_mask, asr_write_addr);
86 reg =
inb(asr_read_addr);
89 static void asr_toggle(
void)
93 spin_unlock(&asr_lock);
96 static void asr_enable(
void)
100 spin_lock(&asr_lock);
103 reg =
inb(asr_read_addr);
113 reg =
inb(asr_read_addr);
114 outb(reg & ~asr_disable_mask, asr_write_addr);
116 reg =
inb(asr_read_addr);
117 spin_unlock(&asr_lock);
120 static void asr_disable(
void)
124 spin_lock(&asr_lock);
125 reg =
inb(asr_read_addr);
132 outb(reg | asr_toggle_mask, asr_write_addr);
133 reg =
inb(asr_read_addr);
135 outb(reg | asr_disable_mask, asr_write_addr);
137 reg =
inb(asr_read_addr);
138 spin_unlock(&asr_lock);
141 static int __init asr_get_base_address(
void)
144 const char *
type =
"";
163 asr_base = (high << 16) | low;
164 asr_read_addr = asr_write_addr =
178 pci_read_config_dword(pdev, 0x58, &r);
179 asr_base = r & 0xFFFE;
188 outl(0x8000f858, 0xcf8);
197 asr_base =
inl(0xcfc) & 0xfffe;
201 asr_read_addr = asr_write_addr =
205 asr_length = JASPER_ASR_REG_OFFSET + 1;
222 asr_read_addr = asr_write_addr = asr_base;
230 asr_read_addr = asr_write_addr = asr_base;
237 pr_err(
"address %#x already in use\n", asr_base);
241 pr_info(
"found %sASR @ addr %#x\n", type, asr_base);
248 size_t count, loff_t *ppos)
255 asr_expect_close = 0;
257 for (i = 0; i !=
count; i++) {
262 asr_expect_close = 42;
270 static long asr_ioctl(
struct file *file,
unsigned int cmd,
unsigned long arg)
275 .identity =
"IBM ASR",
318 static int asr_open(
struct inode *
inode,
struct file *file)
329 static int asr_release(
struct inode *inode,
struct file *file)
331 if (asr_expect_close == 42)
334 pr_crit(
"unexpected close, not stopping watchdog!\n");
338 asr_expect_close = 0;
346 .unlocked_ioctl = asr_ioctl,
348 .release = asr_release,
364 {
"IBM Automatic Server Restart - eserver xSeries 220",
ASMTYPE_TOPAZ },
365 {
"IBM Automatic Server Restart - Machine Type 8673",
ASMTYPE_PEARL },
366 {
"IBM Automatic Server Restart - Machine Type 8480",
ASMTYPE_JASPER },
367 {
"IBM Automatic Server Restart - Machine Type 8482",
ASMTYPE_JUNIPER },
368 {
"IBM Automatic Server Restart - Machine Type 8648",
ASMTYPE_SPRUCE },
372 static int __init ibmasr_init(
void)
377 for (
id = ibmasr_id_table;
id->
desc;
id++) {
387 rc = asr_get_base_address();
394 pr_err(
"failed to register misc device\n");
401 static void __exit ibmasr_exit(
void)
416 "Watchdog cannot be stopped once started (default="