Linux Audio

Check our new training course

Loading...
v3.1
  1/*
  2 * drivers/watchdog/shwdt.c
  3 *
  4 * Watchdog driver for integrated watchdog in the SuperH processors.
  5 *
  6 * Copyright (C) 2001 - 2010  Paul Mundt <lethal@linux-sh.org>
  7 *
  8 * This program is free software; you can redistribute it and/or modify it
  9 * under the terms of the GNU General Public License as published by the
 10 * Free Software Foundation; either version 2 of the License, or (at your
 11 * option) any later version.
 12 *
 13 * 14-Dec-2001 Matt Domsch <Matt_Domsch@dell.com>
 14 *     Added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT
 15 *
 16 * 19-Apr-2002 Rob Radez <rob@osinvestor.com>
 17 *     Added expect close support, made emulated timeout runtime changeable
 18 *     general cleanups, add some ioctls
 19 */
 
 
 
 20#include <linux/module.h>
 21#include <linux/moduleparam.h>
 22#include <linux/platform_device.h>
 23#include <linux/init.h>
 24#include <linux/types.h>
 
 25#include <linux/miscdevice.h>
 26#include <linux/watchdog.h>
 27#include <linux/reboot.h>
 28#include <linux/notifier.h>
 29#include <linux/ioport.h>
 30#include <linux/fs.h>
 31#include <linux/mm.h>
 32#include <linux/slab.h>
 33#include <linux/io.h>
 34#include <linux/uaccess.h>
 35#include <asm/watchdog.h>
 36
 37#define DRV_NAME "sh-wdt"
 38
 39/*
 40 * Default clock division ratio is 5.25 msecs. For an additional table of
 41 * values, consult the asm-sh/watchdog.h. Overload this at module load
 42 * time.
 43 *
 44 * In order for this to work reliably we need to have HZ set to 1000 or
 45 * something quite higher than 100 (or we need a proper high-res timer
 46 * implementation that will deal with this properly), otherwise the 10ms
 47 * resolution of a jiffy is enough to trigger the overflow. For things like
 48 * the SH-4 and SH-5, this isn't necessarily that big of a problem, though
 49 * for the SH-2 and SH-3, this isn't recommended unless the WDT is absolutely
 50 * necssary.
 51 *
 52 * As a result of this timing problem, the only modes that are particularly
 53 * feasible are the 4096 and the 2048 divisors, which yield 5.25 and 2.62ms
 54 * overflow periods respectively.
 55 *
 56 * Also, since we can't really expect userspace to be responsive enough
 57 * before the overflow happens, we maintain two separate timers .. One in
 58 * the kernel for clearing out WOVF every 2ms or so (again, this depends on
 59 * HZ == 1000), and another for monitoring userspace writes to the WDT device.
 60 *
 61 * As such, we currently use a configurable heartbeat interval which defaults
 62 * to 30s. In this case, the userspace daemon is only responsible for periodic
 63 * writes to the device before the next heartbeat is scheduled. If the daemon
 64 * misses its deadline, the kernel timer will allow the WDT to overflow.
 65 */
 66static int clock_division_ratio = WTCSR_CKS_4096;
 67#define next_ping_period(cks)	(jiffies + msecs_to_jiffies(cks - 4))
 68
 69static const struct watchdog_info sh_wdt_info;
 70static struct platform_device *sh_wdt_dev;
 71static DEFINE_SPINLOCK(shwdt_lock);
 72
 73#define WATCHDOG_HEARTBEAT 30			/* 30 sec default heartbeat */
 74static int heartbeat = WATCHDOG_HEARTBEAT;	/* in seconds */
 75static int nowayout = WATCHDOG_NOWAYOUT;
 76static unsigned long next_heartbeat;
 77
 78struct sh_wdt {
 79	void __iomem		*base;
 80	struct device		*dev;
 
 
 81
 82	struct timer_list	timer;
 83
 84	unsigned long		enabled;
 85	char			expect_close;
 86};
 87
 88static void sh_wdt_start(struct sh_wdt *wdt)
 89{
 
 90	unsigned long flags;
 91	u8 csr;
 92
 93	spin_lock_irqsave(&shwdt_lock, flags);
 
 
 
 94
 95	next_heartbeat = jiffies + (heartbeat * HZ);
 96	mod_timer(&wdt->timer, next_ping_period(clock_division_ratio));
 97
 98	csr = sh_wdt_read_csr();
 99	csr |= WTCSR_WT | clock_division_ratio;
100	sh_wdt_write_csr(csr);
101
102	sh_wdt_write_cnt(0);
103
104	/*
105	 * These processors have a bit of an inconsistent initialization
106	 * process.. starting with SH-3, RSTS was moved to WTCSR, and the
107	 * RSTCSR register was removed.
108	 *
109	 * On the SH-2 however, in addition with bits being in different
110	 * locations, we must deal with RSTCSR outright..
111	 */
112	csr = sh_wdt_read_csr();
113	csr |= WTCSR_TME;
114	csr &= ~WTCSR_RSTS;
115	sh_wdt_write_csr(csr);
116
117#ifdef CONFIG_CPU_SH2
118	csr = sh_wdt_read_rstcsr();
119	csr &= ~RSTCSR_RSTS;
120	sh_wdt_write_rstcsr(csr);
121#endif
122	spin_unlock_irqrestore(&shwdt_lock, flags);
 
 
123}
124
125static void sh_wdt_stop(struct sh_wdt *wdt)
126{
 
127	unsigned long flags;
128	u8 csr;
129
130	spin_lock_irqsave(&shwdt_lock, flags);
131
132	del_timer(&wdt->timer);
133
134	csr = sh_wdt_read_csr();
135	csr &= ~WTCSR_TME;
136	sh_wdt_write_csr(csr);
137
138	spin_unlock_irqrestore(&shwdt_lock, flags);
 
 
 
 
 
139}
140
141static inline void sh_wdt_keepalive(struct sh_wdt *wdt)
142{
 
143	unsigned long flags;
144
145	spin_lock_irqsave(&shwdt_lock, flags);
146	next_heartbeat = jiffies + (heartbeat * HZ);
147	spin_unlock_irqrestore(&shwdt_lock, flags);
 
 
148}
149
150static int sh_wdt_set_heartbeat(int t)
151{
 
152	unsigned long flags;
153
154	if (unlikely(t < 1 || t > 3600)) /* arbitrary upper limit */
155		return -EINVAL;
156
157	spin_lock_irqsave(&shwdt_lock, flags);
158	heartbeat = t;
159	spin_unlock_irqrestore(&shwdt_lock, flags);
 
 
160	return 0;
161}
162
163static void sh_wdt_ping(unsigned long data)
164{
165	struct sh_wdt *wdt = (struct sh_wdt *)data;
166	unsigned long flags;
167
168	spin_lock_irqsave(&shwdt_lock, flags);
169	if (time_before(jiffies, next_heartbeat)) {
170		u8 csr;
171
172		csr = sh_wdt_read_csr();
173		csr &= ~WTCSR_IOVF;
174		sh_wdt_write_csr(csr);
175
176		sh_wdt_write_cnt(0);
177
178		mod_timer(&wdt->timer, next_ping_period(clock_division_ratio));
179	} else
180		dev_warn(wdt->dev, "Heartbeat lost! Will not ping "
181		         "the watchdog\n");
182	spin_unlock_irqrestore(&shwdt_lock, flags);
183}
184
185static int sh_wdt_open(struct inode *inode, struct file *file)
186{
187	struct sh_wdt *wdt = platform_get_drvdata(sh_wdt_dev);
188
189	if (test_and_set_bit(0, &wdt->enabled))
190		return -EBUSY;
191	if (nowayout)
192		__module_get(THIS_MODULE);
193
194	file->private_data = wdt;
195
196	sh_wdt_start(wdt);
197
198	return nonseekable_open(inode, file);
199}
200
201static int sh_wdt_close(struct inode *inode, struct file *file)
202{
203	struct sh_wdt *wdt = file->private_data;
204
205	if (wdt->expect_close == 42) {
206		sh_wdt_stop(wdt);
207	} else {
208		dev_crit(wdt->dev, "Unexpected close, not "
209		         "stopping watchdog!\n");
210		sh_wdt_keepalive(wdt);
211	}
212
213	clear_bit(0, &wdt->enabled);
214	wdt->expect_close = 0;
215
216	return 0;
217}
218
219static ssize_t sh_wdt_write(struct file *file, const char *buf,
220			    size_t count, loff_t *ppos)
221{
222	struct sh_wdt *wdt = file->private_data;
223
224	if (count) {
225		if (!nowayout) {
226			size_t i;
227
228			wdt->expect_close = 0;
229
230			for (i = 0; i != count; i++) {
231				char c;
232				if (get_user(c, buf + i))
233					return -EFAULT;
234				if (c == 'V')
235					wdt->expect_close = 42;
236			}
237		}
238		sh_wdt_keepalive(wdt);
239	}
240
241	return count;
242}
243
244static long sh_wdt_ioctl(struct file *file, unsigned int cmd,
245							unsigned long arg)
246{
247	struct sh_wdt *wdt = file->private_data;
248	int new_heartbeat;
249	int options, retval = -EINVAL;
250
251	switch (cmd) {
252	case WDIOC_GETSUPPORT:
253		return copy_to_user((struct watchdog_info *)arg,
254			  &sh_wdt_info, sizeof(sh_wdt_info)) ? -EFAULT : 0;
255	case WDIOC_GETSTATUS:
256	case WDIOC_GETBOOTSTATUS:
257		return put_user(0, (int *)arg);
258	case WDIOC_SETOPTIONS:
259		if (get_user(options, (int *)arg))
260			return -EFAULT;
261
262		if (options & WDIOS_DISABLECARD) {
263			sh_wdt_stop(wdt);
264			retval = 0;
265		}
266
267		if (options & WDIOS_ENABLECARD) {
268			sh_wdt_start(wdt);
269			retval = 0;
270		}
271
272		return retval;
273	case WDIOC_KEEPALIVE:
274		sh_wdt_keepalive(wdt);
275		return 0;
276	case WDIOC_SETTIMEOUT:
277		if (get_user(new_heartbeat, (int *)arg))
278			return -EFAULT;
279
280		if (sh_wdt_set_heartbeat(new_heartbeat))
281			return -EINVAL;
282
283		sh_wdt_keepalive(wdt);
284		/* Fall */
285	case WDIOC_GETTIMEOUT:
286		return put_user(heartbeat, (int *)arg);
287	default:
288		return -ENOTTY;
289	}
290	return 0;
291}
292
293static int sh_wdt_notify_sys(struct notifier_block *this,
294			     unsigned long code, void *unused)
295{
296	struct sh_wdt *wdt = platform_get_drvdata(sh_wdt_dev);
297
298	if (code == SYS_DOWN || code == SYS_HALT)
299		sh_wdt_stop(wdt);
300
301	return NOTIFY_DONE;
302}
303
304static const struct file_operations sh_wdt_fops = {
305	.owner		= THIS_MODULE,
306	.llseek		= no_llseek,
307	.write		= sh_wdt_write,
308	.unlocked_ioctl	= sh_wdt_ioctl,
309	.open		= sh_wdt_open,
310	.release	= sh_wdt_close,
311};
312
313static const struct watchdog_info sh_wdt_info = {
314	.options		= WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT |
315				  WDIOF_MAGICCLOSE,
316	.firmware_version	= 1,
317	.identity		= "SH WDT",
318};
319
320static struct notifier_block sh_wdt_notifier = {
321	.notifier_call		= sh_wdt_notify_sys,
 
 
 
 
322};
323
324static struct miscdevice sh_wdt_miscdev = {
325	.minor		= WATCHDOG_MINOR,
326	.name		= "watchdog",
327	.fops		= &sh_wdt_fops,
328};
329
330static int __devinit sh_wdt_probe(struct platform_device *pdev)
331{
332	struct sh_wdt *wdt;
333	struct resource *res;
334	int rc;
335
336	/*
337	 * As this driver only covers the global watchdog case, reject
338	 * any attempts to register per-CPU watchdogs.
339	 */
340	if (pdev->id != -1)
341		return -EINVAL;
342
343	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
344	if (unlikely(!res))
345		return -EINVAL;
346
347	if (!devm_request_mem_region(&pdev->dev, res->start,
348				     resource_size(res), DRV_NAME))
349		return -EBUSY;
350
351	wdt = devm_kzalloc(&pdev->dev, sizeof(struct sh_wdt), GFP_KERNEL);
352	if (unlikely(!wdt)) {
353		rc = -ENOMEM;
354		goto out_release;
355	}
356
357	wdt->dev = &pdev->dev;
358
359	wdt->base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
 
 
 
 
 
 
 
 
 
360	if (unlikely(!wdt->base)) {
361		rc = -ENXIO;
362		goto out_err;
363	}
364
365	rc = register_reboot_notifier(&sh_wdt_notifier);
 
 
 
 
 
366	if (unlikely(rc)) {
367		dev_err(&pdev->dev,
368			"Can't register reboot notifier (err=%d)\n", rc);
369		goto out_unmap;
 
 
 
370	}
371
372	sh_wdt_miscdev.parent = wdt->dev;
 
373
374	rc = misc_register(&sh_wdt_miscdev);
375	if (unlikely(rc)) {
376		dev_err(&pdev->dev,
377			"Can't register miscdev on minor=%d (err=%d)\n",
378						sh_wdt_miscdev.minor, rc);
379		goto out_unreg;
380	}
381
382	init_timer(&wdt->timer);
383	wdt->timer.function	= sh_wdt_ping;
384	wdt->timer.data		= (unsigned long)wdt;
385	wdt->timer.expires	= next_ping_period(clock_division_ratio);
386
387	platform_set_drvdata(pdev, wdt);
388	sh_wdt_dev = pdev;
389
390	dev_info(&pdev->dev, "initialized.\n");
391
 
 
392	return 0;
393
394out_unreg:
395	unregister_reboot_notifier(&sh_wdt_notifier);
396out_unmap:
397	devm_iounmap(&pdev->dev, wdt->base);
398out_err:
399	devm_kfree(&pdev->dev, wdt);
400out_release:
401	devm_release_mem_region(&pdev->dev, res->start, resource_size(res));
402
403	return rc;
404}
405
406static int __devexit sh_wdt_remove(struct platform_device *pdev)
407{
408	struct sh_wdt *wdt = platform_get_drvdata(pdev);
409	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
410
411	platform_set_drvdata(pdev, NULL);
412
413	misc_deregister(&sh_wdt_miscdev);
414
415	sh_wdt_dev = NULL;
416
417	unregister_reboot_notifier(&sh_wdt_notifier);
418	devm_release_mem_region(&pdev->dev, res->start, resource_size(res));
419	devm_iounmap(&pdev->dev, wdt->base);
420	devm_kfree(&pdev->dev, wdt);
421
422	return 0;
423}
424
 
 
 
 
 
