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); | ||
