static unsigned int sec_to_period(unsigned int secs) { unsigned int period; for (period = 63; period > 0; period--) { if (period_to_sec(period) >= secs) return period; } return 0; }
static long booke_wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { u32 tmp = 0; u32 __user *p = (u32 __user *)arg; switch (cmd) { case WDIOC_GETSUPPORT: if (copy_to_user((void *)arg, &ident, sizeof(ident))) return -EFAULT; case WDIOC_GETSTATUS: return put_user(0, p); case WDIOC_GETBOOTSTATUS: /* XXX: something is clearing TSR */ tmp = mfspr(SPRN_TSR) & TSR_WRS(3); /* returns CARDRESET if last reset was caused by the WDT */ return (tmp ? WDIOF_CARDRESET : 0); case WDIOC_SETOPTIONS: if (get_user(tmp, p)) return -EINVAL; if (tmp == WDIOS_ENABLECARD) { booke_wdt_ping(); break; } else return -EINVAL; return 0; case WDIOC_KEEPALIVE: booke_wdt_ping(); return 0; case WDIOC_SETTIMEOUT: if (get_user(tmp, p)) return -EFAULT; #ifdef CONFIG_FSL_BOOKE /* period of 1 gives the largest possible timeout */ if (tmp > period_to_sec(1)) return -EINVAL; booke_wdt_period = sec_to_period(tmp); #else booke_wdt_period = tmp; #endif mtspr(SPRN_TCR, (mfspr(SPRN_TCR) & ~WDTP_MASK) | WDTP(booke_wdt_period)); return 0; case WDIOC_GETTIMEOUT: return put_user(booke_wdt_period, p); default: return -ENOTTY; } return 0; }
static int __init booke_wdt_init(void) { int ret = 0; bool nowayout = WATCHDOG_NOWAYOUT; pr_info("powerpc book-e watchdog driver loaded\n"); booke_wdt_info.firmware_version = cur_cpu_spec->pvr_value; booke_wdt_set_timeout(&booke_wdt_dev, period_to_sec(CONFIG_BOOKE_WDT_DEFAULT_TIMEOUT)); watchdog_set_nowayout(&booke_wdt_dev, nowayout); if (booke_wdt_enabled) __booke_wdt_start(&booke_wdt_dev); ret = watchdog_register_device(&booke_wdt_dev); return ret; }