aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-09-14 16:28:30 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2017-09-14 16:28:30 -0400
commit939ae58960bb5ce0c51776aec38877a401c03bcf (patch)
tree876ae3c12951c7057c31d8d35807f086a32b4463
parente75f801f1febabfa3cf3dcb3a1a05bf3c243d41e (diff)
parent4cb30b044a8f06e6e6418ae12c3c00bb02679dac (diff)
Merge git://www.linux-watchdog.org/linux-watchdog
Pull watchdog updates from Wim Van Sebroeck: - add support for the watchdog on Meson8 and Meson8m2 - add support for MediaTek MT7623 and MT7622 SoC - add support for the r8a77995 wdt - explicitly request exclusive reset control for asm9260_wdt, zx2967_wdt, rt2880_wdt and mt7621_wdt - improvements to asm9260_wdt, aspeed_wdt, renesas_wdt and cadence_wdt - add support for reading freq via CCF + suspend/resume support for of_xilinx_wdt - constify watchdog_ops and various device-id structures - revert of commit 1fccb73011ea ("iTCO_wdt: all versions count down twice") (Bug 196509) * git://www.linux-watchdog.org/linux-watchdog: (40 commits) watchdog: mei_wdt: constify mei_cl_device_id watchdog: sp805: constify amba_id watchdog: ziirave: constify i2c_device_id watchdog: sc1200: constify pnp_device_id dt-bindings: watchdog: renesas-wdt: Add support for the r8a77995 wdt watchdog: renesas_wdt: update copyright dates watchdog: renesas_wdt: make 'clk' a variable local to probe() watchdog: renesas_wdt: consistently use RuntimePM for clock management watchdog: aspeed: Support configuration of external signal properties dt-bindings: watchdog: aspeed: External reset signal properties drivers/watchdog: Add optional ASPEED device tree properties drivers/watchdog: ASPEED reference dev tree properties for config watchdog: da9063_wdt: Simplify by removing unneeded struct... watchdog: bcm7038: Check the return value from clk_prepare_enable() watchdog: qcom: Check for platform_get_resource() failure watchdog: of_xilinx_wdt: Add suspend/resume support watchdog: of_xilinx_wdt: Add support for reading freq via CCF dt-bindings: watchdog: mediatek: add support for MediaTek MT7623 and MT7622 SoC watchdog: max77620_wdt: constify platform_device_id watchdog: pcwd_usb: constify usb_device_id ...
-rw-r--r--Documentation/devicetree/bindings/watchdog/aspeed-wdt.txt40
-rw-r--r--Documentation/devicetree/bindings/watchdog/meson-wdt.txt6
-rw-r--r--Documentation/devicetree/bindings/watchdog/mtk-wdt.txt2
-rw-r--r--Documentation/devicetree/bindings/watchdog/renesas-wdt.txt1
-rw-r--r--Documentation/watchdog/watchdog-parameters.txt2
-rw-r--r--drivers/watchdog/asm9260_wdt.c4
-rw-r--r--drivers/watchdog/aspeed_wdt.c132
-rw-r--r--drivers/watchdog/bcm7038_wdt.c4
-rw-r--r--drivers/watchdog/cadence_wdt.c6
-rw-r--r--drivers/watchdog/coh901327_wdt.c2
-rw-r--r--drivers/watchdog/da9063_wdt.c67
-rw-r--r--drivers/watchdog/diag288_wdt.c2
-rw-r--r--drivers/watchdog/iTCO_wdt.c22
-rw-r--r--drivers/watchdog/it87_wdt.c2
-rw-r--r--drivers/watchdog/max77620_wdt.c2
-rw-r--r--drivers/watchdog/mei_wdt.c2
-rw-r--r--drivers/watchdog/meson_wdt.c2
-rw-r--r--drivers/watchdog/mt7621_wdt.c4
-rw-r--r--drivers/watchdog/of_xilinx_wdt.c83
-rw-r--r--drivers/watchdog/pcwd_usb.c2
-rw-r--r--drivers/watchdog/qcom-wdt.c2
-rw-r--r--drivers/watchdog/renesas_wdt.c80
-rw-r--r--drivers/watchdog/rt2880_wdt.c4
-rw-r--r--drivers/watchdog/sc1200wdt.c2
-rw-r--r--drivers/watchdog/sp805_wdt.c2
-rw-r--r--drivers/watchdog/stm32_iwdg.c2
-rw-r--r--drivers/watchdog/ts72xx_wdt.c2
-rw-r--r--drivers/watchdog/w83627hf_wdt.c2
-rw-r--r--drivers/watchdog/ziirave_wdt.c2
-rw-r--r--drivers/watchdog/zx2967_wdt.c2
30 files changed, 363 insertions, 124 deletions
diff --git a/Documentation/devicetree/bindings/watchdog/aspeed-wdt.txt b/Documentation/devicetree/bindings/watchdog/aspeed-wdt.txt
index c5e74d7b4406..c5077a1f5cb3 100644
--- a/Documentation/devicetree/bindings/watchdog/aspeed-wdt.txt
+++ b/Documentation/devicetree/bindings/watchdog/aspeed-wdt.txt
@@ -8,9 +8,49 @@ Required properties:
8 - reg: physical base address of the controller and length of memory mapped 8 - reg: physical base address of the controller and length of memory mapped
9 region 9 region
10 10
11Optional properties:
12
13 - aspeed,reset-type = "cpu|soc|system|none"
14
15 Reset behavior - Whenever a timeout occurs the watchdog can be programmed
16 to generate one of three different, mutually exclusive, types of resets.
17
18 Type "none" can be specified to indicate that no resets are to be done.
19 This is useful in situations where another watchdog engine on chip is
20 to perform the reset.
21
22 If 'aspeed,reset-type=' is not specfied the default is to enable system
23 reset.
24
25 Reset types:
26
27 - cpu: Reset CPU on watchdog timeout
28
29 - soc: Reset 'System on Chip' on watchdog timeout
30
31 - system: Reset system on watchdog timeout
32
33 - none: No reset is performed on timeout. Assumes another watchdog
34 engine is responsible for this.
35
36 - aspeed,alt-boot: If property is present then boot from alternate block.
37 - aspeed,external-signal: If property is present then signal is sent to
38 external reset counter (only WDT1 and WDT2). If not
39 specified no external signal is sent.
40 - aspeed,ext-pulse-duration: External signal pulse duration in microseconds
41
42Optional properties for AST2500-compatible watchdogs:
43 - aspeed,ext-push-pull: If aspeed,external-signal is present, set the pin's
44 drive type to push-pull. The default is open-drain.
45 - aspeed,ext-active-high: If aspeed,external-signal is present and and the pin
46 is configured as push-pull, then set the pulse
47 polarity to active-high. The default is active-low.
48
11Example: 49Example:
12 50
13 wdt1: watchdog@1e785000 { 51 wdt1: watchdog@1e785000 {
14 compatible = "aspeed,ast2400-wdt"; 52 compatible = "aspeed,ast2400-wdt";
15 reg = <0x1e785000 0x1c>; 53 reg = <0x1e785000 0x1c>;
54 aspeed,reset-type = "system";
55 aspeed,external-signal;
16 }; 56 };
diff --git a/Documentation/devicetree/bindings/watchdog/meson-wdt.txt b/Documentation/devicetree/bindings/watchdog/meson-wdt.txt
index ae70185d96e6..8a6d84cb36c9 100644
--- a/Documentation/devicetree/bindings/watchdog/meson-wdt.txt
+++ b/Documentation/devicetree/bindings/watchdog/meson-wdt.txt
@@ -2,7 +2,11 @@ Meson SoCs Watchdog timer
2 2
3Required properties: 3Required properties:
4 4
5- compatible : should be "amlogic,meson6-wdt" or "amlogic,meson8b-wdt" 5- compatible : depending on the SoC this should be one of:
6 "amlogic,meson6-wdt" on Meson6 SoCs
7 "amlogic,meson8-wdt" and "amlogic,meson6-wdt" on Meson8 SoCs
8 "amlogic,meson8b-wdt" on Meson8b SoCs
9 "amlogic,meson8m2-wdt" and "amlogic,meson8b-wdt" on Meson8m2 SoCs
6- reg : Specifies base physical address and size of the registers. 10- reg : Specifies base physical address and size of the registers.
7 11
8Example: 12Example:
diff --git a/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt b/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt
index 20ada673ab0c..235de0683bb6 100644
--- a/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt
+++ b/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt
@@ -6,6 +6,8 @@ Required properties:
6 "mediatek,mt2701-wdt", "mediatek,mt6589-wdt": for MT2701 6 "mediatek,mt2701-wdt", "mediatek,mt6589-wdt": for MT2701
7 "mediatek,mt6589-wdt": for MT6589 7 "mediatek,mt6589-wdt": for MT6589
8 "mediatek,mt6797-wdt", "mediatek,mt6589-wdt": for MT6797 8 "mediatek,mt6797-wdt", "mediatek,mt6589-wdt": for MT6797
9 "mediatek,mt7622-wdt", "mediatek,mt6589-wdt": for MT7622
10 "mediatek,mt7623-wdt", "mediatek,mt6589-wdt": for MT7623
9 11
10- reg : Specifies base physical address and size of the registers. 12- reg : Specifies base physical address and size of the registers.
11 13
diff --git a/Documentation/devicetree/bindings/watchdog/renesas-wdt.txt b/Documentation/devicetree/bindings/watchdog/renesas-wdt.txt
index 9e306afbbd49..bf6d1ca58af7 100644
--- a/Documentation/devicetree/bindings/watchdog/renesas-wdt.txt
+++ b/Documentation/devicetree/bindings/watchdog/renesas-wdt.txt
@@ -6,6 +6,7 @@ Required properties:
6 Examples with soctypes are: 6 Examples with soctypes are:
7 - "renesas,r8a7795-wdt" (R-Car H3) 7 - "renesas,r8a7795-wdt" (R-Car H3)
8 - "renesas,r8a7796-wdt" (R-Car M3-W) 8 - "renesas,r8a7796-wdt" (R-Car M3-W)
9 - "renesas,r8a77995-wdt" (R-Car D3)
9 - "renesas,r7s72100-wdt" (RZ/A1) 10 - "renesas,r7s72100-wdt" (RZ/A1)
10 11
11 When compatible with the generic version, nodes must list the SoC-specific 12 When compatible with the generic version, nodes must list the SoC-specific
diff --git a/Documentation/watchdog/watchdog-parameters.txt b/Documentation/watchdog/watchdog-parameters.txt
index b3526365ea8e..6f9d7b418917 100644
--- a/Documentation/watchdog/watchdog-parameters.txt
+++ b/Documentation/watchdog/watchdog-parameters.txt
@@ -117,7 +117,7 @@ nowayout: Watchdog cannot be stopped once started
117------------------------------------------------- 117-------------------------------------------------
118iTCO_wdt: 118iTCO_wdt:
119heartbeat: Watchdog heartbeat in seconds. 119heartbeat: Watchdog heartbeat in seconds.
120 (5<=heartbeat<=74 (TCO v1) or 1226 (TCO v2), default=30) 120 (2<heartbeat<39 (TCO v1) or 613 (TCO v2), default=30)
121nowayout: Watchdog cannot be stopped once started 121nowayout: Watchdog cannot be stopped once started
122 (default=kernel config parameter) 122 (default=kernel config parameter)
123------------------------------------------------- 123-------------------------------------------------
diff --git a/drivers/watchdog/asm9260_wdt.c b/drivers/watchdog/asm9260_wdt.c
index 53da001f0838..7dd0da644a7f 100644
--- a/drivers/watchdog/asm9260_wdt.c
+++ b/drivers/watchdog/asm9260_wdt.c
@@ -82,7 +82,7 @@ static unsigned int asm9260_wdt_gettimeleft(struct watchdog_device *wdd)
82 82
83 counter = ioread32(priv->iobase + HW_WDTV); 83 counter = ioread32(priv->iobase + HW_WDTV);
84 84
85 return DIV_ROUND_CLOSEST(counter, priv->wdt_freq); 85 return counter / priv->wdt_freq;
86} 86}
87 87
88static int asm9260_wdt_updatetimeout(struct watchdog_device *wdd) 88static int asm9260_wdt_updatetimeout(struct watchdog_device *wdd)
@@ -296,7 +296,7 @@ static int asm9260_wdt_probe(struct platform_device *pdev)
296 if (ret) 296 if (ret)
297 return ret; 297 return ret;
298 298
299 priv->rst = devm_reset_control_get(&pdev->dev, "wdt_rst"); 299 priv->rst = devm_reset_control_get_exclusive(&pdev->dev, "wdt_rst");
300 if (IS_ERR(priv->rst)) 300 if (IS_ERR(priv->rst))
301 return PTR_ERR(priv->rst); 301 return PTR_ERR(priv->rst);
302 302
diff --git a/drivers/watchdog/aspeed_wdt.c b/drivers/watchdog/aspeed_wdt.c
index 1c652582de40..79cc766cd30f 100644
--- a/drivers/watchdog/aspeed_wdt.c
+++ b/drivers/watchdog/aspeed_wdt.c
@@ -23,9 +23,21 @@ struct aspeed_wdt {
23 u32 ctrl; 23 u32 ctrl;
24}; 24};
25 25
26struct aspeed_wdt_config {
27 u32 ext_pulse_width_mask;
28};
29
30static const struct aspeed_wdt_config ast2400_config = {
31 .ext_pulse_width_mask = 0xff,
32};
33
34static const struct aspeed_wdt_config ast2500_config = {
35 .ext_pulse_width_mask = 0xfffff,
36};
37
26static const struct of_device_id aspeed_wdt_of_table[] = { 38static const struct of_device_id aspeed_wdt_of_table[] = {
27 { .compatible = "aspeed,ast2400-wdt" }, 39 { .compatible = "aspeed,ast2400-wdt", .data = &ast2400_config },
28 { .compatible = "aspeed,ast2500-wdt" }, 40 { .compatible = "aspeed,ast2500-wdt", .data = &ast2500_config },
29 { }, 41 { },
30}; 42};
31MODULE_DEVICE_TABLE(of, aspeed_wdt_of_table); 43MODULE_DEVICE_TABLE(of, aspeed_wdt_of_table);
@@ -36,12 +48,45 @@ MODULE_DEVICE_TABLE(of, aspeed_wdt_of_table);
36#define WDT_CTRL 0x0C 48#define WDT_CTRL 0x0C
37#define WDT_CTRL_RESET_MODE_SOC (0x00 << 5) 49#define WDT_CTRL_RESET_MODE_SOC (0x00 << 5)
38#define WDT_CTRL_RESET_MODE_FULL_CHIP (0x01 << 5) 50#define WDT_CTRL_RESET_MODE_FULL_CHIP (0x01 << 5)
51#define WDT_CTRL_RESET_MODE_ARM_CPU (0x10 << 5)
39#define WDT_CTRL_1MHZ_CLK BIT(4) 52#define WDT_CTRL_1MHZ_CLK BIT(4)
40#define WDT_CTRL_WDT_EXT BIT(3) 53#define WDT_CTRL_WDT_EXT BIT(3)
41#define WDT_CTRL_WDT_INTR BIT(2) 54#define WDT_CTRL_WDT_INTR BIT(2)
42#define WDT_CTRL_RESET_SYSTEM BIT(1) 55#define WDT_CTRL_RESET_SYSTEM BIT(1)
43#define WDT_CTRL_ENABLE BIT(0) 56#define WDT_CTRL_ENABLE BIT(0)
44 57
58/*
59 * WDT_RESET_WIDTH controls the characteristics of the external pulse (if
60 * enabled), specifically:
61 *
62 * * Pulse duration
63 * * Drive mode: push-pull vs open-drain
64 * * Polarity: Active high or active low
65 *
66 * Pulse duration configuration is available on both the AST2400 and AST2500,
67 * though the field changes between SoCs:
68 *
69 * AST2400: Bits 7:0
70 * AST2500: Bits 19:0
71 *
72 * This difference is captured in struct aspeed_wdt_config.
73 *
74 * The AST2500 exposes the drive mode and polarity options, but not in a
75 * regular fashion. For read purposes, bit 31 represents active high or low,
76 * and bit 30 represents push-pull or open-drain. With respect to write, magic
77 * values need to be written to the top byte to change the state of the drive
78 * mode and polarity bits. Any other value written to the top byte has no
79 * effect on the state of the drive mode or polarity bits. However, the pulse
80 * width value must be preserved (as desired) if written.
81 */
82#define WDT_RESET_WIDTH 0x18
83#define WDT_RESET_WIDTH_ACTIVE_HIGH BIT(31)
84#define WDT_ACTIVE_HIGH_MAGIC (0xA5 << 24)
85#define WDT_ACTIVE_LOW_MAGIC (0x5A << 24)
86#define WDT_RESET_WIDTH_PUSH_PULL BIT(30)
87#define WDT_PUSH_PULL_MAGIC (0xA8 << 24)
88#define WDT_OPEN_DRAIN_MAGIC (0x8A << 24)
89
45#define WDT_RESTART_MAGIC 0x4755 90#define WDT_RESTART_MAGIC 0x4755
46 91
47/* 32 bits at 1MHz, in milliseconds */ 92/* 32 bits at 1MHz, in milliseconds */
@@ -138,8 +183,13 @@ static const struct watchdog_info aspeed_wdt_info = {
138 183
139static int aspeed_wdt_probe(struct platform_device *pdev) 184static int aspeed_wdt_probe(struct platform_device *pdev)
140{ 185{
186 const struct aspeed_wdt_config *config;
187 const struct of_device_id *ofdid;
141 struct aspeed_wdt *wdt; 188 struct aspeed_wdt *wdt;
142 struct resource *res; 189 struct resource *res;
190 struct device_node *np;
191 const char *reset_type;
192 u32 duration;
143 int ret; 193 int ret;
144 194
145 wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL); 195 wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
@@ -164,20 +214,88 @@ static int aspeed_wdt_probe(struct platform_device *pdev)
164 wdt->wdd.timeout = WDT_DEFAULT_TIMEOUT; 214 wdt->wdd.timeout = WDT_DEFAULT_TIMEOUT;
165 watchdog_init_timeout(&wdt->wdd, 0, &pdev->dev); 215 watchdog_init_timeout(&wdt->wdd, 0, &pdev->dev);
166 216
217 np = pdev->dev.of_node;
218
219 ofdid = of_match_node(aspeed_wdt_of_table, np);
220 if (!ofdid)
221 return -EINVAL;
222 config = ofdid->data;
223
224 wdt->ctrl = WDT_CTRL_1MHZ_CLK;
225
167 /* 226 /*
168 * Control reset on a per-device basis to ensure the 227 * Control reset on a per-device basis to ensure the
169 * host is not affected by a BMC reboot, so only reset 228 * host is not affected by a BMC reboot
170 * the SOC and not the full chip
171 */ 229 */
172 wdt->ctrl = WDT_CTRL_RESET_MODE_SOC | 230 ret = of_property_read_string(np, "aspeed,reset-type", &reset_type);
173 WDT_CTRL_1MHZ_CLK | 231 if (ret) {
174 WDT_CTRL_RESET_SYSTEM; 232 wdt->ctrl |= WDT_CTRL_RESET_MODE_SOC | WDT_CTRL_RESET_SYSTEM;
233 } else {
234 if (!strcmp(reset_type, "cpu"))
235 wdt->ctrl |= WDT_CTRL_RESET_MODE_ARM_CPU;
236 else if (!strcmp(reset_type, "soc"))
237 wdt->ctrl |= WDT_CTRL_RESET_MODE_SOC;
238 else if (!strcmp(reset_type, "system"))
239 wdt->ctrl |= WDT_CTRL_RESET_SYSTEM;
240 else if (strcmp(reset_type, "none"))
241 return -EINVAL;
242 }
243 if (of_property_read_bool(np, "aspeed,external-signal"))
244 wdt->ctrl |= WDT_CTRL_WDT_EXT;
245
246 writel(wdt->ctrl, wdt->base + WDT_CTRL);
175 247
176 if (readl(wdt->base + WDT_CTRL) & WDT_CTRL_ENABLE) { 248 if (readl(wdt->base + WDT_CTRL) & WDT_CTRL_ENABLE) {
177 aspeed_wdt_start(&wdt->wdd); 249 aspeed_wdt_start(&wdt->wdd);
178 set_bit(WDOG_HW_RUNNING, &wdt->wdd.status); 250 set_bit(WDOG_HW_RUNNING, &wdt->wdd.status);
179 } 251 }
180 252
253 if (of_device_is_compatible(np, "aspeed,ast2500-wdt")) {
254 u32 reg = readl(wdt->base + WDT_RESET_WIDTH);
255
256 reg &= config->ext_pulse_width_mask;
257 if (of_property_read_bool(np, "aspeed,ext-push-pull"))
258 reg |= WDT_PUSH_PULL_MAGIC;
259 else
260 reg |= WDT_OPEN_DRAIN_MAGIC;
261
262 writel(reg, wdt->base + WDT_RESET_WIDTH);
263
264 reg &= config->ext_pulse_width_mask;
265 if (of_property_read_bool(np, "aspeed,ext-active-high"))
266 reg |= WDT_ACTIVE_HIGH_MAGIC;
267 else
268 reg |= WDT_ACTIVE_LOW_MAGIC;
269
270 writel(reg, wdt->base + WDT_RESET_WIDTH);
271 }
272
273 if (!of_property_read_u32(np, "aspeed,ext-pulse-duration", &duration)) {
274 u32 max_duration = config->ext_pulse_width_mask + 1;
275
276 if (duration == 0 || duration > max_duration) {
277 dev_err(&pdev->dev, "Invalid pulse duration: %uus\n",
278 duration);
279 duration = max(1U, min(max_duration, duration));
280 dev_info(&pdev->dev, "Pulse duration set to %uus\n",
281 duration);
282 }
283
284 /*
285 * The watchdog is always configured with a 1MHz source, so
286 * there is no need to scale the microsecond value. However we
287 * need to offset it - from the datasheet:
288 *
289 * "This register decides the asserting duration of wdt_ext and
290 * wdt_rstarm signal. The default value is 0xFF. It means the
291 * default asserting duration of wdt_ext and wdt_rstarm is
292 * 256us."
293 *
294 * This implies a value of 0 gives a 1us pulse.
295 */
296 writel(duration - 1, wdt->base + WDT_RESET_WIDTH);
297 }
298
181 ret = devm_watchdog_register_device(&pdev->dev, &wdt->wdd); 299 ret = devm_watchdog_register_device(&pdev->dev, &wdt->wdd);
182 if (ret) { 300 if (ret) {
183 dev_err(&pdev->dev, "failed to register\n"); 301 dev_err(&pdev->dev, "failed to register\n");
diff --git a/drivers/watchdog/bcm7038_wdt.c b/drivers/watchdog/bcm7038_wdt.c
index c1b8e534fb55..f88f546e8050 100644
--- a/drivers/watchdog/bcm7038_wdt.c
+++ b/drivers/watchdog/bcm7038_wdt.c
@@ -136,7 +136,9 @@ static int bcm7038_wdt_probe(struct platform_device *pdev)
136 wdt->clk = devm_clk_get(dev, NULL); 136 wdt->clk = devm_clk_get(dev, NULL);
137 /* If unable to get clock, use default frequency */ 137 /* If unable to get clock, use default frequency */
138 if (!IS_ERR(wdt->clk)) { 138 if (!IS_ERR(wdt->clk)) {
139 clk_prepare_enable(wdt->clk); 139 err = clk_prepare_enable(wdt->clk);
140 if (err)
141 return err;
140 wdt->rate = clk_get_rate(wdt->clk); 142 wdt->rate = clk_get_rate(wdt->clk);
141 /* Prevent divide-by-zero exception */ 143 /* Prevent divide-by-zero exception */
142 if (!wdt->rate) 144 if (!wdt->rate)
diff --git a/drivers/watchdog/cadence_wdt.c b/drivers/watchdog/cadence_wdt.c
index 05c000081e9d..064cf7b6c1c5 100644
--- a/drivers/watchdog/cadence_wdt.c
+++ b/drivers/watchdog/cadence_wdt.c
@@ -52,12 +52,12 @@
52static int wdt_timeout; 52static int wdt_timeout;
53static int nowayout = WATCHDOG_NOWAYOUT; 53static int nowayout = WATCHDOG_NOWAYOUT;
54 54
55module_param(wdt_timeout, int, 0); 55module_param(wdt_timeout, int, 0644);
56MODULE_PARM_DESC(wdt_timeout, 56MODULE_PARM_DESC(wdt_timeout,
57 "Watchdog time in seconds. (default=" 57 "Watchdog time in seconds. (default="
58 __MODULE_STRING(CDNS_WDT_DEFAULT_TIMEOUT) ")"); 58 __MODULE_STRING(CDNS_WDT_DEFAULT_TIMEOUT) ")");
59 59
60module_param(nowayout, int, 0); 60module_param(nowayout, int, 0644);
61MODULE_PARM_DESC(nowayout, 61MODULE_PARM_DESC(nowayout,
62 "Watchdog cannot be stopped once started (default=" 62 "Watchdog cannot be stopped once started (default="
63 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 63 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
@@ -368,7 +368,7 @@ static int cdns_wdt_probe(struct platform_device *pdev)
368 } 368 }
369 platform_set_drvdata(pdev, wdt); 369 platform_set_drvdata(pdev, wdt);
370 370
371 dev_dbg(&pdev->dev, "Xilinx Watchdog Timer at %p with timeout %ds%s\n", 371 dev_info(&pdev->dev, "Xilinx Watchdog Timer at %p with timeout %ds%s\n",
372 wdt->regs, cdns_wdt_device->timeout, 372 wdt->regs, cdns_wdt_device->timeout,
373 nowayout ? ", nowayout" : ""); 373 nowayout ? ", nowayout" : "");
374 374
diff --git a/drivers/watchdog/coh901327_wdt.c b/drivers/watchdog/coh901327_wdt.c
index 38dd60f0cfcc..4410337f4f7f 100644
--- a/drivers/watchdog/coh901327_wdt.c
+++ b/drivers/watchdog/coh901327_wdt.c
@@ -218,7 +218,7 @@ static const struct watchdog_info coh901327_ident = {
218 .identity = DRV_NAME, 218 .identity = DRV_NAME,
219}; 219};
220 220
221static struct watchdog_ops coh901327_ops = { 221static const struct watchdog_ops coh901327_ops = {
222 .owner = THIS_MODULE, 222 .owner = THIS_MODULE,
223 .start = coh901327_start, 223 .start = coh901327_start,
224 .stop = coh901327_stop, 224 .stop = coh901327_stop,
diff --git a/drivers/watchdog/da9063_wdt.c b/drivers/watchdog/da9063_wdt.c
index 4691c5509129..2a20fc163ed0 100644
--- a/drivers/watchdog/da9063_wdt.c
+++ b/drivers/watchdog/da9063_wdt.c
@@ -36,11 +36,6 @@ static const unsigned int wdt_timeout[] = { 0, 2, 4, 8, 16, 32, 65, 131 };
36#define DA9063_WDG_TIMEOUT wdt_timeout[3] 36#define DA9063_WDG_TIMEOUT wdt_timeout[3]
37#define DA9063_RESET_PROTECTION_MS 256 37#define DA9063_RESET_PROTECTION_MS 256
38 38
39struct da9063_watchdog {
40 struct da9063 *da9063;
41 struct watchdog_device wdtdev;
42};
43
44static unsigned int da9063_wdt_timeout_to_sel(unsigned int secs) 39static unsigned int da9063_wdt_timeout_to_sel(unsigned int secs)
45{ 40{
46 unsigned int i; 41 unsigned int i;
@@ -61,14 +56,14 @@ static int _da9063_wdt_set_timeout(struct da9063 *da9063, unsigned int regval)
61 56
62static int da9063_wdt_start(struct watchdog_device *wdd) 57static int da9063_wdt_start(struct watchdog_device *wdd)
63{ 58{
64 struct da9063_watchdog *wdt = watchdog_get_drvdata(wdd); 59 struct da9063 *da9063 = watchdog_get_drvdata(wdd);
65 unsigned int selector; 60 unsigned int selector;
66 int ret; 61 int ret;
67 62
68 selector = da9063_wdt_timeout_to_sel(wdt->wdtdev.timeout); 63 selector = da9063_wdt_timeout_to_sel(wdd->timeout);
69 ret = _da9063_wdt_set_timeout(wdt->da9063, selector); 64 ret = _da9063_wdt_set_timeout(da9063, selector);
70 if (ret) 65 if (ret)
71 dev_err(wdt->da9063->dev, "Watchdog failed to start (err = %d)\n", 66 dev_err(da9063->dev, "Watchdog failed to start (err = %d)\n",
72 ret); 67 ret);
73 68
74 return ret; 69 return ret;
@@ -76,13 +71,13 @@ static int da9063_wdt_start(struct watchdog_device *wdd)
76 71
77static int da9063_wdt_stop(struct watchdog_device *wdd) 72static int da9063_wdt_stop(struct watchdog_device *wdd)
78{ 73{
79 struct da9063_watchdog *wdt = watchdog_get_drvdata(wdd); 74 struct da9063 *da9063 = watchdog_get_drvdata(wdd);
80 int ret; 75 int ret;
81 76
82 ret = regmap_update_bits(wdt->da9063->regmap, DA9063_REG_CONTROL_D, 77 ret = regmap_update_bits(da9063->regmap, DA9063_REG_CONTROL_D,
83 DA9063_TWDSCALE_MASK, DA9063_TWDSCALE_DISABLE); 78 DA9063_TWDSCALE_MASK, DA9063_TWDSCALE_DISABLE);
84 if (ret) 79 if (ret)
85 dev_alert(wdt->da9063->dev, "Watchdog failed to stop (err = %d)\n", 80 dev_alert(da9063->dev, "Watchdog failed to stop (err = %d)\n",
86 ret); 81 ret);
87 82
88 return ret; 83 return ret;
@@ -90,13 +85,13 @@ static int da9063_wdt_stop(struct watchdog_device *wdd)
90 85
91static int da9063_wdt_ping(struct watchdog_device *wdd) 86static int da9063_wdt_ping(struct watchdog_device *wdd)
92{ 87{
93 struct da9063_watchdog *wdt = watchdog_get_drvdata(wdd); 88 struct da9063 *da9063 = watchdog_get_drvdata(wdd);
94 int ret; 89 int ret;
95 90
96 ret = regmap_write(wdt->da9063->regmap, DA9063_REG_CONTROL_F, 91 ret = regmap_write(da9063->regmap, DA9063_REG_CONTROL_F,
97 DA9063_WATCHDOG); 92 DA9063_WATCHDOG);
98 if (ret) 93 if (ret)
99 dev_alert(wdt->da9063->dev, "Failed to ping the watchdog (err = %d)\n", 94 dev_alert(da9063->dev, "Failed to ping the watchdog (err = %d)\n",
100 ret); 95 ret);
101 96
102 return ret; 97 return ret;
@@ -105,14 +100,14 @@ static int da9063_wdt_ping(struct watchdog_device *wdd)
105static int da9063_wdt_set_timeout(struct watchdog_device *wdd, 100static int da9063_wdt_set_timeout(struct watchdog_device *wdd,
106 unsigned int timeout) 101 unsigned int timeout)
107{ 102{
108 struct da9063_watchdog *wdt = watchdog_get_drvdata(wdd); 103 struct da9063 *da9063 = watchdog_get_drvdata(wdd);
109 unsigned int selector; 104 unsigned int selector;
110 int ret; 105 int ret;
111 106
112 selector = da9063_wdt_timeout_to_sel(timeout); 107 selector = da9063_wdt_timeout_to_sel(timeout);
113 ret = _da9063_wdt_set_timeout(wdt->da9063, selector); 108 ret = _da9063_wdt_set_timeout(da9063, selector);
114 if (ret) 109 if (ret)
115 dev_err(wdt->da9063->dev, "Failed to set watchdog timeout (err = %d)\n", 110 dev_err(da9063->dev, "Failed to set watchdog timeout (err = %d)\n",
116 ret); 111 ret);
117 else 112 else
118 wdd->timeout = wdt_timeout[selector]; 113 wdd->timeout = wdt_timeout[selector];
@@ -123,13 +118,13 @@ static int da9063_wdt_set_timeout(struct watchdog_device *wdd,
123static int da9063_wdt_restart(struct watchdog_device *wdd, unsigned long action, 118static int da9063_wdt_restart(struct watchdog_device *wdd, unsigned long action,
124 void *data) 119 void *data)
125{ 120{
126 struct da9063_watchdog *wdt = watchdog_get_drvdata(wdd); 121 struct da9063 *da9063 = watchdog_get_drvdata(wdd);
127 int ret; 122 int ret;
128 123
129 ret = regmap_write(wdt->da9063->regmap, DA9063_REG_CONTROL_F, 124 ret = regmap_write(da9063->regmap, DA9063_REG_CONTROL_F,
130 DA9063_SHUTDOWN); 125 DA9063_SHUTDOWN);
131 if (ret) 126 if (ret)
132 dev_alert(wdt->da9063->dev, "Failed to shutdown (err = %d)\n", 127 dev_alert(da9063->dev, "Failed to shutdown (err = %d)\n",
133 ret); 128 ret);
134 129
135 return ret; 130 return ret;
@@ -152,7 +147,7 @@ static const struct watchdog_ops da9063_watchdog_ops = {
152static int da9063_wdt_probe(struct platform_device *pdev) 147static int da9063_wdt_probe(struct platform_device *pdev)
153{ 148{
154 struct da9063 *da9063; 149 struct da9063 *da9063;
155 struct da9063_watchdog *wdt; 150 struct watchdog_device *wdd;
156 151
157 if (!pdev->dev.parent) 152 if (!pdev->dev.parent)
158 return -EINVAL; 153 return -EINVAL;
@@ -161,27 +156,25 @@ static int da9063_wdt_probe(struct platform_device *pdev)
161 if (!da9063) 156 if (!da9063)
162 return -EINVAL; 157 return -EINVAL;
163 158
164 wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL); 159 wdd = devm_kzalloc(&pdev->dev, sizeof(*wdd), GFP_KERNEL);
165 if (!wdt) 160 if (!wdd)
166 return -ENOMEM; 161 return -ENOMEM;
167 162
168 wdt->da9063 = da9063; 163 wdd->info = &da9063_watchdog_info;
169 164 wdd->ops = &da9063_watchdog_ops;
170 wdt->wdtdev.info = &da9063_watchdog_info; 165 wdd->min_timeout = DA9063_WDT_MIN_TIMEOUT;
171 wdt->wdtdev.ops = &da9063_watchdog_ops; 166 wdd->max_timeout = DA9063_WDT_MAX_TIMEOUT;
172 wdt->wdtdev.min_timeout = DA9063_WDT_MIN_TIMEOUT; 167 wdd->min_hw_heartbeat_ms = DA9063_RESET_PROTECTION_MS;
173 wdt->wdtdev.max_timeout = DA9063_WDT_MAX_TIMEOUT; 168 wdd->timeout = DA9063_WDG_TIMEOUT;
174 wdt->wdtdev.min_hw_heartbeat_ms = DA9063_RESET_PROTECTION_MS; 169 wdd->parent = &pdev->dev;
175 wdt->wdtdev.timeout = DA9063_WDG_TIMEOUT;
176 wdt->wdtdev.parent = &pdev->dev;
177 170
178 wdt->wdtdev.status = WATCHDOG_NOWAYOUT_INIT_STATUS; 171 wdd->status = WATCHDOG_NOWAYOUT_INIT_STATUS;
179 172
180 watchdog_set_restart_priority(&wdt->wdtdev, 128); 173 watchdog_set_restart_priority(wdd, 128);
181 174
182 watchdog_set_drvdata(&wdt->wdtdev, wdt); 175 watchdog_set_drvdata(wdd, da9063);
183 176
184 return devm_watchdog_register_device(&pdev->dev, &wdt->wdtdev); 177 return devm_watchdog_register_device(&pdev->dev, wdd);
185} 178}
186 179
187static struct platform_driver da9063_wdt_driver = { 180static struct platform_driver da9063_wdt_driver = {
diff --git a/drivers/watchdog/diag288_wdt.c b/drivers/watchdog/diag288_wdt.c
index 6f591084bb7a..806a04a676b7 100644
--- a/drivers/watchdog/diag288_wdt.c
+++ b/drivers/watchdog/diag288_wdt.c
@@ -213,7 +213,7 @@ static const struct watchdog_ops wdt_ops = {
213 .set_timeout = wdt_set_timeout, 213 .set_timeout = wdt_set_timeout,
214}; 214};
215 215
216static struct watchdog_info wdt_info = { 216static const struct watchdog_info wdt_info = {
217 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, 217 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
218 .firmware_version = 0, 218 .firmware_version = 0,
219 .identity = "z Watchdog", 219 .identity = "z Watchdog",
diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c
index c4f65873bfa4..347f0389b089 100644
--- a/drivers/watchdog/iTCO_wdt.c
+++ b/drivers/watchdog/iTCO_wdt.c
@@ -306,15 +306,16 @@ static int iTCO_wdt_ping(struct watchdog_device *wd_dev)
306 306
307 iTCO_vendor_pre_keepalive(p->smi_res, wd_dev->timeout); 307 iTCO_vendor_pre_keepalive(p->smi_res, wd_dev->timeout);
308 308
309 /* Reset the timeout status bit so that the timer
310 * needs to count down twice again before rebooting */
311 outw(0x0008, TCO1_STS(p)); /* write 1 to clear bit */
312
313 /* Reload the timer by writing to the TCO Timer Counter register */ 309 /* Reload the timer by writing to the TCO Timer Counter register */
314 if (p->iTCO_version >= 2) 310 if (p->iTCO_version >= 2) {
315 outw(0x01, TCO_RLD(p)); 311 outw(0x01, TCO_RLD(p));
316 else if (p->iTCO_version == 1) 312 } else if (p->iTCO_version == 1) {
313 /* Reset the timeout status bit so that the timer
314 * needs to count down twice again before rebooting */
315 outw(0x0008, TCO1_STS(p)); /* write 1 to clear bit */
316
317 outb(0x01, TCO_RLD(p)); 317 outb(0x01, TCO_RLD(p));
318 }
318 319
319 spin_unlock(&p->io_lock); 320 spin_unlock(&p->io_lock);
320 return 0; 321 return 0;
@@ -327,8 +328,11 @@ static int iTCO_wdt_set_timeout(struct watchdog_device *wd_dev, unsigned int t)
327 unsigned char val8; 328 unsigned char val8;
328 unsigned int tmrval; 329 unsigned int tmrval;
329 330
330 /* The timer counts down twice before rebooting */ 331 tmrval = seconds_to_ticks(p, t);
331 tmrval = seconds_to_ticks(p, t) / 2; 332
333 /* For TCO v1 the timer counts down twice before rebooting */
334 if (p->iTCO_version == 1)
335 tmrval /= 2;
332 336
333 /* from the specs: */ 337 /* from the specs: */
334 /* "Values of 0h-3h are ignored and should not be attempted" */ 338 /* "Values of 0h-3h are ignored and should not be attempted" */
@@ -381,8 +385,6 @@ static unsigned int iTCO_wdt_get_timeleft(struct watchdog_device *wd_dev)
381 spin_lock(&p->io_lock); 385 spin_lock(&p->io_lock);
382 val16 = inw(TCO_RLD(p)); 386 val16 = inw(TCO_RLD(p));
383 val16 &= 0x3ff; 387 val16 &= 0x3ff;
384 if (!(inw(TCO1_STS(p)) & 0x0008))
385 val16 += (inw(TCOv2_TMR(p)) & 0x3ff);
386 spin_unlock(&p->io_lock); 388 spin_unlock(&p->io_lock);
387 389
388 time_left = ticks_to_seconds(p, val16); 390 time_left = ticks_to_seconds(p, val16);
diff --git a/drivers/watchdog/it87_wdt.c b/drivers/watchdog/it87_wdt.c
index dd1e7eaef50f..e96faea24925 100644
--- a/drivers/watchdog/it87_wdt.c
+++ b/drivers/watchdog/it87_wdt.c
@@ -253,7 +253,7 @@ static const struct watchdog_info ident = {
253 .identity = WATCHDOG_NAME, 253 .identity = WATCHDOG_NAME,
254}; 254};
255 255
256static struct watchdog_ops wdt_ops = { 256static const struct watchdog_ops wdt_ops = {
257 .owner = THIS_MODULE, 257 .owner = THIS_MODULE,
258 .start = wdt_start, 258 .start = wdt_start,
259 .stop = wdt_stop, 259 .stop = wdt_stop,
diff --git a/drivers/watchdog/max77620_wdt.c b/drivers/watchdog/max77620_wdt.c
index 68c41fa2be27..2c9f53eaff4f 100644
--- a/drivers/watchdog/max77620_wdt.c
+++ b/drivers/watchdog/max77620_wdt.c
@@ -201,7 +201,7 @@ static int max77620_wdt_remove(struct platform_device *pdev)
201 return 0; 201 return 0;
202} 202}
203 203
204static struct platform_device_id max77620_wdt_devtype[] = { 204static const struct platform_device_id max77620_wdt_devtype[] = {
205 { .name = "max77620-watchdog", }, 205 { .name = "max77620-watchdog", },
206 { }, 206 { },
207}; 207};
diff --git a/drivers/watchdog/mei_wdt.c b/drivers/watchdog/mei_wdt.c
index b29c6fde7473..ea60b29494fb 100644
--- a/drivers/watchdog/mei_wdt.c
+++ b/drivers/watchdog/mei_wdt.c
@@ -670,7 +670,7 @@ static int mei_wdt_remove(struct mei_cl_device *cldev)
670#define MEI_UUID_WD UUID_LE(0x05B79A6F, 0x4628, 0x4D7F, \ 670#define MEI_UUID_WD UUID_LE(0x05B79A6F, 0x4628, 0x4D7F, \
671 0x89, 0x9D, 0xA9, 0x15, 0x14, 0xCB, 0x32, 0xAB) 671 0x89, 0x9D, 0xA9, 0x15, 0x14, 0xCB, 0x32, 0xAB)
672 672
673static struct mei_cl_device_id mei_wdt_tbl[] = { 673static const struct mei_cl_device_id mei_wdt_tbl[] = {
674 { .uuid = MEI_UUID_WD, .version = MEI_CL_VERSION_ANY }, 674 { .uuid = MEI_UUID_WD, .version = MEI_CL_VERSION_ANY },
675 /* required last entry */ 675 /* required last entry */
676 { } 676 { }
diff --git a/drivers/watchdog/meson_wdt.c b/drivers/watchdog/meson_wdt.c
index 491b9bf13d84..304274c67735 100644
--- a/drivers/watchdog/meson_wdt.c
+++ b/drivers/watchdog/meson_wdt.c
@@ -155,7 +155,9 @@ static const struct watchdog_ops meson_wdt_ops = {
155 155
156static const struct of_device_id meson_wdt_dt_ids[] = { 156static const struct of_device_id meson_wdt_dt_ids[] = {
157 { .compatible = "amlogic,meson6-wdt", .data = &meson6_wdt_data }, 157 { .compatible = "amlogic,meson6-wdt", .data = &meson6_wdt_data },
158 { .compatible = "amlogic,meson8-wdt", .data = &meson6_wdt_data },
158 { .compatible = "amlogic,meson8b-wdt", .data = &meson8b_wdt_data }, 159 { .compatible = "amlogic,meson8b-wdt", .data = &meson8b_wdt_data },
160 { .compatible = "amlogic,meson8m2-wdt", .data = &meson8b_wdt_data },
159 { /* sentinel */ } 161 { /* sentinel */ }
160}; 162};
161MODULE_DEVICE_TABLE(of, meson_wdt_dt_ids); 163MODULE_DEVICE_TABLE(of, meson_wdt_dt_ids);
diff --git a/drivers/watchdog/mt7621_wdt.c b/drivers/watchdog/mt7621_wdt.c
index 48a06067075d..db38f8017218 100644
--- a/drivers/watchdog/mt7621_wdt.c
+++ b/drivers/watchdog/mt7621_wdt.c
@@ -105,7 +105,7 @@ static int mt7621_wdt_bootcause(void)
105 return 0; 105 return 0;
106} 106}
107 107
108static struct watchdog_info mt7621_wdt_info = { 108static const struct watchdog_info mt7621_wdt_info = {
109 .identity = "Mediatek Watchdog", 109 .identity = "Mediatek Watchdog",
110 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, 110 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
111}; 111};
@@ -135,7 +135,7 @@ static int mt7621_wdt_probe(struct platform_device *pdev)
135 if (IS_ERR(mt7621_wdt_base)) 135 if (IS_ERR(mt7621_wdt_base))
136 return PTR_ERR(mt7621_wdt_base); 136 return PTR_ERR(mt7621_wdt_base);
137 137
138 mt7621_wdt_reset = devm_reset_control_get(&pdev->dev, NULL); 138 mt7621_wdt_reset = devm_reset_control_get_exclusive(&pdev->dev, NULL);
139 if (!IS_ERR(mt7621_wdt_reset)) 139 if (!IS_ERR(mt7621_wdt_reset))
140 reset_control_deassert(mt7621_wdt_reset); 140 reset_control_deassert(mt7621_wdt_reset);
141 141
diff --git a/drivers/watchdog/of_xilinx_wdt.c b/drivers/watchdog/of_xilinx_wdt.c
index fae7fe929ea3..1cf286945b7a 100644
--- a/drivers/watchdog/of_xilinx_wdt.c
+++ b/drivers/watchdog/of_xilinx_wdt.c
@@ -51,9 +51,16 @@ struct xwdt_device {
51 51
52static int xilinx_wdt_start(struct watchdog_device *wdd) 52static int xilinx_wdt_start(struct watchdog_device *wdd)
53{ 53{
54 int ret;
54 u32 control_status_reg; 55 u32 control_status_reg;
55 struct xwdt_device *xdev = watchdog_get_drvdata(wdd); 56 struct xwdt_device *xdev = watchdog_get_drvdata(wdd);
56 57
58 ret = clk_enable(xdev->clk);
59 if (ret) {
60 dev_err(wdd->parent, "Failed to enable clock\n");
61 return ret;
62 }
63
57 spin_lock(&xdev->spinlock); 64 spin_lock(&xdev->spinlock);
58 65
59 /* Clean previous status and enable the watchdog timer */ 66 /* Clean previous status and enable the watchdog timer */
@@ -85,6 +92,9 @@ static int xilinx_wdt_stop(struct watchdog_device *wdd)
85 iowrite32(0, xdev->base + XWT_TWCSR1_OFFSET); 92 iowrite32(0, xdev->base + XWT_TWCSR1_OFFSET);
86 93
87 spin_unlock(&xdev->spinlock); 94 spin_unlock(&xdev->spinlock);
95
96 clk_disable(xdev->clk);
97
88 pr_info("Stopped!\n"); 98 pr_info("Stopped!\n");
89 99
90 return 0; 100 return 0;
@@ -167,11 +177,6 @@ static int xwdt_probe(struct platform_device *pdev)
167 if (IS_ERR(xdev->base)) 177 if (IS_ERR(xdev->base))
168 return PTR_ERR(xdev->base); 178 return PTR_ERR(xdev->base);
169 179
170 rc = of_property_read_u32(pdev->dev.of_node, "clock-frequency", &pfreq);
171 if (rc)
172 dev_warn(&pdev->dev,
173 "The watchdog clock frequency cannot be obtained\n");
174
175 rc = of_property_read_u32(pdev->dev.of_node, "xlnx,wdt-interval", 180 rc = of_property_read_u32(pdev->dev.of_node, "xlnx,wdt-interval",
176 &xdev->wdt_interval); 181 &xdev->wdt_interval);
177 if (rc) 182 if (rc)
@@ -186,6 +191,26 @@ static int xwdt_probe(struct platform_device *pdev)
186 191
187 watchdog_set_nowayout(xilinx_wdt_wdd, enable_once); 192 watchdog_set_nowayout(xilinx_wdt_wdd, enable_once);
188 193
194 xdev->clk = devm_clk_get(&pdev->dev, NULL);
195 if (IS_ERR(xdev->clk)) {
196 if (PTR_ERR(xdev->clk) != -ENOENT)
197 return PTR_ERR(xdev->clk);
198
199 /*
200 * Clock framework support is optional, continue on
201 * anyways if we don't find a matching clock.
202 */
203 xdev->clk = NULL;
204
205 rc = of_property_read_u32(pdev->dev.of_node, "clock-frequency",
206 &pfreq);
207 if (rc)
208 dev_warn(&pdev->dev,
209 "The watchdog clock freq cannot be obtained\n");
210 } else {
211 pfreq = clk_get_rate(xdev->clk);
212 }
213
189 /* 214 /*
190 * Twice of the 2^wdt_interval / freq because the first wdt overflow is 215 * Twice of the 2^wdt_interval / freq because the first wdt overflow is
191 * ignored (interrupt), reset is only generated at second wdt overflow 216 * ignored (interrupt), reset is only generated at second wdt overflow
@@ -197,14 +222,6 @@ static int xwdt_probe(struct platform_device *pdev)
197 spin_lock_init(&xdev->spinlock); 222 spin_lock_init(&xdev->spinlock);
198 watchdog_set_drvdata(xilinx_wdt_wdd, xdev); 223 watchdog_set_drvdata(xilinx_wdt_wdd, xdev);
199 224
200 xdev->clk = devm_clk_get(&pdev->dev, NULL);
201 if (IS_ERR(xdev->clk)) {
202 if (PTR_ERR(xdev->clk) == -ENOENT)
203 xdev->clk = NULL;
204 else
205 return PTR_ERR(xdev->clk);
206 }
207
208 rc = clk_prepare_enable(xdev->clk); 225 rc = clk_prepare_enable(xdev->clk);
209 if (rc) { 226 if (rc) {
210 dev_err(&pdev->dev, "unable to enable clock\n"); 227 dev_err(&pdev->dev, "unable to enable clock\n");
@@ -223,6 +240,8 @@ static int xwdt_probe(struct platform_device *pdev)
223 goto err_clk_disable; 240 goto err_clk_disable;
224 } 241 }
225 242
243 clk_disable(xdev->clk);
244
226 dev_info(&pdev->dev, "Xilinx Watchdog Timer at %p with timeout %ds\n", 245 dev_info(&pdev->dev, "Xilinx Watchdog Timer at %p with timeout %ds\n",
227 xdev->base, xilinx_wdt_wdd->timeout); 246 xdev->base, xilinx_wdt_wdd->timeout);
228 247
@@ -245,6 +264,43 @@ static int xwdt_remove(struct platform_device *pdev)
245 return 0; 264 return 0;
246} 265}
247 266
267/**
268 * xwdt_suspend - Suspend the device.
269 *
270 * @dev: handle to the device structure.
271 * Return: 0 always.
272 */
273static int __maybe_unused xwdt_suspend(struct device *dev)
274{
275 struct platform_device *pdev = to_platform_device(dev);
276 struct xwdt_device *xdev = platform_get_drvdata(pdev);
277
278 if (watchdog_active(&xdev->xilinx_wdt_wdd))
279 xilinx_wdt_stop(&xdev->xilinx_wdt_wdd);
280
281 return 0;
282}
283
284/**
285 * xwdt_resume - Resume the device.
286 *
287 * @dev: handle to the device structure.
288 * Return: 0 on success, errno otherwise.
289 */
290static int __maybe_unused xwdt_resume(struct device *dev)
291{
292 struct platform_device *pdev = to_platform_device(dev);
293 struct xwdt_device *xdev = platform_get_drvdata(pdev);
294 int ret = 0;
295
296 if (watchdog_active(&xdev->xilinx_wdt_wdd))
297 ret = xilinx_wdt_start(&xdev->xilinx_wdt_wdd);
298
299 return ret;
300}
301
302static SIMPLE_DEV_PM_OPS(xwdt_pm_ops, xwdt_suspend, xwdt_resume);
303
248/* Match table for of_platform binding */ 304/* Match table for of_platform binding */
249static const struct of_device_id xwdt_of_match[] = { 305static const struct of_device_id xwdt_of_match[] = {
250 { .compatible = "xlnx,xps-timebase-wdt-1.00.a", }, 306 { .compatible = "xlnx,xps-timebase-wdt-1.00.a", },
@@ -259,6 +315,7 @@ static struct platform_driver xwdt_driver = {
259 .driver = { 315 .driver = {
260 .name = WATCHDOG_NAME, 316 .name = WATCHDOG_NAME,
261 .of_match_table = xwdt_of_match, 317 .of_match_table = xwdt_of_match,
318 .pm = &xwdt_pm_ops,
262 }, 319 },
263}; 320};
264 321
diff --git a/drivers/watchdog/pcwd_usb.c b/drivers/watchdog/pcwd_usb.c
index 5615f4013924..b9e376c8e2e3 100644
--- a/drivers/watchdog/pcwd_usb.c
+++ b/drivers/watchdog/pcwd_usb.c
@@ -74,7 +74,7 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
74#define USB_PCWD_PRODUCT_ID 0x1140 74#define USB_PCWD_PRODUCT_ID 0x1140
75 75
76/* table of devices that work with this driver */ 76/* table of devices that work with this driver */
77static struct usb_device_id usb_pcwd_table[] = { 77static const struct usb_device_id usb_pcwd_table[] = {
78 { USB_DEVICE(USB_PCWD_VENDOR_ID, USB_PCWD_PRODUCT_ID) }, 78 { USB_DEVICE(USB_PCWD_VENDOR_ID, USB_PCWD_PRODUCT_ID) },
79 { } /* Terminating entry */ 79 { } /* Terminating entry */
80}; 80};
diff --git a/drivers/watchdog/qcom-wdt.c b/drivers/watchdog/qcom-wdt.c
index 4f47b5e90956..780971318810 100644
--- a/drivers/watchdog/qcom-wdt.c
+++ b/drivers/watchdog/qcom-wdt.c
@@ -162,6 +162,8 @@ static int qcom_wdt_probe(struct platform_device *pdev)
162 return -ENOMEM; 162 return -ENOMEM;
163 163
164 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 164 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
165 if (!res)
166 return -ENOMEM;
165 167
166 /* We use CPU0's DGT for the watchdog */ 168 /* We use CPU0's DGT for the watchdog */
167 if (of_property_read_u32(np, "cpu-offset", &percpu_offset)) 169 if (of_property_read_u32(np, "cpu-offset", &percpu_offset))
diff --git a/drivers/watchdog/renesas_wdt.c b/drivers/watchdog/renesas_wdt.c
index cf61c92f7ecd..831ef83f6de1 100644
--- a/drivers/watchdog/renesas_wdt.c
+++ b/drivers/watchdog/renesas_wdt.c
@@ -1,8 +1,8 @@
1/* 1/*
2 * Watchdog driver for Renesas WDT watchdog 2 * Watchdog driver for Renesas WDT watchdog
3 * 3 *
4 * Copyright (C) 2015-16 Wolfram Sang, Sang Engineering <wsa@sang-engineering.com> 4 * Copyright (C) 2015-17 Wolfram Sang, Sang Engineering <wsa@sang-engineering.com>
5 * Copyright (C) 2015-16 Renesas Electronics Corporation 5 * Copyright (C) 2015-17 Renesas Electronics Corporation
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify it 7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License version 2 as published by 8 * under the terms of the GNU General Public License version 2 as published by
@@ -23,10 +23,22 @@
23#define RWTCSRA_WOVF BIT(4) 23#define RWTCSRA_WOVF BIT(4)
24#define RWTCSRA_WRFLG BIT(5) 24#define RWTCSRA_WRFLG BIT(5)
25#define RWTCSRA_TME BIT(7) 25#define RWTCSRA_TME BIT(7)
26#define RWTCSRB 8
26 27
27#define RWDT_DEFAULT_TIMEOUT 60U 28#define RWDT_DEFAULT_TIMEOUT 60U
28 29
29static const unsigned int clk_divs[] = { 1, 4, 16, 32, 64, 128, 1024 }; 30/*
31 * In probe, clk_rate is checked to be not more than 16 bit * biggest clock
32 * divider (12 bits). d is only a factor to fully utilize the WDT counter and
33 * will not exceed its 16 bits. Thus, no overflow, we stay below 32 bits.
34 */
35#define MUL_BY_CLKS_PER_SEC(p, d) \
36 DIV_ROUND_UP((d) * (p)->clk_rate, clk_divs[(p)->cks])
37
38/* d is 16 bit, clk_divs 12 bit -> no 32 bit overflow */
39#define DIV_BY_CLKS_PER_SEC(p, d) ((d) * clk_divs[(p)->cks] / (p)->clk_rate)
40
41static const unsigned int clk_divs[] = { 1, 4, 16, 32, 64, 128, 1024, 4096 };
30 42
31static bool nowayout = WATCHDOG_NOWAYOUT; 43static bool nowayout = WATCHDOG_NOWAYOUT;
32module_param(nowayout, bool, 0); 44module_param(nowayout, bool, 0);
@@ -36,8 +48,7 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
36struct rwdt_priv { 48struct rwdt_priv {
37 void __iomem *base; 49 void __iomem *base;
38 struct watchdog_device wdev; 50 struct watchdog_device wdev;
39 struct clk *clk; 51 unsigned long clk_rate;
40 unsigned int clks_per_sec;
41 u8 cks; 52 u8 cks;
42}; 53};
43 54
@@ -55,7 +66,7 @@ static int rwdt_init_timeout(struct watchdog_device *wdev)
55{ 66{
56 struct rwdt_priv *priv = watchdog_get_drvdata(wdev); 67 struct rwdt_priv *priv = watchdog_get_drvdata(wdev);
57 68
58 rwdt_write(priv, 65536 - wdev->timeout * priv->clks_per_sec, RWTCNT); 69 rwdt_write(priv, 65536 - MUL_BY_CLKS_PER_SEC(priv, wdev->timeout), RWTCNT);
59 70
60 return 0; 71 return 0;
61} 72}
@@ -64,8 +75,9 @@ static int rwdt_start(struct watchdog_device *wdev)
64{ 75{
65 struct rwdt_priv *priv = watchdog_get_drvdata(wdev); 76 struct rwdt_priv *priv = watchdog_get_drvdata(wdev);
66 77
67 clk_prepare_enable(priv->clk); 78 pm_runtime_get_sync(wdev->parent);
68 79
80 rwdt_write(priv, 0, RWTCSRB);
69 rwdt_write(priv, priv->cks, RWTCSRA); 81 rwdt_write(priv, priv->cks, RWTCSRA);
70 rwdt_init_timeout(wdev); 82 rwdt_init_timeout(wdev);
71 83
@@ -82,7 +94,7 @@ static int rwdt_stop(struct watchdog_device *wdev)
82 struct rwdt_priv *priv = watchdog_get_drvdata(wdev); 94 struct rwdt_priv *priv = watchdog_get_drvdata(wdev);
83 95
84 rwdt_write(priv, priv->cks, RWTCSRA); 96 rwdt_write(priv, priv->cks, RWTCSRA);
85 clk_disable_unprepare(priv->clk); 97 pm_runtime_put(wdev->parent);
86 98
87 return 0; 99 return 0;
88} 100}
@@ -92,7 +104,7 @@ static unsigned int rwdt_get_timeleft(struct watchdog_device *wdev)
92 struct rwdt_priv *priv = watchdog_get_drvdata(wdev); 104 struct rwdt_priv *priv = watchdog_get_drvdata(wdev);
93 u16 val = readw_relaxed(priv->base + RWTCNT); 105 u16 val = readw_relaxed(priv->base + RWTCNT);
94 106
95 return DIV_ROUND_CLOSEST(65536 - val, priv->clks_per_sec); 107 return DIV_BY_CLKS_PER_SEC(priv, 65536 - val);
96} 108}
97 109
98static const struct watchdog_info rwdt_ident = { 110static const struct watchdog_info rwdt_ident = {
@@ -112,8 +124,8 @@ static int rwdt_probe(struct platform_device *pdev)
112{ 124{
113 struct rwdt_priv *priv; 125 struct rwdt_priv *priv;
114 struct resource *res; 126 struct resource *res;
115 unsigned long rate; 127 struct clk *clk;
116 unsigned int clks_per_sec; 128 unsigned long clks_per_sec;
117 int ret, i; 129 int ret, i;
118 130
119 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); 131 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
@@ -125,36 +137,40 @@ static int rwdt_probe(struct platform_device *pdev)
125 if (IS_ERR(priv->base)) 137 if (IS_ERR(priv->base))
126 return PTR_ERR(priv->base); 138 return PTR_ERR(priv->base);
127 139
128 priv->clk = devm_clk_get(&pdev->dev, NULL); 140 clk = devm_clk_get(&pdev->dev, NULL);
129 if (IS_ERR(priv->clk)) 141 if (IS_ERR(clk))
130 return PTR_ERR(priv->clk); 142 return PTR_ERR(clk);
143
144 pm_runtime_enable(&pdev->dev);
131 145
132 rate = clk_get_rate(priv->clk); 146 pm_runtime_get_sync(&pdev->dev);
133 if (!rate) 147 priv->clk_rate = clk_get_rate(clk);
134 return -ENOENT; 148 pm_runtime_put(&pdev->dev);
149
150 if (!priv->clk_rate) {
151 ret = -ENOENT;
152 goto out_pm_disable;
153 }
135 154
136 for (i = ARRAY_SIZE(clk_divs) - 1; i >= 0; i--) { 155 for (i = ARRAY_SIZE(clk_divs) - 1; i >= 0; i--) {
137 clks_per_sec = DIV_ROUND_UP(rate, clk_divs[i]); 156 clks_per_sec = priv->clk_rate / clk_divs[i];
138 if (clks_per_sec) { 157 if (clks_per_sec && clks_per_sec < 65536) {
139 priv->clks_per_sec = clks_per_sec;
140 priv->cks = i; 158 priv->cks = i;
141 break; 159 break;
142 } 160 }
143 } 161 }
144 162
145 if (!clks_per_sec) { 163 if (i < 0) {
146 dev_err(&pdev->dev, "Can't find suitable clock divider\n"); 164 dev_err(&pdev->dev, "Can't find suitable clock divider\n");
147 return -ERANGE; 165 ret = -ERANGE;
166 goto out_pm_disable;
148 } 167 }
149 168
150 pm_runtime_enable(&pdev->dev);
151 pm_runtime_get_sync(&pdev->dev);
152
153 priv->wdev.info = &rwdt_ident, 169 priv->wdev.info = &rwdt_ident,
154 priv->wdev.ops = &rwdt_ops, 170 priv->wdev.ops = &rwdt_ops,
155 priv->wdev.parent = &pdev->dev; 171 priv->wdev.parent = &pdev->dev;
156 priv->wdev.min_timeout = 1; 172 priv->wdev.min_timeout = 1;
157 priv->wdev.max_timeout = 65536 / clks_per_sec; 173 priv->wdev.max_timeout = DIV_BY_CLKS_PER_SEC(priv, 65536);
158 priv->wdev.timeout = min(priv->wdev.max_timeout, RWDT_DEFAULT_TIMEOUT); 174 priv->wdev.timeout = min(priv->wdev.max_timeout, RWDT_DEFAULT_TIMEOUT);
159 175
160 platform_set_drvdata(pdev, priv); 176 platform_set_drvdata(pdev, priv);
@@ -167,13 +183,14 @@ static int rwdt_probe(struct platform_device *pdev)
167 dev_warn(&pdev->dev, "Specified timeout value invalid, using default\n"); 183 dev_warn(&pdev->dev, "Specified timeout value invalid, using default\n");
168 184
169 ret = watchdog_register_device(&priv->wdev); 185 ret = watchdog_register_device(&priv->wdev);
170 if (ret < 0) { 186 if (ret < 0)
171 pm_runtime_put(&pdev->dev); 187 goto out_pm_disable;
172 pm_runtime_disable(&pdev->dev);
173 return ret;
174 }
175 188
176 return 0; 189 return 0;
190
191 out_pm_disable:
192 pm_runtime_disable(&pdev->dev);
193 return ret;
177} 194}
178 195
179static int rwdt_remove(struct platform_device *pdev) 196static int rwdt_remove(struct platform_device *pdev)
@@ -181,7 +198,6 @@ static int rwdt_remove(struct platform_device *pdev)
181 struct rwdt_priv *priv = platform_get_drvdata(pdev); 198 struct rwdt_priv *priv = platform_get_drvdata(pdev);
182 199
183 watchdog_unregister_device(&priv->wdev); 200 watchdog_unregister_device(&priv->wdev);
184 pm_runtime_put(&pdev->dev);
185 pm_runtime_disable(&pdev->dev); 201 pm_runtime_disable(&pdev->dev);
186 202
187 return 0; 203 return 0;
diff --git a/drivers/watchdog/rt2880_wdt.c b/drivers/watchdog/rt2880_wdt.c
index 05524baf7dcc..98967f0a7d10 100644
--- a/drivers/watchdog/rt2880_wdt.c
+++ b/drivers/watchdog/rt2880_wdt.c
@@ -119,7 +119,7 @@ static int rt288x_wdt_bootcause(void)
119 return 0; 119 return 0;
120} 120}
121 121
122static struct watchdog_info rt288x_wdt_info = { 122static const struct watchdog_info rt288x_wdt_info = {
123 .identity = "Ralink Watchdog", 123 .identity = "Ralink Watchdog",
124 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, 124 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
125}; 125};
@@ -152,7 +152,7 @@ static int rt288x_wdt_probe(struct platform_device *pdev)
152 if (IS_ERR(rt288x_wdt_clk)) 152 if (IS_ERR(rt288x_wdt_clk))
153 return PTR_ERR(rt288x_wdt_clk); 153 return PTR_ERR(rt288x_wdt_clk);
154 154
155 rt288x_wdt_reset = devm_reset_control_get(&pdev->dev, NULL); 155 rt288x_wdt_reset = devm_reset_control_get_exclusive(&pdev->dev, NULL);
156 if (!IS_ERR(rt288x_wdt_reset)) 156 if (!IS_ERR(rt288x_wdt_reset))
157 reset_control_deassert(rt288x_wdt_reset); 157 reset_control_deassert(rt288x_wdt_reset);
158 158
diff --git a/drivers/watchdog/sc1200wdt.c b/drivers/watchdog/sc1200wdt.c
index b34d3d5ba632..8e4e2fc13f87 100644
--- a/drivers/watchdog/sc1200wdt.c
+++ b/drivers/watchdog/sc1200wdt.c
@@ -342,7 +342,7 @@ static int __init sc1200wdt_probe(void)
342 342
343#if defined CONFIG_PNP 343#if defined CONFIG_PNP
344 344
345static struct pnp_device_id scl200wdt_pnp_devices[] = { 345static const struct pnp_device_id scl200wdt_pnp_devices[] = {
346 /* National Semiconductor PC87307/PC97307 watchdog component */ 346 /* National Semiconductor PC87307/PC97307 watchdog component */
347 {.id = "NSC0800", .driver_data = 0}, 347 {.id = "NSC0800", .driver_data = 0},
348 {.id = ""}, 348 {.id = ""},
diff --git a/drivers/watchdog/sp805_wdt.c b/drivers/watchdog/sp805_wdt.c
index e7a715e82021..03805bc5d67a 100644
--- a/drivers/watchdog/sp805_wdt.c
+++ b/drivers/watchdog/sp805_wdt.c
@@ -281,7 +281,7 @@ static int __maybe_unused sp805_wdt_resume(struct device *dev)
281static SIMPLE_DEV_PM_OPS(sp805_wdt_dev_pm_ops, sp805_wdt_suspend, 281static SIMPLE_DEV_PM_OPS(sp805_wdt_dev_pm_ops, sp805_wdt_suspend,
282 sp805_wdt_resume); 282 sp805_wdt_resume);
283 283
284static struct amba_id sp805_wdt_ids[] = { 284static const struct amba_id sp805_wdt_ids[] = {
285 { 285 {
286 .id = 0x00141805, 286 .id = 0x00141805,
287 .mask = 0x00ffffff, 287 .mask = 0x00ffffff,
diff --git a/drivers/watchdog/stm32_iwdg.c b/drivers/watchdog/stm32_iwdg.c
index 6c501b7dba29..be64a8699de3 100644
--- a/drivers/watchdog/stm32_iwdg.c
+++ b/drivers/watchdog/stm32_iwdg.c
@@ -140,7 +140,7 @@ static const struct watchdog_info stm32_iwdg_info = {
140 .identity = "STM32 Independent Watchdog", 140 .identity = "STM32 Independent Watchdog",
141}; 141};
142 142
143static struct watchdog_ops stm32_iwdg_ops = { 143static const struct watchdog_ops stm32_iwdg_ops = {
144 .owner = THIS_MODULE, 144 .owner = THIS_MODULE,
145 .start = stm32_iwdg_start, 145 .start = stm32_iwdg_start,
146 .ping = stm32_iwdg_ping, 146 .ping = stm32_iwdg_ping,
diff --git a/drivers/watchdog/ts72xx_wdt.c b/drivers/watchdog/ts72xx_wdt.c
index 17c25daebcce..811e43c39ec4 100644
--- a/drivers/watchdog/ts72xx_wdt.c
+++ b/drivers/watchdog/ts72xx_wdt.c
@@ -112,7 +112,7 @@ static const struct watchdog_info ts72xx_wdt_ident = {
112 .identity = "TS-72XX WDT", 112 .identity = "TS-72XX WDT",
113}; 113};
114 114
115static struct watchdog_ops ts72xx_wdt_ops = { 115static const struct watchdog_ops ts72xx_wdt_ops = {
116 .owner = THIS_MODULE, 116 .owner = THIS_MODULE,
117 .start = ts72xx_wdt_start, 117 .start = ts72xx_wdt_start,
118 .stop = ts72xx_wdt_stop, 118 .stop = ts72xx_wdt_stop,
diff --git a/drivers/watchdog/w83627hf_wdt.c b/drivers/watchdog/w83627hf_wdt.c
index d9ba0496713c..7817836bff55 100644
--- a/drivers/watchdog/w83627hf_wdt.c
+++ b/drivers/watchdog/w83627hf_wdt.c
@@ -429,7 +429,7 @@ static int __init wdt_init(void)
429{ 429{
430 int ret; 430 int ret;
431 int chip; 431 int chip;
432 const char * const chip_name[] = { 432 static const char * const chip_name[] = {
433 "W83627HF", 433 "W83627HF",
434 "W83627S", 434 "W83627S",
435 "W83697HF", 435 "W83697HF",
diff --git a/drivers/watchdog/ziirave_wdt.c b/drivers/watchdog/ziirave_wdt.c
index b4e0cea5a64e..d3594aa3a374 100644
--- a/drivers/watchdog/ziirave_wdt.c
+++ b/drivers/watchdog/ziirave_wdt.c
@@ -737,7 +737,7 @@ static int ziirave_wdt_remove(struct i2c_client *client)
737 return 0; 737 return 0;
738} 738}
739 739
740static struct i2c_device_id ziirave_wdt_id[] = { 740static const struct i2c_device_id ziirave_wdt_id[] = {
741 { "rave-wdt", 0 }, 741 { "rave-wdt", 0 },
742 { } 742 { }
743}; 743};
diff --git a/drivers/watchdog/zx2967_wdt.c b/drivers/watchdog/zx2967_wdt.c
index 69ec5855584b..9261f7c77f6d 100644
--- a/drivers/watchdog/zx2967_wdt.c
+++ b/drivers/watchdog/zx2967_wdt.c
@@ -229,7 +229,7 @@ static int zx2967_wdt_probe(struct platform_device *pdev)
229 } 229 }
230 clk_set_rate(wdt->clock, ZX2967_WDT_CLK_FREQ); 230 clk_set_rate(wdt->clock, ZX2967_WDT_CLK_FREQ);
231 231
232 rstc = devm_reset_control_get(dev, NULL); 232 rstc = devm_reset_control_get_exclusive(dev, NULL);
233 if (IS_ERR(rstc)) { 233 if (IS_ERR(rstc)) {
234 dev_err(dev, "failed to get rstc"); 234 dev_err(dev, "failed to get rstc");
235 ret = PTR_ERR(rstc); 235 ret = PTR_ERR(rstc);