Merge tag 'mips_5.14_1' of git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux
[linux-2.6-microblaze.git] / drivers / watchdog / mtk_wdt.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Mediatek Watchdog Driver
4  *
5  * Copyright (C) 2014 Matthias Brugger
6  *
7  * Matthias Brugger <matthias.bgg@gmail.com>
8  *
9  * Based on sunxi_wdt.c
10  */
11
12 #include <dt-bindings/reset-controller/mt2712-resets.h>
13 #include <dt-bindings/reset-controller/mt8183-resets.h>
14 #include <dt-bindings/reset-controller/mt8192-resets.h>
15 #include <linux/delay.h>
16 #include <linux/err.h>
17 #include <linux/init.h>
18 #include <linux/io.h>
19 #include <linux/kernel.h>
20 #include <linux/module.h>
21 #include <linux/moduleparam.h>
22 #include <linux/of.h>
23 #include <linux/of_device.h>
24 #include <linux/platform_device.h>
25 #include <linux/reset-controller.h>
26 #include <linux/types.h>
27 #include <linux/watchdog.h>
28 #include <linux/interrupt.h>
29
30 #define WDT_MAX_TIMEOUT         31
31 #define WDT_MIN_TIMEOUT         2
32 #define WDT_LENGTH_TIMEOUT(n)   ((n) << 5)
33
34 #define WDT_LENGTH              0x04
35 #define WDT_LENGTH_KEY          0x8
36
37 #define WDT_RST                 0x08
38 #define WDT_RST_RELOAD          0x1971
39
40 #define WDT_MODE                0x00
41 #define WDT_MODE_EN             (1 << 0)
42 #define WDT_MODE_EXT_POL_LOW    (0 << 1)
43 #define WDT_MODE_EXT_POL_HIGH   (1 << 1)
44 #define WDT_MODE_EXRST_EN       (1 << 2)
45 #define WDT_MODE_IRQ_EN         (1 << 3)
46 #define WDT_MODE_AUTO_START     (1 << 4)
47 #define WDT_MODE_DUAL_EN        (1 << 6)
48 #define WDT_MODE_KEY            0x22000000
49
50 #define WDT_SWRST               0x14
51 #define WDT_SWRST_KEY           0x1209
52
53 #define WDT_SWSYSRST            0x18U
54 #define WDT_SWSYS_RST_KEY       0x88000000
55
56 #define DRV_NAME                "mtk-wdt"
57 #define DRV_VERSION             "1.0"
58
59 static bool nowayout = WATCHDOG_NOWAYOUT;
60 static unsigned int timeout;
61
62 struct mtk_wdt_dev {
63         struct watchdog_device wdt_dev;
64         void __iomem *wdt_base;
65         spinlock_t lock; /* protects WDT_SWSYSRST reg */
66         struct reset_controller_dev rcdev;
67 };
68
69 struct mtk_wdt_data {
70         int toprgu_sw_rst_num;
71 };
72
73 static const struct mtk_wdt_data mt2712_data = {
74         .toprgu_sw_rst_num = MT2712_TOPRGU_SW_RST_NUM,
75 };
76
77 static const struct mtk_wdt_data mt8183_data = {
78         .toprgu_sw_rst_num = MT8183_TOPRGU_SW_RST_NUM,
79 };
80
81 static const struct mtk_wdt_data mt8192_data = {
82         .toprgu_sw_rst_num = MT8192_TOPRGU_SW_RST_NUM,
83 };
84
85 static int toprgu_reset_update(struct reset_controller_dev *rcdev,
86                                unsigned long id, bool assert)
87 {
88         unsigned int tmp;
89         unsigned long flags;
90         struct mtk_wdt_dev *data =
91                  container_of(rcdev, struct mtk_wdt_dev, rcdev);
92
93         spin_lock_irqsave(&data->lock, flags);
94
95         tmp = readl(data->wdt_base + WDT_SWSYSRST);
96         if (assert)
97                 tmp |= BIT(id);
98         else
99                 tmp &= ~BIT(id);
100         tmp |= WDT_SWSYS_RST_KEY;
101         writel(tmp, data->wdt_base + WDT_SWSYSRST);
102
103         spin_unlock_irqrestore(&data->lock, flags);
104
105         return 0;
106 }
107
108 static int toprgu_reset_assert(struct reset_controller_dev *rcdev,
109                                unsigned long id)
110 {
111         return toprgu_reset_update(rcdev, id, true);
112 }
113
114 static int toprgu_reset_deassert(struct reset_controller_dev *rcdev,
115                                  unsigned long id)
116 {
117         return toprgu_reset_update(rcdev, id, false);
118 }
119
120 static int toprgu_reset(struct reset_controller_dev *rcdev,
121                         unsigned long id)
122 {
123         int ret;
124
125         ret = toprgu_reset_assert(rcdev, id);
126         if (ret)
127                 return ret;
128
129         return toprgu_reset_deassert(rcdev, id);
130 }
131
132 static const struct reset_control_ops toprgu_reset_ops = {
133         .assert = toprgu_reset_assert,
134         .deassert = toprgu_reset_deassert,
135         .reset = toprgu_reset,
136 };
137
138 static int toprgu_register_reset_controller(struct platform_device *pdev,
139                                             int rst_num)
140 {
141         int ret;
142         struct mtk_wdt_dev *mtk_wdt = platform_get_drvdata(pdev);
143
144         spin_lock_init(&mtk_wdt->lock);
145
146         mtk_wdt->rcdev.owner = THIS_MODULE;
147         mtk_wdt->rcdev.nr_resets = rst_num;
148         mtk_wdt->rcdev.ops = &toprgu_reset_ops;
149         mtk_wdt->rcdev.of_node = pdev->dev.of_node;
150         ret = devm_reset_controller_register(&pdev->dev, &mtk_wdt->rcdev);
151         if (ret != 0)
152                 dev_err(&pdev->dev,
153                         "couldn't register wdt reset controller: %d\n", ret);
154         return ret;
155 }
156
157 static int mtk_wdt_restart(struct watchdog_device *wdt_dev,
158                            unsigned long action, void *data)
159 {
160         struct mtk_wdt_dev *mtk_wdt = watchdog_get_drvdata(wdt_dev);
161         void __iomem *wdt_base;
162
163         wdt_base = mtk_wdt->wdt_base;
164
165         while (1) {
166                 writel(WDT_SWRST_KEY, wdt_base + WDT_SWRST);
167                 mdelay(5);
168         }
169
170         return 0;
171 }
172
173 static int mtk_wdt_ping(struct watchdog_device *wdt_dev)
174 {
175         struct mtk_wdt_dev *mtk_wdt = watchdog_get_drvdata(wdt_dev);
176         void __iomem *wdt_base = mtk_wdt->wdt_base;
177
178         iowrite32(WDT_RST_RELOAD, wdt_base + WDT_RST);
179
180         return 0;
181 }
182
183 static int mtk_wdt_set_timeout(struct watchdog_device *wdt_dev,
184                                 unsigned int timeout)
185 {
186         struct mtk_wdt_dev *mtk_wdt = watchdog_get_drvdata(wdt_dev);
187         void __iomem *wdt_base = mtk_wdt->wdt_base;
188         u32 reg;
189
190         wdt_dev->timeout = timeout;
191         /*
192          * In dual mode, irq will be triggered at timeout / 2
193          * the real timeout occurs at timeout
194          */
195         if (wdt_dev->pretimeout)
196                 wdt_dev->pretimeout = timeout / 2;
197
198         /*
199          * One bit is the value of 512 ticks
200          * The clock has 32 KHz
201          */
202         reg = WDT_LENGTH_TIMEOUT((timeout - wdt_dev->pretimeout) << 6)
203                         | WDT_LENGTH_KEY;
204         iowrite32(reg, wdt_base + WDT_LENGTH);
205
206         mtk_wdt_ping(wdt_dev);
207
208         return 0;
209 }
210
211 static void mtk_wdt_init(struct watchdog_device *wdt_dev)
212 {
213         struct mtk_wdt_dev *mtk_wdt = watchdog_get_drvdata(wdt_dev);
214         void __iomem *wdt_base;
215
216         wdt_base = mtk_wdt->wdt_base;
217
218         if (readl(wdt_base + WDT_MODE) & WDT_MODE_EN) {
219                 set_bit(WDOG_HW_RUNNING, &wdt_dev->status);
220                 mtk_wdt_set_timeout(wdt_dev, wdt_dev->timeout);
221         }
222 }
223
224 static int mtk_wdt_stop(struct watchdog_device *wdt_dev)
225 {
226         struct mtk_wdt_dev *mtk_wdt = watchdog_get_drvdata(wdt_dev);
227         void __iomem *wdt_base = mtk_wdt->wdt_base;
228         u32 reg;
229
230         reg = readl(wdt_base + WDT_MODE);
231         reg &= ~WDT_MODE_EN;
232         reg |= WDT_MODE_KEY;
233         iowrite32(reg, wdt_base + WDT_MODE);
234
235         return 0;
236 }
237
238 static int mtk_wdt_start(struct watchdog_device *wdt_dev)
239 {
240         u32 reg;
241         struct mtk_wdt_dev *mtk_wdt = watchdog_get_drvdata(wdt_dev);
242         void __iomem *wdt_base = mtk_wdt->wdt_base;
243         int ret;
244
245         ret = mtk_wdt_set_timeout(wdt_dev, wdt_dev->timeout);
246         if (ret < 0)
247                 return ret;
248
249         reg = ioread32(wdt_base + WDT_MODE);
250         if (wdt_dev->pretimeout)
251                 reg |= (WDT_MODE_IRQ_EN | WDT_MODE_DUAL_EN);
252         else
253                 reg &= ~(WDT_MODE_IRQ_EN | WDT_MODE_DUAL_EN);
254         reg |= (WDT_MODE_EN | WDT_MODE_KEY);
255         iowrite32(reg, wdt_base + WDT_MODE);
256
257         return 0;
258 }
259
260 static int mtk_wdt_set_pretimeout(struct watchdog_device *wdd,
261                                   unsigned int timeout)
262 {
263         struct mtk_wdt_dev *mtk_wdt = watchdog_get_drvdata(wdd);
264         void __iomem *wdt_base = mtk_wdt->wdt_base;
265         u32 reg = ioread32(wdt_base + WDT_MODE);
266
267         if (timeout && !wdd->pretimeout) {
268                 wdd->pretimeout = wdd->timeout / 2;
269                 reg |= (WDT_MODE_IRQ_EN | WDT_MODE_DUAL_EN);
270         } else if (!timeout && wdd->pretimeout) {
271                 wdd->pretimeout = 0;
272                 reg &= ~(WDT_MODE_IRQ_EN | WDT_MODE_DUAL_EN);
273         } else {
274                 return 0;
275         }
276
277         reg |= WDT_MODE_KEY;
278         iowrite32(reg, wdt_base + WDT_MODE);
279
280         return mtk_wdt_set_timeout(wdd, wdd->timeout);
281 }
282
283 static irqreturn_t mtk_wdt_isr(int irq, void *arg)
284 {
285         struct watchdog_device *wdd = arg;
286
287         watchdog_notify_pretimeout(wdd);
288
289         return IRQ_HANDLED;
290 }
291
292 static const struct watchdog_info mtk_wdt_info = {
293         .identity       = DRV_NAME,
294         .options        = WDIOF_SETTIMEOUT |
295                           WDIOF_KEEPALIVEPING |
296                           WDIOF_MAGICCLOSE,
297 };
298
299 static const struct watchdog_info mtk_wdt_pt_info = {
300         .identity       = DRV_NAME,
301         .options        = WDIOF_SETTIMEOUT |
302                           WDIOF_PRETIMEOUT |
303                           WDIOF_KEEPALIVEPING |
304                           WDIOF_MAGICCLOSE,
305 };
306
307 static const struct watchdog_ops mtk_wdt_ops = {
308         .owner          = THIS_MODULE,
309         .start          = mtk_wdt_start,
310         .stop           = mtk_wdt_stop,
311         .ping           = mtk_wdt_ping,
312         .set_timeout    = mtk_wdt_set_timeout,
313         .set_pretimeout = mtk_wdt_set_pretimeout,
314         .restart        = mtk_wdt_restart,
315 };
316
317 static int mtk_wdt_probe(struct platform_device *pdev)
318 {
319         struct device *dev = &pdev->dev;
320         struct mtk_wdt_dev *mtk_wdt;
321         const struct mtk_wdt_data *wdt_data;
322         int err, irq;
323
324         mtk_wdt = devm_kzalloc(dev, sizeof(*mtk_wdt), GFP_KERNEL);
325         if (!mtk_wdt)
326                 return -ENOMEM;
327
328         platform_set_drvdata(pdev, mtk_wdt);
329
330         mtk_wdt->wdt_base = devm_platform_ioremap_resource(pdev, 0);
331         if (IS_ERR(mtk_wdt->wdt_base))
332                 return PTR_ERR(mtk_wdt->wdt_base);
333
334         irq = platform_get_irq(pdev, 0);
335         if (irq > 0) {
336                 err = devm_request_irq(&pdev->dev, irq, mtk_wdt_isr, 0, "wdt_bark",
337                                        &mtk_wdt->wdt_dev);
338                 if (err)
339                         return err;
340
341                 mtk_wdt->wdt_dev.info = &mtk_wdt_pt_info;
342                 mtk_wdt->wdt_dev.pretimeout = WDT_MAX_TIMEOUT / 2;
343         } else {
344                 if (irq == -EPROBE_DEFER)
345                         return -EPROBE_DEFER;
346
347                 mtk_wdt->wdt_dev.info = &mtk_wdt_info;
348         }
349
350         mtk_wdt->wdt_dev.ops = &mtk_wdt_ops;
351         mtk_wdt->wdt_dev.timeout = WDT_MAX_TIMEOUT;
352         mtk_wdt->wdt_dev.max_hw_heartbeat_ms = WDT_MAX_TIMEOUT * 1000;
353         mtk_wdt->wdt_dev.min_timeout = WDT_MIN_TIMEOUT;
354         mtk_wdt->wdt_dev.parent = dev;
355
356         watchdog_init_timeout(&mtk_wdt->wdt_dev, timeout, dev);
357         watchdog_set_nowayout(&mtk_wdt->wdt_dev, nowayout);
358         watchdog_set_restart_priority(&mtk_wdt->wdt_dev, 128);
359
360         watchdog_set_drvdata(&mtk_wdt->wdt_dev, mtk_wdt);
361
362         mtk_wdt_init(&mtk_wdt->wdt_dev);
363
364         watchdog_stop_on_reboot(&mtk_wdt->wdt_dev);
365         err = devm_watchdog_register_device(dev, &mtk_wdt->wdt_dev);
366         if (unlikely(err))
367                 return err;
368
369         dev_info(dev, "Watchdog enabled (timeout=%d sec, nowayout=%d)\n",
370                  mtk_wdt->wdt_dev.timeout, nowayout);
371
372         wdt_data = of_device_get_match_data(dev);
373         if (wdt_data) {
374                 err = toprgu_register_reset_controller(pdev,
375                                                        wdt_data->toprgu_sw_rst_num);
376                 if (err)
377                         return err;
378         }
379         return 0;
380 }
381
382 #ifdef CONFIG_PM_SLEEP
383 static int mtk_wdt_suspend(struct device *dev)
384 {
385         struct mtk_wdt_dev *mtk_wdt = dev_get_drvdata(dev);
386
387         if (watchdog_active(&mtk_wdt->wdt_dev))
388                 mtk_wdt_stop(&mtk_wdt->wdt_dev);
389
390         return 0;
391 }
392
393 static int mtk_wdt_resume(struct device *dev)
394 {
395         struct mtk_wdt_dev *mtk_wdt = dev_get_drvdata(dev);
396
397         if (watchdog_active(&mtk_wdt->wdt_dev)) {
398                 mtk_wdt_start(&mtk_wdt->wdt_dev);
399                 mtk_wdt_ping(&mtk_wdt->wdt_dev);
400         }
401
402         return 0;
403 }
404 #endif
405
406 static const struct of_device_id mtk_wdt_dt_ids[] = {
407         { .compatible = "mediatek,mt2712-wdt", .data = &mt2712_data },
408         { .compatible = "mediatek,mt6589-wdt" },
409         { .compatible = "mediatek,mt8183-wdt", .data = &mt8183_data },
410         { .compatible = "mediatek,mt8192-wdt", .data = &mt8192_data },
411         { /* sentinel */ }
412 };
413 MODULE_DEVICE_TABLE(of, mtk_wdt_dt_ids);
414
415 static const struct dev_pm_ops mtk_wdt_pm_ops = {
416         SET_SYSTEM_SLEEP_PM_OPS(mtk_wdt_suspend,
417                                 mtk_wdt_resume)
418 };
419
420 static struct platform_driver mtk_wdt_driver = {
421         .probe          = mtk_wdt_probe,
422         .driver         = {
423                 .name           = DRV_NAME,
424                 .pm             = &mtk_wdt_pm_ops,
425                 .of_match_table = mtk_wdt_dt_ids,
426         },
427 };
428
429 module_platform_driver(mtk_wdt_driver);
430
431 module_param(timeout, uint, 0);
432 MODULE_PARM_DESC(timeout, "Watchdog heartbeat in seconds");
433
434 module_param(nowayout, bool, 0);
435 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
436                         __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
437
438 MODULE_LICENSE("GPL");
439 MODULE_AUTHOR("Matthias Brugger <matthias.bgg@gmail.com>");
440 MODULE_DESCRIPTION("Mediatek WatchDog Timer Driver");
441 MODULE_VERSION(DRV_VERSION);