diff options
author | John Crispin <john@openwrt.org> | 2010-12-12 22:57:16 +0000 |
---|---|---|
committer | John Crispin <john@openwrt.org> | 2010-12-12 22:57:16 +0000 |
commit | 9f47e80bb30bed05ebcdfe671d4f2a9e9c7bfe55 (patch) | |
tree | 3d80c2524b0e73b5f7c9982eca4fe9301efdf75a /target/linux/lantiq/patches/250-watchdog.patch | |
parent | f590b304ef7d22242e08c86866cbb37927f0a404 (diff) | |
download | upstream-9f47e80bb30bed05ebcdfe671d4f2a9e9c7bfe55.tar.gz upstream-9f47e80bb30bed05ebcdfe671d4f2a9e9c7bfe55.tar.bz2 upstream-9f47e80bb30bed05ebcdfe671d4f2a9e9c7bfe55.zip |
adds new lantiq kernel. once the codebase is fully tested and know to be working on all the devices previously supported by ifxmips, we will drop ifxmips support.
SVN-Revision: 24526
Diffstat (limited to 'target/linux/lantiq/patches/250-watchdog.patch')
-rw-r--r-- | target/linux/lantiq/patches/250-watchdog.patch | 246 |
1 files changed, 246 insertions, 0 deletions
diff --git a/target/linux/lantiq/patches/250-watchdog.patch b/target/linux/lantiq/patches/250-watchdog.patch new file mode 100644 index 0000000000..f86ff71868 --- /dev/null +++ b/target/linux/lantiq/patches/250-watchdog.patch @@ -0,0 +1,246 @@ +--- a/drivers/watchdog/Kconfig ++++ b/drivers/watchdog/Kconfig +@@ -840,6 +840,12 @@ config TXX9_WDT + help + Hardware driver for the built-in watchdog timer on TXx9 MIPS SoCs. + ++config LANTIQ_WDT ++ bool "Lantiq SoC watchdog" ++ depends on LANTIQ ++ help ++ Hardware driver for the Lantiq SoC Watchdog Timer. ++ + # PARISC Architecture + + # POWERPC Architecture +--- a/drivers/watchdog/Makefile ++++ b/drivers/watchdog/Makefile +@@ -112,6 +112,7 @@ obj-$(CONFIG_PNX833X_WDT) += pnx833x_wdt + obj-$(CONFIG_SIBYTE_WDOG) += sb_wdog.o + obj-$(CONFIG_AR7_WDT) += ar7_wdt.o + obj-$(CONFIG_TXX9_WDT) += txx9wdt.o ++obj-$(CONFIG_LANTIQ_WDT) += lantiq_wdt.o + + # PARISC Architecture + +--- /dev/null ++++ b/drivers/watchdog/lantiq_wdt.c +@@ -0,0 +1,218 @@ ++/* ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ * ++ * Copyright (C) 2010 John Crispin <blogic@openwrt.org> ++ * Based on EP93xx wdt driver ++ */ ++ ++#include <linux/module.h> ++#include <linux/fs.h> ++#include <linux/miscdevice.h> ++#include <linux/miscdevice.h> ++#include <linux/watchdog.h> ++#include <linux/platform_device.h> ++#include <linux/uaccess.h> ++#include <linux/clk.h> ++ ++#include <lantiq.h> ++ ++#define LQ_WDT_PW1 0x00BE0000 ++#define LQ_WDT_PW2 0x00DC0000 ++ ++#define LQ_BIU_WDT_CR 0x3F0 ++#define LQ_BIU_WDT_SR 0x3F8 ++ ++#ifndef CONFIG_WATCHDOG_NOWAYOUT ++static int wdt_ok_to_close; ++#endif ++ ++static int wdt_timeout = 30; ++static __iomem void *wdt_membase = NULL; ++static unsigned long io_region_clk = 0; ++ ++static int ++lq_wdt_enable(unsigned int timeout) ++{ ++/* printk("%s:%s[%d] %08X\n", ++ __FILE__, __func__, __LINE__, ++ lq_r32(wdt_membase + LQ_BIU_WDT_SR)); ++ if(!lq_r32(wdt_membase + LQ_BIU_WDT_SR)) ++ { ++*/ lq_w32(LQ_WDT_PW1, wdt_membase + LQ_BIU_WDT_CR); ++ lq_w32(LQ_WDT_PW2 | ++ (0x3 << 26) | /* PWL */ ++ (0x3 << 24) | /* CLKDIV */ ++ (0x1 << 31) | /* enable */ ++ ((timeout * (io_region_clk / 0x40000)) + 0x1000), /* reload */ ++ wdt_membase + LQ_BIU_WDT_CR); ++// } ++ return 0; ++} ++ ++static void ++lq_wdt_disable(void) ++{ ++#ifndef CONFIG_WATCHDOG_NOWAYOUT ++ wdt_ok_to_close = 0; ++#endif ++ lq_w32(LQ_WDT_PW1, wdt_membase + LQ_BIU_WDT_CR); ++ lq_w32(LQ_WDT_PW2, wdt_membase+ LQ_BIU_WDT_CR); ++} ++ ++static ssize_t ++lq_wdt_write(struct file *file, const char __user *data, ++ size_t len, loff_t *ppos) ++{ ++ size_t i; ++ ++ if (!len) ++ return 0; ++ ++#ifndef CONFIG_WATCHDOG_NOWAYOUT ++ for (i = 0; i != len; i++) { ++ char c; ++ if (get_user(c, data + i)) ++ return -EFAULT; ++ if (c == 'V') ++ wdt_ok_to_close = 1; ++ } ++#endif ++ lq_wdt_enable(wdt_timeout); ++ return len; ++} ++ ++static struct watchdog_info ident = { ++ .options = WDIOF_MAGICCLOSE, ++ .identity = "lq_wdt", ++}; ++ ++static int ++lq_wdt_ioctl(struct inode *inode, struct file *file, ++ unsigned int cmd, unsigned long arg) ++{ ++ int ret = -ENOTTY; ++ ++ switch (cmd) { ++ case WDIOC_GETSUPPORT: ++ ret = copy_to_user((struct watchdog_info __user *)arg, &ident, ++ sizeof(ident)) ? -EFAULT : 0; ++ break; ++ ++ case WDIOC_GETTIMEOUT: ++ ret = put_user(wdt_timeout, (int __user *)arg); ++ break; ++ ++ case WDIOC_SETTIMEOUT: ++ ret = get_user(wdt_timeout, (int __user *)arg); ++ break; ++ ++ case WDIOC_KEEPALIVE: ++ lq_wdt_enable(wdt_timeout); ++ ret = 0; ++ break; ++ } ++ return ret; ++} ++ ++static int ++lq_wdt_open(struct inode *inode, struct file *file) ++{ ++ lq_wdt_enable(wdt_timeout); ++ return nonseekable_open(inode, file); ++} ++ ++static int ++lq_wdt_release(struct inode *inode, struct file *file) ++{ ++#ifndef CONFIG_WATCHDOG_NOWAYOUT ++ if (wdt_ok_to_close) ++ lq_wdt_disable(); ++ else ++#endif ++ printk(KERN_ERR "lq_wdt: watchdog closed without warning," ++ " rebooting system\n"); ++ return 0; ++} ++ ++static const struct file_operations lq_wdt_fops = { ++ .owner = THIS_MODULE, ++ .write = lq_wdt_write, ++ .ioctl = lq_wdt_ioctl, ++ .open = lq_wdt_open, ++ .release = lq_wdt_release, ++}; ++ ++static struct miscdevice lq_wdt_miscdev = { ++ .minor = WATCHDOG_MINOR, ++ .name = "watchdog", ++ .fops = &lq_wdt_fops, ++}; ++ ++static int ++lq_wdt_probe(struct platform_device *pdev) ++{ ++ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ struct clk *clk; ++ int ret = 0; ++ if(!res) ++ return -ENOENT; ++ res = request_mem_region(res->start, resource_size(res), ++ dev_name(&pdev->dev)); ++ if(!res) ++ return -EBUSY; ++ wdt_membase = ioremap_nocache(res->start, resource_size(res)); ++ if(!wdt_membase) ++ { ++ ret = -ENOMEM; ++ goto err_release_mem_region; ++ } ++ clk = clk_get(&pdev->dev, "io"); ++ io_region_clk = clk_get_rate(clk);; ++ ret = misc_register(&lq_wdt_miscdev); ++ if(!ret) ++ return 0; ++ ++ iounmap(wdt_membase); ++err_release_mem_region: ++ release_mem_region(res->start, resource_size(res)); ++ return ret; ++} ++ ++static int ++lq_wdt_remove(struct platform_device *dev) ++{ ++ lq_wdt_disable(); ++ misc_deregister(&lq_wdt_miscdev); ++ return 0; ++} ++ ++static struct platform_driver lq_wdt_driver = { ++ .probe = lq_wdt_probe, ++ .remove = lq_wdt_remove, ++ .driver = { ++ .name = "lq_wdt", ++ .owner = THIS_MODULE, ++ }, ++}; ++ ++static int __init ++init_lq_wdt(void) ++{ ++ return platform_driver_register(&lq_wdt_driver); ++} ++ ++static void __exit ++exit_lq_wdt(void) ++{ ++ platform_driver_unregister(&lq_wdt_driver); ++} ++ ++module_init(init_lq_wdt); ++module_exit(exit_lq_wdt); ++ ++MODULE_AUTHOR("John Crispin <blogic@openwrt.org>"); ++MODULE_DESCRIPTION("ifxmips Watchdog"); ++MODULE_LICENSE("GPL"); ++MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); |