29 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
31 #include <linux/module.h>
32 #include <linux/types.h>
33 #include <linux/kernel.h>
37 #include <linux/watchdog.h>
38 #include <linux/reboot.h>
43 #include <linux/bitops.h>
46 #include <linux/slab.h>
48 #include <mach/hardware.h>
56 static unsigned timer_margin;
60 static unsigned int wdt_trgr_pattern = 0x1234;
71 static void omap_wdt_ping(
struct omap_wdt_dev *wdev)
79 wdt_trgr_pattern = ~wdt_trgr_pattern;
88 static void omap_wdt_enable(
struct omap_wdt_dev *wdev)
102 static void omap_wdt_disable(
struct omap_wdt_dev *wdev)
116 static void omap_wdt_adjust_timeout(
unsigned new_timeout)
122 timer_margin = new_timeout;
125 static void omap_wdt_set_timeout(
struct omap_wdt_dev *wdev)
144 struct omap_wdt_dev *wdev = platform_get_drvdata(omap_wdt_dev);
150 pm_runtime_get_sync(wdev->
dev);
162 omap_wdt_set_timeout(wdev);
164 omap_wdt_enable(wdev);
169 static int omap_wdt_release(
struct inode *inode,
struct file *file)
176 #ifndef CONFIG_WATCHDOG_NOWAYOUT
177 omap_wdt_disable(wdev);
179 pm_runtime_put_sync(wdev->
dev);
181 pr_crit(
"Unexpected close, not stopping!\n");
188 static ssize_t omap_wdt_write(
struct file *file,
const char __user *
data,
189 size_t len, loff_t *ppos)
195 spin_lock(&wdt_lock);
197 spin_unlock(&wdt_lock);
202 static long omap_wdt_ioctl(
struct file *file,
unsigned int cmd,
205 struct omap_wdt_dev *wdev;
208 .identity =
"OMAP Watchdog",
210 .firmware_version = 0,
220 return put_user(0, (
int __user *)arg);
222 #ifdef CONFIG_ARCH_OMAP1
227 #ifdef CONFIG_ARCH_OMAP2PLUS
232 return put_user(0, (
int __user *)arg);
234 spin_lock(&wdt_lock);
236 spin_unlock(&wdt_lock);
239 if (
get_user(new_margin, (
int __user *)arg))
241 omap_wdt_adjust_timeout(new_margin);
243 spin_lock(&wdt_lock);
244 omap_wdt_disable(wdev);
245 omap_wdt_set_timeout(wdev);
246 omap_wdt_enable(wdev);
249 spin_unlock(&wdt_lock);
252 return put_user(timer_margin, (
int __user *)arg);
260 .write = omap_wdt_write,
261 .unlocked_ioctl = omap_wdt_ioctl,
262 .open = omap_wdt_open,
263 .release = omap_wdt_release,
270 struct omap_wdt_dev *wdev;
277 goto err_get_resource;
291 wdev = kzalloc(
sizeof(
struct omap_wdt_dev),
GFP_KERNEL);
307 platform_set_drvdata(pdev, wdev);
310 pm_runtime_get_sync(wdev->
dev);
312 omap_wdt_disable(wdev);
313 omap_wdt_adjust_timeout(timer_margin);
324 pr_info(
"OMAP Watchdog Timer Rev 0x%02x: initial timeout %d sec\n",
328 pm_runtime_put_sync(wdev->
dev);
335 pm_runtime_disable(wdev->
dev);
336 platform_set_drvdata(pdev,
NULL);
354 struct omap_wdt_dev *wdev = platform_get_drvdata(pdev);
357 omap_wdt_disable(wdev);
358 pm_runtime_put_sync(wdev->
dev);
364 struct omap_wdt_dev *wdev = platform_get_drvdata(pdev);
367 pm_runtime_disable(wdev->
dev);
373 platform_set_drvdata(pdev,
NULL);
393 struct omap_wdt_dev *wdev = platform_get_drvdata(pdev);
396 omap_wdt_disable(wdev);
397 pm_runtime_put_sync(wdev->
dev);
405 struct omap_wdt_dev *wdev = platform_get_drvdata(pdev);
408 pm_runtime_get_sync(wdev->
dev);
409 omap_wdt_enable(wdev);
417 #define omap_wdt_suspend NULL
418 #define omap_wdt_resume NULL
421 static const struct of_device_id omap_wdt_of_match[] = {
422 { .compatible =
"ti,omap3-wdt", },
428 .probe = omap_wdt_probe,
430 .shutdown = omap_wdt_shutdown,
436 .of_match_table = omap_wdt_of_match,