Hi, All
The patch series is intended to convert to use the watchdog framework,
and add support to device tree.
It has been tested on sam9m10g45ek, sam9g20ek, sam9263ek and sam9g25ek.
It is based on v3.7-rc5.
Best Regards
Wenyou Yang
Wenyou Yang (11):
watchdog/at91sam9_wdt: remove the file_operations struct
watchdog/at91sam9_wdt: change the at91wdt_private struct to the
at91wdt_drvdata struct
watchdog/at91sam9_wdt: change the wdt_read and wdt_write macro to the
inline function
watchdog/at91sam9_wdt: change "at91_wdt_settimeout" function name to
"at91wdt_enable"
watchdog/at91sam9_wdt: add to use the watchdog framework
watchdog/at91sam9_wdt: change the timer function name
watchdog/at91sam9_wdt: add nowayout helpers to Watchdog Timer Driver
Kernel API
watchdog/at91sam9_wdt: use module_platform_driver()
watchdog/at91sam9_wdt: add support to device tree
watchdog/at91sam9_wdt: using dev_info replaces pr_info, dev_crit
repalces pr_crit
ARM: dts: add the watchdog nodes for atmel SoC
.../devicetree/bindings/watchdog/atmel-wdt.txt | 14 +
arch/arm/boot/dts/at91sam9260.dtsi | 6 +
arch/arm/boot/dts/at91sam9263.dtsi | 6 +
arch/arm/boot/dts/at91sam9263ek.dts | 4 +
arch/arm/boot/dts/at91sam9g20ek_common.dtsi | 4 +
arch/arm/boot/dts/at91sam9g25ek.dts | 4 +
arch/arm/boot/dts/at91sam9g45.dtsi | 5 +
arch/arm/boot/dts/at91sam9m10g45ek.dts | 4 +
arch/arm/boot/dts/at91sam9n12.dtsi | 6 +
arch/arm/boot/dts/at91sam9n12ek.dts | 4 +
arch/arm/boot/dts/at91sam9x5.dtsi | 6 +
drivers/watchdog/Kconfig | 1 +
drivers/watchdog/at91sam9_wdt.c | 294 ++++++++------------
13 files changed, 185 insertions(+), 173 deletions(-)
create mode 100644 Documentation/devicetree/bindings/watchdog/atmel-wdt.txt
--
1.7.9.5
Remove the file_operations struct and miscdevice struct for future
add to use the watchdog framework.
Signed-off-by: Wenyou Yang <[email protected]>
---
drivers/watchdog/at91sam9_wdt.c | 131 ---------------------------------------
1 file changed, 131 deletions(-)
diff --git a/drivers/watchdog/at91sam9_wdt.c b/drivers/watchdog/at91sam9_wdt.c
index 05e1be8..549c256 100644
--- a/drivers/watchdog/at91sam9_wdt.c
+++ b/drivers/watchdog/at91sam9_wdt.c
@@ -18,11 +18,9 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/errno.h>
-#include <linux/fs.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/kernel.h>
-#include <linux/miscdevice.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/platform_device.h>
@@ -31,7 +29,6 @@
#include <linux/jiffies.h>
#include <linux/timer.h>
#include <linux/bitops.h>
-#include <linux/uaccess.h>
#include "at91sam9_wdt.h"
@@ -102,35 +99,6 @@ static void at91_ping(unsigned long data)
}
/*
- * Watchdog device is opened, and watchdog starts running.
- */
-static int at91_wdt_open(struct inode *inode, struct file *file)
-{
- if (test_and_set_bit(0, &at91wdt_private.open))
- return -EBUSY;
-
- at91wdt_private.next_heartbeat = jiffies + heartbeat * HZ;
- mod_timer(&at91wdt_private.timer, jiffies + WDT_TIMEOUT);
-
- return nonseekable_open(inode, file);
-}
-
-/*
- * Close the watchdog device.
- */
-static int at91_wdt_close(struct inode *inode, struct file *file)
-{
- clear_bit(0, &at91wdt_private.open);
-
- /* stop internal ping */
- if (!at91wdt_private.expect_close)
- del_timer(&at91wdt_private.timer);
-
- at91wdt_private.expect_close = 0;
- return 0;
-}
-
-/*
* Set the watchdog time interval in 1/256Hz (write-once)
* Counter is 12 bit.
*/
@@ -168,101 +136,11 @@ static const struct watchdog_info at91_wdt_info = {
WDIOF_MAGICCLOSE,
};
-/*
- * Handle commands from user-space.
- */
-static long at91_wdt_ioctl(struct file *file,
- unsigned int cmd, unsigned long arg)
-{
- void __user *argp = (void __user *)arg;
- int __user *p = argp;
- int new_value;
-
- switch (cmd) {
- case WDIOC_GETSUPPORT:
- return copy_to_user(argp, &at91_wdt_info,
- sizeof(at91_wdt_info)) ? -EFAULT : 0;
-
- case WDIOC_GETSTATUS:
- case WDIOC_GETBOOTSTATUS:
- return put_user(0, p);
-
- case WDIOC_KEEPALIVE:
- at91wdt_private.next_heartbeat = jiffies + heartbeat * HZ;
- return 0;
-
- case WDIOC_SETTIMEOUT:
- if (get_user(new_value, p))
- return -EFAULT;
-
- heartbeat = new_value;
- at91wdt_private.next_heartbeat = jiffies + heartbeat * HZ;
-
- return put_user(new_value, p); /* return current value */
-
- case WDIOC_GETTIMEOUT:
- return put_user(heartbeat, p);
- }
- return -ENOTTY;
-}
-
-/*
- * Pat the watchdog whenever device is written to.
- */
-static ssize_t at91_wdt_write(struct file *file, const char *data, size_t len,
- loff_t *ppos)
-{
- if (!len)
- return 0;
-
- /* Scan for magic character */
- if (!nowayout) {
- size_t i;
-
- at91wdt_private.expect_close = 0;
-
- for (i = 0; i < len; i++) {
- char c;
- if (get_user(c, data + i))
- return -EFAULT;
- if (c == 'V') {
- at91wdt_private.expect_close = 42;
- break;
- }
- }
- }
-
- at91wdt_private.next_heartbeat = jiffies + heartbeat * HZ;
-
- return len;
-}
-
-/* ......................................................................... */
-
-static const struct file_operations at91wdt_fops = {
- .owner = THIS_MODULE,
- .llseek = no_llseek,
- .unlocked_ioctl = at91_wdt_ioctl,
- .open = at91_wdt_open,
- .release = at91_wdt_close,
- .write = at91_wdt_write,
-};
-
-static struct miscdevice at91wdt_miscdev = {
- .minor = WATCHDOG_MINOR,
- .name = "watchdog",
- .fops = &at91wdt_fops,
-};
-
static int __init at91wdt_probe(struct platform_device *pdev)
{
struct resource *r;
int res;
- if (at91wdt_miscdev.parent)
- return -EBUSY;
- at91wdt_miscdev.parent = &pdev->dev;
-
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!r)
return -ENODEV;
@@ -277,10 +155,6 @@ static int __init at91wdt_probe(struct platform_device *pdev)
if (res)
return res;
- res = misc_register(&at91wdt_miscdev);
- if (res)
- return res;
-
at91wdt_private.next_heartbeat = jiffies + heartbeat * HZ;
setup_timer(&at91wdt_private.timer, at91_ping, 0);
mod_timer(&at91wdt_private.timer, jiffies + WDT_TIMEOUT);
@@ -295,10 +169,6 @@ static int __exit at91wdt_remove(struct platform_device *pdev)
{
int res;
- res = misc_deregister(&at91wdt_miscdev);
- if (!res)
- at91wdt_miscdev.parent = NULL;
-
return res;
}
@@ -326,4 +196,3 @@ module_exit(at91sam_wdt_exit);
MODULE_AUTHOR("Renaud CERRATO <[email protected]>");
MODULE_DESCRIPTION("Watchdog driver for Atmel AT91SAM9x processors");
MODULE_LICENSE("GPL");
-MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
--
1.7.9.5
Signed-off-by: Wenyou Yang <[email protected]>
---
drivers/watchdog/at91sam9_wdt.c | 28 ++++++++++++++++++----------
1 file changed, 18 insertions(+), 10 deletions(-)
diff --git a/drivers/watchdog/at91sam9_wdt.c b/drivers/watchdog/at91sam9_wdt.c
index 31c914a..98e7d5a 100644
--- a/drivers/watchdog/at91sam9_wdt.c
+++ b/drivers/watchdog/at91sam9_wdt.c
@@ -34,11 +34,6 @@
#define DRV_NAME "AT91SAM9 Watchdog"
-#define wdt_read(field) \
- __raw_readl(at91wdt_private.base + field)
-#define wdt_write(field, val) \
- __raw_writel((val), at91wdt_private.base + field)
-
/* AT91SAM9 watchdog runs a 12bit counter @ 256Hz,
* use this to convert a watchdog
* value from/to milliseconds.
@@ -75,13 +70,24 @@ struct at91wdt_drvdata {
/* ......................................................................... */
+static inline unsigned int wdt_read(struct at91wdt_drvdata *driver_data,
+ unsigned int field)
+{
+ return __raw_readl(driver_data->base + field);
+}
+
+static inline void wdt_write(struct at91wdt_drvdata *driver_data,
+ unsigned int field, unsigned int val)
+{
+ __raw_writel((val), driver_data->base + field);
+}
/*
* Reload the watchdog timer. (ie, pat the watchdog)
*/
-static inline void at91_wdt_reset(void)
+static inline void at91_wdt_reset(struct at91wdt_drvdata *driver_data)
{
- wdt_write(AT91_WDT_CR, AT91_WDT_KEY | AT91_WDT_WDRSTT);
+ wdt_write(driver_data, AT91_WDT_CR, AT91_WDT_KEY | AT91_WDT_WDRSTT);
}
/*
@@ -103,13 +109,15 @@ static void at91_ping(unsigned long data)
* Set the watchdog time interval in 1/256Hz (write-once)
* Counter is 12 bit.
*/
-static int at91_wdt_settimeout(unsigned int timeout)
+static int at91_wdt_settimeout(struct watchdog_device *wddev,
+ unsigned int timeout)
{
+ struct at91wdt_drvdata *driver_data = watchdog_get_drvdata(wddev);
unsigned int reg;
unsigned int mr;
/* Check if disabled */
- mr = wdt_read(AT91_WDT_MR);
+ mr = wdt_read(driver_data, AT91_WDT_MR);
if (mr & AT91_WDT_WDDIS) {
pr_err("sorry, watchdog is disabled\n");
return -EIO;
@@ -126,7 +134,7 @@ static int at91_wdt_settimeout(unsigned int timeout)
| AT91_WDT_WDDBGHLT /* disabled in debug mode */
| AT91_WDT_WDD /* restart at any time */
| (timeout & AT91_WDT_WDV); /* timer value */
- wdt_write(AT91_WDT_MR, reg);
+ wdt_write(driver_data, AT91_WDT_MR, reg);
return 0;
}
--
1.7.9.5
Using module_platform_driver() replaces module_init() and module_exit()
and makes the code simpler.
Signed-off-by: Wenyou Yang <[email protected]>
---
drivers/watchdog/at91sam9_wdt.c | 14 ++------------
1 file changed, 2 insertions(+), 12 deletions(-)
diff --git a/drivers/watchdog/at91sam9_wdt.c b/drivers/watchdog/at91sam9_wdt.c
index 187e33f..e7ce9ea 100644
--- a/drivers/watchdog/at91sam9_wdt.c
+++ b/drivers/watchdog/at91sam9_wdt.c
@@ -252,6 +252,7 @@ static int __exit at91wdt_remove(struct platform_device *pdev)
}
static struct platform_driver at91wdt_driver = {
+ .probe = at91wdt_probe,
.remove = __exit_p(at91wdt_remove),
.driver = {
.name = "at91_wdt",
@@ -259,18 +260,7 @@ static struct platform_driver at91wdt_driver = {
},
};
-static int __init at91sam_wdt_init(void)
-{
- return platform_driver_probe(&at91wdt_driver, at91wdt_probe);
-}
-
-static void __exit at91sam_wdt_exit(void)
-{
- platform_driver_unregister(&at91wdt_driver);
-}
-
-module_init(at91sam_wdt_init);
-module_exit(at91sam_wdt_exit);
+module_platform_driver(at91wdt_driver);
MODULE_AUTHOR("Renaud CERRATO <[email protected]>");
MODULE_DESCRIPTION("Watchdog driver for Atmel AT91SAM9x processors");
--
1.7.9.5
Signed-off-by: Wenyou Yang <[email protected]>
---
drivers/watchdog/at91sam9_wdt.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/watchdog/at91sam9_wdt.c b/drivers/watchdog/at91sam9_wdt.c
index cba5c5d..bd74f40 100644
--- a/drivers/watchdog/at91sam9_wdt.c
+++ b/drivers/watchdog/at91sam9_wdt.c
@@ -106,7 +106,7 @@ static void at91wdt_timer_tick(unsigned long data)
if (!watchdog_is_open(wddev))
driver_data->next_heartbeat = jiffies + heartbeat * HZ;
} else
- pr_crit("I will reset your machine !\n");
+ dev_crit(wddev->dev, "I will reset your machine !\n");
}
static int at91wdt_enable(struct watchdog_device *wddev, unsigned int timeout)
@@ -239,7 +239,7 @@ static int __init at91wdt_probe(struct platform_device *pdev)
(unsigned long)&at91_wddev);
mod_timer(&driver_data->timer, jiffies + WDT_TIMEOUT);
- pr_info("enabled (heartbeat=%d sec, nowayout=%d)\n",
+ dev_info(&pdev->dev, "enabled (heartbeat=%d sec, nowayout=%d)\n",
heartbeat, nowayout);
return 0;
--
1.7.9.5
Signed-off-by: Wenyou Yang <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
---
drivers/watchdog/at91sam9_wdt.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/drivers/watchdog/at91sam9_wdt.c b/drivers/watchdog/at91sam9_wdt.c
index e7ce9ea..cba5c5d 100644
--- a/drivers/watchdog/at91sam9_wdt.c
+++ b/drivers/watchdog/at91sam9_wdt.c
@@ -32,6 +32,7 @@
#include <linux/jiffies.h>
#include <linux/timer.h>
#include <linux/bitops.h>
+#include <linux/of.h>
#include "at91sam9_wdt.h"
@@ -251,12 +252,21 @@ static int __exit at91wdt_remove(struct platform_device *pdev)
return 0;
}
+#ifdef CONFIG_OF
+static const struct of_device_id at91wdt_match[] = {
+ { .compatible = "atmel,at91sam-wdt" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, at91wdt_match);
+#endif
+
static struct platform_driver at91wdt_driver = {
.probe = at91wdt_probe,
.remove = __exit_p(at91wdt_remove),
.driver = {
.name = "at91_wdt",
.owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(at91wdt_match),
},
};
--
1.7.9.5
Signed-off-by: Wenyou Yang <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
---
.../devicetree/bindings/watchdog/atmel-wdt.txt | 14 ++++++++++++++
arch/arm/boot/dts/at91sam9260.dtsi | 6 ++++++
arch/arm/boot/dts/at91sam9263.dtsi | 6 ++++++
arch/arm/boot/dts/at91sam9263ek.dts | 4 ++++
arch/arm/boot/dts/at91sam9g20ek_common.dtsi | 4 ++++
arch/arm/boot/dts/at91sam9g25ek.dts | 4 ++++
arch/arm/boot/dts/at91sam9g45.dtsi | 5 +++++
arch/arm/boot/dts/at91sam9m10g45ek.dts | 4 ++++
arch/arm/boot/dts/at91sam9n12.dtsi | 6 ++++++
arch/arm/boot/dts/at91sam9n12ek.dts | 4 ++++
arch/arm/boot/dts/at91sam9x5.dtsi | 6 ++++++
11 files changed, 63 insertions(+)
create mode 100644 Documentation/devicetree/bindings/watchdog/atmel-wdt.txt
diff --git a/Documentation/devicetree/bindings/watchdog/atmel-wdt.txt b/Documentation/devicetree/bindings/watchdog/atmel-wdt.txt
new file mode 100644
index 0000000..5d09b87
--- /dev/null
+++ b/Documentation/devicetree/bindings/watchdog/atmel-wdt.txt
@@ -0,0 +1,14 @@
+* Atmel's Watchdog Timer Controller
+
+Required properties:
+- compatible : should be "atmel,at91sam-wdt"
+- reg : base physical address of the controller and length of memory mapped
+ region.
+
+Example:
+
+ watchdog@fffffd40 {
+ compatible = "atmel,at91sam-wdt";
+ reg = <0xfffffd40 0x10>;
+ status = "okay";
+ };
diff --git a/arch/arm/boot/dts/at91sam9260.dtsi b/arch/arm/boot/dts/at91sam9260.dtsi
index d410581..81687a3 100644
--- a/arch/arm/boot/dts/at91sam9260.dtsi
+++ b/arch/arm/boot/dts/at91sam9260.dtsi
@@ -86,6 +86,12 @@
interrupts = <1 4 7>;
};
+ watchdog@fffffd40 {
+ compatible = "atmel,at91sam-wdt";
+ reg = <0xfffffd40 0x10>;
+ status = "disabled";
+ };
+
tcb0: timer@fffa0000 {
compatible = "atmel,at91rm9200-tcb";
reg = <0xfffa0000 0x100>;
diff --git a/arch/arm/boot/dts/at91sam9263.dtsi b/arch/arm/boot/dts/at91sam9263.dtsi
index 3e6e5c1..a25826b 100644
--- a/arch/arm/boot/dts/at91sam9263.dtsi
+++ b/arch/arm/boot/dts/at91sam9263.dtsi
@@ -73,6 +73,12 @@
interrupts = <1 4 7>;
};
+ watchdog@fffffd40 {
+ compatible = "atmel,at91sam-wdt";
+ reg = <0xfffffd40 0x10>;
+ status = "disabled";
+ };
+
tcb0: timer@fff7c000 {
compatible = "atmel,at91rm9200-tcb";
reg = <0xfff7c000 0x100>;
diff --git a/arch/arm/boot/dts/at91sam9263ek.dts b/arch/arm/boot/dts/at91sam9263ek.dts
index f86ac4b..bc947ea 100644
--- a/arch/arm/boot/dts/at91sam9263ek.dts
+++ b/arch/arm/boot/dts/at91sam9263ek.dts
@@ -50,6 +50,10 @@
atmel,vbus-gpio = <&pioA 25 0>;
status = "okay";
};
+
+ watchdog@fffffd40 {
+ status = "okay";
+ };
};
nand0: nand@40000000 {
diff --git a/arch/arm/boot/dts/at91sam9g20ek_common.dtsi b/arch/arm/boot/dts/at91sam9g20ek_common.dtsi
index e6391a4..e5797b7 100644
--- a/arch/arm/boot/dts/at91sam9g20ek_common.dtsi
+++ b/arch/arm/boot/dts/at91sam9g20ek_common.dtsi
@@ -51,6 +51,10 @@
atmel,vbus-gpio = <&pioC 5 0>;
status = "okay";
};
+
+ watchdog@fffffd40 {
+ status = "okay";
+ };
};
nand0: nand@40000000 {
diff --git a/arch/arm/boot/dts/at91sam9g25ek.dts b/arch/arm/boot/dts/at91sam9g25ek.dts
index 877c08f..2f03edc 100644
--- a/arch/arm/boot/dts/at91sam9g25ek.dts
+++ b/arch/arm/boot/dts/at91sam9g25ek.dts
@@ -44,6 +44,10 @@
i2c2: i2c@f8018000 {
status = "okay";
};
+
+ watchdog@fffffe40 {
+ status = "okay";
+ };
};
usb0: ohci@00600000 {
diff --git a/arch/arm/boot/dts/at91sam9g45.dtsi b/arch/arm/boot/dts/at91sam9g45.dtsi
index 3add030..c6c2c09 100644
--- a/arch/arm/boot/dts/at91sam9g45.dtsi
+++ b/arch/arm/boot/dts/at91sam9g45.dtsi
@@ -84,6 +84,11 @@
interrupts = <1 4 7>;
};
+ watchdog@fffffd40 {
+ compatible = "atmel,at91sam-wdt";
+ reg = <0xfffffd40 0x10>;
+ status = "disabled";
+ };
shdwc@fffffd10 {
compatible = "atmel,at91sam9rl-shdwc";
diff --git a/arch/arm/boot/dts/at91sam9m10g45ek.dts b/arch/arm/boot/dts/at91sam9m10g45ek.dts
index 15e1dd4..371ab40 100644
--- a/arch/arm/boot/dts/at91sam9m10g45ek.dts
+++ b/arch/arm/boot/dts/at91sam9m10g45ek.dts
@@ -54,6 +54,10 @@
i2c1: i2c@fff88000 {
status = "okay";
};
+
+ watchdog@fffffd40 {
+ status = "okay";
+ };
};
nand0: nand@40000000 {
diff --git a/arch/arm/boot/dts/at91sam9n12.dtsi b/arch/arm/boot/dts/at91sam9n12.dtsi
index 82508d6..e5e6363 100644
--- a/arch/arm/boot/dts/at91sam9n12.dtsi
+++ b/arch/arm/boot/dts/at91sam9n12.dtsi
@@ -79,6 +79,12 @@
interrupts = <1 4 7>;
};
+ watchdog@fffffe40 {
+ compatible = "atmel,at91sam-wdt";
+ reg = <0xfffffe40 0x10>;
+ status = "disabled";
+ };
+
shdwc@fffffe10 {
compatible = "atmel,at91sam9x5-shdwc";
reg = <0xfffffe10 0x10>;
diff --git a/arch/arm/boot/dts/at91sam9n12ek.dts b/arch/arm/boot/dts/at91sam9n12ek.dts
index 912b2c2..abeda7a 100644
--- a/arch/arm/boot/dts/at91sam9n12ek.dts
+++ b/arch/arm/boot/dts/at91sam9n12ek.dts
@@ -45,6 +45,10 @@
i2c1: i2c@f8014000 {
status = "okay";
};
+
+ watchdog@fffffe40 {
+ status = "okay";
+ };
};
nand0: nand@40000000 {
diff --git a/arch/arm/boot/dts/at91sam9x5.dtsi b/arch/arm/boot/dts/at91sam9x5.dtsi
index 03fc136..485f171 100644
--- a/arch/arm/boot/dts/at91sam9x5.dtsi
+++ b/arch/arm/boot/dts/at91sam9x5.dtsi
@@ -87,6 +87,12 @@
interrupts = <1 4 7>;
};
+ watchdog@fffffe40 {
+ compatible = "atmel,at91sam-wdt";
+ reg = <0xfffffe40 0x10>;
+ status = "disabled";
+ };
+
tcb0: timer@f8008000 {
compatible = "atmel,at91sam9x5-tcb";
reg = <0xf8008000 0x100>;
--
1.7.9.5
Signed-off-by: Wenyou Yang <[email protected]>
---
drivers/watchdog/at91sam9_wdt.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/watchdog/at91sam9_wdt.c b/drivers/watchdog/at91sam9_wdt.c
index d764f36..187e33f 100644
--- a/drivers/watchdog/at91sam9_wdt.c
+++ b/drivers/watchdog/at91sam9_wdt.c
@@ -225,6 +225,8 @@ static int __init at91wdt_probe(struct platform_device *pdev)
return ret;
}
+ watchdog_set_nowayout(&at91_wddev, nowayout);
+
ret = watchdog_register_device(&at91_wddev);
if (ret) {
dev_err(&pdev->dev, "cannot register watchdog (%d)\n", ret);
--
1.7.9.5
Change the "at91_wdt_settimeout" function name to "at91wdt_enable" for more reasonable,
and also set the drvdata->enabled value.
Signed-off-by: Wenyou Yang <[email protected]>
---
drivers/watchdog/at91sam9_wdt.c | 28 +++++++++++++++++-----------
1 file changed, 17 insertions(+), 11 deletions(-)
diff --git a/drivers/watchdog/at91sam9_wdt.c b/drivers/watchdog/at91sam9_wdt.c
index 98e7d5a..e2d6111 100644
--- a/drivers/watchdog/at91sam9_wdt.c
+++ b/drivers/watchdog/at91sam9_wdt.c
@@ -13,6 +13,9 @@
* The Watchdog Timer Mode Register can be only written to once. If the
* timeout need to be set from Linux, be sure that the bootstrap or the
* bootloader doesn't write to this register.
+ * The Watchdog Timer default is running with maximum counter value
+ * (WDV=0xfff) at reset, i.e., at power-up. It MUST be either disabled
+ * or be reprogrammed within the maxinum margin(16s).
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@@ -105,20 +108,20 @@ static void at91_ping(unsigned long data)
pr_crit("I will reset your machine !\n");
}
-/*
- * Set the watchdog time interval in 1/256Hz (write-once)
- * Counter is 12 bit.
- */
-static int at91_wdt_settimeout(struct watchdog_device *wddev,
- unsigned int timeout)
+static int at91wdt_enable(struct watchdog_device *wddev, unsigned int timeout)
{
struct at91wdt_drvdata *driver_data = watchdog_get_drvdata(wddev);
unsigned int reg;
unsigned int mr;
- /* Check if disabled */
+ /* Check if the watchdog is disabled,
+ * if disabled, the reason is the bootstrap or the bootloader has
+ * written the Watchdog Timer Mode Register to disable the
+ * watchdog timer
+ */
mr = wdt_read(driver_data, AT91_WDT_MR);
if (mr & AT91_WDT_WDDIS) {
+ driver_data->enabled = false;
pr_err("sorry, watchdog is disabled\n");
return -EIO;
}
@@ -136,6 +139,8 @@ static int at91_wdt_settimeout(struct watchdog_device *wddev,
| (timeout & AT91_WDT_WDV); /* timer value */
wdt_write(driver_data, AT91_WDT_MR, reg);
+ driver_data->enabled = true;
+
return 0;
}
@@ -169,10 +174,11 @@ static int __init at91wdt_probe(struct platform_device *pdev)
watchdog_set_drvdata(&at91_wddev, driver_data);
- /* Set watchdog */
- res = at91_wdt_settimeout(ms_to_ticks(WDT_HW_TIMEOUT * 1000));
- if (res)
- return res;
+ res = at91wdt_enable(&at91_wddev);
+ if (res) {
+ dev_err(&pdev->dev, "cannot enable watchdog (%d)\n", ret);
+ return ret;
+ }
driver_data->next_heartbeat = jiffies + heartbeat * HZ;
setup_timer(&driver_data->timer, at91_ping, 0);
--
1.7.9.5
Change the timer function name "at91_ping" to "at91wdt_timer_tick"
as an appropriate name, and change at91_wdt_reset to at91wdt_reset
Signed-off-by: Wenyou Yang <[email protected]>
---
drivers/watchdog/at91sam9_wdt.c | 16 ++++------------
1 file changed, 4 insertions(+), 12 deletions(-)
diff --git a/drivers/watchdog/at91sam9_wdt.c b/drivers/watchdog/at91sam9_wdt.c
index 84c2aa7..d764f36 100644
--- a/drivers/watchdog/at91sam9_wdt.c
+++ b/drivers/watchdog/at91sam9_wdt.c
@@ -62,8 +62,6 @@ module_param(nowayout, bool, 0);
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started "
"(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
-static void at91_ping(unsigned long data);
-
struct at91wdt_drvdata {
void __iomem *base;
bool enabled; /* indicate if the watchdog is eabled */
@@ -90,24 +88,18 @@ static inline bool watchdog_is_open(struct watchdog_device *wddev)
return test_bit(WDOG_DEV_OPEN, &wddev->status);
}
-/*
- * Reload the watchdog timer. (ie, pat the watchdog)
- */
-static inline void at91_wdt_reset(struct at91wdt_drvdata *driver_data)
+static inline void at91wdt_reset(struct at91wdt_drvdata *driver_data)
{
wdt_write(driver_data, AT91_WDT_CR, AT91_WDT_KEY | AT91_WDT_WDRSTT);
}
-/*
- * Timer tick
- */
-static void at91_ping(unsigned long data)
+static void at91wdt_timer_tick(unsigned long data)
{
struct watchdog_device *wddev = (struct watchdog_device *)data;
struct at91wdt_drvdata *driver_data = watchdog_get_drvdata(wddev);
if (time_before(jiffies, driver_data->next_heartbeat)) {
- at91_wdt_reset(driver_data);
+ at91wdt_reset(driver_data);
mod_timer(&driver_data->timer, jiffies + WDT_TIMEOUT);
if (!watchdog_is_open(wddev))
@@ -240,7 +232,7 @@ static int __init at91wdt_probe(struct platform_device *pdev)
}
driver_data->next_heartbeat = jiffies + heartbeat * HZ;
- setup_timer(&driver_data->timer, at91_ping,
+ setup_timer(&driver_data->timer, at91wdt_timer_tick,
(unsigned long)&at91_wddev);
mod_timer(&driver_data->timer, jiffies + WDT_TIMEOUT);
--
1.7.9.5
For the Watchdog Timer Mode Register can be only written only once,
so struct watchdog_info options only support WDIOF_KEEPALIVEPING,
not support WDIOF_SETTIMEOUT and WDIOF_MAGICCLOSE.
Signed-off-by: Wenyou Yang <[email protected]>
---
drivers/watchdog/Kconfig | 1 +
drivers/watchdog/at91sam9_wdt.c | 90 ++++++++++++++++++++++++++++++++-------
2 files changed, 76 insertions(+), 15 deletions(-)
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index ad1bb93..dda695f 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -114,6 +114,7 @@ config AT91RM9200_WATCHDOG
config AT91SAM9X_WATCHDOG
tristate "AT91SAM9X / AT91CAP9 watchdog"
depends on ARCH_AT91 && !ARCH_AT91RM9200
+ select WATCHDOG_CORE
help
Watchdog timer embedded into AT91SAM9X and AT91CAP9 chips. This will
reboot your system when the timeout is reached.
diff --git a/drivers/watchdog/at91sam9_wdt.c b/drivers/watchdog/at91sam9_wdt.c
index e2d6111..84c2aa7 100644
--- a/drivers/watchdog/at91sam9_wdt.c
+++ b/drivers/watchdog/at91sam9_wdt.c
@@ -85,6 +85,11 @@ static inline void wdt_write(struct at91wdt_drvdata *driver_data,
__raw_writel((val), driver_data->base + field);
}
+static inline bool watchdog_is_open(struct watchdog_device *wddev)
+{
+ return test_bit(WDOG_DEV_OPEN, &wddev->status);
+}
+
/*
* Reload the watchdog timer. (ie, pat the watchdog)
*/
@@ -101,9 +106,12 @@ static void at91_ping(unsigned long data)
struct watchdog_device *wddev = (struct watchdog_device *)data;
struct at91wdt_drvdata *driver_data = watchdog_get_drvdata(wddev);
- if (time_before(jiffies, driver_data->next_heartbeat))
- at91_wdt_reset();
+ if (time_before(jiffies, driver_data->next_heartbeat)) {
+ at91_wdt_reset(driver_data);
mod_timer(&driver_data->timer, jiffies + WDT_TIMEOUT);
+
+ if (!watchdog_is_open(wddev))
+ driver_data->next_heartbeat = jiffies + heartbeat * HZ;
} else
pr_crit("I will reset your machine !\n");
}
@@ -144,17 +152,62 @@ static int at91wdt_enable(struct watchdog_device *wddev, unsigned int timeout)
return 0;
}
-static const struct watchdog_info at91_wdt_info = {
+static int at91wdt_start(struct watchdog_device *wddev)
+{
+ struct at91wdt_drvdata *driver_data = watchdog_get_drvdata(wddev);
+
+ if (driver_data->enabled)
+ return 0;
+ else
+ return -EIO;
+}
+
+static int at91wdt_stop(struct watchdog_device *wddev)
+{
+ struct at91wdt_drvdata *driver_data = watchdog_get_drvdata(wddev);
+
+ if (driver_data->enabled)
+ return -EIO;
+ else
+ return 0;
+}
+
+static int at91wdt_keepalive(struct watchdog_device *wddev)
+{
+ struct at91wdt_drvdata *driver_data = watchdog_get_drvdata(wddev);
+
+ if (driver_data->enabled) {
+ driver_data->next_heartbeat = jiffies + heartbeat * HZ;
+ return 0;
+ } else
+ return -EIO;
+}
+
+/* ......................................................................... */
+
+static const struct watchdog_info at91wdt_info = {
.identity = DRV_NAME,
- .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING |
- WDIOF_MAGICCLOSE,
+ .options = WDIOF_KEEPALIVEPING,
+ .firmware_version = 0,
+};
+
+static struct watchdog_ops at91wdt_ops = {
+ .owner = THIS_MODULE,
+ .start = at91wdt_start,
+ .stop = at91wdt_stop,
+ .ping = at91wdt_keepalive,
+};
+
+static struct watchdog_device at91_wddev = {
+ .info = &at91wdt_info,
+ .ops = &at91wdt_ops,
};
static int __init at91wdt_probe(struct platform_device *pdev)
{
struct at91wdt_drvdata *driver_data;
- struct resource *r;
- int res;
+ struct resource *res;
+ int ret;
driver_data = devm_kzalloc(&pdev->dev,
sizeof(*driver_data), GFP_KERNEL);
@@ -163,10 +216,10 @@ static int __init at91wdt_probe(struct platform_device *pdev)
return -ENOMEM;
}
- r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!r)
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res)
return -ENODEV;
- driver_data->base = ioremap(r->start, resource_size(r));
+ driver_data->base = ioremap(res->start, resource_size(res));
if (!driver_data->base) {
dev_err(&pdev->dev, "failed to map registers, aborting.\n");
return -ENOMEM;
@@ -174,14 +227,21 @@ static int __init at91wdt_probe(struct platform_device *pdev)
watchdog_set_drvdata(&at91_wddev, driver_data);
- res = at91wdt_enable(&at91_wddev);
- if (res) {
+ ret = at91wdt_enable(&at91_wddev, ms_to_ticks(WDT_HW_TIMEOUT * 1000));
+ if (ret) {
dev_err(&pdev->dev, "cannot enable watchdog (%d)\n", ret);
return ret;
}
+ ret = watchdog_register_device(&at91_wddev);
+ if (ret) {
+ dev_err(&pdev->dev, "cannot register watchdog (%d)\n", ret);
+ return ret;
+ }
+
driver_data->next_heartbeat = jiffies + heartbeat * HZ;
- setup_timer(&driver_data->timer, at91_ping, 0);
+ setup_timer(&driver_data->timer, at91_ping,
+ (unsigned long)&at91_wddev);
mod_timer(&driver_data->timer, jiffies + WDT_TIMEOUT);
pr_info("enabled (heartbeat=%d sec, nowayout=%d)\n",
@@ -192,9 +252,9 @@ static int __init at91wdt_probe(struct platform_device *pdev)
static int __exit at91wdt_remove(struct platform_device *pdev)
{
- int res;
+ watchdog_unregister_device(&at91_wddev);
- return res;
+ return 0;
}
static struct platform_driver at91wdt_driver = {
--
1.7.9.5
Set the at91wdt_drvdata struct as the driver data of struct watchdog_device.
Signed-off-by: Wenyou Yang <[email protected]>
---
drivers/watchdog/at91sam9_wdt.c | 35 +++++++++++++++++++++++------------
1 file changed, 23 insertions(+), 12 deletions(-)
diff --git a/drivers/watchdog/at91sam9_wdt.c b/drivers/watchdog/at91sam9_wdt.c
index 549c256..31c914a 100644
--- a/drivers/watchdog/at91sam9_wdt.c
+++ b/drivers/watchdog/at91sam9_wdt.c
@@ -66,13 +66,12 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started "
static void at91_ping(unsigned long data);
-static struct {
+struct at91wdt_drvdata {
void __iomem *base;
+ bool enabled; /* indicate if the watchdog is eabled */
unsigned long next_heartbeat; /* the next_heartbeat for the timer */
- unsigned long open;
- char expect_close;
struct timer_list timer; /* The timer that pings the watchdog */
-} at91wdt_private;
+};
/* ......................................................................... */
@@ -90,10 +89,12 @@ static inline void at91_wdt_reset(void)
*/
static void at91_ping(unsigned long data)
{
- if (time_before(jiffies, at91wdt_private.next_heartbeat) ||
- (!nowayout && !at91wdt_private.open)) {
+ struct watchdog_device *wddev = (struct watchdog_device *)data;
+ struct at91wdt_drvdata *driver_data = watchdog_get_drvdata(wddev);
+
+ if (time_before(jiffies, driver_data->next_heartbeat))
at91_wdt_reset();
- mod_timer(&at91wdt_private.timer, jiffies + WDT_TIMEOUT);
+ mod_timer(&driver_data->timer, jiffies + WDT_TIMEOUT);
} else
pr_crit("I will reset your machine !\n");
}
@@ -138,26 +139,36 @@ static const struct watchdog_info at91_wdt_info = {
static int __init at91wdt_probe(struct platform_device *pdev)
{
+ struct at91wdt_drvdata *driver_data;
struct resource *r;
int res;
+ driver_data = devm_kzalloc(&pdev->dev,
+ sizeof(*driver_data), GFP_KERNEL);
+ if (!driver_data) {
+ dev_err(&pdev->dev, "Unable to alloacate watchdog device\n");
+ return -ENOMEM;
+ }
+
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!r)
return -ENODEV;
- at91wdt_private.base = ioremap(r->start, resource_size(r));
- if (!at91wdt_private.base) {
+ driver_data->base = ioremap(r->start, resource_size(r));
+ if (!driver_data->base) {
dev_err(&pdev->dev, "failed to map registers, aborting.\n");
return -ENOMEM;
}
+ watchdog_set_drvdata(&at91_wddev, driver_data);
+
/* Set watchdog */
res = at91_wdt_settimeout(ms_to_ticks(WDT_HW_TIMEOUT * 1000));
if (res)
return res;
- at91wdt_private.next_heartbeat = jiffies + heartbeat * HZ;
- setup_timer(&at91wdt_private.timer, at91_ping, 0);
- mod_timer(&at91wdt_private.timer, jiffies + WDT_TIMEOUT);
+ driver_data->next_heartbeat = jiffies + heartbeat * HZ;
+ setup_timer(&driver_data->timer, at91_ping, 0);
+ mod_timer(&driver_data->timer, jiffies + WDT_TIMEOUT);
pr_info("enabled (heartbeat=%d sec, nowayout=%d)\n",
heartbeat, nowayout);
--
1.7.9.5
On 15:16 Wed 14 Nov , Wenyou Yang wrote:
> Signed-off-by: Wenyou Yang <[email protected]>
> ---
> drivers/watchdog/at91sam9_wdt.c | 28 ++++++++++++++++++----------
> 1 file changed, 18 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/watchdog/at91sam9_wdt.c b/drivers/watchdog/at91sam9_wdt.c
> index 31c914a..98e7d5a 100644
> --- a/drivers/watchdog/at91sam9_wdt.c
> +++ b/drivers/watchdog/at91sam9_wdt.c
> @@ -34,11 +34,6 @@
>
> #define DRV_NAME "AT91SAM9 Watchdog"
>
> -#define wdt_read(field) \
> - __raw_readl(at91wdt_private.base + field)
> -#define wdt_write(field, val) \
> - __raw_writel((val), at91wdt_private.base + field)
> -
> /* AT91SAM9 watchdog runs a 12bit counter @ 256Hz,
> * use this to convert a watchdog
> * value from/to milliseconds.
> @@ -75,13 +70,24 @@ struct at91wdt_drvdata {
>
> /* ......................................................................... */
>
> +static inline unsigned int wdt_read(struct at91wdt_drvdata *driver_data,
> + unsigned int field)
> +{
> + return __raw_readl(driver_data->base + field);
> +}
> +
> +static inline void wdt_write(struct at91wdt_drvdata *driver_data,
> + unsigned int field, unsigned int val)
> +{
> + __raw_writel((val), driver_data->base + field);
> +}
use relaxed version
Best Regrds,
J.
On 11/14/2012 08:16 AM, Wenyou Yang :
> Signed-off-by: Wenyou Yang <[email protected]>
No. The work has already been done by Fabio Porcedda and he managed to
sustain the discussion and reach a consensus at his v9 patch series: so
please take into account his work and build yours on top of his patch
series.
Best regards,
> Cc: [email protected]
> Cc: [email protected]
> Cc: [email protected]
> ---
> drivers/watchdog/at91sam9_wdt.c | 10 ++++++++++
> 1 file changed, 10 insertions(+)
>
> diff --git a/drivers/watchdog/at91sam9_wdt.c b/drivers/watchdog/at91sam9_wdt.c
> index e7ce9ea..cba5c5d 100644
> --- a/drivers/watchdog/at91sam9_wdt.c
> +++ b/drivers/watchdog/at91sam9_wdt.c
> @@ -32,6 +32,7 @@
> #include <linux/jiffies.h>
> #include <linux/timer.h>
> #include <linux/bitops.h>
> +#include <linux/of.h>
>
> #include "at91sam9_wdt.h"
>
> @@ -251,12 +252,21 @@ static int __exit at91wdt_remove(struct platform_device *pdev)
> return 0;
> }
>
> +#ifdef CONFIG_OF
> +static const struct of_device_id at91wdt_match[] = {
> + { .compatible = "atmel,at91sam-wdt" },
> + {},
> +};
> +MODULE_DEVICE_TABLE(of, at91wdt_match);
> +#endif
> +
> static struct platform_driver at91wdt_driver = {
> .probe = at91wdt_probe,
> .remove = __exit_p(at91wdt_remove),
> .driver = {
> .name = "at91_wdt",
> .owner = THIS_MODULE,
> + .of_match_table = of_match_ptr(at91wdt_match),
> },
> };
>
>
--
Nicolas Ferre
On 15:15 Wed 14 Nov , Wenyou Yang wrote:
> Hi, All
>
> The patch series is intended to convert to use the watchdog framework,
> and add support to device tree.
> It has been tested on sam9m10g45ek, sam9g20ek, sam9263ek and sam9g25ek.
you need to check Fabio wrok which is present on the ML for a while and was
reviewed and binding too
Best Regards,
J.
>
> It is based on v3.7-rc5.
>
> Best Regards
> Wenyou Yang
>
> Wenyou Yang (11):
> watchdog/at91sam9_wdt: remove the file_operations struct
> watchdog/at91sam9_wdt: change the at91wdt_private struct to the
> at91wdt_drvdata struct
> watchdog/at91sam9_wdt: change the wdt_read and wdt_write macro to the
> inline function
> watchdog/at91sam9_wdt: change "at91_wdt_settimeout" function name to
> "at91wdt_enable"
> watchdog/at91sam9_wdt: add to use the watchdog framework
> watchdog/at91sam9_wdt: change the timer function name
> watchdog/at91sam9_wdt: add nowayout helpers to Watchdog Timer Driver
> Kernel API
> watchdog/at91sam9_wdt: use module_platform_driver()
> watchdog/at91sam9_wdt: add support to device tree
> watchdog/at91sam9_wdt: using dev_info replaces pr_info, dev_crit
> repalces pr_crit
> ARM: dts: add the watchdog nodes for atmel SoC
>
> .../devicetree/bindings/watchdog/atmel-wdt.txt | 14 +
> arch/arm/boot/dts/at91sam9260.dtsi | 6 +
> arch/arm/boot/dts/at91sam9263.dtsi | 6 +
> arch/arm/boot/dts/at91sam9263ek.dts | 4 +
> arch/arm/boot/dts/at91sam9g20ek_common.dtsi | 4 +
> arch/arm/boot/dts/at91sam9g25ek.dts | 4 +
> arch/arm/boot/dts/at91sam9g45.dtsi | 5 +
> arch/arm/boot/dts/at91sam9m10g45ek.dts | 4 +
> arch/arm/boot/dts/at91sam9n12.dtsi | 6 +
> arch/arm/boot/dts/at91sam9n12ek.dts | 4 +
> arch/arm/boot/dts/at91sam9x5.dtsi | 6 +
> drivers/watchdog/Kconfig | 1 +
> drivers/watchdog/at91sam9_wdt.c | 294 ++++++++------------
> 13 files changed, 185 insertions(+), 173 deletions(-)
> create mode 100644 Documentation/devicetree/bindings/watchdog/atmel-wdt.txt
>
> --
> 1.7.9.5
>
On 15:15 Wed 14 Nov , Wenyou Yang wrote:
> Remove the file_operations struct and miscdevice struct for future
> add to use the watchdog framework.
NACK
you break the watchdog support
you must not break the kernel suport except if it's impossible to do otherwise
here it is no the case
Best Regards,
J.
>
> Signed-off-by: Wenyou Yang <[email protected]>
> ---
> drivers/watchdog/at91sam9_wdt.c | 131 ---------------------------------------
> 1 file changed, 131 deletions(-)
>
> diff --git a/drivers/watchdog/at91sam9_wdt.c b/drivers/watchdog/at91sam9_wdt.c
> index 05e1be8..549c256 100644
> --- a/drivers/watchdog/at91sam9_wdt.c
> +++ b/drivers/watchdog/at91sam9_wdt.c
> @@ -18,11 +18,9 @@
> #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
>
> #include <linux/errno.h>
> -#include <linux/fs.h>
> #include <linux/init.h>
> #include <linux/io.h>
> #include <linux/kernel.h>
> -#include <linux/miscdevice.h>
> #include <linux/module.h>
> #include <linux/moduleparam.h>
> #include <linux/platform_device.h>
> @@ -31,7 +29,6 @@
> #include <linux/jiffies.h>
> #include <linux/timer.h>
> #include <linux/bitops.h>
> -#include <linux/uaccess.h>
>
> #include "at91sam9_wdt.h"
>
> @@ -102,35 +99,6 @@ static void at91_ping(unsigned long data)
> }
>
> /*
> - * Watchdog device is opened, and watchdog starts running.
> - */
> -static int at91_wdt_open(struct inode *inode, struct file *file)
> -{
> - if (test_and_set_bit(0, &at91wdt_private.open))
> - return -EBUSY;
> -
> - at91wdt_private.next_heartbeat = jiffies + heartbeat * HZ;
> - mod_timer(&at91wdt_private.timer, jiffies + WDT_TIMEOUT);
> -
> - return nonseekable_open(inode, file);
> -}
> -
> -/*
> - * Close the watchdog device.
> - */
> -static int at91_wdt_close(struct inode *inode, struct file *file)
> -{
> - clear_bit(0, &at91wdt_private.open);
> -
> - /* stop internal ping */
> - if (!at91wdt_private.expect_close)
> - del_timer(&at91wdt_private.timer);
> -
> - at91wdt_private.expect_close = 0;
> - return 0;
> -}
> -
> -/*
> * Set the watchdog time interval in 1/256Hz (write-once)
> * Counter is 12 bit.
> */
> @@ -168,101 +136,11 @@ static const struct watchdog_info at91_wdt_info = {
> WDIOF_MAGICCLOSE,
> };
>
> -/*
> - * Handle commands from user-space.
> - */
> -static long at91_wdt_ioctl(struct file *file,
> - unsigned int cmd, unsigned long arg)
> -{
> - void __user *argp = (void __user *)arg;
> - int __user *p = argp;
> - int new_value;
> -
> - switch (cmd) {
> - case WDIOC_GETSUPPORT:
> - return copy_to_user(argp, &at91_wdt_info,
> - sizeof(at91_wdt_info)) ? -EFAULT : 0;
> -
> - case WDIOC_GETSTATUS:
> - case WDIOC_GETBOOTSTATUS:
> - return put_user(0, p);
> -
> - case WDIOC_KEEPALIVE:
> - at91wdt_private.next_heartbeat = jiffies + heartbeat * HZ;
> - return 0;
> -
> - case WDIOC_SETTIMEOUT:
> - if (get_user(new_value, p))
> - return -EFAULT;
> -
> - heartbeat = new_value;
> - at91wdt_private.next_heartbeat = jiffies + heartbeat * HZ;
> -
> - return put_user(new_value, p); /* return current value */
> -
> - case WDIOC_GETTIMEOUT:
> - return put_user(heartbeat, p);
> - }
> - return -ENOTTY;
> -}
> -
> -/*
> - * Pat the watchdog whenever device is written to.
> - */
> -static ssize_t at91_wdt_write(struct file *file, const char *data, size_t len,
> - loff_t *ppos)
> -{
> - if (!len)
> - return 0;
> -
> - /* Scan for magic character */
> - if (!nowayout) {
> - size_t i;
> -
> - at91wdt_private.expect_close = 0;
> -
> - for (i = 0; i < len; i++) {
> - char c;
> - if (get_user(c, data + i))
> - return -EFAULT;
> - if (c == 'V') {
> - at91wdt_private.expect_close = 42;
> - break;
> - }
> - }
> - }
> -
> - at91wdt_private.next_heartbeat = jiffies + heartbeat * HZ;
> -
> - return len;
> -}
> -
> -/* ......................................................................... */
> -
> -static const struct file_operations at91wdt_fops = {
> - .owner = THIS_MODULE,
> - .llseek = no_llseek,
> - .unlocked_ioctl = at91_wdt_ioctl,
> - .open = at91_wdt_open,
> - .release = at91_wdt_close,
> - .write = at91_wdt_write,
> -};
> -
> -static struct miscdevice at91wdt_miscdev = {
> - .minor = WATCHDOG_MINOR,
> - .name = "watchdog",
> - .fops = &at91wdt_fops,
> -};
> -
> static int __init at91wdt_probe(struct platform_device *pdev)
> {
> struct resource *r;
> int res;
>
> - if (at91wdt_miscdev.parent)
> - return -EBUSY;
> - at91wdt_miscdev.parent = &pdev->dev;
> -
> r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> if (!r)
> return -ENODEV;
> @@ -277,10 +155,6 @@ static int __init at91wdt_probe(struct platform_device *pdev)
> if (res)
> return res;
>
> - res = misc_register(&at91wdt_miscdev);
> - if (res)
> - return res;
> -
> at91wdt_private.next_heartbeat = jiffies + heartbeat * HZ;
> setup_timer(&at91wdt_private.timer, at91_ping, 0);
> mod_timer(&at91wdt_private.timer, jiffies + WDT_TIMEOUT);
> @@ -295,10 +169,6 @@ static int __exit at91wdt_remove(struct platform_device *pdev)
> {
> int res;
>
> - res = misc_deregister(&at91wdt_miscdev);
> - if (!res)
> - at91wdt_miscdev.parent = NULL;
> -
> return res;
> }
>
> @@ -326,4 +196,3 @@ module_exit(at91sam_wdt_exit);
> MODULE_AUTHOR("Renaud CERRATO <[email protected]>");
> MODULE_DESCRIPTION("Watchdog driver for Atmel AT91SAM9x processors");
> MODULE_LICENSE("GPL");
> -MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
> --
> 1.7.9.5
>