static void wdt_reloading_timer (unsigned long unused) { at91_wdt_reload(); mod_timer(&wdt_timer, jiffies + WDT_RELOAD_DELAY); if(reload_flag == 0 && time_flag == 1) { time_flag = 0; wdt_timeout = 3; if (at91_wdt_settimeout(wdt_timeout) == -EINVAL) { at91_wdt_reload(); pr_info("at91sam9_wdt: invalid timeout (must be between 1 and %d)\n", WDT_MAX_TIME); } } else if (reload_flag > 0) { reload_flag --; } else; }
/* * Change the watchdog time interval. */ static int at91_wdt_settimeout(int new_time) { unsigned int reg, mr; /* * All counting occurs at SLOW_CLOCK / 128 = 256 Hz * * Since WDV is a 12-bit counter, the maximum period is * 4096 / 256 = 16 seconds. */ if ((new_time <= 0) || (new_time > WDT_MAX_TIME)) { mr = at91_sys_read(AT91_WDT_MR); return -EINVAL; } wdt_timeout = new_time; if(mtd_id == 0x7f) { /* Program the Watchdog */ reg = AT91_WDT_WDRSTEN /* causes watchdog reset */ | AT91_WDT_WDRPROC /* causes processor reset if useing this register, it will effect to flash functions. */ | AT91_WDT_WDDBGHLT /* disabled in debug mode */ | AT91_WDT_WDD /* restart at any time */ | (((wdt_timeout * 256) - 1) & AT91_WDT_WDV); /* timer value */ at91_sys_write(AT91_WDT_MR, reg); } else { /* Program the Watchdog */ reg = AT91_WDT_WDRSTEN /* causes watchdog reset */ // | AT91_WDT_WDRPROC /* causes processor reset if useing this register, it will effect to flash functions. */ | AT91_WDT_WDDBGHLT /* disabled in debug mode */ | AT91_WDT_WDD /* restart at any time */ | (((wdt_timeout * 256) - 1) & AT91_WDT_WDV); /* timer value */ at91_sys_write(AT91_WDT_MR, reg); } /* Check if watchdog could be programmed */ mr = at91_sys_read(AT91_WDT_MR); if (mr != reg) { printk(KERN_ERR "at91sam9_wdt: Watchdog register already programmed.\n"); return -EIO; } at91_wdt_reload(); printk(KERN_INFO "AT91SAM9 Watchdog enabled (%d seconds, nowayout = 0x%x )\n", wdt_timeout,mr); return 0; }
static int __init at91wdt_probe(struct platform_device *pdev) { int res; if (at91wdt_miscdev.parent) return -EBUSY; at91wdt_miscdev.parent = &pdev->dev; res = misc_register(&at91wdt_miscdev); if (res) return res; /* Set watchdog */ if (at91_wdt_settimeout(wdt_timeout) == -EINVAL) { at91_wdt_reload(); pr_info("at91sam9_wdt: invalid timeout (must be between 1 and %d)\n", WDT_MAX_TIME); return 0; } return 0; }
/* * Handle commands from user-space. */ static int at91_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { void __user *argp = (void __user *)arg; int __user *p = argp; int new_value, err; switch (cmd) { case WDIOC_KEEPALIVE: at91_wdt_reload(); /* pat the watchdog */ return 0; case WDIOC_GETSUPPORT: return copy_to_user(argp, &at91_wdt_info, sizeof(at91_wdt_info)) ? -EFAULT : 0; case WDIOC_SETTIMEOUT: if (get_user(new_value, p)) { return -EFAULT; } err = at91_wdt_settimeout(new_value); if (err) return err; return put_user(wdt_timeout, p); /* return current value */ case WDIOC_GETTIMEOUT: return put_user(wdt_timeout, p); case WDIOC_GETSTATUS: case WDIOC_GETBOOTSTATUS: return put_user(0, p); } return -ENOTTY; }
static void wdt_reloading_timer (unsigned long unused) { at91_wdt_reload(); mod_timer(&wdt_timer, jiffies + WDT_RELOAD_DELAY); }
/* * Pat the watchdog whenever device is written to. */ static ssize_t at91_wdt_write(struct file *file, const char *data, size_t len, loff_t *ppos) { at91_wdt_reload(); /* pat the watchdog */ return len; }