···11451145config BOOKE_WDT11461146 tristate "PowerPC Book-E Watchdog Timer"11471147 depends on BOOKE || 4xx11481148+ select WATCHDOG_CORE11481149 ---help---11491150 Watchdog driver for PowerPC Book-E chips, such as the Freescale11501151 MPC85xx SOCs and the IBM PowerPC 440.
+75-130
drivers/watchdog/booke_wdt.c
···1515#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt16161717#include <linux/module.h>1818-#include <linux/fs.h>1918#include <linux/smp.h>2020-#include <linux/miscdevice.h>2121-#include <linux/notifier.h>2219#include <linux/watchdog.h>2323-#include <linux/uaccess.h>24202521#include <asm/reg_booke.h>2622#include <asm/time.h>···4145#define WDTP_MASK (TCR_WP_MASK)4246#endif43474444-static DEFINE_SPINLOCK(booke_wdt_lock);4848+#ifdef CONFIG_PPC_FSL_BOOK3E45494650/* For the specified period, determine the number of seconds4751 * corresponding to the reset time. There will be a watchdog···8286 return 0;8387}84888989+#define MAX_WDT_TIMEOUT period_to_sec(1)9090+9191+#else /* CONFIG_PPC_FSL_BOOK3E */9292+9393+static unsigned long long period_to_sec(unsigned int period)9494+{9595+ return period;9696+}9797+9898+static unsigned int sec_to_period(unsigned int secs)9999+{100100+ return secs;101101+}102102+103103+#define MAX_WDT_TIMEOUT 3 /* from Kconfig */104104+105105+#endif /* !CONFIG_PPC_FSL_BOOK3E */106106+85107static void __booke_wdt_set(void *data)86108{87109 u32 val;···121107 mtspr(SPRN_TSR, TSR_ENW|TSR_WIS);122108}123109124124-static void booke_wdt_ping(void)110110+static int booke_wdt_ping(struct watchdog_device *wdog)125111{126112 on_each_cpu(__booke_wdt_ping, NULL, 0);113113+114114+ return 0;127115}128116129117static void __booke_wdt_enable(void *data)···162146163147}164148165165-static ssize_t booke_wdt_write(struct file *file, const char __user *buf,166166- size_t count, loff_t *ppos)149149+static void __booke_wdt_start(struct watchdog_device *wdog)167150{168168- booke_wdt_ping();169169- return count;151151+ on_each_cpu(__booke_wdt_enable, NULL, 0);152152+ pr_debug("watchdog enabled (timeout = %u sec)\n", wdog->timeout);170153}171154172172-static struct watchdog_info ident = {155155+static int booke_wdt_start(struct watchdog_device *wdog)156156+{157157+ if (booke_wdt_enabled == 0) {158158+ booke_wdt_enabled = 1;159159+ __booke_wdt_start(wdog);160160+ }161161+ return 0;162162+}163163+164164+static int booke_wdt_stop(struct watchdog_device *wdog)165165+{166166+ on_each_cpu(__booke_wdt_disable, NULL, 0);167167+ booke_wdt_enabled = 0;168168+ pr_debug("watchdog disabled\n");169169+170170+ return 0;171171+}172172+173173+static int booke_wdt_set_timeout(struct watchdog_device *wdt_dev,174174+ unsigned int timeout)175175+{176176+ if (timeout > MAX_WDT_TIMEOUT)177177+ return -EINVAL;178178+ booke_wdt_period = sec_to_period(timeout);179179+ wdt_dev->timeout = timeout;180180+ booke_wdt_set();181181+182182+ return 0;183183+}184184+185185+static struct watchdog_info booke_wdt_info = {173186 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,174187 .identity = "PowerPC Book-E Watchdog",175188};176189177177-static long booke_wdt_ioctl(struct file *file,178178- unsigned int cmd, unsigned long arg)179179-{180180- u32 tmp = 0;181181- u32 __user *p = (u32 __user *)arg;182182-183183- switch (cmd) {184184- case WDIOC_GETSUPPORT:185185- return copy_to_user(p, &ident, sizeof(ident)) ? -EFAULT : 0;186186- case WDIOC_GETSTATUS:187187- return put_user(0, p);188188- case WDIOC_GETBOOTSTATUS:189189- /* XXX: something is clearing TSR */190190- tmp = mfspr(SPRN_TSR) & TSR_WRS(3);191191- /* returns CARDRESET if last reset was caused by the WDT */192192- return put_user((tmp ? WDIOF_CARDRESET : 0), p);193193- case WDIOC_SETOPTIONS:194194- if (get_user(tmp, p))195195- return -EFAULT;196196- if (tmp == WDIOS_ENABLECARD) {197197- booke_wdt_ping();198198- break;199199- } else200200- return -EINVAL;201201- return 0;202202- case WDIOC_KEEPALIVE:203203- booke_wdt_ping();204204- return 0;205205- case WDIOC_SETTIMEOUT:206206- if (get_user(tmp, p))207207- return -EFAULT;208208-#ifdef CONFIG_PPC_FSL_BOOK3E209209- /* period of 1 gives the largest possible timeout */210210- if (tmp > period_to_sec(1))211211- return -EINVAL;212212- booke_wdt_period = sec_to_period(tmp);213213-#else214214- booke_wdt_period = tmp;215215-#endif216216- booke_wdt_set();217217- /* Fall */218218- case WDIOC_GETTIMEOUT:219219-#ifdef CONFIG_FSL_BOOKE220220- return put_user(period_to_sec(booke_wdt_period), p);221221-#else222222- return put_user(booke_wdt_period, p);223223-#endif224224- default:225225- return -ENOTTY;226226- }227227-228228- return 0;229229-}230230-231231-/* wdt_is_active stores whether or not the /dev/watchdog device is opened */232232-static unsigned long wdt_is_active;233233-234234-static int booke_wdt_open(struct inode *inode, struct file *file)235235-{236236- /* /dev/watchdog can only be opened once */237237- if (test_and_set_bit(0, &wdt_is_active))238238- return -EBUSY;239239-240240- spin_lock(&booke_wdt_lock);241241- if (booke_wdt_enabled == 0) {242242- booke_wdt_enabled = 1;243243- on_each_cpu(__booke_wdt_enable, NULL, 0);244244- pr_debug("watchdog enabled (timeout = %llu sec)\n",245245- period_to_sec(booke_wdt_period));246246- }247247- spin_unlock(&booke_wdt_lock);248248-249249- return nonseekable_open(inode, file);250250-}251251-252252-static int booke_wdt_release(struct inode *inode, struct file *file)253253-{254254-#ifndef CONFIG_WATCHDOG_NOWAYOUT255255- /* Normally, the watchdog is disabled when /dev/watchdog is closed, but256256- * if CONFIG_WATCHDOG_NOWAYOUT is defined, then it means that the257257- * watchdog should remain enabled. So we disable it only if258258- * CONFIG_WATCHDOG_NOWAYOUT is not defined.259259- */260260- on_each_cpu(__booke_wdt_disable, NULL, 0);261261- booke_wdt_enabled = 0;262262- pr_debug("watchdog disabled\n");263263-#endif264264-265265- clear_bit(0, &wdt_is_active);266266-267267- return 0;268268-}269269-270270-static const struct file_operations booke_wdt_fops = {190190+static struct watchdog_ops booke_wdt_ops = {271191 .owner = THIS_MODULE,272272- .llseek = no_llseek,273273- .write = booke_wdt_write,274274- .unlocked_ioctl = booke_wdt_ioctl,275275- .open = booke_wdt_open,276276- .release = booke_wdt_release,192192+ .start = booke_wdt_start,193193+ .stop = booke_wdt_stop,194194+ .ping = booke_wdt_ping,195195+ .set_timeout = booke_wdt_set_timeout,277196};278197279279-static struct miscdevice booke_wdt_miscdev = {280280- .minor = WATCHDOG_MINOR,281281- .name = "watchdog",282282- .fops = &booke_wdt_fops,198198+static struct watchdog_device booke_wdt_dev = {199199+ .info = &booke_wdt_info,200200+ .ops = &booke_wdt_ops,201201+ .min_timeout = 1,202202+ .max_timeout = 0xFFFF283203};284204285205static void __exit booke_wdt_exit(void)286206{287287- misc_deregister(&booke_wdt_miscdev);207207+ watchdog_unregister_device(&booke_wdt_dev);288208}289209290210static int __init booke_wdt_init(void)291211{292212 int ret = 0;213213+ bool nowayout = WATCHDOG_NOWAYOUT;293214294215 pr_info("powerpc book-e watchdog driver loaded\n");295295- ident.firmware_version = cur_cpu_spec->pvr_value;216216+ booke_wdt_info.firmware_version = cur_cpu_spec->pvr_value;217217+ booke_wdt_set_timeout(&booke_wdt_dev,218218+ period_to_sec(CONFIG_BOOKE_WDT_DEFAULT_TIMEOUT));219219+ watchdog_set_nowayout(&booke_wdt_dev, nowayout);220220+ if (booke_wdt_enabled)221221+ __booke_wdt_start(&booke_wdt_dev);296222297297- ret = misc_register(&booke_wdt_miscdev);298298- if (ret) {299299- pr_err("cannot register device (minor=%u, ret=%i)\n",300300- WATCHDOG_MINOR, ret);301301- return ret;302302- }303303-304304- spin_lock(&booke_wdt_lock);305305- if (booke_wdt_enabled == 1) {306306- pr_info("watchdog enabled (timeout = %llu sec)\n",307307- period_to_sec(booke_wdt_period));308308- on_each_cpu(__booke_wdt_enable, NULL, 0);309309- }310310- spin_unlock(&booke_wdt_lock);223223+ ret = watchdog_register_device(&booke_wdt_dev);311224312225 return ret;313226}