diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/power/reset/Kconfig | 9 | ||||
-rw-r--r-- | drivers/power/reset/Makefile | 1 | ||||
-rw-r--r-- | drivers/power/reset/arm-versatile-reboot.c | 111 |
3 files changed, 121 insertions, 0 deletions
diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig index 81b445122eea..527a0f47ef44 100644 --- a/drivers/power/reset/Kconfig +++ b/drivers/power/reset/Kconfig | |||
@@ -92,6 +92,15 @@ config POWER_RESET_SUN6I | |||
92 | help | 92 | help |
93 | Reboot support for the Allwinner A31 SoCs. | 93 | Reboot support for the Allwinner A31 SoCs. |
94 | 94 | ||
95 | config POWER_RESET_VERSATILE | ||
96 | bool "ARM Versatile family reboot driver" | ||
97 | depends on ARM | ||
98 | depends on MFD_SYSCON | ||
99 | depends on OF | ||
100 | help | ||
101 | Power off and restart support for ARM Versatile family of | ||
102 | reference boards. | ||
103 | |||
95 | config POWER_RESET_VEXPRESS | 104 | config POWER_RESET_VEXPRESS |
96 | bool "ARM Versatile Express power-off and reset driver" | 105 | bool "ARM Versatile Express power-off and reset driver" |
97 | depends on ARM || ARM64 | 106 | depends on ARM || ARM64 |
diff --git a/drivers/power/reset/Makefile b/drivers/power/reset/Makefile index 4433a753fd93..73221009f2bf 100644 --- a/drivers/power/reset/Makefile +++ b/drivers/power/reset/Makefile | |||
@@ -9,6 +9,7 @@ obj-$(CONFIG_POWER_RESET_MSM) += msm-poweroff.o | |||
9 | obj-$(CONFIG_POWER_RESET_QNAP) += qnap-poweroff.o | 9 | obj-$(CONFIG_POWER_RESET_QNAP) += qnap-poweroff.o |
10 | obj-$(CONFIG_POWER_RESET_RESTART) += restart-poweroff.o | 10 | obj-$(CONFIG_POWER_RESET_RESTART) += restart-poweroff.o |
11 | obj-$(CONFIG_POWER_RESET_SUN6I) += sun6i-reboot.o | 11 | obj-$(CONFIG_POWER_RESET_SUN6I) += sun6i-reboot.o |
12 | obj-$(CONFIG_POWER_RESET_VERSATILE) += arm-versatile-reboot.o | ||
12 | obj-$(CONFIG_POWER_RESET_VEXPRESS) += vexpress-poweroff.o | 13 | obj-$(CONFIG_POWER_RESET_VEXPRESS) += vexpress-poweroff.o |
13 | obj-$(CONFIG_POWER_RESET_XGENE) += xgene-reboot.o | 14 | obj-$(CONFIG_POWER_RESET_XGENE) += xgene-reboot.o |
14 | obj-$(CONFIG_POWER_RESET_KEYSTONE) += keystone-reset.o | 15 | obj-$(CONFIG_POWER_RESET_KEYSTONE) += keystone-reset.o |
diff --git a/drivers/power/reset/arm-versatile-reboot.c b/drivers/power/reset/arm-versatile-reboot.c new file mode 100644 index 000000000000..5b08bffcf1a8 --- /dev/null +++ b/drivers/power/reset/arm-versatile-reboot.c | |||
@@ -0,0 +1,111 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014 Linaro Ltd. | ||
3 | * | ||
4 | * Author: Linus Walleij <linus.walleij@linaro.org> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2, as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | */ | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/mfd/syscon.h> | ||
13 | #include <linux/reboot.h> | ||
14 | #include <linux/regmap.h> | ||
15 | #include <linux/of.h> | ||
16 | #include <asm/system_misc.h> | ||
17 | |||
18 | #define REALVIEW_SYS_LOCK_OFFSET 0x20 | ||
19 | #define REALVIEW_SYS_LOCK_VAL 0xA05F | ||
20 | #define REALVIEW_SYS_RESETCTL_OFFSET 0x40 | ||
21 | |||
22 | /* | ||
23 | * We detect the different syscon types from the compatible strings. | ||
24 | */ | ||
25 | enum versatile_reboot { | ||
26 | REALVIEW_REBOOT_EB, | ||
27 | REALVIEW_REBOOT_PB1176, | ||
28 | REALVIEW_REBOOT_PB11MP, | ||
29 | REALVIEW_REBOOT_PBA8, | ||
30 | REALVIEW_REBOOT_PBX, | ||
31 | }; | ||
32 | |||
33 | /* Pointer to the system controller */ | ||
34 | static struct regmap *syscon_regmap; | ||
35 | static enum versatile_reboot versatile_reboot_type; | ||
36 | |||
37 | static const struct of_device_id versatile_reboot_of_match[] = { | ||
38 | { | ||
39 | .compatible = "arm,realview-eb-syscon", | ||
40 | .data = (void *)REALVIEW_REBOOT_EB, | ||
41 | }, | ||
42 | { | ||
43 | .compatible = "arm,realview-pb1176-syscon", | ||
44 | .data = (void *)REALVIEW_REBOOT_PB1176, | ||
45 | }, | ||
46 | { | ||
47 | .compatible = "arm,realview-pb11mp-syscon", | ||
48 | .data = (void *)REALVIEW_REBOOT_PB11MP, | ||
49 | }, | ||
50 | { | ||
51 | .compatible = "arm,realview-pba8-syscon", | ||
52 | .data = (void *)REALVIEW_REBOOT_PBA8, | ||
53 | }, | ||
54 | { | ||
55 | .compatible = "arm,realview-pbx-syscon", | ||
56 | .data = (void *)REALVIEW_REBOOT_PBX, | ||
57 | }, | ||
58 | }; | ||
59 | |||
60 | static void versatile_reboot(enum reboot_mode mode, const char *cmd) | ||
61 | { | ||
62 | /* Unlock the reset register */ | ||
63 | regmap_write(syscon_regmap, REALVIEW_SYS_LOCK_OFFSET, | ||
64 | REALVIEW_SYS_LOCK_VAL); | ||
65 | /* Then hit reset on the different machines */ | ||
66 | switch (versatile_reboot_type) { | ||
67 | case REALVIEW_REBOOT_EB: | ||
68 | regmap_write(syscon_regmap, | ||
69 | REALVIEW_SYS_RESETCTL_OFFSET, 0x0008); | ||
70 | break; | ||
71 | case REALVIEW_REBOOT_PB1176: | ||
72 | regmap_write(syscon_regmap, | ||
73 | REALVIEW_SYS_RESETCTL_OFFSET, 0x0100); | ||
74 | break; | ||
75 | case REALVIEW_REBOOT_PB11MP: | ||
76 | case REALVIEW_REBOOT_PBA8: | ||
77 | regmap_write(syscon_regmap, REALVIEW_SYS_RESETCTL_OFFSET, | ||
78 | 0x0000); | ||
79 | regmap_write(syscon_regmap, REALVIEW_SYS_RESETCTL_OFFSET, | ||
80 | 0x0004); | ||
81 | break; | ||
82 | case REALVIEW_REBOOT_PBX: | ||
83 | regmap_write(syscon_regmap, REALVIEW_SYS_RESETCTL_OFFSET, | ||
84 | 0x00f0); | ||
85 | regmap_write(syscon_regmap, REALVIEW_SYS_RESETCTL_OFFSET, | ||
86 | 0x00f4); | ||
87 | break; | ||
88 | } | ||
89 | dsb(); | ||
90 | } | ||
91 | |||
92 | static int __init versatile_reboot_probe(void) | ||
93 | { | ||
94 | const struct of_device_id *reboot_id; | ||
95 | struct device_node *np; | ||
96 | |||
97 | np = of_find_matching_node_and_match(NULL, versatile_reboot_of_match, | ||
98 | &reboot_id); | ||
99 | if (!np) | ||
100 | return -ENODEV; | ||
101 | versatile_reboot_type = (enum versatile_reboot)reboot_id->data; | ||
102 | |||
103 | syscon_regmap = syscon_node_to_regmap(np); | ||
104 | if (IS_ERR(syscon_regmap)) | ||
105 | return PTR_ERR(syscon_regmap); | ||
106 | |||
107 | arm_pm_restart = versatile_reboot; | ||
108 | pr_info("versatile reboot driver registered\n"); | ||
109 | return 0; | ||
110 | } | ||
111 | device_initcall(versatile_reboot_probe); | ||