summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShreshtha SAHU <ssahu@nvidia.com>2017-06-05 04:18:29 -0400
committerShreshtha SAHU <ssahu@nvidia.com>2017-10-23 08:31:15 -0400
commitf6ce52c606966d96dd37ae6f233668dbc4d389e0 (patch)
tree56b318de082b097ef51a94c1f4697a13d82b6dd2
parent40428683d955314c5e529bf5d35446ea73ca5b1f (diff)
watchdog: tegra: revamp timeout calculation and usage
- update calculation of timeout for TIMER_PTV, - update watchdog ping to first disable timer, update timeut value and then restart the timer. - init watchdog timeout using watchdog_init_timeout - program default trigger period in watchdog configuration regiter Bug 200314562 Change-Id: Iec9e5a94c995653e5a3c653eccfa23a0877ae2e9 Signed-off-by: Shreshtha SAHU <ssahu@nvidia.com> Reviewed-on: https://git-master/r/1515195 (cherry picked from commit c11b5748efb4f3cbf51bc4f25e5b59f3bddfffa8) Reviewed-on: https://git-master.nvidia.com/r/1526898 Reviewed-by: svccoveritychecker <svccoveritychecker@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Laxman Dewangan <ldewangan@nvidia.com>
-rw-r--r--drivers/watchdog/tegra_wdt.c36
1 files changed, 27 insertions, 9 deletions
diff --git a/drivers/watchdog/tegra_wdt.c b/drivers/watchdog/tegra_wdt.c
index 0a2b897f1..3871cd0cf 100644
--- a/drivers/watchdog/tegra_wdt.c
+++ b/drivers/watchdog/tegra_wdt.c
@@ -68,6 +68,14 @@ struct tegra_wdt {
68 */ 68 */
69static int expiry_count = 1; 69static int expiry_count = 1;
70 70
71/*
72 * Period value: Trigger Value is the time period and period value determines
73 * number of periods for watchdog expiration i.e. effectively after time:
74 * "period value" * "Trigger Vaue"
75 */
76#define WDT_TRG_PERIOD 1
77static int trigger_period = WDT_TRG_PERIOD;
78
71#define WDT_HEARTBEAT 120 79#define WDT_HEARTBEAT 120
72static int heartbeat = WDT_HEARTBEAT; 80static int heartbeat = WDT_HEARTBEAT;
73module_param(heartbeat, int, 0); 81module_param(heartbeat, int, 0);
@@ -87,12 +95,12 @@ static int tegra_wdt_start(struct watchdog_device *wdd)
87 u32 val; 95 u32 val;
88 96
89 /* 97 /*
90 * This thing has a fixed 1MHz clock. Normally, we would set the 98 * The timeout needs to be divided by expiry_count here so as to
91 * period to 1 second by writing 1000000ul, but the watchdog system 99 * keep the ultimate watchdog reset timeout the same as the program
92 * reset actually occurs on the expiry_count'th expiration of this 100 * timeout requested by application. The program timeout should make
93 * counter, so we set the period to 1/expiry_count of this amount. 101 * sure WDT FIQ will never be asserted in a valid use case.
94 */ 102 */
95 val = 1000000ul / expiry_count; 103 val = (wdd->timeout * USEC_PER_SEC) / expiry_count;
96 val |= (TIMER_EN | TIMER_PERIODIC); 104 val |= (TIMER_EN | TIMER_PERIODIC);
97 writel(val, wdt->tmr_regs + TIMER_PTV); 105 writel(val, wdt->tmr_regs + TIMER_PTV);
98 106
@@ -104,7 +112,7 @@ static int tegra_wdt_start(struct watchdog_device *wdd)
104 * WDT to reset the counter before expiration, through ioctls. 112 * WDT to reset the counter before expiration, through ioctls.
105 */ 113 */
106 val = WDT_TIMER_ID | 114 val = WDT_TIMER_ID |
107 (wdd->timeout << WDT_CFG_PERIOD_SHIFT) | 115 (trigger_period << WDT_CFG_PERIOD_SHIFT) |
108 WDT_CFG_PMC2CAR_RST_EN; 116 WDT_CFG_PMC2CAR_RST_EN;
109 writel(val, wdt->wdt_regs + WDT_CFG); 117 writel(val, wdt->wdt_regs + WDT_CFG);
110 118
@@ -126,8 +134,18 @@ static int tegra_wdt_stop(struct watchdog_device *wdd)
126 134
127static int tegra_wdt_ping(struct watchdog_device *wdd) 135static int tegra_wdt_ping(struct watchdog_device *wdd)
128{ 136{
137 u32 val;
129 struct tegra_wdt *wdt = watchdog_get_drvdata(wdd); 138 struct tegra_wdt *wdt = watchdog_get_drvdata(wdd);
130 139
140 /* Disable timer */
141 tegra_wdt_stop(wdd);
142
143 /* Load the timeout value */
144 val = (wdd->timeout * USEC_PER_SEC) / expiry_count;
145 val |= (TIMER_EN | TIMER_PERIODIC);
146 writel(val, wdt->tmr_regs + TIMER_PTV);
147
148 /* Restart */
131 writel(WDT_CMD_START_COUNTER, wdt->wdt_regs + WDT_CMD); 149 writel(WDT_CMD_START_COUNTER, wdt->wdt_regs + WDT_CMD);
132 150
133 return 0; 151 return 0;
@@ -160,7 +178,6 @@ static unsigned int tegra_wdt_get_timeleft(struct watchdog_device *wdd)
160 178
161 /* Number of expirations */ 179 /* Number of expirations */
162 exp = (val >> WDT_STS_EXP_SHIFT) & WDT_STS_EXP_MASK; 180 exp = (val >> WDT_STS_EXP_SHIFT) & WDT_STS_EXP_MASK;
163
164 /* 181 /*
165 * The entire thing is divided by expiry_count because we are ticking 182 * The entire thing is divided by expiry_count because we are ticking
166 * down expiry_count times faster due to needing to wait for the 183 * down expiry_count times faster due to needing to wait for the
@@ -242,6 +259,7 @@ static int tegra_wdt_probe(struct platform_device *pdev)
242 259
243 watchdog_set_drvdata(wdd, wdt); 260 watchdog_set_drvdata(wdd, wdt);
244 261
262 watchdog_init_timeout(wdd, heartbeat, &pdev->dev);
245 watchdog_set_nowayout(wdd, nowayout); 263 watchdog_set_nowayout(wdd, nowayout);
246 264
247 ret = watchdog_register_device(wdd); 265 ret = watchdog_register_device(wdd);
@@ -254,8 +272,8 @@ static int tegra_wdt_probe(struct platform_device *pdev)
254 platform_set_drvdata(pdev, wdt); 272 platform_set_drvdata(pdev, wdt);
255 273
256 dev_info(&pdev->dev, 274 dev_info(&pdev->dev,
257 "initialized (heartbeat = %d sec, nowayout = %d)\n", 275 "initialized (timeout = %d sec, nowayout = %d)\n",
258 heartbeat, nowayout); 276 wdt->wdd.timeout, nowayout);
259 277
260 return 0; 278 return 0;
261} 279}