diff options
author | Dmitriy Gruzman <dmitriy.gruzman@motorola.com> | 2011-01-24 20:52:02 -0600 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2011-11-30 21:36:56 -0800 |
commit | debb888fb46e2d7643f53be2f0d9f69824a558bf (patch) | |
tree | 73141dc8acac80e7dad3a735381aba59eaa9b2e7 /drivers/watchdog | |
parent | 57b462acc6df373fb19b191d407ab3f2cb644cc9 (diff) |
watchdog: tegra_wdt: Several changes to watchdog driver
Fix not re-enabling watchdog resume if it was enabled in probe
Add clearing watchdog interrupt in probe
Remove tegra_wdt_set_timeout
Change-Id: I8fdbb6da3eda64a85a73ed85ab979a5ee0261c37
Signed-off-by: Dmitriy Gruzman <dmitriy.gruzman@motorola.com>
Diffstat (limited to 'drivers/watchdog')
-rw-r--r-- | drivers/watchdog/tegra_wdt.c | 45 |
1 files changed, 16 insertions, 29 deletions
diff --git a/drivers/watchdog/tegra_wdt.c b/drivers/watchdog/tegra_wdt.c index d7ad6238d4f3..d11b99816ca6 100644 --- a/drivers/watchdog/tegra_wdt.c +++ b/drivers/watchdog/tegra_wdt.c @@ -40,17 +40,17 @@ #define MAX_WDT_PERIOD 1000 #define TIMER_PTV 0x0 - #define TIMER_EN (1 << 31) - #define TIMER_PERIODIC (1 << 30) +#define TIMER_EN (1 << 31) +#define TIMER_PERIODIC (1 << 30) #define TIMER_PCR 0x4 - #define TIMER_PCR_INTR (1 << 30) +#define TIMER_PCR_INTR (1 << 30) #define WDT_EN (1 << 5) #define WDT_SEL_TMR1 (0 << 4) #define WDT_SYS_RST (1 << 2) -static int heartbeat = 30; +static int heartbeat = 30; /* must be greater than MIN_WDT_PERIOD and lower than MAX_WDT_PERIOD */ struct tegra_wdt { struct miscdevice miscdev; @@ -67,31 +67,13 @@ struct tegra_wdt { static struct tegra_wdt *tegra_wdt_dev; -static void tegra_wdt_set_timeout(struct tegra_wdt *wdt, int sec) -{ - u32 ptv, src; - - ptv = readl(wdt->wdt_timer + TIMER_PTV); - src = readl(wdt->wdt_source); - - writel(0, wdt->wdt_source); - wdt->timeout = clamp(sec, MIN_WDT_PERIOD, MAX_WDT_PERIOD); - if (ptv & TIMER_EN) { - /* since the watchdog reset occurs when a second interrupt - * is asserted before the first is processed, program the - * timer period to one-half of the watchdog period */ - ptv = wdt->timeout * 1000000ul / 2; - ptv |= (TIMER_EN | TIMER_PERIODIC); - writel(ptv, wdt->wdt_timer + TIMER_PTV); - } - writel(src, wdt->wdt_source); -} - - static void tegra_wdt_enable(struct tegra_wdt *wdt) { u32 val; + /* since the watchdog reset occurs when a second interrupt + * is asserted before the first is processed, program the + * timer period to one-half of the watchdog period */ val = wdt->timeout * 1000000ul / 2; val |= (TIMER_EN | TIMER_PERIODIC); writel(val, wdt->wdt_timer + TIMER_PTV); @@ -133,7 +115,7 @@ static int tegra_wdt_open(struct inode *inode, struct file *file) return -EBUSY; wdt->enabled = true; - tegra_wdt_set_timeout(wdt, heartbeat); + wdt->timeout = heartbeat; tegra_wdt_enable(wdt); file->private_data = wdt; return nonseekable_open(inode, file); @@ -179,7 +161,7 @@ static long tegra_wdt_ioctl(struct file *file, unsigned int cmd, return -EFAULT; spin_lock(&lock); tegra_wdt_disable(wdt); - tegra_wdt_set_timeout(wdt, new_timeout); + wdt->timeout = clamp(new_timeout, MIN_WDT_PERIOD, MAX_WDT_PERIOD); tegra_wdt_enable(wdt); spin_unlock(&lock); case WDIOC_GETTIMEOUT: @@ -268,6 +250,7 @@ static int tegra_wdt_probe(struct platform_device *pdev) dev_info(&pdev->dev, "last reset due to watchdog timeout\n"); tegra_wdt_disable(wdt); + writel(TIMER_PCR_INTR, wdt->wdt_timer + TIMER_PCR); ret = request_irq(res_irq->start, tegra_wdt_interrupt, IRQF_DISABLED, dev_name(&pdev->dev), wdt); @@ -280,8 +263,6 @@ static int tegra_wdt_probe(struct platform_device *pdev) wdt->res_src = res_src; wdt->res_wdt = res_wdt; - wdt->timeout = heartbeat; - ret = register_reboot_notifier(&wdt->notifier); if (ret) { dev_err(&pdev->dev, "cannot register reboot notifier\n"); @@ -298,6 +279,8 @@ static int tegra_wdt_probe(struct platform_device *pdev) platform_set_drvdata(pdev, wdt); tegra_wdt_dev = wdt; #ifdef CONFIG_TEGRA_WATCHDOG_ENABLE_ON_PROBE + wdt->enabled = true; + wdt->timeout = heartbeat; tegra_wdt_enable(wdt); #endif return 0; @@ -334,6 +317,7 @@ static int tegra_wdt_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_PM static int tegra_wdt_suspend(struct platform_device *pdev, pm_message_t state) { struct tegra_wdt *wdt = platform_get_drvdata(pdev); @@ -351,12 +335,15 @@ static int tegra_wdt_resume(struct platform_device *pdev) return 0; } +#endif static struct platform_driver tegra_wdt_driver = { .probe = tegra_wdt_probe, .remove = __devexit_p(tegra_wdt_remove), +#ifdef CONFIG_PM .suspend = tegra_wdt_suspend, .resume = tegra_wdt_resume, +#endif .driver = { .owner = THIS_MODULE, .name = "tegra_wdt", |