aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWim Van Sebroeck <wim@linux-watchdog.org>2018-03-13 14:14:41 -0400
committerWim Van Sebroeck <wim@linux-watchdog.org>2018-03-13 14:14:41 -0400
commit2e8ebed6ede01f187f8a06bbae3e3b3325bda36c (patch)
tree4c4594857bb0b1455dcabae3c5638fcbe53c46b2
parent1462eecfc534fbfe85645d632527b358354fa3f4 (diff)
parent8c088370c2a684acad45e0035d9f2dfd85087db0 (diff)
Merge branch 'v4.16-fixes'
-rw-r--r--drivers/watchdog/aspeed_wdt.c9
-rw-r--r--drivers/watchdog/dw_wdt.c32
-rw-r--r--drivers/watchdog/sprd_wdt.c4
3 files changed, 33 insertions, 12 deletions
diff --git a/drivers/watchdog/aspeed_wdt.c b/drivers/watchdog/aspeed_wdt.c
index ca5b91e2eb92..d1987d63b37c 100644
--- a/drivers/watchdog/aspeed_wdt.c
+++ b/drivers/watchdog/aspeed_wdt.c
@@ -232,11 +232,14 @@ static int aspeed_wdt_probe(struct platform_device *pdev)
232 wdt->ctrl |= WDT_CTRL_RESET_MODE_SOC | WDT_CTRL_RESET_SYSTEM; 232 wdt->ctrl |= WDT_CTRL_RESET_MODE_SOC | WDT_CTRL_RESET_SYSTEM;
233 } else { 233 } else {
234 if (!strcmp(reset_type, "cpu")) 234 if (!strcmp(reset_type, "cpu"))
235 wdt->ctrl |= WDT_CTRL_RESET_MODE_ARM_CPU; 235 wdt->ctrl |= WDT_CTRL_RESET_MODE_ARM_CPU |
236 WDT_CTRL_RESET_SYSTEM;
236 else if (!strcmp(reset_type, "soc")) 237 else if (!strcmp(reset_type, "soc"))
237 wdt->ctrl |= WDT_CTRL_RESET_MODE_SOC; 238 wdt->ctrl |= WDT_CTRL_RESET_MODE_SOC |
239 WDT_CTRL_RESET_SYSTEM;
238 else if (!strcmp(reset_type, "system")) 240 else if (!strcmp(reset_type, "system"))
239 wdt->ctrl |= WDT_CTRL_RESET_SYSTEM; 241 wdt->ctrl |= WDT_CTRL_RESET_MODE_FULL_CHIP |
242 WDT_CTRL_RESET_SYSTEM;
240 else if (strcmp(reset_type, "none")) 243 else if (strcmp(reset_type, "none"))
241 return -EINVAL; 244 return -EINVAL;
242 } 245 }
diff --git a/drivers/watchdog/dw_wdt.c b/drivers/watchdog/dw_wdt.c
index c2f4ff516230..501aebb5b81f 100644
--- a/drivers/watchdog/dw_wdt.c
+++ b/drivers/watchdog/dw_wdt.c
@@ -34,6 +34,7 @@
34 34
35#define WDOG_CONTROL_REG_OFFSET 0x00 35#define WDOG_CONTROL_REG_OFFSET 0x00
36#define WDOG_CONTROL_REG_WDT_EN_MASK 0x01 36#define WDOG_CONTROL_REG_WDT_EN_MASK 0x01
37#define WDOG_CONTROL_REG_RESP_MODE_MASK 0x02
37#define WDOG_TIMEOUT_RANGE_REG_OFFSET 0x04 38#define WDOG_TIMEOUT_RANGE_REG_OFFSET 0x04
38#define WDOG_TIMEOUT_RANGE_TOPINIT_SHIFT 4 39#define WDOG_TIMEOUT_RANGE_TOPINIT_SHIFT 4
39#define WDOG_CURRENT_COUNT_REG_OFFSET 0x08 40#define WDOG_CURRENT_COUNT_REG_OFFSET 0x08
@@ -56,6 +57,9 @@ struct dw_wdt {
56 unsigned long rate; 57 unsigned long rate;
57 struct watchdog_device wdd; 58 struct watchdog_device wdd;
58 struct reset_control *rst; 59 struct reset_control *rst;
60 /* Save/restore */
61 u32 control;
62 u32 timeout;
59}; 63};
60 64
61#define to_dw_wdt(wdd) container_of(wdd, struct dw_wdt, wdd) 65#define to_dw_wdt(wdd) container_of(wdd, struct dw_wdt, wdd)
@@ -121,14 +125,23 @@ static int dw_wdt_set_timeout(struct watchdog_device *wdd, unsigned int top_s)
121 return 0; 125 return 0;
122} 126}
123 127
128static void dw_wdt_arm_system_reset(struct dw_wdt *dw_wdt)
129{
130 u32 val = readl(dw_wdt->regs + WDOG_CONTROL_REG_OFFSET);
131
132 /* Disable interrupt mode; always perform system reset. */
133 val &= ~WDOG_CONTROL_REG_RESP_MODE_MASK;
134 /* Enable watchdog. */
135 val |= WDOG_CONTROL_REG_WDT_EN_MASK;
136 writel(val, dw_wdt->regs + WDOG_CONTROL_REG_OFFSET);
137}
138
124static int dw_wdt_start(struct watchdog_device *wdd) 139static int dw_wdt_start(struct watchdog_device *wdd)
125{ 140{
126 struct dw_wdt *dw_wdt = to_dw_wdt(wdd); 141 struct dw_wdt *dw_wdt = to_dw_wdt(wdd);
127 142
128 dw_wdt_set_timeout(wdd, wdd->timeout); 143 dw_wdt_set_timeout(wdd, wdd->timeout);
129 144 dw_wdt_arm_system_reset(dw_wdt);
130 writel(WDOG_CONTROL_REG_WDT_EN_MASK,
131 dw_wdt->regs + WDOG_CONTROL_REG_OFFSET);
132 145
133 return 0; 146 return 0;
134} 147}
@@ -152,16 +165,13 @@ static int dw_wdt_restart(struct watchdog_device *wdd,
152 unsigned long action, void *data) 165 unsigned long action, void *data)
153{ 166{
154 struct dw_wdt *dw_wdt = to_dw_wdt(wdd); 167 struct dw_wdt *dw_wdt = to_dw_wdt(wdd);
155 u32 val;
156 168
157 writel(0, dw_wdt->regs + WDOG_TIMEOUT_RANGE_REG_OFFSET); 169 writel(0, dw_wdt->regs + WDOG_TIMEOUT_RANGE_REG_OFFSET);
158 val = readl(dw_wdt->regs + WDOG_CONTROL_REG_OFFSET); 170 if (dw_wdt_is_enabled(dw_wdt))
159 if (val & WDOG_CONTROL_REG_WDT_EN_MASK)
160 writel(WDOG_COUNTER_RESTART_KICK_VALUE, 171 writel(WDOG_COUNTER_RESTART_KICK_VALUE,
161 dw_wdt->regs + WDOG_COUNTER_RESTART_REG_OFFSET); 172 dw_wdt->regs + WDOG_COUNTER_RESTART_REG_OFFSET);
162 else 173 else
163 writel(WDOG_CONTROL_REG_WDT_EN_MASK, 174 dw_wdt_arm_system_reset(dw_wdt);
164 dw_wdt->regs + WDOG_CONTROL_REG_OFFSET);
165 175
166 /* wait for reset to assert... */ 176 /* wait for reset to assert... */
167 mdelay(500); 177 mdelay(500);
@@ -198,6 +208,9 @@ static int dw_wdt_suspend(struct device *dev)
198{ 208{
199 struct dw_wdt *dw_wdt = dev_get_drvdata(dev); 209 struct dw_wdt *dw_wdt = dev_get_drvdata(dev);
200 210
211 dw_wdt->control = readl(dw_wdt->regs + WDOG_CONTROL_REG_OFFSET);
212 dw_wdt->timeout = readl(dw_wdt->regs + WDOG_TIMEOUT_RANGE_REG_OFFSET);
213
201 clk_disable_unprepare(dw_wdt->clk); 214 clk_disable_unprepare(dw_wdt->clk);
202 215
203 return 0; 216 return 0;
@@ -211,6 +224,9 @@ static int dw_wdt_resume(struct device *dev)
211 if (err) 224 if (err)
212 return err; 225 return err;
213 226
227 writel(dw_wdt->timeout, dw_wdt->regs + WDOG_TIMEOUT_RANGE_REG_OFFSET);
228 writel(dw_wdt->control, dw_wdt->regs + WDOG_CONTROL_REG_OFFSET);
229
214 dw_wdt_ping(&dw_wdt->wdd); 230 dw_wdt_ping(&dw_wdt->wdd);
215 231
216 return 0; 232 return 0;
diff --git a/drivers/watchdog/sprd_wdt.c b/drivers/watchdog/sprd_wdt.c
index a8b280ff33e0..b4d484a42b70 100644
--- a/drivers/watchdog/sprd_wdt.c
+++ b/drivers/watchdog/sprd_wdt.c
@@ -154,8 +154,10 @@ static int sprd_wdt_enable(struct sprd_wdt *wdt)
154 if (ret) 154 if (ret)
155 return ret; 155 return ret;
156 ret = clk_prepare_enable(wdt->rtc_enable); 156 ret = clk_prepare_enable(wdt->rtc_enable);
157 if (ret) 157 if (ret) {
158 clk_disable_unprepare(wdt->enable);
158 return ret; 159 return ret;
160 }
159 161
160 sprd_wdt_unlock(wdt->base); 162 sprd_wdt_unlock(wdt->base);
161 val = readl_relaxed(wdt->base + SPRD_WDT_CTRL); 163 val = readl_relaxed(wdt->base + SPRD_WDT_CTRL);