1 From 3c6c80a04d6ca99c4f9fbb5e4f279bd644b2df48 Mon Sep 17 00:00:00 2001
2 From: Kurt Mahan <kmahan@freescale.com>
3 Date: Tue, 8 Jul 2008 14:10:46 -0600
4 Subject: [PATCH] Add Coldfire Watchdog support.
6 LTIBName: mcfv4e-watchdog
7 Signed-off-by: Kurt Mahan <kmahan@freescale.com>
9 drivers/watchdog/Kconfig | 9 ++
10 drivers/watchdog/Makefile | 1 +
11 drivers/watchdog/mcf_wdt.c | 220 ++++++++++++++++++++++++++++++++++++++++++++
12 3 files changed, 230 insertions(+), 0 deletions(-)
13 create mode 100644 drivers/watchdog/mcf_wdt.c
15 --- a/drivers/watchdog/Kconfig
16 +++ b/drivers/watchdog/Kconfig
17 @@ -672,6 +672,15 @@ config TXX9_WDT
21 +# ColdFire Architecture
23 +config COLDFIRE_WATCHDOG
24 + tristate "ColdFire watchdog support"
27 + To compile this driver as a module, choose M here: the
28 + module will be called softdog.
30 # POWERPC Architecture
33 --- a/drivers/watchdog/Makefile
34 +++ b/drivers/watchdog/Makefile
35 @@ -86,6 +86,7 @@ obj-$(CONFIG_SBC_EPX_C3_WATCHDOG) += sbc
39 +obj-$(CONFIG_COLDFIRE_WATCHDOG) += mcf_wdt.o
41 # M68KNOMMU Architecture
44 +++ b/drivers/watchdog/mcf_wdt.c
47 + * drivers/watchdog/mcf_wdt.c
49 + * Watchdog driver for ColdFire processors
51 + * Adapted from the IXP4xx watchdog driver.
52 + * The original version carries these notices:
54 + * Author: Deepak Saxena <dsaxena@plexity.net>
56 + * Copyright 2004 (c) MontaVista, Software, Inc.
57 + * Based on sa1100 driver, Copyright (C) 2000 Oleg Drokin <green@crimea.edu>
59 + * This file is licensed under the terms of the GNU General Public
60 + * License version 2. This program is licensed "as is" without any
61 + * warranty of any kind, whether express or implied.
64 +#include <linux/module.h>
65 +#include <linux/moduleparam.h>
66 +#include <linux/types.h>
67 +#include <linux/kernel.h>
68 +#include <linux/fs.h>
69 +#include <linux/miscdevice.h>
70 +#include <linux/watchdog.h>
71 +#include <linux/init.h>
72 +#include <linux/bitops.h>
74 +#include <asm-m68k/uaccess.h>
75 +#include <asm-m68k/coldfire.h>
76 +#include <asm-m68k/m5485gpt.h>
79 +static unsigned int heartbeat = 30; /* (secs) Default is 0.5 minute */
80 +static unsigned long wdt_status;
83 +#define WDT_OK_TO_CLOSE 1
85 +static unsigned long wdt_tick_rate;
91 + MCF_GPT_GCIR0 = MCF_GPT_GCIR_PRE(heartbeat*wdt_tick_rate) |
92 + MCF_GPT_GCIR_CNT(0xffff);
93 + MCF_GPT_GMS0 = MCF_GPT_GMS_OCPW(0xA5) | MCF_GPT_GMS_WDEN |
94 + MCF_GPT_GMS_CE | MCF_GPT_GMS_TMS_GPIO;
106 + MCF_GPT_GMS0 = MCF_GPT_GMS_OCPW(0xA5) | MCF_GPT_GMS0;
110 +mcf_wdt_open(struct inode *inode, struct file *file)
112 + if (test_and_set_bit(WDT_IN_USE, &wdt_status))
115 + clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
119 + return nonseekable_open(inode, file);
123 +mcf_wdt_write(struct file *file, const char *data, size_t len, loff_t *ppos)
129 + clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
131 + for (i = 0; i != len; i++) {
134 + if (get_user(c, data + i))
137 + set_bit(WDT_OK_TO_CLOSE, &wdt_status);
147 +static struct watchdog_info ident = {
148 + .options = WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT |
149 + WDIOF_KEEPALIVEPING,
150 + .identity = "Coldfire Watchdog",
154 +mcf_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
157 + int ret = -ENOIOCTLCMD;
161 + case WDIOC_GETSUPPORT:
162 + ret = copy_to_user((struct watchdog_info *)arg, &ident,
163 + sizeof(ident)) ? -EFAULT : 0;
166 + case WDIOC_GETSTATUS:
167 + ret = put_user(0, (int *)arg);
170 + case WDIOC_GETBOOTSTATUS:
171 + ret = put_user(0, (int *)arg);
174 + case WDIOC_SETTIMEOUT:
175 + ret = get_user(time, (int *)arg);
179 + if (time <= 0 || time > 30) {
188 + case WDIOC_GETTIMEOUT:
189 + ret = put_user(heartbeat, (int *)arg);
192 + case WDIOC_KEEPALIVE:
202 +mcf_wdt_release(struct inode *inode, struct file *file)
204 + if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) {
207 + printk(KERN_CRIT "WATCHDOG: Device closed unexpectdly - "
208 + "timer will not stop\n");
211 + clear_bit(WDT_IN_USE, &wdt_status);
212 + clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
218 +static struct file_operations mcf_wdt_fops = {
219 + .owner = THIS_MODULE,
220 + .llseek = no_llseek,
221 + .write = mcf_wdt_write,
222 + .ioctl = mcf_wdt_ioctl,
223 + .open = mcf_wdt_open,
224 + .release = mcf_wdt_release,
227 +static struct miscdevice mcf_wdt_miscdev = {
228 + .minor = WATCHDOG_MINOR,
229 + .name = "watchdog",
230 + .fops = &mcf_wdt_fops,
233 +static int __init mcf_wdt_init(void)
235 + wdt_tick_rate = MCF_BUSCLK/0xffff;
236 +#ifdef CONFIG_WATCHDOG_NOWAYOUT
241 + printk("ColdFire watchdog driver is loaded.\n");
243 + return misc_register(&mcf_wdt_miscdev);
246 +static void __exit mcf_wdt_exit(void)
248 + misc_deregister(&mcf_wdt_miscdev);
251 +module_init(mcf_wdt_init);
252 +module_exit(mcf_wdt_exit);
254 +MODULE_AUTHOR("Deepak Saxena");
255 +MODULE_DESCRIPTION("ColdFire Watchdog");
257 +module_param(heartbeat, int, 0);
258 +MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds (default 60s)");
260 +module_param(nowayout, int, 0);
261 +MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started");
263 +MODULE_LICENSE("GPL");
264 +MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);