diff options
author | Arnd Bergmann <arnd@arndb.de> | 2014-05-23 18:46:39 -0400 |
---|---|---|
committer | Arnd Bergmann <arnd@arndb.de> | 2014-05-23 18:46:55 -0400 |
commit | b3d491e85dcd65d0ffdb60f56652e314cc278b55 (patch) | |
tree | e1b9bfb099d70788ae2cd50d8c5dbb570e2ace05 | |
parent | 34b16f74ebfb586d97e90bdb72f369aa5d8f16a1 (diff) | |
parent | 1be7f5520a3885747174008d2905ae551f74ea78 (diff) |
Merge tag 'sunxi-drivers-for-3.16-2' of https://github.com/mripard/linux into next/drivers
Allwinner drivers changes for 3.16, take 2
Add reset driver for the A31
* tag 'sunxi-drivers-for-3.16-2' of https://github.com/mripard/linux:
power: reset: Add Allwinner A31 reset code
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
-rw-r--r-- | drivers/power/reset/Kconfig | 7 | ||||
-rw-r--r-- | drivers/power/reset/Makefile | 1 | ||||
-rw-r--r-- | drivers/power/reset/sun6i-reboot.c | 85 |
3 files changed, 93 insertions, 0 deletions
diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig index fa0e4e057b99..67aeb6ec08f9 100644 --- a/drivers/power/reset/Kconfig +++ b/drivers/power/reset/Kconfig | |||
@@ -43,6 +43,13 @@ config POWER_RESET_RESTART | |||
43 | Instead they restart, and u-boot holds the SoC until the | 43 | Instead they restart, and u-boot holds the SoC until the |
44 | user presses a key. u-boot then boots into Linux. | 44 | user presses a key. u-boot then boots into Linux. |
45 | 45 | ||
46 | config POWER_RESET_SUN6I | ||
47 | bool "Allwinner A31 SoC reset driver" | ||
48 | depends on ARCH_SUNXI | ||
49 | depends on POWER_RESET | ||
50 | help | ||
51 | Reboot support for the Allwinner A31 SoCs. | ||
52 | |||
46 | config POWER_RESET_VEXPRESS | 53 | config POWER_RESET_VEXPRESS |
47 | bool "ARM Versatile Express power-off and reset driver" | 54 | bool "ARM Versatile Express power-off and reset driver" |
48 | depends on ARM || ARM64 | 55 | depends on ARM || ARM64 |
diff --git a/drivers/power/reset/Makefile b/drivers/power/reset/Makefile index a5b4a77d1a41..950fdc011c7a 100644 --- a/drivers/power/reset/Makefile +++ b/drivers/power/reset/Makefile | |||
@@ -3,5 +3,6 @@ obj-$(CONFIG_POWER_RESET_GPIO) += gpio-poweroff.o | |||
3 | obj-$(CONFIG_POWER_RESET_MSM) += msm-poweroff.o | 3 | obj-$(CONFIG_POWER_RESET_MSM) += msm-poweroff.o |
4 | obj-$(CONFIG_POWER_RESET_QNAP) += qnap-poweroff.o | 4 | obj-$(CONFIG_POWER_RESET_QNAP) += qnap-poweroff.o |
5 | obj-$(CONFIG_POWER_RESET_RESTART) += restart-poweroff.o | 5 | obj-$(CONFIG_POWER_RESET_RESTART) += restart-poweroff.o |
6 | obj-$(CONFIG_POWER_RESET_SUN6I) += sun6i-reboot.o | ||
6 | obj-$(CONFIG_POWER_RESET_VEXPRESS) += vexpress-poweroff.o | 7 | obj-$(CONFIG_POWER_RESET_VEXPRESS) += vexpress-poweroff.o |
7 | obj-$(CONFIG_POWER_RESET_XGENE) += xgene-reboot.o | 8 | obj-$(CONFIG_POWER_RESET_XGENE) += xgene-reboot.o |
diff --git a/drivers/power/reset/sun6i-reboot.c b/drivers/power/reset/sun6i-reboot.c new file mode 100644 index 000000000000..af2cd7ff2fe8 --- /dev/null +++ b/drivers/power/reset/sun6i-reboot.c | |||
@@ -0,0 +1,85 @@ | |||
1 | /* | ||
2 | * Allwinner A31 SoCs reset code | ||
3 | * | ||
4 | * Copyright (C) 2012-2014 Maxime Ripard | ||
5 | * | ||
6 | * Maxime Ripard <maxime.ripard@free-electrons.com> | ||
7 | * | ||
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. | ||
11 | */ | ||
12 | |||
13 | #include <linux/delay.h> | ||
14 | #include <linux/io.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/of_address.h> | ||
17 | #include <linux/platform_device.h> | ||
18 | #include <linux/reboot.h> | ||
19 | |||
20 | #include <asm/system_misc.h> | ||
21 | |||
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) | ||
30 | |||
31 | static void __iomem *wdt_base; | ||
32 | |||
33 | static void sun6i_wdt_restart(enum reboot_mode mode, const char *cmd) | ||
34 | { | ||
35 | if (!wdt_base) | ||
36 | return; | ||
37 | |||
38 | /* Disable interrupts */ | ||
39 | writel(0, wdt_base + SUN6I_WATCHDOG1_IRQ_REG); | ||
40 | |||
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); | ||
44 | |||
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); | ||
48 | |||
49 | /* Restart the watchdog. */ | ||
50 | writel(SUN6I_WATCHDOG1_CTRL_RESTART, | ||
51 | wdt_base + SUN6I_WATCHDOG1_CTRL_REG); | ||
52 | |||
53 | while (1) { | ||
54 | mdelay(5); | ||
55 | writel(SUN6I_WATCHDOG1_MODE_ENABLE, | ||
56 | wdt_base + SUN6I_WATCHDOG1_MODE_REG); | ||
57 | } | ||
58 | } | ||
59 | |||
60 | static int sun6i_reboot_probe(struct platform_device *pdev) | ||
61 | { | ||
62 | wdt_base = of_iomap(pdev->dev.of_node, 0); | ||
63 | if (!wdt_base) { | ||
64 | WARN(1, "failed to map watchdog base address"); | ||
65 | return -ENODEV; | ||
66 | } | ||
67 | |||
68 | arm_pm_restart = sun6i_wdt_restart; | ||
69 | |||
70 | return 0; | ||
71 | } | ||
72 | |||
73 | static struct of_device_id sun6i_reboot_of_match[] = { | ||
74 | { .compatible = "allwinner,sun6i-a31-wdt" }, | ||
75 | {} | ||
76 | }; | ||
77 | |||
78 | static struct platform_driver sun6i_reboot_driver = { | ||
79 | .probe = sun6i_reboot_probe, | ||
80 | .driver = { | ||
81 | .name = "sun6i-reboot", | ||
82 | .of_match_table = sun6i_reboot_of_match, | ||
83 | }, | ||
84 | }; | ||
85 | module_platform_driver(sun6i_reboot_driver); | ||