Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *  W83977F Watchdog Timer Driver for Winbond W83977F I/O Chip
0004  *
0005  *  (c) Copyright 2005  Jose Goncalves <jose.goncalves@inov.pt>
0006  *
0007  *      Based on w83877f_wdt.c by Scott Jennings,
0008  *           and wdt977.c by Woody Suwalski
0009  *
0010  *          -----------------------
0011  */
0012 
0013 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0014 
0015 #include <linux/module.h>
0016 #include <linux/moduleparam.h>
0017 #include <linux/types.h>
0018 #include <linux/kernel.h>
0019 #include <linux/fs.h>
0020 #include <linux/miscdevice.h>
0021 #include <linux/init.h>
0022 #include <linux/ioport.h>
0023 #include <linux/watchdog.h>
0024 #include <linux/notifier.h>
0025 #include <linux/reboot.h>
0026 #include <linux/uaccess.h>
0027 #include <linux/io.h>
0028 
0029 
0030 #define WATCHDOG_VERSION  "1.00"
0031 #define WATCHDOG_NAME     "W83977F WDT"
0032 
0033 #define IO_INDEX_PORT     0x3F0
0034 #define IO_DATA_PORT      (IO_INDEX_PORT+1)
0035 
0036 #define UNLOCK_DATA       0x87
0037 #define LOCK_DATA         0xAA
0038 #define DEVICE_REGISTER   0x07
0039 
0040 #define DEFAULT_TIMEOUT   45        /* default timeout in seconds */
0041 
0042 static  int timeout = DEFAULT_TIMEOUT;
0043 static  int timeoutW;           /* timeout in watchdog counter units */
0044 static  unsigned long timer_alive;
0045 static  int testmode;
0046 static  char expect_close;
0047 static  DEFINE_SPINLOCK(spinlock);
0048 
0049 module_param(timeout, int, 0);
0050 MODULE_PARM_DESC(timeout,
0051         "Watchdog timeout in seconds (15..7635), default="
0052                 __MODULE_STRING(DEFAULT_TIMEOUT) ")");
0053 module_param(testmode, int, 0);
0054 MODULE_PARM_DESC(testmode, "Watchdog testmode (1 = no reboot), default=0");
0055 
0056 static bool nowayout = WATCHDOG_NOWAYOUT;
0057 module_param(nowayout, bool, 0);
0058 MODULE_PARM_DESC(nowayout,
0059         "Watchdog cannot be stopped once started (default="
0060                 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
0061 
0062 /*
0063  * Start the watchdog
0064  */
0065 
0066 static int wdt_start(void)
0067 {
0068     unsigned long flags;
0069 
0070     spin_lock_irqsave(&spinlock, flags);
0071 
0072     /* Unlock the SuperIO chip */
0073     outb_p(UNLOCK_DATA, IO_INDEX_PORT);
0074     outb_p(UNLOCK_DATA, IO_INDEX_PORT);
0075 
0076     /*
0077      * Select device Aux2 (device=8) to set watchdog regs F2, F3 and F4.
0078      * F2 has the timeout in watchdog counter units.
0079      * F3 is set to enable watchdog LED blink at timeout.
0080      * F4 is used to just clear the TIMEOUT'ed state (bit 0).
0081      */
0082     outb_p(DEVICE_REGISTER, IO_INDEX_PORT);
0083     outb_p(0x08, IO_DATA_PORT);
0084     outb_p(0xF2, IO_INDEX_PORT);
0085     outb_p(timeoutW, IO_DATA_PORT);
0086     outb_p(0xF3, IO_INDEX_PORT);
0087     outb_p(0x08, IO_DATA_PORT);
0088     outb_p(0xF4, IO_INDEX_PORT);
0089     outb_p(0x00, IO_DATA_PORT);
0090 
0091     /* Set device Aux2 active */
0092     outb_p(0x30, IO_INDEX_PORT);
0093     outb_p(0x01, IO_DATA_PORT);
0094 
0095     /*
0096      * Select device Aux1 (dev=7) to set GP16 as the watchdog output
0097      * (in reg E6) and GP13 as the watchdog LED output (in reg E3).
0098      * Map GP16 at pin 119.
0099      * In test mode watch the bit 0 on F4 to indicate "triggered" or
0100      * check watchdog LED on SBC.
0101      */
0102     outb_p(DEVICE_REGISTER, IO_INDEX_PORT);
0103     outb_p(0x07, IO_DATA_PORT);
0104     if (!testmode) {
0105         unsigned pin_map;
0106 
0107         outb_p(0xE6, IO_INDEX_PORT);
0108         outb_p(0x0A, IO_DATA_PORT);
0109         outb_p(0x2C, IO_INDEX_PORT);
0110         pin_map = inb_p(IO_DATA_PORT);
0111         pin_map |= 0x10;
0112         pin_map &= ~(0x20);
0113         outb_p(0x2C, IO_INDEX_PORT);
0114         outb_p(pin_map, IO_DATA_PORT);
0115     }
0116     outb_p(0xE3, IO_INDEX_PORT);
0117     outb_p(0x08, IO_DATA_PORT);
0118 
0119     /* Set device Aux1 active */
0120     outb_p(0x30, IO_INDEX_PORT);
0121     outb_p(0x01, IO_DATA_PORT);
0122 
0123     /* Lock the SuperIO chip */
0124     outb_p(LOCK_DATA, IO_INDEX_PORT);
0125 
0126     spin_unlock_irqrestore(&spinlock, flags);
0127 
0128     pr_info("activated\n");
0129 
0130     return 0;
0131 }
0132 
0133 /*
0134  * Stop the watchdog
0135  */
0136 
0137 static int wdt_stop(void)
0138 {
0139     unsigned long flags;
0140 
0141     spin_lock_irqsave(&spinlock, flags);
0142 
0143     /* Unlock the SuperIO chip */
0144     outb_p(UNLOCK_DATA, IO_INDEX_PORT);
0145     outb_p(UNLOCK_DATA, IO_INDEX_PORT);
0146 
0147     /*
0148      * Select device Aux2 (device=8) to set watchdog regs F2, F3 and F4.
0149      * F2 is reset to its default value (watchdog timer disabled).
0150      * F3 is reset to its default state.
0151      * F4 clears the TIMEOUT'ed state (bit 0) - back to default.
0152      */
0153     outb_p(DEVICE_REGISTER, IO_INDEX_PORT);
0154     outb_p(0x08, IO_DATA_PORT);
0155     outb_p(0xF2, IO_INDEX_PORT);
0156     outb_p(0xFF, IO_DATA_PORT);
0157     outb_p(0xF3, IO_INDEX_PORT);
0158     outb_p(0x00, IO_DATA_PORT);
0159     outb_p(0xF4, IO_INDEX_PORT);
0160     outb_p(0x00, IO_DATA_PORT);
0161     outb_p(0xF2, IO_INDEX_PORT);
0162     outb_p(0x00, IO_DATA_PORT);
0163 
0164     /*
0165      * Select device Aux1 (dev=7) to set GP16 (in reg E6) and
0166      * Gp13 (in reg E3) as inputs.
0167      */
0168     outb_p(DEVICE_REGISTER, IO_INDEX_PORT);
0169     outb_p(0x07, IO_DATA_PORT);
0170     if (!testmode) {
0171         outb_p(0xE6, IO_INDEX_PORT);
0172         outb_p(0x01, IO_DATA_PORT);
0173     }
0174     outb_p(0xE3, IO_INDEX_PORT);
0175     outb_p(0x01, IO_DATA_PORT);
0176 
0177     /* Lock the SuperIO chip */
0178     outb_p(LOCK_DATA, IO_INDEX_PORT);
0179 
0180     spin_unlock_irqrestore(&spinlock, flags);
0181 
0182     pr_info("shutdown\n");
0183 
0184     return 0;
0185 }
0186 
0187 /*
0188  * Send a keepalive ping to the watchdog
0189  * This is done by simply re-writing the timeout to reg. 0xF2
0190  */
0191 
0192 static int wdt_keepalive(void)
0193 {
0194     unsigned long flags;
0195 
0196     spin_lock_irqsave(&spinlock, flags);
0197 
0198     /* Unlock the SuperIO chip */
0199     outb_p(UNLOCK_DATA, IO_INDEX_PORT);
0200     outb_p(UNLOCK_DATA, IO_INDEX_PORT);
0201 
0202     /* Select device Aux2 (device=8) to kick watchdog reg F2 */
0203     outb_p(DEVICE_REGISTER, IO_INDEX_PORT);
0204     outb_p(0x08, IO_DATA_PORT);
0205     outb_p(0xF2, IO_INDEX_PORT);
0206     outb_p(timeoutW, IO_DATA_PORT);
0207 
0208     /* Lock the SuperIO chip */
0209     outb_p(LOCK_DATA, IO_INDEX_PORT);
0210 
0211     spin_unlock_irqrestore(&spinlock, flags);
0212 
0213     return 0;
0214 }
0215 
0216 /*
0217  * Set the watchdog timeout value
0218  */
0219 
0220 static int wdt_set_timeout(int t)
0221 {
0222     unsigned int tmrval;
0223 
0224     /*
0225      * Convert seconds to watchdog counter time units, rounding up.
0226      * On PCM-5335 watchdog units are 30 seconds/step with 15 sec startup
0227      * value. This information is supplied in the PCM-5335 manual and was
0228      * checked by me on a real board. This is a bit strange because W83977f
0229      * datasheet says counter unit is in minutes!
0230      */
0231     if (t < 15)
0232         return -EINVAL;
0233 
0234     tmrval = ((t + 15) + 29) / 30;
0235 
0236     if (tmrval > 255)
0237         return -EINVAL;
0238 
0239     /*
0240      * timeout is the timeout in seconds,
0241      * timeoutW is the timeout in watchdog counter units.
0242      */
0243     timeoutW = tmrval;
0244     timeout = (timeoutW * 30) - 15;
0245     return 0;
0246 }
0247 
0248 /*
0249  * Get the watchdog status
0250  */
0251 
0252 static int wdt_get_status(int *status)
0253 {
0254     int new_status;
0255     unsigned long flags;
0256 
0257     spin_lock_irqsave(&spinlock, flags);
0258 
0259     /* Unlock the SuperIO chip */
0260     outb_p(UNLOCK_DATA, IO_INDEX_PORT);
0261     outb_p(UNLOCK_DATA, IO_INDEX_PORT);
0262 
0263     /* Select device Aux2 (device=8) to read watchdog reg F4 */
0264     outb_p(DEVICE_REGISTER, IO_INDEX_PORT);
0265     outb_p(0x08, IO_DATA_PORT);
0266     outb_p(0xF4, IO_INDEX_PORT);
0267     new_status = inb_p(IO_DATA_PORT);
0268 
0269     /* Lock the SuperIO chip */
0270     outb_p(LOCK_DATA, IO_INDEX_PORT);
0271 
0272     spin_unlock_irqrestore(&spinlock, flags);
0273 
0274     *status = 0;
0275     if (new_status & 1)
0276         *status |= WDIOF_CARDRESET;
0277 
0278     return 0;
0279 }
0280 
0281 
0282 /*
0283  *  /dev/watchdog handling
0284  */
0285 
0286 static int wdt_open(struct inode *inode, struct file *file)
0287 {
0288     /* If the watchdog is alive we don't need to start it again */
0289     if (test_and_set_bit(0, &timer_alive))
0290         return -EBUSY;
0291 
0292     if (nowayout)
0293         __module_get(THIS_MODULE);
0294 
0295     wdt_start();
0296     return stream_open(inode, file);
0297 }
0298 
0299 static int wdt_release(struct inode *inode, struct file *file)
0300 {
0301     /*
0302      * Shut off the timer.
0303      * Lock it in if it's a module and we set nowayout
0304      */
0305     if (expect_close == 42) {
0306         wdt_stop();
0307         clear_bit(0, &timer_alive);
0308     } else {
0309         wdt_keepalive();
0310         pr_crit("unexpected close, not stopping watchdog!\n");
0311     }
0312     expect_close = 0;
0313     return 0;
0314 }
0315 
0316 /*
0317  *      wdt_write:
0318  *      @file: file handle to the watchdog
0319  *      @buf: buffer to write (unused as data does not matter here
0320  *      @count: count of bytes
0321  *      @ppos: pointer to the position to write. No seeks allowed
0322  *
0323  *      A write to a watchdog device is defined as a keepalive signal. Any
0324  *      write of data will do, as we we don't define content meaning.
0325  */
0326 
0327 static ssize_t wdt_write(struct file *file, const char __user *buf,
0328                 size_t count, loff_t *ppos)
0329 {
0330     /* See if we got the magic character 'V' and reload the timer */
0331     if (count) {
0332         if (!nowayout) {
0333             size_t ofs;
0334 
0335             /* note: just in case someone wrote the
0336                magic character long ago */
0337             expect_close = 0;
0338 
0339             /* scan to see whether or not we got the
0340                magic character */
0341             for (ofs = 0; ofs != count; ofs++) {
0342                 char c;
0343                 if (get_user(c, buf + ofs))
0344                     return -EFAULT;
0345                 if (c == 'V')
0346                     expect_close = 42;
0347             }
0348         }
0349 
0350         /* someone wrote to us, we should restart timer */
0351         wdt_keepalive();
0352     }
0353     return count;
0354 }
0355 
0356 /*
0357  *      wdt_ioctl:
0358  *      @inode: inode of the device
0359  *      @file: file handle to the device
0360  *      @cmd: watchdog command
0361  *      @arg: argument pointer
0362  *
0363  *      The watchdog API defines a common set of functions for all watchdogs
0364  *      according to their available features.
0365  */
0366 
0367 static const struct watchdog_info ident = {
0368     .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING,
0369     .firmware_version = 1,
0370     .identity = WATCHDOG_NAME,
0371 };
0372 
0373 static long wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
0374 {
0375     int status;
0376     int new_options, retval = -EINVAL;
0377     int new_timeout;
0378     union {
0379         struct watchdog_info __user *ident;
0380         int __user *i;
0381     } uarg;
0382 
0383     uarg.i = (int __user *)arg;
0384 
0385     switch (cmd) {
0386     case WDIOC_GETSUPPORT:
0387         return copy_to_user(uarg.ident, &ident,
0388                         sizeof(ident)) ? -EFAULT : 0;
0389 
0390     case WDIOC_GETSTATUS:
0391         wdt_get_status(&status);
0392         return put_user(status, uarg.i);
0393 
0394     case WDIOC_GETBOOTSTATUS:
0395         return put_user(0, uarg.i);
0396 
0397     case WDIOC_SETOPTIONS:
0398         if (get_user(new_options, uarg.i))
0399             return -EFAULT;
0400 
0401         if (new_options & WDIOS_DISABLECARD) {
0402             wdt_stop();
0403             retval = 0;
0404         }
0405 
0406         if (new_options & WDIOS_ENABLECARD) {
0407             wdt_start();
0408             retval = 0;
0409         }
0410 
0411         return retval;
0412 
0413     case WDIOC_KEEPALIVE:
0414         wdt_keepalive();
0415         return 0;
0416 
0417     case WDIOC_SETTIMEOUT:
0418         if (get_user(new_timeout, uarg.i))
0419             return -EFAULT;
0420 
0421         if (wdt_set_timeout(new_timeout))
0422             return -EINVAL;
0423 
0424         wdt_keepalive();
0425         fallthrough;
0426 
0427     case WDIOC_GETTIMEOUT:
0428         return put_user(timeout, uarg.i);
0429 
0430     default:
0431         return -ENOTTY;
0432 
0433     }
0434 }
0435 
0436 static int wdt_notify_sys(struct notifier_block *this, unsigned long code,
0437     void *unused)
0438 {
0439     if (code == SYS_DOWN || code == SYS_HALT)
0440         wdt_stop();
0441     return NOTIFY_DONE;
0442 }
0443 
0444 static const struct file_operations wdt_fops = {
0445     .owner      = THIS_MODULE,
0446     .llseek     = no_llseek,
0447     .write      = wdt_write,
0448     .unlocked_ioctl = wdt_ioctl,
0449     .compat_ioctl   = compat_ptr_ioctl,
0450     .open       = wdt_open,
0451     .release    = wdt_release,
0452 };
0453 
0454 static struct miscdevice wdt_miscdev = {
0455     .minor      = WATCHDOG_MINOR,
0456     .name       = "watchdog",
0457     .fops       = &wdt_fops,
0458 };
0459 
0460 static struct notifier_block wdt_notifier = {
0461     .notifier_call = wdt_notify_sys,
0462 };
0463 
0464 static int __init w83977f_wdt_init(void)
0465 {
0466     int rc;
0467 
0468     pr_info("driver v%s\n", WATCHDOG_VERSION);
0469 
0470     /*
0471      * Check that the timeout value is within it's range;
0472      * if not reset to the default
0473      */
0474     if (wdt_set_timeout(timeout)) {
0475         wdt_set_timeout(DEFAULT_TIMEOUT);
0476         pr_info("timeout value must be 15 <= timeout <= 7635, using %d\n",
0477             DEFAULT_TIMEOUT);
0478     }
0479 
0480     if (!request_region(IO_INDEX_PORT, 2, WATCHDOG_NAME)) {
0481         pr_err("I/O address 0x%04x already in use\n", IO_INDEX_PORT);
0482         rc = -EIO;
0483         goto err_out;
0484     }
0485 
0486     rc = register_reboot_notifier(&wdt_notifier);
0487     if (rc) {
0488         pr_err("cannot register reboot notifier (err=%d)\n", rc);
0489         goto err_out_region;
0490     }
0491 
0492     rc = misc_register(&wdt_miscdev);
0493     if (rc) {
0494         pr_err("cannot register miscdev on minor=%d (err=%d)\n",
0495                wdt_miscdev.minor, rc);
0496         goto err_out_reboot;
0497     }
0498 
0499     pr_info("initialized. timeout=%d sec (nowayout=%d testmode=%d)\n",
0500         timeout, nowayout, testmode);
0501 
0502     return 0;
0503 
0504 err_out_reboot:
0505     unregister_reboot_notifier(&wdt_notifier);
0506 err_out_region:
0507     release_region(IO_INDEX_PORT, 2);
0508 err_out:
0509     return rc;
0510 }
0511 
0512 static void __exit w83977f_wdt_exit(void)
0513 {
0514     wdt_stop();
0515     misc_deregister(&wdt_miscdev);
0516     unregister_reboot_notifier(&wdt_notifier);
0517     release_region(IO_INDEX_PORT, 2);
0518 }
0519 
0520 module_init(w83977f_wdt_init);
0521 module_exit(w83977f_wdt_exit);
0522 
0523 MODULE_AUTHOR("Jose Goncalves <jose.goncalves@inov.pt>");
0524 MODULE_DESCRIPTION("Driver for watchdog timer in W83977F I/O chip");
0525 MODULE_LICENSE("GPL");