425static struct platform_driver sh_wdt_driver = {
426	.driver		= {
427		.name	= DRV_NAME,
428		.owner	= THIS_MODULE,
429	},
430
431	.probe	= sh_wdt_probe,
432	.remove	= __devexit_p(sh_wdt_remove),
 
433};
434
435static int __init sh_wdt_init(void)
436{
437	int rc;
438
439	if (unlikely(clock_division_ratio < 0x5 ||
440		     clock_division_ratio > 0x7)) {
441		clock_division_ratio = WTCSR_CKS_4096;
442
443		pr_info("%s: divisor must be 0x5<=x<=0x7, using %d\n",
444			 DRV_NAME, clock_division_ratio);
445	}
446
447	rc = sh_wdt_set_heartbeat(heartbeat);
448	if (unlikely(rc)) {
449		heartbeat = WATCHDOG_HEARTBEAT;
450
451		pr_info("%s: heartbeat value must be 1<=x<=3600, using %d\n",
452			DRV_NAME, heartbeat);
453	}
454
455	pr_info("%s: configured with heartbeat=%d sec (nowayout=%d)\n",
456		DRV_NAME, heartbeat, nowayout);
457
458	return platform_driver_register(&sh_wdt_driver);
459}
460
461static void __exit sh_wdt_exit(void)
462{
463	platform_driver_unregister(&sh_wdt_driver);
464}
465module_init(sh_wdt_init);
466module_exit(sh_wdt_exit);
467
468MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>");
469MODULE_DESCRIPTION("SuperH watchdog driver");
470MODULE_LICENSE("GPL");
471MODULE_ALIAS("platform:" DRV_NAME);
472MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
473
474module_param(clock_division_ratio, int, 0);
475MODULE_PARM_DESC(clock_division_ratio,
476	"Clock division ratio. Valid ranges are from 0x5 (1.31ms) "
477	"to 0x7 (5.25ms). (default=" __MODULE_STRING(WTCSR_CKS_4096) ")");
478
479module_param(heartbeat, int, 0);
480MODULE_PARM_DESC(heartbeat,
481	"Watchdog heartbeat in seconds. (1 <= heartbeat <= 3600, default="
482				__MODULE_STRING(WATCHDOG_HEARTBEAT) ")");
483
484module_param(nowayout, int, 0);
485MODULE_PARM_DESC(nowayout,
486	"Watchdog cannot be stopped once started (default="
487				__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
v3.5.6
  1/*
  2 * drivers/watchdog/shwdt.c
  3 *
  4 * Watchdog driver for integrated watchdog in the SuperH processors.
  5 *
  6 * Copyright (C) 2001 - 2012  Paul Mundt <lethal@linux-sh.org>
  7 *
  8 * This program is free software; you can redistribute it and/or modify it
  9 * under the terms of the GNU General Public License as published by the
 10 * Free Software Foundation; either version 2 of the License, or (at your
 11 * option) any later version.
 12 *
 13 * 14-Dec-2001 Matt Domsch <Matt_Domsch@dell.com>
 14 *     Added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT
 15 *
 16 * 19-Apr-2002 Rob Radez <rob@osinvestor.com>
 17 *     Added expect close support, made emulated timeout runtime changeable
 18 *     general cleanups, add some ioctls
 19 */
 20
 21#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 22
 23#include <linux/module.h>
 24#include <linux/moduleparam.h>
 25#include <linux/platform_device.h>
 26#include <linux/init.h>
 27#include <linux/types.h>
 28#include <linux/spinlock.h>
 29#include <linux/miscdevice.h>
 30#include <linux/watchdog.h>
 31#include <linux/pm_runtime.h>
 
 
 32#include <linux/fs.h>
 33#include <linux/mm.h>
 34#include <linux/slab.h>
 35#include <linux/io.h>
 36#include <linux/clk.h>
 37#include <asm/watchdog.h>
 38
 39#define DRV_NAME "sh-wdt"
 40
 41/*
 42 * Default clock division ratio is 5.25 msecs. For an additional table of
 43 * values, consult the asm-sh/watchdog.h. Overload this at module load
 44 * time.
 45 *
 46 * In order for this to work reliably we need to have HZ set to 1000 or
 47 * something quite higher than 100 (or we need a proper high-res timer
 48 * implementation that will deal with this properly), otherwise the 10ms
 49 * resolution of a jiffy is enough to trigger the overflow. For things like
 50 * the SH-4 and SH-5, this isn't necessarily that big of a problem, though
 51 * for the SH-2 and SH-3, this isn't recommended unless the WDT is absolutely
 52 * necssary.
 53 *
 54 * As a result of this timing problem, the only modes that are particularly
 55 * feasible are the 4096 and the 2048 divisors, which yield 5.25 and 2.62ms
 56 * overflow periods respectively.
 57 *
 58 * Also, since we can't really expect userspace to be responsive enough
 59 * before the overflow happens, we maintain two separate timers .. One in
 60 * the kernel for clearing out WOVF every 2ms or so (again, this depends on
 61 * HZ == 1000), and another for monitoring userspace writes to the WDT device.
 62 *
 63 * As such, we currently use a configurable heartbeat interval which defaults
 64 * to 30s. In this case, the userspace daemon is only responsible for periodic
 65 * writes to the device before the next heartbeat is scheduled. If the daemon
 66 * misses its deadline, the kernel timer will allow the WDT to overflow.
 67 */
 68static int clock_division_ratio = WTCSR_CKS_4096;
 69#define next_ping_period(cks)	(jiffies + msecs_to_jiffies(cks - 4))
 70
 
 
 
 
 71#define WATCHDOG_HEARTBEAT 30			/* 30 sec default heartbeat */
 72static int heartbeat = WATCHDOG_HEARTBEAT;	/* in seconds */
 73static bool nowayout = WATCHDOG_NOWAYOUT;
 74static unsigned long next_heartbeat;
 75
 76struct sh_wdt {
 77	void __iomem		*base;
 78	struct device		*dev;
 79	struct clk		*clk;
 80	spinlock_t		lock;
 81
 82	struct timer_list	timer;
 
 
 
 83};
 84
 85static int sh_wdt_start(struct watchdog_device *wdt_dev)
 86{
 87	struct sh_wdt *wdt = watchdog_get_drvdata(wdt_dev);
 88	unsigned long flags;
 89	u8 csr;
 90
 91	pm_runtime_get_sync(wdt->dev);
 92	clk_enable(wdt->clk);
 93
 94	spin_lock_irqsave(&wdt->lock, flags);
 95
 96	next_heartbeat = jiffies + (heartbeat * HZ);
 97	mod_timer(&wdt->timer, next_ping_period(clock_division_ratio));
 98
 99	csr = sh_wdt_read_csr();
100	csr |= WTCSR_WT | clock_division_ratio;
101	sh_wdt_write_csr(csr);
102
103	sh_wdt_write_cnt(0);
104
105	/*
106	 * These processors have a bit of an inconsistent initialization
107	 * process.. starting with SH-3, RSTS was moved to WTCSR, and the
108	 * RSTCSR register was removed.
109	 *
110	 * On the SH-2 however, in addition with bits being in different
111	 * locations, we must deal with RSTCSR outright..
112	 */
113	csr = sh_wdt_read_csr();
114	csr |= WTCSR_TME;
115	csr &= ~WTCSR_RSTS;
116	sh_wdt_write_csr(csr);
117
118#ifdef CONFIG_CPU_SH2
119	csr = sh_wdt_read_rstcsr();
120	csr &= ~RSTCSR_RSTS;
121	sh_wdt_write_rstcsr(csr);
122#endif
123	spin_unlock_irqrestore(&wdt->lock, flags);
124
125	return 0;
126}
127
128static int sh_wdt_stop(struct watchdog_device *wdt_dev)
129{
130	struct sh_wdt *wdt = watchdog_get_drvdata(wdt_dev);
131	unsigned long flags;
132	u8 csr;
133
134	spin_lock_irqsave(&wdt->lock, flags);
135
136	del_timer(&wdt->timer);
137
138	csr = sh_wdt_read_csr();
139	csr &= ~WTCSR_TME;
140	sh_wdt_write_csr(csr);
141
142	spin_unlock_irqrestore(&wdt->lock, flags);
143
144	clk_disable(wdt->clk);
145	pm_runtime_put_sync(wdt->dev);
146
147	return 0;
148}
149
150static int sh_wdt_keepalive(struct watchdog_device *wdt_dev)
151{
152	struct sh_wdt *wdt = watchdog_get_drvdata(wdt_dev);
153	unsigned long flags;
154
155	spin_lock_irqsave(&wdt->lock, flags);
156	next_heartbeat = jiffies + (heartbeat * HZ);
157	spin_unlock_irqrestore(&wdt->lock, flags);
158
159	return 0;
160}
161
162static int sh_wdt_set_heartbeat(struct watchdog_device *wdt_dev, unsigned t)
163{
164	struct sh_wdt *wdt = watchdog_get_drvdata(wdt_dev);
165	unsigned long flags;
166
167	if (unlikely(t < 1 || t > 3600)) /* arbitrary upper limit */
168		return -EINVAL;
169
170	spin_lock_irqsave(&wdt->lock, flags);
171	heartbeat = t;
172	wdt_dev->timeout = t;
173	spin_unlock_irqrestore(&wdt->lock, flags);
174
175	return 0;
176}
177
178static void sh_wdt_ping(unsigned long data)
179{
180	struct sh_wdt *wdt = (struct sh_wdt *)data;
181	unsigned long flags;
182
183	spin_lock_irqsave(&wdt->lock, flags);
184	if (time_before(jiffies, next_heartbeat)) {
185		u8 csr;
186
187		csr = sh_wdt_read_csr();
188		csr &= ~WTCSR_IOVF;
189		sh_wdt_write_csr(csr);
190
191		sh_wdt_write_cnt(0);
192
193		mod_timer(&wdt->timer, next_ping_period(clock_division_ratio));
194	} else
195		dev_warn(wdt->dev, "Heartbeat lost! Will not ping "
196		         "the watchdog\n");
197	spin_unlock_irqrestore(&wdt->lock, flags);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
198}
199
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
200static const struct watchdog_info sh_wdt_info = {
201	.options		= WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT |
202				  WDIOF_MAGICCLOSE,
203	.firmware_version	= 1,
204	.identity		= "SH WDT",
205};
206
207static const struct watchdog_ops sh_wdt_ops = {
208	.owner		= THIS_MODULE,
209	.start		= sh_wdt_start,
210	.stop		= sh_wdt_stop,
211	.ping		= sh_wdt_keepalive,
212	.set_timeout	= sh_wdt_set_heartbeat,
213};
214
215static struct watchdog_device sh_wdt_dev = {
216	.info	= &sh_wdt_info,
217	.ops	= &sh_wdt_ops,
 
218};
219
220static int __devinit sh_wdt_probe(struct platform_device *pdev)
221{
222	struct sh_wdt *wdt;
223	struct resource *res;
224	int rc;
225
226	/*
227	 * As this driver only covers the global watchdog case, reject
228	 * any attempts to register per-CPU watchdogs.
229	 */
230	if (pdev->id != -1)
231		return -EINVAL;
232
233	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
234	if (unlikely(!res))
235		return -EINVAL;
236
 
 
 
 
237	wdt = devm_kzalloc(&pdev->dev, sizeof(struct sh_wdt), GFP_KERNEL);
238	if (unlikely(!wdt))
239		return -ENOMEM;
 
 
240
241	wdt->dev = &pdev->dev;
242
243	wdt->clk = clk_get(&pdev->dev, NULL);
244	if (IS_ERR(wdt->clk)) {
245		/*
246		 * Clock framework support is optional, continue on
247		 * anyways if we don't find a matching clock.
248		 */
249		wdt->clk = NULL;
250	}
251
252	wdt->base = devm_request_and_ioremap(wdt->dev, res);
253	if (unlikely(!wdt->base)) {
254		rc = -EADDRNOTAVAIL;
255		goto err;
256	}
257
258	watchdog_set_nowayout(&sh_wdt_dev, nowayout);
259	watchdog_set_drvdata(&sh_wdt_dev, wdt);
260
261	spin_lock_init(&wdt->lock);
262
263	rc = sh_wdt_set_heartbeat(&sh_wdt_dev, heartbeat);
264	if (unlikely(rc)) {
265		/* Default timeout if invalid */
266		sh_wdt_set_heartbeat(&sh_wdt_dev, WATCHDOG_HEARTBEAT);
267
268		dev_warn(&pdev->dev,
269			 "heartbeat value must be 1<=x<=3600, using %d\n",
270			 sh_wdt_dev.timeout);
271	}
272
273	dev_info(&pdev->dev, "configured with heartbeat=%d sec (nowayout=%d)\n",
274		 sh_wdt_dev.timeout, nowayout);
275
276	rc = watchdog_register_device(&sh_wdt_dev);
277	if (unlikely(rc)) {
278		dev_err(&pdev->dev, "Can't register watchdog (err=%d)\n", rc);
279		goto err;
 
 
280	}
281
282	init_timer(&wdt->timer);
283	wdt->timer.function	= sh_wdt_ping;
284	wdt->timer.data		= (unsigned long)wdt;
285	wdt->timer.expires	= next_ping_period(clock_division_ratio);
286
287	platform_set_drvdata(pdev, wdt);
 
288
289	dev_info(&pdev->dev, "initialized.\n");
290
291	pm_runtime_enable(&pdev->dev);
292
293	return 0;
294
295err:
296	clk_put(wdt->clk);
 
 
 
 
 
 
297
298	return rc;
299}
300
301static int __devexit sh_wdt_remove(struct platform_device *pdev)
302{
303	struct sh_wdt *wdt = platform_get_drvdata(pdev);
 
304
305	platform_set_drvdata(pdev, NULL);
306
307	watchdog_unregister_device(&sh_wdt_dev);
 
 
308
309	pm_runtime_disable(&pdev->dev);
310	clk_put(wdt->clk);
 
 
311
312	return 0;
313}
314
315static void sh_wdt_shutdown(struct platform_device *pdev)
316{
317	sh_wdt_stop(&sh_wdt_dev);
318}
319
320static struct platform_driver sh_wdt_driver = {
321	.driver		= {
322		.name	= DRV_NAME,
323		.owner	= THIS_MODULE,
324	},
325
326	.probe		= sh_wdt_probe,
327	.remove		= __devexit_p(sh_wdt_remove),
328	.shutdown	= sh_wdt_shutdown,
329};
330
331static int __init sh_wdt_init(void)
332{
 
 
333	if (unlikely(clock_division_ratio < 0x5 ||
334		     clock_division_ratio > 0x7)) {
335		clock_division_ratio = WTCSR_CKS_4096;
336
337		pr_info("divisor must be 0x5<=x<=0x7, using %d\n",
338			clock_division_ratio);
 
 
 
 
 
 
 
 
339	}
340
 
 
 
341	return platform_driver_register(&sh_wdt_driver);
342}
343
344static void __exit sh_wdt_exit(void)
345{
346	platform_driver_unregister(&sh_wdt_driver);
347}
348module_init(sh_wdt_init);
349module_exit(sh_wdt_exit);
350
351MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>");
352MODULE_DESCRIPTION("SuperH watchdog driver");
353MODULE_LICENSE("GPL");
354MODULE_ALIAS("platform:" DRV_NAME);
355MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
356
357module_param(clock_division_ratio, int, 0);
358MODULE_PARM_DESC(clock_division_ratio,
359	"Clock division ratio. Valid ranges are from 0x5 (1.31ms) "
360	"to 0x7 (5.25ms). (default=" __MODULE_STRING(WTCSR_CKS_4096) ")");
361
362module_param(heartbeat, int, 0);
363MODULE_PARM_DESC(heartbeat,
364	"Watchdog heartbeat in seconds. (1 <= heartbeat <= 3600, default="
365				__MODULE_STRING(WATCHDOG_HEARTBEAT) ")");
366
367module_param(nowayout, bool, 0);
368MODULE_PARM_DESC(nowayout,
369	"Watchdog cannot be stopped once started (default="
370				__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");