/* * System shutdown handler. Turn off the watchdog if we're * restarting or halting the system. */ static void mpcore_wdt_shutdown(struct platform_device *dev) { struct mpcore_wdt *wdt = platform_get_drvdata(dev); if (system_state == SYSTEM_RESTART || system_state == SYSTEM_HALT) mpcore_wdt_stop(wdt); }
void mpcore_wk_wdt_stop(void) { struct mpcore_wdt *wdt = &mp_wdt; mpcore_wdt_print("mpcore_wk_wdt_stop\n"); mpcore_wdt_irq_disable(wdt->irq); mpcore_wdt_stop(wdt); }
int mpcore_wdt_restart(WD_RES_TYPE type) { struct mpcore_wdt *wdt = &mp_wdt; mpcore_wdt_print("enter:type:%d\n", type); mpcore_wdt_stop(wdt); mpcore_wdt_start(wdt); #ifndef WDT_CPU0 mpcore_wdt_irq_enable(wdt->irq); #endif return 0; }
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 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 int __devinit mpcore_wdt_probe(struct platform_device *dev) { struct mpcore_wdt *wdt; struct resource *res; int ret; /* We only accept one device, and it must have an id of -1 */ if (dev->id != -1) return -ENODEV; res = platform_get_resource(dev, IORESOURCE_MEM, 0); if (!res) { ret = -ENODEV; goto err_out; } wdt = kmalloc(sizeof(struct mpcore_wdt), GFP_KERNEL); if (!wdt) { ret = -ENOMEM; goto err_out; } memset(wdt, 0, sizeof(struct mpcore_wdt)); wdt->dev = &dev->dev; wdt->irq = platform_get_irq(dev, 0); if (wdt->irq < 0) { ret = -ENXIO; goto err_free; } wdt->base = ioremap(res->start, res->end - res->start + 1); if (!wdt->base) { ret = -ENOMEM; goto err_free; } mpcore_wdt_miscdev.dev = &dev->dev; ret = misc_register(&mpcore_wdt_miscdev); if (ret) { dev_printk(KERN_ERR, _dev, "cannot register miscdev on minor=%d (err=%d)\n", WATCHDOG_MINOR, ret); goto err_misc; } ret = request_irq(wdt->irq, mpcore_wdt_fire, SA_INTERRUPT, "mpcore_wdt", wdt); if (ret) { dev_printk(KERN_ERR, _dev, "cannot register IRQ%d for watchdog\n", wdt->irq); goto err_irq; } mpcore_wdt_stop(wdt); platform_set_drvdata(&dev->dev, wdt); mpcore_wdt_dev = dev; return 0; err_irq: misc_deregister(&mpcore_wdt_miscdev); err_misc: iounmap(wdt->base); err_free: kfree(wdt); err_out: return ret; }
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; }