35 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
37 #include <linux/module.h>
39 #include <linux/types.h>
40 #include <linux/errno.h>
41 #include <linux/kernel.h>
44 #include <linux/watchdog.h>
46 #include <linux/reboot.h>
49 #include <linux/pci.h>
56 #define WATCHDOG_VERSION "1.03"
57 #define WATCHDOG_DRIVER_NAME "PCI-PC Watchdog"
58 #define WATCHDOG_NAME "pcwd_pci"
59 #define DRIVER_VERSION WATCHDOG_DRIVER_NAME " driver, v" WATCHDOG_VERSION
62 #ifndef PCI_VENDOR_ID_QUICKLOGIC
63 #define PCI_VENDOR_ID_QUICKLOGIC 0x11e3
66 #ifndef PCI_DEVICE_ID_WATCHDOG_PCIPCWD
67 #define PCI_DEVICE_ID_WATCHDOG_PCIPCWD 0x5030
75 #define WD_PCI_WTRP 0x01
76 #define WD_PCI_HRBT 0x02
77 #define WD_PCI_TTRP 0x04
78 #define WD_PCI_RL2A 0x08
79 #define WD_PCI_RL1A 0x10
80 #define WD_PCI_R2DS 0x40
82 #define WD_PCI_RLY2 0x80
84 #define WD_PCI_WDIS 0x10
85 #define WD_PCI_ENTP 0x20
86 #define WD_PCI_WRSP 0x40
87 #define WD_PCI_PCMD 0x80
91 #define PCI_COMMAND_TIMEOUT 150
94 #define CMD_GET_STATUS 0x04
95 #define CMD_GET_FIRMWARE_VERSION 0x08
96 #define CMD_READ_WATCHDOG_TIMEOUT 0x18
97 #define CMD_WRITE_WATCHDOG_TIMEOUT 0x19
98 #define CMD_GET_CLEAR_RESET_COUNT 0x84
101 static const int heartbeat_tbl[] = {
113 static int cards_found;
116 static int temp_panic;
118 static char expect_release;
141 #define WATCHDOG_HEARTBEAT 0
146 "(0<heartbeat<65536 or 0=delay-time from dip-switches, default="
151 MODULE_PARM_DESC(nowayout,
"Watchdog cannot be stopped once started (default="
158 static int send_command(
int cmd,
int *
msb,
int *
lsb)
160 int got_response,
count;
163 pr_debug(
"sending following data cmd=0x%02x msb=0x%02x lsb=0x%02x\n",
166 spin_lock(&pcipcwd_private.io_lock);
173 outb_p(*lsb, pcipcwd_private.io_addr + 4);
174 outb_p(*msb, pcipcwd_private.io_addr + 5);
175 outb_p(cmd, pcipcwd_private.io_addr + 6);
189 pr_debug(
"time to process command was: %d ms\n",
192 pr_debug(
"card did not respond on command!\n");
198 *lsb =
inb_p(pcipcwd_private.io_addr + 4);
199 *msb =
inb_p(pcipcwd_private.io_addr + 5);
202 inb_p(pcipcwd_private.io_addr + 6);
205 pr_debug(
"received following data for cmd=0x%02x: msb=0x%02x lsb=0x%02x\n",
209 spin_unlock(&pcipcwd_private.io_lock);
214 static inline void pcipcwd_check_temperature_support(
void)
216 if (
inb_p(pcipcwd_private.io_addr) != 0xF0)
217 pcipcwd_private.supports_temp = 1;
220 static int pcipcwd_get_option_switches(
void)
224 option_switches =
inb_p(pcipcwd_private.io_addr + 3);
225 return option_switches;
228 static void pcipcwd_show_card_info(
void)
230 int got_fw_rev, fw_rev_major, fw_rev_minor;
237 sprintf(fw_ver_str,
"%u.%02u", fw_rev_major, fw_rev_minor);
239 sprintf(fw_ver_str,
"<card no answer>");
242 option_switches = pcipcwd_get_option_switches();
244 pr_info(
"Found card at port 0x%04x (Firmware: %s) %s temp option\n",
245 (
int) pcipcwd_private.io_addr, fw_ver_str,
246 (pcipcwd_private.supports_temp ?
"with" :
"without"));
248 pr_info(
"Option switches (0x%02x): Temperature Reset Enable=%s, Power On Delay=%s\n",
250 ((option_switches & 0x10) ?
"ON" :
"OFF"),
251 ((option_switches & 0x08) ?
"ON" :
"OFF"));
254 pr_info(
"Previous reset was caused by the Watchdog card\n");
257 pr_info(
"Card sensed a CPU Overheat\n");
259 if (pcipcwd_private.boot_status == 0)
260 pr_info(
"No previous trip detected - Cold boot or reset\n");
263 static int pcipcwd_start(
void)
267 spin_lock(&pcipcwd_private.io_lock);
268 outb_p(0x00, pcipcwd_private.io_addr + 3);
271 stat_reg =
inb_p(pcipcwd_private.io_addr + 2);
272 spin_unlock(&pcipcwd_private.io_lock);
275 pr_err(
"Card timer not enabled\n");
285 static int pcipcwd_stop(
void)
289 spin_lock(&pcipcwd_private.io_lock);
290 outb_p(0xA5, pcipcwd_private.io_addr + 3);
293 outb_p(0xA5, pcipcwd_private.io_addr + 3);
296 stat_reg =
inb_p(pcipcwd_private.io_addr + 2);
297 spin_unlock(&pcipcwd_private.io_lock);
299 if (!(stat_reg & WD_PCI_WDIS)) {
300 pr_err(
"Card did not acknowledge disable attempt\n");
310 static int pcipcwd_keepalive(
void)
313 spin_lock(&pcipcwd_private.io_lock);
314 outb_p(0x42, pcipcwd_private.io_addr);
315 spin_unlock(&pcipcwd_private.io_lock);
318 pr_debug(
"Watchdog keepalive signal send\n");
323 static int pcipcwd_set_heartbeat(
int t)
328 if ((t < 0x0001) || (t > 0xFFFF))
341 static int pcipcwd_get_status(
int *
status)
346 control_status =
inb_p(pcipcwd_private.io_addr + 1);
352 panic(KBUILD_MODNAME
": Temperature overheat trip!\n");
356 pr_debug(
"Control Status #1: 0x%02x\n", control_status);
361 static int pcipcwd_clear_status(
void)
368 pr_info(
"clearing watchdog trip status & LED\n");
370 control_status =
inb_p(pcipcwd_private.io_addr + 1);
373 pr_debug(
"status was: 0x%02x\n", control_status);
380 pcipcwd_private.io_addr + 1);
384 reset_counter = 0xff;
388 pr_debug(
"reset count was: 0x%02x\n", reset_counter);
394 static int pcipcwd_get_temperature(
int *
temperature)
397 if (!pcipcwd_private.supports_temp)
400 spin_lock(&pcipcwd_private.io_lock);
401 *temperature =
inb_p(pcipcwd_private.io_addr);
402 spin_unlock(&pcipcwd_private.io_lock);
408 *temperature = (*temperature * 9 / 5) + 32;
411 pr_debug(
"temperature is: %d F\n", *temperature);
417 static int pcipcwd_get_timeleft(
int *time_left)
426 *time_left = (msb << 8) + lsb;
429 pr_debug(
"Time left before next reboot: %d\n", *time_left);
439 size_t len, loff_t *ppos)
452 for (i = 0; i != len; i++) {
467 static long pcipcwd_ioctl(
struct file *file,
unsigned int cmd,
478 .firmware_version = 1,
489 pcipcwd_get_status(&status);
494 return put_user(pcipcwd_private.boot_status, p);
500 if (pcipcwd_get_temperature(&temperature))
544 if (pcipcwd_set_heartbeat(new_heartbeat))
558 if (pcipcwd_get_timeleft(&time_left))
569 static int pcipcwd_open(
struct inode *
inode,
struct file *file)
574 pr_err(
"Attempt to open already opened device\n");
584 static int pcipcwd_release(
struct inode *inode,
struct file *file)
589 if (expect_release == 42) {
592 pr_crit(
"Unexpected close, not stopping watchdog!\n");
604 static ssize_t pcipcwd_temp_read(
struct file *file,
char __user *data,
605 size_t len, loff_t *ppos)
609 if (pcipcwd_get_temperature(&temperature))
618 static int pcipcwd_temp_open(
struct inode *inode,
struct file *file)
620 if (!pcipcwd_private.supports_temp)
626 static int pcipcwd_temp_release(
struct inode *inode,
struct file *file)
651 .write = pcipcwd_write,
652 .unlocked_ioctl = pcipcwd_ioctl,
653 .open = pcipcwd_open,
654 .release = pcipcwd_release,
660 .fops = &pcipcwd_fops,
666 .read = pcipcwd_temp_read,
667 .open = pcipcwd_temp_open,
668 .release = pcipcwd_temp_release,
671 static struct miscdevice pcipcwd_temp_miscdev = {
673 .name =
"temperature",
674 .fops = &pcipcwd_temp_fops,
678 .notifier_call = pcipcwd_notify_sys,
691 if (cards_found == 1)
694 if (cards_found > 1) {
695 pr_err(
"This driver only supports 1 device\n");
700 pr_err(
"Not possible to enable PCI Device\n");
705 pr_err(
"No I/O-Address for card detected\n");
707 goto err_out_disable_device;
711 pcipcwd_private.pdev = pdev;
715 pr_err(
"I/O address 0x%04x already in use\n",
716 (
int) pcipcwd_private.io_addr);
718 goto err_out_disable_device;
722 pcipcwd_get_status(&pcipcwd_private.boot_status);
725 pcipcwd_clear_status();
731 pcipcwd_check_temperature_support();
734 pcipcwd_show_card_info();
739 heartbeat_tbl[(pcipcwd_get_option_switches() & 0x07)];
745 pr_info(
"heartbeat value must be 0<heartbeat<65536, using %d\n",
751 pr_err(
"cannot register reboot notifier (err=%d)\n", ret);
752 goto err_out_release_region;
755 if (pcipcwd_private.supports_temp) {
758 pr_err(
"cannot register miscdev on minor=%d (err=%d)\n",
760 goto err_out_unregister_reboot;
766 pr_err(
"cannot register miscdev on minor=%d (err=%d)\n",
768 goto err_out_misc_deregister;
771 pr_info(
"initialized. heartbeat=%d sec (nowayout=%d)\n",
776 err_out_misc_deregister:
777 if (pcipcwd_private.supports_temp)
779 err_out_unregister_reboot:
781 err_out_release_region:
783 err_out_disable_device:
796 if (pcipcwd_private.supports_temp)
813 .id_table = pcipcwd_pci_tbl,
814 .probe = pcipcwd_card_init,