static ssize_t mpcore_wdt_write(struct file *file, const char *data, size_t len, loff_t *ppos) { struct mpcore_wdt *wdt = file->private_data; /* * Refresh the timer. */ if (len) { if (!nowayout) { size_t i; /* In case it was set long ago */ wdt->expect_close = 0; for (i = 0; i != len; i++) { char c; if (get_user(c, data + i)) return -EFAULT; if (c == 'V') wdt->expect_close = 42; } } mpcore_wdt_keepalive(wdt); } return len; }
static void mpcore_wdt_start(struct mpcore_wdt *wdt) { dev_printk(KERN_INFO, wdt->dev, "enabling watchdog.\n"); /* This loads the count register but does NOT start the count yet */ mpcore_wdt_keepalive(wdt); if (mpcore_noboot) { /* Enable watchdog - prescale=256, watchdog mode=0, enable=1 */ writel(0x0000FF01, wdt->base + TWD_WDOG_CONTROL); } else { /* Enable watchdog - prescale=256, watchdog mode=1, enable=1 */ writel(0x0000FF09, wdt->base + TWD_WDOG_CONTROL); } }
static int mpcore_wdt_release(struct inode *inode, struct file *file) { struct mpcore_wdt *wdt = file->private_data; if (wdt->expect_close == 42) mpcore_wdt_stop(wdt); else { dev_printk(KERN_CRIT, wdt->dev, "unexpected close, not stopping watchdog!\n"); mpcore_wdt_keepalive(wdt); } clear_bit(0, &wdt->timer_alive); wdt->expect_close = 0; return 0; }
static void mpcore_wdt_start(struct mpcore_wdt *wdt) { dev_printk(KERN_INFO, wdt->dev, "enabling watchdog.\n"); spin_lock(&wdt_lock); mpcore_wdt_keepalive(wdt); if (mpcore_noboot) { writel(0x0000FF01, wdt->base + TWD_WDOG_CONTROL); } else { writel(0x0000FF09, wdt->base + TWD_WDOG_CONTROL); } spin_unlock(&wdt_lock); }
static int mpcore_wdt_release(struct inode *inode, struct file *file) { struct mpcore_wdt *wdt = file->private_data; /* * Shut off the timer. * Lock it in if it's a module and we set nowayout */ if (wdt->expect_close == 42) { mpcore_wdt_stop(wdt); } else { dev_printk(KERN_CRIT, wdt->dev, "unexpected close, not stopping watchdog!\n"); mpcore_wdt_keepalive(wdt); } clear_bit(0, &wdt->timer_alive); wdt->expect_close = 0; return 0; }
static void mpcore_wdt_start_fiq(struct mpcore_wdt *wdt) { //unsigned long flags; //int cpu = 0; //mpcore_wdt_print("start watchdog.\n"); /* This loads the count register but does NOT start the count yet */ mpcore_wdt_keepalive(wdt); //spin_lock_irqsave(&wdt_lock, flags); //cpu = smp_processor_id(); if (mpcore_noboot) { /* Enable watchdog - prescale=0, watchdog mode=0, enable=1, IT = 1, reload = 1 */ *(volatile u32 *)(wdt->base + TWD_WDOG_CONTROL)=0x00000007; } else { /* Enable watchdog - prescale=0, watchdog mode=1, enable=1, IT = 1, reload = 1 */ *(volatile u32 *)( wdt->base + TWD_WDOG_CONTROL)=0x0000000F; } //spin_unlock_irqrestore(&wdt_lock, flags); //printk("WDT mpcore_wdt_start:cpu-%d,control: 0x%x, count:0x%x, load:0x%x\n", cpu, readl(wdt->base + TWD_WDOG_CONTROL), readl(wdt->base + TWD_WDOG_COUNTER), readl(wdt->base + TWD_WDOG_LOAD)); //mpcore_wdt_print("cpu-%d,control: 0x%x, count:0x%x, load:0x%x\n", cpu, readl(wdt->base + TWD_WDOG_CONTROL), readl(wdt->base + TWD_WDOG_COUNTER), readl(wdt->base + TWD_WDOG_LOAD)); }
static int mpcore_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { struct mpcore_wdt *wdt = file->private_data; int ret; union { struct watchdog_info ident; int i; } uarg; if (_IOC_DIR(cmd) && _IOC_SIZE(cmd) > sizeof(uarg)) return -ENOIOCTLCMD; if (_IOC_DIR(cmd) & _IOC_WRITE) { ret = copy_from_user(&uarg, (void __user *)arg, _IOC_SIZE(cmd)); if (ret) return -EFAULT; } switch (cmd) { case WDIOC_GETSUPPORT: uarg.ident = ident; ret = 0; break; case WDIOC_SETOPTIONS: ret = -EINVAL; if (uarg.i & WDIOS_DISABLECARD) { mpcore_wdt_stop(wdt); ret = 0; } if (uarg.i & WDIOS_ENABLECARD) { mpcore_wdt_start(wdt); ret = 0; } break; case WDIOC_GETSTATUS: case WDIOC_GETBOOTSTATUS: uarg.i = 0; ret = 0; break; case WDIOC_KEEPALIVE: mpcore_wdt_keepalive(wdt); ret = 0; break; case WDIOC_SETTIMEOUT: ret = mpcore_wdt_set_heartbeat(uarg.i); if (ret) break; mpcore_wdt_keepalive(wdt); /* Fall */ case WDIOC_GETTIMEOUT: uarg.i = mpcore_margin; ret = 0; break; default: return -ENOIOCTLCMD; } if (ret == 0 && _IOC_DIR(cmd) & _IOC_READ) { ret = copy_to_user((void __user *)arg, &uarg, _IOC_SIZE(cmd)); if (ret) ret = -EFAULT; } return ret; }