diff options
Diffstat (limited to 'target/linux/coldfire/patches/075-mcfv4e_watchdog.patch')
-rw-r--r-- | target/linux/coldfire/patches/075-mcfv4e_watchdog.patch | 265 |
1 files changed, 265 insertions, 0 deletions
diff --git a/target/linux/coldfire/patches/075-mcfv4e_watchdog.patch b/target/linux/coldfire/patches/075-mcfv4e_watchdog.patch new file mode 100644 index 0000000000..5b865bdd32 --- /dev/null +++ b/target/linux/coldfire/patches/075-mcfv4e_watchdog.patch @@ -0,0 +1,265 @@ +From 3c6c80a04d6ca99c4f9fbb5e4f279bd644b2df48 Mon Sep 17 00:00:00 2001 +From: Kurt Mahan <kmahan@freescale.com> +Date: Tue, 8 Jul 2008 14:10:46 -0600 +Subject: [PATCH] Add Coldfire Watchdog support. + +LTIBName: mcfv4e-watchdog +Signed-off-by: Kurt Mahan <kmahan@freescale.com> +--- + drivers/watchdog/Kconfig | 9 ++ + drivers/watchdog/Makefile | 1 + + drivers/watchdog/mcf_wdt.c | 220 ++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 230 insertions(+), 0 deletions(-) + create mode 100644 drivers/watchdog/mcf_wdt.c + +--- a/drivers/watchdog/Kconfig ++++ b/drivers/watchdog/Kconfig +@@ -672,6 +672,15 @@ config TXX9_WDT + + # PARISC Architecture + ++# ColdFire Architecture ++ ++config COLDFIRE_WATCHDOG ++ tristate "ColdFire watchdog support" ++ depends on WATCHDOG ++ help ++ To compile this driver as a module, choose M here: the ++ module will be called softdog. ++ + # POWERPC Architecture + + config MPC5200_WDT +--- a/drivers/watchdog/Makefile ++++ b/drivers/watchdog/Makefile +@@ -86,6 +86,7 @@ obj-$(CONFIG_SBC_EPX_C3_WATCHDOG) += sbc + # M32R Architecture + + # M68K Architecture ++obj-$(CONFIG_COLDFIRE_WATCHDOG) += mcf_wdt.o + + # M68KNOMMU Architecture + +--- /dev/null ++++ b/drivers/watchdog/mcf_wdt.c +@@ -0,0 +1,220 @@ ++/* ++ * drivers/watchdog/mcf_wdt.c ++ * ++ * Watchdog driver for ColdFire processors ++ * ++ * Adapted from the IXP4xx watchdog driver. ++ * The original version carries these notices: ++ * ++ * Author: Deepak Saxena <dsaxena@plexity.net> ++ * ++ * Copyright 2004 (c) MontaVista, Software, Inc. ++ * Based on sa1100 driver, Copyright (C) 2000 Oleg Drokin <green@crimea.edu> ++ * ++ * This file is licensed under the terms of the GNU General Public ++ * License version 2. This program is licensed "as is" without any ++ * warranty of any kind, whether express or implied. ++ */ ++ ++#include <linux/module.h> ++#include <linux/moduleparam.h> ++#include <linux/types.h> ++#include <linux/kernel.h> ++#include <linux/fs.h> ++#include <linux/miscdevice.h> ++#include <linux/watchdog.h> ++#include <linux/init.h> ++#include <linux/bitops.h> ++ ++#include <asm-m68k/uaccess.h> ++#include <asm-m68k/coldfire.h> ++#include <asm-m68k/m5485gpt.h> ++ ++static int nowayout; ++static unsigned int heartbeat = 30; /* (secs) Default is 0.5 minute */ ++static unsigned long wdt_status; ++ ++#define WDT_IN_USE 0 ++#define WDT_OK_TO_CLOSE 1 ++ ++static unsigned long wdt_tick_rate; ++ ++static void ++wdt_enable(void) ++{ ++ MCF_GPT_GMS0 = 0; ++ MCF_GPT_GCIR0 = MCF_GPT_GCIR_PRE(heartbeat*wdt_tick_rate) | ++ MCF_GPT_GCIR_CNT(0xffff); ++ MCF_GPT_GMS0 = MCF_GPT_GMS_OCPW(0xA5) | MCF_GPT_GMS_WDEN | ++ MCF_GPT_GMS_CE | MCF_GPT_GMS_TMS_GPIO; ++} ++ ++static void ++wdt_disable(void) ++{ ++ MCF_GPT_GMS0 = 0; ++} ++ ++static void ++wdt_keepalive(void) ++{ ++ MCF_GPT_GMS0 = MCF_GPT_GMS_OCPW(0xA5) | MCF_GPT_GMS0; ++} ++ ++static int ++mcf_wdt_open(struct inode *inode, struct file *file) ++{ ++ if (test_and_set_bit(WDT_IN_USE, &wdt_status)) ++ return -EBUSY; ++ ++ clear_bit(WDT_OK_TO_CLOSE, &wdt_status); ++ ++ wdt_enable(); ++ ++ return nonseekable_open(inode, file); ++} ++ ++static ssize_t ++mcf_wdt_write(struct file *file, const char *data, size_t len, loff_t *ppos) ++{ ++ if (len) { ++ if (!nowayout) { ++ size_t i; ++ ++ clear_bit(WDT_OK_TO_CLOSE, &wdt_status); ++ ++ for (i = 0; i != len; i++) { ++ char c; ++ ++ if (get_user(c, data + i)) ++ return -EFAULT; ++ if (c == 'V') ++ set_bit(WDT_OK_TO_CLOSE, &wdt_status); ++ } ++ } ++ wdt_keepalive(); ++ } ++ ++ return len; ++} ++ ++ ++static struct watchdog_info ident = { ++ .options = WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT | ++ WDIOF_KEEPALIVEPING, ++ .identity = "Coldfire Watchdog", ++}; ++ ++static int ++mcf_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ++ unsigned long arg) ++{ ++ int ret = -ENOIOCTLCMD; ++ int time; ++ ++ switch (cmd) { ++ case WDIOC_GETSUPPORT: ++ ret = copy_to_user((struct watchdog_info *)arg, &ident, ++ sizeof(ident)) ? -EFAULT : 0; ++ break; ++ ++ case WDIOC_GETSTATUS: ++ ret = put_user(0, (int *)arg); ++ break; ++ ++ case WDIOC_GETBOOTSTATUS: ++ ret = put_user(0, (int *)arg); ++ break; ++ ++ case WDIOC_SETTIMEOUT: ++ ret = get_user(time, (int *)arg); ++ if (ret) ++ break; ++ ++ if (time <= 0 || time > 30) { ++ ret = -EINVAL; ++ break; ++ } ++ ++ heartbeat = time; ++ wdt_enable(); ++ /* Fall through */ ++ ++ case WDIOC_GETTIMEOUT: ++ ret = put_user(heartbeat, (int *)arg); ++ break; ++ ++ case WDIOC_KEEPALIVE: ++ wdt_keepalive(); ++ ret = 0; ++ break; ++ } ++ ++ return ret; ++} ++ ++static int ++mcf_wdt_release(struct inode *inode, struct file *file) ++{ ++ if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) { ++ wdt_disable(); ++ } else { ++ printk(KERN_CRIT "WATCHDOG: Device closed unexpectdly - " ++ "timer will not stop\n"); ++ } ++ ++ clear_bit(WDT_IN_USE, &wdt_status); ++ clear_bit(WDT_OK_TO_CLOSE, &wdt_status); ++ ++ return 0; ++} ++ ++ ++static struct file_operations mcf_wdt_fops = { ++ .owner = THIS_MODULE, ++ .llseek = no_llseek, ++ .write = mcf_wdt_write, ++ .ioctl = mcf_wdt_ioctl, ++ .open = mcf_wdt_open, ++ .release = mcf_wdt_release, ++}; ++ ++static struct miscdevice mcf_wdt_miscdev = { ++ .minor = WATCHDOG_MINOR, ++ .name = "watchdog", ++ .fops = &mcf_wdt_fops, ++}; ++ ++static int __init mcf_wdt_init(void) ++{ ++ wdt_tick_rate = MCF_BUSCLK/0xffff; ++#ifdef CONFIG_WATCHDOG_NOWAYOUT ++ nowayout = 1; ++#else ++ nowayout = 0; ++#endif ++ printk("ColdFire watchdog driver is loaded.\n"); ++ ++ return misc_register(&mcf_wdt_miscdev); ++} ++ ++static void __exit mcf_wdt_exit(void) ++{ ++ misc_deregister(&mcf_wdt_miscdev); ++} ++ ++module_init(mcf_wdt_init); ++module_exit(mcf_wdt_exit); ++ ++MODULE_AUTHOR("Deepak Saxena"); ++MODULE_DESCRIPTION("ColdFire Watchdog"); ++ ++module_param(heartbeat, int, 0); ++MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds (default 60s)"); ++ ++module_param(nowayout, int, 0); ++MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started"); ++ ++MODULE_LICENSE("GPL"); ++MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); ++ |