Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 06d71bcf authored by Maxime Ripard's avatar Maxime Ripard
Browse files

ARM: sun6i: Add restart code for the A31



The Allwinner A31 has a different watchdog, with a slightly different
register layout, that requires a different restart code.

Signed-off-by: default avatarMaxime Ripard <maxime.ripard@free-electrons.com>
parent 2d794510
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
Allwinner sun4i Watchdog timer
Allwinner SoCs Watchdog timer

Required properties:

- compatible : should be "allwinner,sun4i-wdt"
- compatible : should be "allwinner,<soc-family>-wdt", the currently supported
  SoC families being sun4i and sun6i
- reg : Specifies base physical address and size of the registers.

Example:
+40 −3
Original line number Diff line number Diff line
@@ -27,10 +27,19 @@
#include <asm/system_misc.h>

#define SUN4I_WATCHDOG_CTRL_REG		0x00
#define SUN4I_WATCHDOG_CTRL_RESTART		(1 << 0)
#define SUN4I_WATCHDOG_CTRL_RESTART		BIT(0)
#define SUN4I_WATCHDOG_MODE_REG		0x04
#define SUN4I_WATCHDOG_MODE_ENABLE		(1 << 0)
#define SUN4I_WATCHDOG_MODE_RESET_ENABLE	(1 << 1)
#define SUN4I_WATCHDOG_MODE_ENABLE		BIT(0)
#define SUN4I_WATCHDOG_MODE_RESET_ENABLE	BIT(1)

#define SUN6I_WATCHDOG1_IRQ_REG		0x00
#define SUN6I_WATCHDOG1_CTRL_REG	0x10
#define SUN6I_WATCHDOG1_CTRL_RESTART		BIT(0)
#define SUN6I_WATCHDOG1_CONFIG_REG	0x14
#define SUN6I_WATCHDOG1_CONFIG_RESTART		BIT(0)
#define SUN6I_WATCHDOG1_CONFIG_IRQ		BIT(1)
#define SUN6I_WATCHDOG1_MODE_REG	0x18
#define SUN6I_WATCHDOG1_MODE_ENABLE		BIT(0)

static void __iomem *wdt_base;

@@ -56,8 +65,36 @@ static void sun4i_restart(enum reboot_mode mode, const char *cmd)
	}
}

static void sun6i_restart(enum reboot_mode mode, const char *cmd)
{
	if (!wdt_base)
		return;

	/* Disable interrupts */
	writel(0, wdt_base + SUN6I_WATCHDOG1_IRQ_REG);

	/* We want to disable the IRQ and just reset the whole system */
	writel(SUN6I_WATCHDOG1_CONFIG_RESTART,
		wdt_base + SUN6I_WATCHDOG1_CONFIG_REG);

	/* Enable timer. The default and lowest interval value is 0.5s */
	writel(SUN6I_WATCHDOG1_MODE_ENABLE,
		wdt_base + SUN6I_WATCHDOG1_MODE_REG);

	/* Restart the watchdog. */
	writel(SUN6I_WATCHDOG1_CTRL_RESTART,
		wdt_base + SUN6I_WATCHDOG1_CTRL_REG);

	while (1) {
		mdelay(5);
		writel(SUN6I_WATCHDOG1_MODE_ENABLE,
			wdt_base + SUN6I_WATCHDOG1_MODE_REG);
	}
}

static struct of_device_id sunxi_restart_ids[] = {
	{ .compatible = "allwinner,sun4i-wdt", .data = sun4i_restart },
	{ .compatible = "allwinner,sun6i-wdt", .data = sun6i_restart },
	{ /*sentinel*/ }
};