2 * Allwinner A31 SoCs reset code
4 * Copyright (C) 2012-2014 Maxime Ripard
6 * Maxime Ripard <maxime.ripard@free-electrons.com>
8 * This file is licensed under the terms of the GNU General Public
9 * License version 2. This program is licensed "as is" without any
10 * warranty of any kind, whether express or implied.
13 #include <linux/delay.h>
15 #include <linux/module.h>
16 #include <linux/of_address.h>
17 #include <linux/platform_device.h>
18 #include <linux/reboot.h>
20 #include <asm/system_misc.h>
22 #define SUN6I_WATCHDOG1_IRQ_REG 0x00
23 #define SUN6I_WATCHDOG1_CTRL_REG 0x10
24 #define SUN6I_WATCHDOG1_CTRL_RESTART BIT(0)
25 #define SUN6I_WATCHDOG1_CONFIG_REG 0x14
26 #define SUN6I_WATCHDOG1_CONFIG_RESTART BIT(0)
27 #define SUN6I_WATCHDOG1_CONFIG_IRQ BIT(1)
28 #define SUN6I_WATCHDOG1_MODE_REG 0x18
29 #define SUN6I_WATCHDOG1_MODE_ENABLE BIT(0)
31 static void __iomem *wdt_base;
33 static void sun6i_wdt_restart(enum reboot_mode mode, const char *cmd)
38 /* Disable interrupts */
39 writel(0, wdt_base + SUN6I_WATCHDOG1_IRQ_REG);
41 /* We want to disable the IRQ and just reset the whole system */
42 writel(SUN6I_WATCHDOG1_CONFIG_RESTART,
43 wdt_base + SUN6I_WATCHDOG1_CONFIG_REG);
45 /* Enable timer. The default and lowest interval value is 0.5s */
46 writel(SUN6I_WATCHDOG1_MODE_ENABLE,
47 wdt_base + SUN6I_WATCHDOG1_MODE_REG);
49 /* Restart the watchdog. */
50 writel(SUN6I_WATCHDOG1_CTRL_RESTART,
51 wdt_base + SUN6I_WATCHDOG1_CTRL_REG);
55 writel(SUN6I_WATCHDOG1_MODE_ENABLE,
56 wdt_base + SUN6I_WATCHDOG1_MODE_REG);
60 static int sun6i_reboot_probe(struct platform_device *pdev)
62 wdt_base = of_iomap(pdev->dev.of_node, 0);
64 WARN(1, "failed to map watchdog base address");
68 arm_pm_restart = sun6i_wdt_restart;
73 static struct of_device_id sun6i_reboot_of_match[] = {
74 { .compatible = "allwinner,sun6i-a31-wdt" },
78 static struct platform_driver sun6i_reboot_driver = {
79 .probe = sun6i_reboot_probe,
81 .name = "sun6i-reboot",
82 .of_match_table = sun6i_reboot_of_match,
85 module_platform_driver(sun6i_reboot_driver);