static int coh901327_suspend(struct platform_device *pdev, pm_message_t state) { irqmaskstore = readw(virtbase + U300_WDOG_IMR) & 0x0001U; wdogenablestore = readw(virtbase + U300_WDOG_D2R); /* If watchdog is on, disable it here and now */ if (wdogenablestore == U300_WDOG_D2R_DISABLE_STATUS_ENABLED) coh901327_disable(); return 0; }
static int __exit coh901327_remove(struct platform_device *pdev) { watchdog_unregister_device(&coh901327_wdt); coh901327_disable(); free_irq(irq, pdev); clk_disable_unprepare(clk); clk_put(clk); return 0; }
static int __exit coh901327_remove(struct platform_device *pdev) { watchdog_unregister_device(&coh901327_wdt); coh901327_disable(); free_irq(irq, pdev); clk_put(clk); iounmap(virtbase); release_mem_region(phybase, physize); return 0; }
static long coh901327_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { int ret = -ENOTTY; u16 val; int time; int new_options; union { struct watchdog_info __user *ident; int __user *i; } uarg; static const struct watchdog_info ident = { .options = WDIOF_CARDRESET | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, .identity = "COH 901 327 Watchdog", .firmware_version = 1, }; uarg.i = (int __user *)arg; switch (cmd) { case WDIOC_GETSUPPORT: ret = copy_to_user(uarg.ident, &ident, sizeof(ident)) ? -EFAULT : 0; break; case WDIOC_GETSTATUS: ret = put_user(0, uarg.i); break; case WDIOC_GETBOOTSTATUS: ret = put_user(boot_status, uarg.i); break; case WDIOC_SETOPTIONS: ret = get_user(new_options, uarg.i); if (ret) break; if (new_options & WDIOS_DISABLECARD) coh901327_disable(); if (new_options & WDIOS_ENABLECARD) coh901327_start(); ret = 0; break; case WDIOC_KEEPALIVE: coh901327_keepalive(); ret = 0; break; case WDIOC_SETTIMEOUT: ret = get_user(time, uarg.i); if (ret) break; ret = coh901327_settimeout(time); if (ret) break; /* Then fall through to return set value */ case WDIOC_GETTIMEOUT: ret = put_user(margin, uarg.i); break; case WDIOC_GETTIMELEFT: clk_enable(clk); /* Read repeatedly until the value is stable! */ val = readw(virtbase + U300_WDOG_CR); while (val & U300_WDOG_CR_VALID_IND) val = readw(virtbase + U300_WDOG_CR); val &= U300_WDOG_CR_COUNT_VALUE_MASK; clk_disable(clk); if (val != 0) val /= 100; ret = put_user(val, uarg.i); break; } return ret; } static const struct file_operations coh901327_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .write = coh901327_write, .unlocked_ioctl = coh901327_ioctl, .open = coh901327_open, .release = coh901327_release, }; static struct miscdevice coh901327_miscdev = { .minor = WATCHDOG_MINOR, .name = "watchdog", .fops = &coh901327_fops, }; static int __exit coh901327_remove(struct platform_device *pdev) { misc_deregister(&coh901327_miscdev); coh901327_disable(); free_irq(irq, pdev); clk_put(clk); iounmap(virtbase); release_mem_region(phybase, physize); return 0; } static int __init coh901327_probe(struct platform_device *pdev) { int ret; u16 val; struct resource *res; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) return -ENOENT; parent = &pdev->dev; physize = resource_size(res); phybase = res->start; if (request_mem_region(phybase, physize, DRV_NAME) == NULL) { ret = -EBUSY; goto out; } virtbase = ioremap(phybase, physize); if (!virtbase) { ret = -ENOMEM; goto out_no_remap; } clk = clk_get(&pdev->dev, NULL); if (IS_ERR(clk)) { ret = PTR_ERR(clk); dev_err(&pdev->dev, "could not get clock\n"); goto out_no_clk; } ret = clk_enable(clk); if (ret) { dev_err(&pdev->dev, "could not enable clock\n"); goto out_no_clk_enable; } val = readw(virtbase + U300_WDOG_SR); switch (val) { case U300_WDOG_SR_STATUS_TIMED_OUT: dev_info(&pdev->dev, "watchdog timed out since last chip reset!\n"); boot_status = WDIOF_CARDRESET; /* Status will be cleared below */ break; case U300_WDOG_SR_STATUS_NORMAL: dev_info(&pdev->dev, "in normal status, no timeouts have occurred.\n"); break; default: dev_info(&pdev->dev, "contains an illegal status code (%08x)\n", val); break; } val = readw(virtbase + U300_WDOG_D2R); switch (val) { case U300_WDOG_D2R_DISABLE_STATUS_DISABLED: dev_info(&pdev->dev, "currently disabled.\n"); break; case U300_WDOG_D2R_DISABLE_STATUS_ENABLED: dev_info(&pdev->dev, "currently enabled! (disabling it now)\n"); coh901327_disable(); break; default: dev_err(&pdev->dev, "contains an illegal enable/disable code (%08x)\n", val); break; } /* Reset the watchdog */ writew(U300_WDOG_SR_RESET_STATUS_RESET, virtbase + U300_WDOG_SR); irq = platform_get_irq(pdev, 0); if (request_irq(irq, coh901327_interrupt, IRQF_DISABLED, DRV_NAME " Bark", pdev)) { ret = -EIO; goto out_no_irq; } clk_disable(clk); ret = misc_register(&coh901327_miscdev); if (ret == 0) dev_info(&pdev->dev, "initialized. timer margin=%d sec\n", margin); else goto out_no_wdog; return 0; out_no_wdog: free_irq(irq, pdev); out_no_irq: clk_disable(clk); out_no_clk_enable: clk_put(clk); out_no_clk: iounmap(virtbase); out_no_remap: release_mem_region(phybase, SZ_4K); out: return ret; }
static int coh901327_release(struct inode *inode, struct file *file) { clear_bit(1, &coh901327_users); coh901327_disable(); return 0; }
static int __init coh901327_probe(struct platform_device *pdev) { int ret; u16 val; struct resource *res; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) return -ENOENT; parent = &pdev->dev; physize = resource_size(res); phybase = res->start; if (request_mem_region(phybase, physize, DRV_NAME) == NULL) { ret = -EBUSY; goto out; } virtbase = ioremap(phybase, physize); if (!virtbase) { ret = -ENOMEM; goto out_no_remap; } clk = clk_get(&pdev->dev, NULL); if (IS_ERR(clk)) { ret = PTR_ERR(clk); dev_err(&pdev->dev, "could not get clock\n"); goto out_no_clk; } ret = clk_enable(clk); if (ret) { dev_err(&pdev->dev, "could not enable clock\n"); goto out_no_clk_enable; } val = readw(virtbase + U300_WDOG_SR); switch (val) { case U300_WDOG_SR_STATUS_TIMED_OUT: dev_info(&pdev->dev, "watchdog timed out since last chip reset!\n"); coh901327_wdt.bootstatus |= WDIOF_CARDRESET; /* Status will be cleared below */ break; case U300_WDOG_SR_STATUS_NORMAL: dev_info(&pdev->dev, "in normal status, no timeouts have occurred.\n"); break; default: dev_info(&pdev->dev, "contains an illegal status code (%08x)\n", val); break; } val = readw(virtbase + U300_WDOG_D2R); switch (val) { case U300_WDOG_D2R_DISABLE_STATUS_DISABLED: dev_info(&pdev->dev, "currently disabled.\n"); break; case U300_WDOG_D2R_DISABLE_STATUS_ENABLED: dev_info(&pdev->dev, "currently enabled! (disabling it now)\n"); coh901327_disable(); break; default: dev_err(&pdev->dev, "contains an illegal enable/disable code (%08x)\n", val); break; } /* Reset the watchdog */ writew(U300_WDOG_SR_RESET_STATUS_RESET, virtbase + U300_WDOG_SR); irq = platform_get_irq(pdev, 0); if (request_irq(irq, coh901327_interrupt, 0, DRV_NAME " Bark", pdev)) { ret = -EIO; goto out_no_irq; } clk_disable(clk); if (margin < 1 || margin > 327) margin = 60; coh901327_wdt.timeout = margin; ret = watchdog_register_device(&coh901327_wdt); if (ret == 0) dev_info(&pdev->dev, "initialized. timer margin=%d sec\n", margin); else goto out_no_wdog; return 0; out_no_wdog: free_irq(irq, pdev); out_no_irq: clk_disable(clk); out_no_clk_enable: clk_put(clk); out_no_clk: iounmap(virtbase); out_no_remap: release_mem_region(phybase, SZ_4K); out: return ret; }
static int coh901327_stop(struct watchdog_device *wdt_dev) { coh901327_disable(); return 0; }
static int __init coh901327_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; int ret; u16 val; struct resource *res; parent = dev; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); virtbase = devm_ioremap_resource(dev, res); if (IS_ERR(virtbase)) return PTR_ERR(virtbase); clk = clk_get(dev, NULL); if (IS_ERR(clk)) { ret = PTR_ERR(clk); dev_err(dev, "could not get clock\n"); return ret; } ret = clk_prepare_enable(clk); if (ret) { dev_err(dev, "could not prepare and enable clock\n"); goto out_no_clk_enable; } val = readw(virtbase + U300_WDOG_SR); switch (val) { case U300_WDOG_SR_STATUS_TIMED_OUT: dev_info(dev, "watchdog timed out since last chip reset!\n"); coh901327_wdt.bootstatus |= WDIOF_CARDRESET; /* Status will be cleared below */ break; case U300_WDOG_SR_STATUS_NORMAL: dev_info(dev, "in normal status, no timeouts have occurred.\n"); break; default: dev_info(dev, "contains an illegal status code (%08x)\n", val); break; } val = readw(virtbase + U300_WDOG_D2R); switch (val) { case U300_WDOG_D2R_DISABLE_STATUS_DISABLED: dev_info(dev, "currently disabled.\n"); break; case U300_WDOG_D2R_DISABLE_STATUS_ENABLED: dev_info(dev, "currently enabled! (disabling it now)\n"); coh901327_disable(); break; default: dev_err(dev, "contains an illegal enable/disable code (%08x)\n", val); break; } /* Reset the watchdog */ writew(U300_WDOG_SR_RESET_STATUS_RESET, virtbase + U300_WDOG_SR); irq = platform_get_irq(pdev, 0); if (request_irq(irq, coh901327_interrupt, 0, DRV_NAME " Bark", pdev)) { ret = -EIO; goto out_no_irq; } watchdog_init_timeout(&coh901327_wdt, margin, dev); coh901327_wdt.parent = dev; ret = watchdog_register_device(&coh901327_wdt); if (ret) goto out_no_wdog; dev_info(dev, "initialized. (timeout=%d sec)\n", coh901327_wdt.timeout); return 0; out_no_wdog: free_irq(irq, pdev); out_no_irq: clk_disable_unprepare(clk); out_no_clk_enable: clk_put(clk); return ret; }