ath79: add support for D-Link COVR-P2500 A1
[openwrt/staging/hauke.git] / target / linux / ixp4xx / patches-6.1 / 0007-watchdog-ixp4xx-Make-sure-restart-always-works.patch
1 From b09e5ea32e099821b1cddc1e26e625ad994ba11e Mon Sep 17 00:00:00 2001
2 From: Linus Walleij <linus.walleij@linaro.org>
3 Date: Sun, 24 Sep 2023 21:20:24 +0200
4 Subject: [PATCH] watchdog: ixp4xx: Make sure restart always works
5
6 The IXP4xx watchdog in early "A0" silicon is unreliable and
7 cannot be registered, however for some systems such as the
8 USRobotics USR8200 the watchdog is the only restart option,
9 so implement a "dummy" watchdog that can only support restart
10 in this case.
11
12 Fixes: 1aea522809e6 ("watchdog: ixp4xx: Implement restart")
13 Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
14 ---
15 Other solutions like implementing a pure restart notifier
16 callback catch in the driver is possible, but this method
17 will minimize the amount of code and reuse infrastructure
18 in the core.
19 ---
20 drivers/watchdog/ixp4xx_wdt.c | 28 +++++++++++++++++++++++++---
21 1 file changed, 25 insertions(+), 3 deletions(-)
22
23 --- a/drivers/watchdog/ixp4xx_wdt.c
24 +++ b/drivers/watchdog/ixp4xx_wdt.c
25 @@ -105,6 +105,25 @@ static const struct watchdog_ops ixp4xx_
26 .owner = THIS_MODULE,
27 };
28
29 +/*
30 + * The A0 version of the IXP422 had a bug in the watchdog making
31 + * is useless, but we still need to use it to restart the system
32 + * as it is the only way, so in this special case we register a
33 + * "dummy" watchdog that doesn't really work, but will support
34 + * the restart operation.
35 + */
36 +static int ixp4xx_wdt_dummy(struct watchdog_device *wdd)
37 +{
38 + return 0;
39 +}
40 +
41 +static const struct watchdog_ops ixp4xx_wdt_restart_only_ops = {
42 + .start = ixp4xx_wdt_dummy,
43 + .stop = ixp4xx_wdt_dummy,
44 + .restart = ixp4xx_wdt_restart,
45 + .owner = THIS_MODULE,
46 +};
47 +
48 static const struct watchdog_info ixp4xx_wdt_info = {
49 .options = WDIOF_KEEPALIVEPING
50 | WDIOF_MAGICCLOSE
51 @@ -120,14 +139,17 @@ static void ixp4xx_clock_action(void *d)
52
53 static int ixp4xx_wdt_probe(struct platform_device *pdev)
54 {
55 + static const struct watchdog_ops *iwdt_ops;
56 struct device *dev = &pdev->dev;
57 struct ixp4xx_wdt *iwdt;
58 struct clk *clk;
59 int ret;
60
61 if (!(read_cpuid_id() & 0xf) && !cpu_is_ixp46x()) {
62 - dev_err(dev, "Rev. A0 IXP42x CPU detected - watchdog disabled\n");
63 - return -ENODEV;
64 + dev_err(dev, "Rev. A0 IXP42x CPU detected - only restart supported\n");
65 + iwdt_ops = &ixp4xx_wdt_restart_only_ops;
66 + } else {
67 + iwdt_ops = &ixp4xx_wdt_ops;
68 }
69
70 iwdt = devm_kzalloc(dev, sizeof(*iwdt), GFP_KERNEL);
71 @@ -153,7 +175,7 @@ static int ixp4xx_wdt_probe(struct platf
72 iwdt->rate = IXP4XX_TIMER_FREQ;
73
74 iwdt->wdd.info = &ixp4xx_wdt_info;
75 - iwdt->wdd.ops = &ixp4xx_wdt_ops;
76 + iwdt->wdd.ops = iwdt_ops;
77 iwdt->wdd.min_timeout = 1;
78 iwdt->wdd.max_timeout = U32_MAX / iwdt->rate;
79 iwdt->wdd.parent = dev;