aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorWolfram Sang <w.sang@pengutronix.de>2011-09-27 16:35:40 -0400
committerWim Van Sebroeck <wim@iguana.be>2013-03-01 06:44:34 -0500
commitde6303ab934b1386cad1f62ea6e2200ab7be7d78 (patch)
tree50ca0ccc0d2dabc3a846b83d515be080bce1c136 /drivers
parent1a71fb84fda651105e1e194c2d3a3a13a38210a9 (diff)
watchdog: add new driver for STMP3xxx and i.MX23/28
Replace the existing STMP3xxx driver because it has enough drawbacks that a rewrite is apropriate. The new driver is designed to use the watchdog framework which makes it a lot smaller and avoids open coding the watchdog API again. It also uses now an explicitly exported function from the RTC driver to set up its registers (the old driver silently reused the hopefully(!) already remapped RTC registers). Also, this driver is mach independent, while the old one depends on a mach replaced by another one a year ago. Since the user interface is still the standard watchdog API, users don't need to adapt. Signed-off-by: Wolfram Sang <w.sang@pengutronix.de> Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/watchdog/Kconfig10
-rw-r--r--drivers/watchdog/Makefile1
-rw-r--r--drivers/watchdog/stmp3xxx_rtc_wdt.c111
3 files changed, 122 insertions, 0 deletions
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 7f61687504b7..879232186ca6 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -326,6 +326,16 @@ config STMP3XXX_WATCHDOG
326 To compile this driver as a module, choose M here: the 326 To compile this driver as a module, choose M here: the
327 module will be called stmp3xxx_wdt. 327 module will be called stmp3xxx_wdt.
328 328
329config STMP3XXX_RTC_WATCHDOG
330 tristate "Freescale STMP3XXX & i.MX23/28 watchdog"
331 depends on RTC_DRV_STMP
332 select WATCHDOG_CORE
333 help
334 Say Y here to include support for the watchdog timer inside
335 the RTC for the STMP37XX/378X or i.MX23/28 SoC.
336 To compile this driver as a module, choose M here: the
337 module will be called stmp3xxx_rtc_wdt.
338
329config NUC900_WATCHDOG 339config NUC900_WATCHDOG
330 tristate "Nuvoton NUC900 watchdog" 340 tristate "Nuvoton NUC900 watchdog"
331 depends on ARCH_W90X900 341 depends on ARCH_W90X900
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index f7a612c0a5b4..f1fc6a1d92ca 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -49,6 +49,7 @@ obj-$(CONFIG_DAVINCI_WATCHDOG) += davinci_wdt.o
49obj-$(CONFIG_ORION_WATCHDOG) += orion_wdt.o 49obj-$(CONFIG_ORION_WATCHDOG) += orion_wdt.o
50obj-$(CONFIG_COH901327_WATCHDOG) += coh901327_wdt.o 50obj-$(CONFIG_COH901327_WATCHDOG) += coh901327_wdt.o
51obj-$(CONFIG_STMP3XXX_WATCHDOG) += stmp3xxx_wdt.o 51obj-$(CONFIG_STMP3XXX_WATCHDOG) += stmp3xxx_wdt.o
52obj-$(CONFIG_STMP3XXX_RTC_WATCHDOG) += stmp3xxx_rtc_wdt.o
52obj-$(CONFIG_NUC900_WATCHDOG) += nuc900_wdt.o 53obj-$(CONFIG_NUC900_WATCHDOG) += nuc900_wdt.o
53obj-$(CONFIG_TS72XX_WATCHDOG) += ts72xx_wdt.o 54obj-$(CONFIG_TS72XX_WATCHDOG) += ts72xx_wdt.o
54obj-$(CONFIG_IMX2_WDT) += imx2_wdt.o 55obj-$(CONFIG_IMX2_WDT) += imx2_wdt.o
diff --git a/drivers/watchdog/stmp3xxx_rtc_wdt.c b/drivers/watchdog/stmp3xxx_rtc_wdt.c
new file mode 100644
index 000000000000..c97e98dcde62
--- /dev/null
+++ b/drivers/watchdog/stmp3xxx_rtc_wdt.c
@@ -0,0 +1,111 @@
1/*
2 * Watchdog driver for the RTC based watchdog in STMP3xxx and i.MX23/28
3 *
4 * Author: Wolfram Sang <w.sang@pengutronix.de>
5 *
6 * Copyright (C) 2011-12 Wolfram Sang, Pengutronix
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 version 2 as published by
10 * the Free Software Foundation.
11 */
12#include <linux/init.h>
13#include <linux/kernel.h>
14#include <linux/module.h>
15#include <linux/miscdevice.h>
16#include <linux/watchdog.h>
17#include <linux/platform_device.h>
18#include <linux/stmp3xxx_rtc_wdt.h>
19
20#define WDOG_TICK_RATE 1000 /* 1 kHz clock */
21#define STMP3XXX_DEFAULT_TIMEOUT 19
22#define STMP3XXX_MAX_TIMEOUT (UINT_MAX / WDOG_TICK_RATE)
23
24static int heartbeat = STMP3XXX_DEFAULT_TIMEOUT;
25module_param(heartbeat, uint, 0);
26MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat period in seconds from 1 to "
27 __MODULE_STRING(STMP3XXX_MAX_TIMEOUT) ", default "
28 __MODULE_STRING(STMP3XXX_DEFAULT_TIMEOUT));
29
30static int wdt_start(struct watchdog_device *wdd)
31{
32 struct device *dev = watchdog_get_drvdata(wdd);
33 struct stmp3xxx_wdt_pdata *pdata = dev->platform_data;
34
35 pdata->wdt_set_timeout(dev->parent, wdd->timeout * WDOG_TICK_RATE);
36 return 0;
37}
38
39static int wdt_stop(struct watchdog_device *wdd)
40{
41 struct device *dev = watchdog_get_drvdata(wdd);
42 struct stmp3xxx_wdt_pdata *pdata = dev->platform_data;
43
44 pdata->wdt_set_timeout(dev->parent, 0);
45 return 0;
46}
47
48static int wdt_set_timeout(struct watchdog_device *wdd, unsigned new_timeout)
49{
50 wdd->timeout = new_timeout;
51 return wdt_start(wdd);
52}
53
54static const struct watchdog_info stmp3xxx_wdt_ident = {
55 .options = WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
56 .identity = "STMP3XXX RTC Watchdog",
57};
58
59static const struct watchdog_ops stmp3xxx_wdt_ops = {
60 .owner = THIS_MODULE,
61 .start = wdt_start,
62 .stop = wdt_stop,
63 .set_timeout = wdt_set_timeout,
64};
65
66static struct watchdog_device stmp3xxx_wdd = {
67 .info = &stmp3xxx_wdt_ident,
68 .ops = &stmp3xxx_wdt_ops,
69 .min_timeout = 1,
70 .max_timeout = STMP3XXX_MAX_TIMEOUT,
71 .status = WATCHDOG_NOWAYOUT_INIT_STATUS,
72};
73
74static int stmp3xxx_wdt_probe(struct platform_device *pdev)
75{
76 int ret;
77
78 watchdog_set_drvdata(&stmp3xxx_wdd, &pdev->dev);
79
80 stmp3xxx_wdd.timeout = clamp_t(unsigned, heartbeat, 1, STMP3XXX_MAX_TIMEOUT);
81
82 ret = watchdog_register_device(&stmp3xxx_wdd);
83 if (ret < 0) {
84 dev_err(&pdev->dev, "cannot register watchdog device\n");
85 return ret;
86 }
87
88 dev_info(&pdev->dev, "initialized watchdog with heartbeat %ds\n",
89 stmp3xxx_wdd.timeout);
90 return 0;
91}
92
93static int stmp3xxx_wdt_remove(struct platform_device *pdev)
94{
95 watchdog_unregister_device(&stmp3xxx_wdd);
96 return 0;
97}
98
99static struct platform_driver stmp3xxx_wdt_driver = {
100 .driver = {
101 .name = "stmp3xxx_rtc_wdt",
102 },
103 .probe = stmp3xxx_wdt_probe,
104 .remove = stmp3xxx_wdt_remove,
105};
106module_platform_driver(stmp3xxx_wdt_driver);
107
108MODULE_DESCRIPTION("STMP3XXX RTC Watchdog Driver");
109MODULE_LICENSE("GPL v2");
110MODULE_AUTHOR("Wolfram Sang <w.sang@pengutronix.de>");
111MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);