18 #include <linux/module.h>
23 #include <linux/slab.h>
24 #include <linux/watchdog.h>
27 #define TS72XX_WDT_FEED_VAL 0x05
28 #define TS72XX_WDT_DEFAULT_TIMEOUT 8
33 "(1 <= timeout <= 8, default="
54 #define TS72XX_WDT_BUSY_FLAG 1
55 #define TS72XX_WDT_EXPECT_CLOSE_FLAG 2
89 } ts72xx_wdt_map[] = {
104 static int timeout_to_regval(
int new_timeout)
109 new_timeout =
clamp_val(new_timeout, 1, 8);
111 for (i = 0; i <
ARRAY_SIZE(ts72xx_wdt_map); i++) {
112 if (ts72xx_wdt_map[i].timeout >= new_timeout)
113 return ts72xx_wdt_map[
i].regval;
126 static int regval_to_timeout(
int regval)
130 for (i = 0; i <
ARRAY_SIZE(ts72xx_wdt_map); i++) {
131 if (ts72xx_wdt_map[i].regval == regval)
132 return ts72xx_wdt_map[
i].timeout;
144 static inline void ts72xx_wdt_kick(
struct ts72xx_wdt *wdt)
158 static void ts72xx_wdt_start(
struct ts72xx_wdt *wdt)
165 ts72xx_wdt_kick(wdt);
175 static void ts72xx_wdt_stop(
struct ts72xx_wdt *wdt)
177 ts72xx_wdt_kick(wdt);
183 struct ts72xx_wdt *wdt = platform_get_drvdata(ts72xx_wdt_pdev);
190 regval = timeout_to_regval(timeout);
193 "failed to convert timeout (%d) to register value\n",
210 ts72xx_wdt_start(wdt);
216 static int ts72xx_wdt_release(
struct inode *inode,
struct file *file)
224 ts72xx_wdt_stop(wdt);
227 "TS-72XX WDT device closed unexpectly. "
228 "Watchdog timer will not stop!\n");
234 ts72xx_wdt_kick(wdt);
243 static ssize_t ts72xx_wdt_write(
struct file *file,
244 const char __user *
data,
256 ts72xx_wdt_kick(wdt);
267 for (i = 0; i < len; i++) {
291 .firmware_version = 1,
292 .identity =
"TS-72XX WDT",
295 static long ts72xx_wdt_ioctl(
struct file *file,
unsigned int cmd,
316 ts72xx_wdt_kick(wdt);
330 ts72xx_wdt_stop(wdt);
334 ts72xx_wdt_start(wdt);
349 regval = timeout_to_regval(new_timeout);
353 ts72xx_wdt_stop(wdt);
355 ts72xx_wdt_start(wdt);
381 .open = ts72xx_wdt_open,
382 .release = ts72xx_wdt_release,
383 .write = ts72xx_wdt_write,
384 .unlocked_ioctl = ts72xx_wdt_ioctl,
387 static struct miscdevice ts72xx_wdt_miscdev = {
390 .fops = &ts72xx_wdt_fops,
401 dev_err(&pdev->
dev,
"failed to allocate memory\n");
407 dev_err(&pdev->
dev,
"failed to get memory resource\n");
414 dev_err(&pdev->
dev,
"cannot request memory region\n");
421 dev_err(&pdev->
dev,
"failed to map memory\n");
423 goto fail_free_control;
428 dev_err(&pdev->
dev,
"failed to get memory resource\n");
430 goto fail_unmap_control;
435 dev_err(&pdev->
dev,
"cannot request memory region\n");
437 goto fail_unmap_control;
442 dev_err(&pdev->
dev,
"failed to map memory\n");
447 platform_set_drvdata(pdev, wdt);
448 ts72xx_wdt_pdev = pdev;
453 ts72xx_wdt_stop(wdt);
457 dev_err(&pdev->
dev,
"failed to register miscdev\n");
458 goto fail_unmap_feed;
466 platform_set_drvdata(pdev,
NULL);
481 struct ts72xx_wdt *wdt = platform_get_drvdata(pdev);
486 platform_set_drvdata(pdev,
NULL);
501 .probe = ts72xx_wdt_probe,
504 .name =
"ts72xx-wdt",