static long s3c2410wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { void __user *argp = (void __user *)arg; int __user *p = argp; int new_margin; switch (cmd) { case WDIOC_GETSUPPORT: return copy_to_user(argp, &s3c2410_wdt_ident, sizeof(s3c2410_wdt_ident)) ? -EFAULT : 0; case WDIOC_GETSTATUS: case WDIOC_GETBOOTSTATUS: return put_user(0, p); case WDIOC_KEEPALIVE: s3c2410wdt_keepalive(); return 0; case WDIOC_SETTIMEOUT: if (get_user(new_margin, p)) return -EFAULT; if (s3c2410wdt_set_heartbeat(new_margin)) return -EINVAL; s3c2410wdt_keepalive(); return put_user(tmr_margin, p); case WDIOC_GETTIMEOUT: return put_user(tmr_margin, p); default: return -ENOTTY; } }
static int s3c2410wdt_cpufreq_transition(struct notifier_block *nb, unsigned long val, void *data) { if (!s3c2410wdt_is_running()) return 0; if (val == CPUFREQ_PRECHANGE) { /* To ensure that over the change we don't cause the * watchdog to trigger, we perform an keep-alive if * the watchdog is running. */ s3c2410wdt_keepalive(&s3c2410_wdd); } else if (val == CPUFREQ_POSTCHANGE) { /* Exynos4 do not change pclk freq after boot, so don't need to do this */ #if !defined (CONFIG_MX_SERIAL_TYPE) && !defined(CONFIG_MX2_SERIAL_TYPE) int ret; s3c2410wdt_stop(&s3c2410_wdd); ret = s3c2410wdt_set_heartbeat(&s3c2410_wdd, s3c2410_wdd.timeout); if (ret >= 0) { s3c2410wdt_start(&s3c2410_wdd); } else { dev_err(wdt_dev, "cannot set new value for timeout %d\n", s3c2410_wdd.timeout); return ret; } #endif } return 0; }
static irqreturn_t s3c2410wdt_irq(int irqno, void *param) { dev_info(wdt_dev, "watchdog timer expired (irq)\n"); s3c2410wdt_keepalive(&s3c2410_wdd); return IRQ_HANDLED; }
static ssize_t s3c2410wdt_write(struct file *file, const char __user *data, size_t len, loff_t *ppos) { /* * Refresh the timer. */ if(len) { if (!nowayout) { size_t i; /* In case it was set long ago */ allow_close = CLOSE_STATE_NOT; for (i = 0; i != len; i++) { char c; if (get_user(c, data + i)) return -EFAULT; if (c == 'V') allow_close = CLOSE_STATE_ALLOW; } } s3c2410wdt_keepalive(); } return len; }
static int s3c2410wdt_cpufreq_transition(struct notifier_block *nb, unsigned long val, void *data) { int ret; if (!s3c2410wdt_is_running()) goto done; if (val == CPUFREQ_PRECHANGE) { /* To ensure that over the change we don't cause the * watchdog to trigger, we perform an keep-alive if * the watchdog is running. */ s3c2410wdt_keepalive(&s3c2410_wdd); } else if (val == CPUFREQ_POSTCHANGE) { s3c2410wdt_stop(&s3c2410_wdd); ret = s3c2410wdt_set_heartbeat(&s3c2410_wdd, s3c2410_wdd.timeout); if (ret >= 0) s3c2410wdt_start(&s3c2410_wdd); else goto err; } done: return 0; err: dev_err(wdt_dev, "cannot set new value for timeout %d\n", s3c2410_wdd.timeout); return ret; }
static irqreturn_t s3c2410wdt_irq(int irqno, void *param, struct pt_regs *regs) { printk(KERN_INFO PFX "Watchdog timer expired!\n"); s3c2410wdt_keepalive(); return IRQ_HANDLED; }
static int watchdog_thread(void *data) { pr_info("%s: Enter into watchdog_thread\n", __func__); while (1) { pr_debug("%s: feed the watchdog\n", __func__); s3c2410wdt_keepalive(&s3c2410_wdd); schedule_timeout_interruptible(HZ); } return 0; }
static irqreturn_t s3c2410wdt_irq(int irqno, void *param) { dev_info(wdt_dev, "watchdog timer expired (irq)\n"); s3c2410wdt_keepalive(&s3c2410_wdd); /* Clear the interrupt */ __raw_writel(0xff, wdt_base + S3C2410_WTCLRINT); /* Print backtrace of all cpus. */ handle_sysrq('l'); return IRQ_HANDLED; }
static int watchdog_thread(void *data) { unsigned int keepalive_cycle = tmr_margin / 2; pr_info("%s: Enter into watchdog_thread\n", __func__); while (1) { msleep_interruptible(keepalive_cycle * 1000); pr_debug("%s: feed the watchdog\n", __func__); s3c2410wdt_keepalive(&s3c2410_wdd); } return 0; }
static int s3c2410wdt_release(struct inode *inode, struct file *file) { /* * Shut off the timer. * Lock it in if it's a module and we set nowayout */ if (allow_close == CLOSE_STATE_ALLOW) { s3c2410wdt_stop(); } else { printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); s3c2410wdt_keepalive(); } allow_close = CLOSE_STATE_NOT; up(&open_lock); return 0; }
static int s3c2410wdt_release(struct inode *inode, struct file *file) { /* * Shut off the timer. * Lock it in if it's a module and we set nowayout */ if (expect_close == 42) s3c2410wdt_stop(); else { dev_err(wdt_dev, "Unexpected close, not stopping watchdog\n"); s3c2410wdt_keepalive(); } expect_close = 0; clear_bit(0, &open_lock); return 0; }
static irqreturn_t s3c2410wdt_irq(int irqno, void *param) { dev_info(wdt_dev, "watchdog timer expired (irq)\n"); s3c2410wdt_keepalive(&s3c2410_wdd); /* Clear the interrupt */ s3c2410wdt_int_clear(&s3c2410_wdd); /* Print backtrace of all cpus. */ handle_sysrq('l'); /* Restart for availability */ pr_info("%s: emergency reboot\n", __func__); emergency_restart(); return IRQ_HANDLED; }
static int wdt_thread(void *arg) { int ret = 0; int ms = (tmr_margin*1000)>>1; DEBG("--- enter WATCHDOG KTHREAD ---\n"); while (1) { // check whether we should exit or not if(kthread_should_stop()){ DEBG("--- WATCHDOG KTHREAD should stop ---\n"); break; } s3c2410wdt_keepalive(); DEBG("--- feed the s3c2410 watchdog before timeout = %d ---\n", tmr_margin); msleep(ms); } DEBG("--- exit WATCHDOG KTHREAD ---\n"); return ret; }
void touch_s3c2410wdt(void) { s3c2410wdt_keepalive(&s3c2410_wdd); }