aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/power_supply/gpio-charger.txt27
-rw-r--r--drivers/power/ds2782_battery.c8
-rw-r--r--drivers/power/gpio-charger.c72
-rw-r--r--drivers/power/reset/axxia-reset.c21
-rw-r--r--drivers/power/reset/brcmstb-reboot.c28
-rw-r--r--drivers/power/reset/hisi-reboot.c20
-rw-r--r--drivers/power/reset/keystone-reset.c20
-rw-r--r--drivers/power/reset/syscon-reboot.c2
-rw-r--r--drivers/power/reset/vexpress-poweroff.c40
-rw-r--r--drivers/power/reset/xgene-reboot.c56
10 files changed, 225 insertions, 69 deletions
diff --git a/Documentation/devicetree/bindings/power_supply/gpio-charger.txt b/Documentation/devicetree/bindings/power_supply/gpio-charger.txt
new file mode 100644
index 000000000000..adbb5dc5b6e9
--- /dev/null
+++ b/Documentation/devicetree/bindings/power_supply/gpio-charger.txt
@@ -0,0 +1,27 @@
1gpio-charger
2
3Required properties :
4 - compatible : "gpio-charger"
5 - gpios : GPIO indicating the charger presence.
6 See GPIO binding in bindings/gpio/gpio.txt .
7 - charger-type : power supply type, one of
8 unknown
9 battery
10 ups
11 mains
12 usb-sdp (USB standard downstream port)
13 usb-dcp (USB dedicated charging port)
14 usb-cdp (USB charging downstream port)
15 usb-aca (USB accessory charger adapter)
16
17Example:
18
19 usb_charger: charger {
20 compatible = "gpio-charger";
21 charger-type = "usb-sdp";
22 gpios = <&gpf0 2 0 0 0>;
23 }
24
25 battery {
26 power-supplies = <&usb_charger>;
27 };
diff --git a/drivers/power/ds2782_battery.c b/drivers/power/ds2782_battery.c
index 041f9b638d28..39694883d3bf 100644
--- a/drivers/power/ds2782_battery.c
+++ b/drivers/power/ds2782_battery.c
@@ -351,13 +351,9 @@ static int ds278x_resume(struct device *dev)
351 schedule_delayed_work(&info->bat_work, DS278x_DELAY); 351 schedule_delayed_work(&info->bat_work, DS278x_DELAY);
352 return 0; 352 return 0;
353} 353}
354#endif /* CONFIG_PM_SLEEP */
354 355
355static SIMPLE_DEV_PM_OPS(ds278x_battery_pm_ops, ds278x_suspend, ds278x_resume); 356static SIMPLE_DEV_PM_OPS(ds278x_battery_pm_ops, ds278x_suspend, ds278x_resume);
356#define DS278X_BATTERY_PM_OPS (&ds278x_battery_pm_ops)
357
358#else
359#define DS278X_BATTERY_PM_OPS NULL
360#endif /* CONFIG_PM_SLEEP */
361 357
362enum ds278x_num_id { 358enum ds278x_num_id {
363 DS2782 = 0, 359 DS2782 = 0,
@@ -460,7 +456,7 @@ MODULE_DEVICE_TABLE(i2c, ds278x_id);
460static struct i2c_driver ds278x_battery_driver = { 456static struct i2c_driver ds278x_battery_driver = {
461 .driver = { 457 .driver = {
462 .name = "ds2782-battery", 458 .name = "ds2782-battery",
463 .pm = DS278X_BATTERY_PM_OPS, 459 .pm = &ds278x_battery_pm_ops,
464 }, 460 },
465 .probe = ds278x_battery_probe, 461 .probe = ds278x_battery_probe,
466 .remove = ds278x_battery_remove, 462 .remove = ds278x_battery_remove,
diff --git a/drivers/power/gpio-charger.c b/drivers/power/gpio-charger.c
index 3ee889fe0021..aef74bdf7ab3 100644
--- a/drivers/power/gpio-charger.c
+++ b/drivers/power/gpio-charger.c
@@ -22,6 +22,8 @@
22#include <linux/platform_device.h> 22#include <linux/platform_device.h>
23#include <linux/power_supply.h> 23#include <linux/power_supply.h>
24#include <linux/slab.h> 24#include <linux/slab.h>
25#include <linux/of.h>
26#include <linux/of_gpio.h>
25 27
26#include <linux/power/gpio-charger.h> 28#include <linux/power/gpio-charger.h>
27 29
@@ -69,6 +71,59 @@ static enum power_supply_property gpio_charger_properties[] = {
69 POWER_SUPPLY_PROP_ONLINE, 71 POWER_SUPPLY_PROP_ONLINE,
70}; 72};
71 73
74static
75struct gpio_charger_platform_data *gpio_charger_parse_dt(struct device *dev)
76{
77 struct device_node *np = dev->of_node;
78 struct gpio_charger_platform_data *pdata;
79 const char *chargetype;
80 enum of_gpio_flags flags;
81 int ret;
82
83 if (!np)
84 return ERR_PTR(-ENOENT);
85
86 pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
87 if (!pdata)
88 return ERR_PTR(-ENOMEM);
89
90 pdata->name = np->name;
91
92 pdata->gpio = of_get_gpio_flags(np, 0, &flags);
93 if (pdata->gpio < 0) {
94 if (pdata->gpio != -EPROBE_DEFER)
95 dev_err(dev, "could not get charger gpio\n");
96 return ERR_PTR(pdata->gpio);
97 }
98
99 pdata->gpio_active_low = !!(flags & OF_GPIO_ACTIVE_LOW);
100
101 pdata->type = POWER_SUPPLY_TYPE_UNKNOWN;
102 ret = of_property_read_string(np, "charger-type", &chargetype);
103 if (ret >= 0) {
104 if (!strncmp("unknown", chargetype, 7))
105 pdata->type = POWER_SUPPLY_TYPE_UNKNOWN;
106 else if (!strncmp("battery", chargetype, 7))
107 pdata->type = POWER_SUPPLY_TYPE_BATTERY;
108 else if (!strncmp("ups", chargetype, 3))
109 pdata->type = POWER_SUPPLY_TYPE_UPS;
110 else if (!strncmp("mains", chargetype, 5))
111 pdata->type = POWER_SUPPLY_TYPE_MAINS;
112 else if (!strncmp("usb-sdp", chargetype, 7))
113 pdata->type = POWER_SUPPLY_TYPE_USB;
114 else if (!strncmp("usb-dcp", chargetype, 7))
115 pdata->type = POWER_SUPPLY_TYPE_USB_DCP;
116 else if (!strncmp("usb-cdp", chargetype, 7))
117 pdata->type = POWER_SUPPLY_TYPE_USB_CDP;
118 else if (!strncmp("usb-aca", chargetype, 7))
119 pdata->type = POWER_SUPPLY_TYPE_USB_ACA;
120 else
121 dev_warn(dev, "unknown charger type %s\n", chargetype);
122 }
123
124 return pdata;
125}
126
72static int gpio_charger_probe(struct platform_device *pdev) 127static int gpio_charger_probe(struct platform_device *pdev)
73{ 128{
74 const struct gpio_charger_platform_data *pdata = pdev->dev.platform_data; 129 const struct gpio_charger_platform_data *pdata = pdev->dev.platform_data;
@@ -78,8 +133,13 @@ static int gpio_charger_probe(struct platform_device *pdev)
78 int irq; 133 int irq;
79 134
80 if (!pdata) { 135 if (!pdata) {
81 dev_err(&pdev->dev, "No platform data\n"); 136 pdata = gpio_charger_parse_dt(&pdev->dev);
82 return -EINVAL; 137 if (IS_ERR(pdata)) {
138 ret = PTR_ERR(pdata);
139 if (ret != -EPROBE_DEFER)
140 dev_err(&pdev->dev, "No platform data\n");
141 return ret;
142 }
83 } 143 }
84 144
85 if (!gpio_is_valid(pdata->gpio)) { 145 if (!gpio_is_valid(pdata->gpio)) {
@@ -103,6 +163,7 @@ static int gpio_charger_probe(struct platform_device *pdev)
103 charger->get_property = gpio_charger_get_property; 163 charger->get_property = gpio_charger_get_property;
104 charger->supplied_to = pdata->supplied_to; 164 charger->supplied_to = pdata->supplied_to;
105 charger->num_supplicants = pdata->num_supplicants; 165 charger->num_supplicants = pdata->num_supplicants;
166 charger->of_node = pdev->dev.of_node;
106 167
107 ret = gpio_request(pdata->gpio, dev_name(&pdev->dev)); 168 ret = gpio_request(pdata->gpio, dev_name(&pdev->dev));
108 if (ret) { 169 if (ret) {
@@ -189,12 +250,19 @@ static int gpio_charger_resume(struct device *dev)
189static SIMPLE_DEV_PM_OPS(gpio_charger_pm_ops, 250static SIMPLE_DEV_PM_OPS(gpio_charger_pm_ops,
190 gpio_charger_suspend, gpio_charger_resume); 251 gpio_charger_suspend, gpio_charger_resume);
191 252
253static const struct of_device_id gpio_charger_match[] = {
254 { .compatible = "gpio-charger" },
255 { }
256};
257MODULE_DEVICE_TABLE(of, gpio_charger_match);
258
192static struct platform_driver gpio_charger_driver = { 259static struct platform_driver gpio_charger_driver = {
193 .probe = gpio_charger_probe, 260 .probe = gpio_charger_probe,
194 .remove = gpio_charger_remove, 261 .remove = gpio_charger_remove,
195 .driver = { 262 .driver = {
196 .name = "gpio-charger", 263 .name = "gpio-charger",
197 .pm = &gpio_charger_pm_ops, 264 .pm = &gpio_charger_pm_ops,
265 .of_match_table = gpio_charger_match,
198 }, 266 },
199}; 267};
200 268
diff --git a/drivers/power/reset/axxia-reset.c b/drivers/power/reset/axxia-reset.c
index 3b1f8d601784..4e4cd1c8fe50 100644
--- a/drivers/power/reset/axxia-reset.c
+++ b/drivers/power/reset/axxia-reset.c
@@ -19,14 +19,12 @@
19#include <linux/kernel.h> 19#include <linux/kernel.h>
20#include <linux/mfd/syscon.h> 20#include <linux/mfd/syscon.h>
21#include <linux/module.h> 21#include <linux/module.h>
22#include <linux/notifier.h>
22#include <linux/of.h> 23#include <linux/of.h>
23#include <linux/platform_device.h> 24#include <linux/platform_device.h>
24#include <linux/reboot.h> 25#include <linux/reboot.h>
25#include <linux/regmap.h> 26#include <linux/regmap.h>
26 27
27#include <asm/system_misc.h>
28
29
30#define SC_CRIT_WRITE_KEY 0x1000 28#define SC_CRIT_WRITE_KEY 0x1000
31#define SC_LATCH_ON_RESET 0x1004 29#define SC_LATCH_ON_RESET 0x1004
32#define SC_RESET_CONTROL 0x1008 30#define SC_RESET_CONTROL 0x1008
@@ -39,7 +37,8 @@
39 37
40static struct regmap *syscon; 38static struct regmap *syscon;
41 39
42static void do_axxia_restart(enum reboot_mode reboot_mode, const char *cmd) 40static int axxia_restart_handler(struct notifier_block *this,
41 unsigned long mode, void *cmd)
43{ 42{
44 /* Access Key (0xab) */ 43 /* Access Key (0xab) */
45 regmap_write(syscon, SC_CRIT_WRITE_KEY, 0xab); 44 regmap_write(syscon, SC_CRIT_WRITE_KEY, 0xab);
@@ -50,11 +49,19 @@ static void do_axxia_restart(enum reboot_mode reboot_mode, const char *cmd)
50 /* Assert chip reset */ 49 /* Assert chip reset */
51 regmap_update_bits(syscon, SC_RESET_CONTROL, 50 regmap_update_bits(syscon, SC_RESET_CONTROL,
52 RSTCTL_RST_CHIP, RSTCTL_RST_CHIP); 51 RSTCTL_RST_CHIP, RSTCTL_RST_CHIP);
52
53 return NOTIFY_DONE;
53} 54}
54 55
56static struct notifier_block axxia_restart_nb = {
57 .notifier_call = axxia_restart_handler,
58 .priority = 128,
59};
60
55static int axxia_reset_probe(struct platform_device *pdev) 61static int axxia_reset_probe(struct platform_device *pdev)
56{ 62{
57 struct device *dev = &pdev->dev; 63 struct device *dev = &pdev->dev;
64 int err;
58 65
59 syscon = syscon_regmap_lookup_by_phandle(dev->of_node, "syscon"); 66 syscon = syscon_regmap_lookup_by_phandle(dev->of_node, "syscon");
60 if (IS_ERR(syscon)) { 67 if (IS_ERR(syscon)) {
@@ -62,9 +69,11 @@ static int axxia_reset_probe(struct platform_device *pdev)
62 return PTR_ERR(syscon); 69 return PTR_ERR(syscon);
63 } 70 }
64 71
65 arm_pm_restart = do_axxia_restart; 72 err = register_restart_handler(&axxia_restart_nb);
73 if (err)
74 dev_err(dev, "cannot register restart handler (err=%d)\n", err);
66 75
67 return 0; 76 return err;
68} 77}
69 78
70static const struct of_device_id of_axxia_reset_match[] = { 79static const struct of_device_id of_axxia_reset_match[] = {
diff --git a/drivers/power/reset/brcmstb-reboot.c b/drivers/power/reset/brcmstb-reboot.c
index c523ea7a90ee..100606f9b3dc 100644
--- a/drivers/power/reset/brcmstb-reboot.c
+++ b/drivers/power/reset/brcmstb-reboot.c
@@ -16,6 +16,7 @@
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/io.h> 17#include <linux/io.h>
18#include <linux/jiffies.h> 18#include <linux/jiffies.h>
19#include <linux/notifier.h>
19#include <linux/of_address.h> 20#include <linux/of_address.h>
20#include <linux/of_irq.h> 21#include <linux/of_irq.h>
21#include <linux/of_platform.h> 22#include <linux/of_platform.h>
@@ -26,8 +27,6 @@
26#include <linux/smp.h> 27#include <linux/smp.h>
27#include <linux/mfd/syscon.h> 28#include <linux/mfd/syscon.h>
28 29
29#include <asm/system_misc.h>
30
31#define RESET_SOURCE_ENABLE_REG 1 30#define RESET_SOURCE_ENABLE_REG 1
32#define SW_MASTER_RESET_REG 2 31#define SW_MASTER_RESET_REG 2
33 32
@@ -35,7 +34,8 @@ static struct regmap *regmap;
35static u32 rst_src_en; 34static u32 rst_src_en;
36static u32 sw_mstr_rst; 35static u32 sw_mstr_rst;
37 36
38static void brcmstb_reboot(enum reboot_mode mode, const char *cmd) 37static int brcmstb_restart_handler(struct notifier_block *this,
38 unsigned long mode, void *cmd)
39{ 39{
40 int rc; 40 int rc;
41 u32 tmp; 41 u32 tmp;
@@ -43,31 +43,38 @@ static void brcmstb_reboot(enum reboot_mode mode, const char *cmd)
43 rc = regmap_write(regmap, rst_src_en, 1); 43 rc = regmap_write(regmap, rst_src_en, 1);
44 if (rc) { 44 if (rc) {
45 pr_err("failed to write rst_src_en (%d)\n", rc); 45 pr_err("failed to write rst_src_en (%d)\n", rc);
46 return; 46 return NOTIFY_DONE;
47 } 47 }
48 48
49 rc = regmap_read(regmap, rst_src_en, &tmp); 49 rc = regmap_read(regmap, rst_src_en, &tmp);
50 if (rc) { 50 if (rc) {
51 pr_err("failed to read rst_src_en (%d)\n", rc); 51 pr_err("failed to read rst_src_en (%d)\n", rc);
52 return; 52 return NOTIFY_DONE;
53 } 53 }
54 54
55 rc = regmap_write(regmap, sw_mstr_rst, 1); 55 rc = regmap_write(regmap, sw_mstr_rst, 1);
56 if (rc) { 56 if (rc) {
57 pr_err("failed to write sw_mstr_rst (%d)\n", rc); 57 pr_err("failed to write sw_mstr_rst (%d)\n", rc);
58 return; 58 return NOTIFY_DONE;
59 } 59 }
60 60
61 rc = regmap_read(regmap, sw_mstr_rst, &tmp); 61 rc = regmap_read(regmap, sw_mstr_rst, &tmp);
62 if (rc) { 62 if (rc) {
63 pr_err("failed to read sw_mstr_rst (%d)\n", rc); 63 pr_err("failed to read sw_mstr_rst (%d)\n", rc);
64 return; 64 return NOTIFY_DONE;
65 } 65 }
66 66
67 while (1) 67 while (1)
68 ; 68 ;
69
70 return NOTIFY_DONE;
69} 71}
70 72
73static struct notifier_block brcmstb_restart_nb = {
74 .notifier_call = brcmstb_restart_handler,
75 .priority = 128,
76};
77
71static int brcmstb_reboot_probe(struct platform_device *pdev) 78static int brcmstb_reboot_probe(struct platform_device *pdev)
72{ 79{
73 int rc; 80 int rc;
@@ -93,9 +100,12 @@ static int brcmstb_reboot_probe(struct platform_device *pdev)
93 return -EINVAL; 100 return -EINVAL;
94 } 101 }
95 102
96 arm_pm_restart = brcmstb_reboot; 103 rc = register_restart_handler(&brcmstb_restart_nb);
104 if (rc)
105 dev_err(&pdev->dev,
106 "cannot register restart handler (err=%d)\n", rc);
97 107
98 return 0; 108 return rc;
99} 109}
100 110
101static const struct of_device_id of_match[] = { 111static const struct of_device_id of_match[] = {
diff --git a/drivers/power/reset/hisi-reboot.c b/drivers/power/reset/hisi-reboot.c
index 0c91d0231d36..5385460e23bb 100644
--- a/drivers/power/reset/hisi-reboot.c
+++ b/drivers/power/reset/hisi-reboot.c
@@ -14,27 +14,36 @@
14#include <linux/delay.h> 14#include <linux/delay.h>
15#include <linux/io.h> 15#include <linux/io.h>
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/notifier.h>
17#include <linux/of_address.h> 18#include <linux/of_address.h>
18#include <linux/platform_device.h> 19#include <linux/platform_device.h>
19#include <linux/reboot.h> 20#include <linux/reboot.h>
20 21
21#include <asm/proc-fns.h> 22#include <asm/proc-fns.h>
22#include <asm/system_misc.h>
23 23
24static void __iomem *base; 24static void __iomem *base;
25static u32 reboot_offset; 25static u32 reboot_offset;
26 26
27static void hisi_restart(enum reboot_mode mode, const char *cmd) 27static int hisi_restart_handler(struct notifier_block *this,
28 unsigned long mode, void *cmd)
28{ 29{
29 writel_relaxed(0xdeadbeef, base + reboot_offset); 30 writel_relaxed(0xdeadbeef, base + reboot_offset);
30 31
31 while (1) 32 while (1)
32 cpu_do_idle(); 33 cpu_do_idle();
34
35 return NOTIFY_DONE;
33} 36}
34 37
38static struct notifier_block hisi_restart_nb = {
39 .notifier_call = hisi_restart_handler,
40 .priority = 128,
41};
42
35static int hisi_reboot_probe(struct platform_device *pdev) 43static int hisi_reboot_probe(struct platform_device *pdev)
36{ 44{
37 struct device_node *np = pdev->dev.of_node; 45 struct device_node *np = pdev->dev.of_node;
46 int err;
38 47
39 base = of_iomap(np, 0); 48 base = of_iomap(np, 0);
40 if (!base) { 49 if (!base) {
@@ -47,9 +56,12 @@ static int hisi_reboot_probe(struct platform_device *pdev)
47 return -EINVAL; 56 return -EINVAL;
48 } 57 }
49 58
50 arm_pm_restart = hisi_restart; 59 err = register_restart_handler(&hisi_restart_nb);
60 if (err)
61 dev_err(&pdev->dev, "cannot register restart handler (err=%d)\n",
62 err);
51 63
52 return 0; 64 return err;
53} 65}
54 66
55static struct of_device_id hisi_reboot_of_match[] = { 67static struct of_device_id hisi_reboot_of_match[] = {
diff --git a/drivers/power/reset/keystone-reset.c b/drivers/power/reset/keystone-reset.c
index 86bc100818b2..faedf16c8111 100644
--- a/drivers/power/reset/keystone-reset.c
+++ b/drivers/power/reset/keystone-reset.c
@@ -12,9 +12,9 @@
12 12
13#include <linux/io.h> 13#include <linux/io.h>
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/notifier.h>
15#include <linux/reboot.h> 16#include <linux/reboot.h>
16#include <linux/regmap.h> 17#include <linux/regmap.h>
17#include <asm/system_misc.h>
18#include <linux/mfd/syscon.h> 18#include <linux/mfd/syscon.h>
19#include <linux/of_platform.h> 19#include <linux/of_platform.h>
20 20
@@ -52,7 +52,8 @@ static inline int rsctrl_enable_rspll_write(void)
52 RSCTRL_KEY_MASK, RSCTRL_KEY); 52 RSCTRL_KEY_MASK, RSCTRL_KEY);
53} 53}
54 54
55static void rsctrl_restart(enum reboot_mode mode, const char *cmd) 55static int rsctrl_restart_handler(struct notifier_block *this,
56 unsigned long mode, void *cmd)
56{ 57{
57 /* enable write access to RSTCTRL */ 58 /* enable write access to RSTCTRL */
58 rsctrl_enable_rspll_write(); 59 rsctrl_enable_rspll_write();
@@ -60,8 +61,15 @@ static void rsctrl_restart(enum reboot_mode mode, const char *cmd)
60 /* reset the SOC */ 61 /* reset the SOC */
61 regmap_update_bits(pllctrl_regs, rspll_offset + RSCTRL_RG, 62 regmap_update_bits(pllctrl_regs, rspll_offset + RSCTRL_RG,
62 RSCTRL_RESET_MASK, 0); 63 RSCTRL_RESET_MASK, 0);
64
65 return NOTIFY_DONE;
63} 66}
64 67
68static struct notifier_block rsctrl_restart_nb = {
69 .notifier_call = rsctrl_restart_handler,
70 .priority = 128,
71};
72
65static struct of_device_id rsctrl_of_match[] = { 73static struct of_device_id rsctrl_of_match[] = {
66 {.compatible = "ti,keystone-reset", }, 74 {.compatible = "ti,keystone-reset", },
67 {}, 75 {},
@@ -114,8 +122,6 @@ static int rsctrl_probe(struct platform_device *pdev)
114 if (ret) 122 if (ret)
115 return ret; 123 return ret;
116 124
117 arm_pm_restart = rsctrl_restart;
118
119 /* disable a reset isolation for all module clocks */ 125 /* disable a reset isolation for all module clocks */
120 ret = regmap_write(pllctrl_regs, rspll_offset + RSISO_RG, 0); 126 ret = regmap_write(pllctrl_regs, rspll_offset + RSISO_RG, 0);
121 if (ret) 127 if (ret)
@@ -147,7 +153,11 @@ static int rsctrl_probe(struct platform_device *pdev)
147 return ret; 153 return ret;
148 } 154 }
149 155
150 return 0; 156 ret = register_restart_handler(&rsctrl_restart_nb);
157 if (ret)
158 dev_err(dev, "cannot register restart handler (err=%d)\n", ret);
159
160 return ret;
151} 161}
152 162
153static struct platform_driver rsctrl_driver = { 163static struct platform_driver rsctrl_driver = {
diff --git a/drivers/power/reset/syscon-reboot.c b/drivers/power/reset/syscon-reboot.c
index 815b901822cf..c4049f45663f 100644
--- a/drivers/power/reset/syscon-reboot.c
+++ b/drivers/power/reset/syscon-reboot.c
@@ -68,7 +68,7 @@ static int syscon_reboot_probe(struct platform_device *pdev)
68 return -EINVAL; 68 return -EINVAL;
69 69
70 ctx->restart_handler.notifier_call = syscon_restart_handle; 70 ctx->restart_handler.notifier_call = syscon_restart_handle;
71 ctx->restart_handler.priority = 128; 71 ctx->restart_handler.priority = 192;
72 err = register_restart_handler(&ctx->restart_handler); 72 err = register_restart_handler(&ctx->restart_handler);
73 if (err) 73 if (err)
74 dev_err(dev, "can't register restart notifier (err=%d)\n", err); 74 dev_err(dev, "can't register restart notifier (err=%d)\n", err);
diff --git a/drivers/power/reset/vexpress-poweroff.c b/drivers/power/reset/vexpress-poweroff.c
index 4dc102e2b230..9dfc9cee3232 100644
--- a/drivers/power/reset/vexpress-poweroff.c
+++ b/drivers/power/reset/vexpress-poweroff.c
@@ -12,14 +12,14 @@
12 */ 12 */
13 13
14#include <linux/delay.h> 14#include <linux/delay.h>
15#include <linux/notifier.h>
15#include <linux/of.h> 16#include <linux/of.h>
16#include <linux/of_device.h> 17#include <linux/of_device.h>
17#include <linux/platform_device.h> 18#include <linux/platform_device.h>
19#include <linux/reboot.h>
18#include <linux/stat.h> 20#include <linux/stat.h>
19#include <linux/vexpress.h> 21#include <linux/vexpress.h>
20 22
21#include <asm/system_misc.h>
22
23static void vexpress_reset_do(struct device *dev, const char *what) 23static void vexpress_reset_do(struct device *dev, const char *what)
24{ 24{
25 int err = -ENOENT; 25 int err = -ENOENT;
@@ -43,11 +43,19 @@ static void vexpress_power_off(void)
43 43
44static struct device *vexpress_restart_device; 44static struct device *vexpress_restart_device;
45 45
46static void vexpress_restart(enum reboot_mode reboot_mode, const char *cmd) 46static int vexpress_restart(struct notifier_block *this, unsigned long mode,
47 void *cmd)
47{ 48{
48 vexpress_reset_do(vexpress_restart_device, "restart"); 49 vexpress_reset_do(vexpress_restart_device, "restart");
50
51 return NOTIFY_DONE;
49} 52}
50 53
54static struct notifier_block vexpress_restart_nb = {
55 .notifier_call = vexpress_restart,
56 .priority = 128,
57};
58
51static ssize_t vexpress_reset_active_show(struct device *dev, 59static ssize_t vexpress_reset_active_show(struct device *dev,
52 struct device_attribute *attr, char *buf) 60 struct device_attribute *attr, char *buf)
53{ 61{
@@ -86,12 +94,28 @@ static struct of_device_id vexpress_reset_of_match[] = {
86 {} 94 {}
87}; 95};
88 96
97static int _vexpress_register_restart_handler(struct device *dev)
98{
99 int err;
100
101 vexpress_restart_device = dev;
102 err = register_restart_handler(&vexpress_restart_nb);
103 if (err) {
104 dev_err(dev, "cannot register restart handler (err=%d)\n", err);
105 return err;
106 }
107 device_create_file(dev, &dev_attr_active);
108
109 return 0;
110}
111
89static int vexpress_reset_probe(struct platform_device *pdev) 112static int vexpress_reset_probe(struct platform_device *pdev)
90{ 113{
91 enum vexpress_reset_func func; 114 enum vexpress_reset_func func;
92 const struct of_device_id *match = 115 const struct of_device_id *match =
93 of_match_device(vexpress_reset_of_match, &pdev->dev); 116 of_match_device(vexpress_reset_of_match, &pdev->dev);
94 struct regmap *regmap; 117 struct regmap *regmap;
118 int ret = 0;
95 119
96 if (match) 120 if (match)
97 func = (enum vexpress_reset_func)match->data; 121 func = (enum vexpress_reset_func)match->data;
@@ -110,18 +134,14 @@ static int vexpress_reset_probe(struct platform_device *pdev)
110 break; 134 break;
111 case FUNC_RESET: 135 case FUNC_RESET:
112 if (!vexpress_restart_device) 136 if (!vexpress_restart_device)
113 vexpress_restart_device = &pdev->dev; 137 ret = _vexpress_register_restart_handler(&pdev->dev);
114 arm_pm_restart = vexpress_restart;
115 device_create_file(&pdev->dev, &dev_attr_active);
116 break; 138 break;
117 case FUNC_REBOOT: 139 case FUNC_REBOOT:
118 vexpress_restart_device = &pdev->dev; 140 ret = _vexpress_register_restart_handler(&pdev->dev);
119 arm_pm_restart = vexpress_restart;
120 device_create_file(&pdev->dev, &dev_attr_active);
121 break; 141 break;
122 }; 142 };
123 143
124 return 0; 144 return ret;
125} 145}
126 146
127static const struct platform_device_id vexpress_reset_id_table[] = { 147static const struct platform_device_id vexpress_reset_id_table[] = {
diff --git a/drivers/power/reset/xgene-reboot.c b/drivers/power/reset/xgene-reboot.c
index 6b49be6867ab..b0e5002f8deb 100644
--- a/drivers/power/reset/xgene-reboot.c
+++ b/drivers/power/reset/xgene-reboot.c
@@ -24,63 +24,67 @@
24 * For system shutdown, this is board specify. If a board designer 24 * For system shutdown, this is board specify. If a board designer
25 * implements GPIO shutdown, use the gpio-poweroff.c driver. 25 * implements GPIO shutdown, use the gpio-poweroff.c driver.
26 */ 26 */
27#include <linux/delay.h>
27#include <linux/io.h> 28#include <linux/io.h>
29#include <linux/notifier.h>
28#include <linux/of_device.h> 30#include <linux/of_device.h>
29#include <linux/of_address.h> 31#include <linux/of_address.h>
30#include <linux/platform_device.h> 32#include <linux/platform_device.h>
33#include <linux/reboot.h>
31#include <linux/stat.h> 34#include <linux/stat.h>
32#include <linux/slab.h> 35#include <linux/slab.h>
33#include <asm/system_misc.h>
34 36
35struct xgene_reboot_context { 37struct xgene_reboot_context {
36 struct platform_device *pdev; 38 struct device *dev;
37 void *csr; 39 void *csr;
38 u32 mask; 40 u32 mask;
41 struct notifier_block restart_handler;
39}; 42};
40 43
41static struct xgene_reboot_context *xgene_restart_ctx; 44static int xgene_restart_handler(struct notifier_block *this,
42 45 unsigned long mode, void *cmd)
43static void xgene_restart(enum reboot_mode mode, const char *cmd)
44{ 46{
45 struct xgene_reboot_context *ctx = xgene_restart_ctx; 47 struct xgene_reboot_context *ctx =
46 unsigned long timeout; 48 container_of(this, struct xgene_reboot_context,
49 restart_handler);
47 50
48 /* Issue the reboot */ 51 /* Issue the reboot */
49 if (ctx) 52 writel(ctx->mask, ctx->csr);
50 writel(ctx->mask, ctx->csr); 53
54 mdelay(1000);
51 55
52 timeout = jiffies + HZ; 56 dev_emerg(ctx->dev, "Unable to restart system\n");
53 while (time_before(jiffies, timeout))
54 cpu_relax();
55 57
56 dev_emerg(&ctx->pdev->dev, "Unable to restart system\n"); 58 return NOTIFY_DONE;
57} 59}
58 60
59static int xgene_reboot_probe(struct platform_device *pdev) 61static int xgene_reboot_probe(struct platform_device *pdev)
60{ 62{
61 struct xgene_reboot_context *ctx; 63 struct xgene_reboot_context *ctx;
64 struct device *dev = &pdev->dev;
65 int err;
62 66
63 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); 67 ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
64 if (!ctx) { 68 if (!ctx)
65 dev_err(&pdev->dev, "out of memory for context\n"); 69 return -ENOMEM;
66 return -ENODEV;
67 }
68 70
69 ctx->csr = of_iomap(pdev->dev.of_node, 0); 71 ctx->csr = of_iomap(dev->of_node, 0);
70 if (!ctx->csr) { 72 if (!ctx->csr) {
71 devm_kfree(&pdev->dev, ctx); 73 dev_err(dev, "can not map resource\n");
72 dev_err(&pdev->dev, "can not map resource\n");
73 return -ENODEV; 74 return -ENODEV;
74 } 75 }
75 76
76 if (of_property_read_u32(pdev->dev.of_node, "mask", &ctx->mask)) 77 if (of_property_read_u32(dev->of_node, "mask", &ctx->mask))
77 ctx->mask = 0xFFFFFFFF; 78 ctx->mask = 0xFFFFFFFF;
78 79
79 ctx->pdev = pdev; 80 ctx->dev = dev;
80 arm_pm_restart = xgene_restart; 81 ctx->restart_handler.notifier_call = xgene_restart_handler;
81 xgene_restart_ctx = ctx; 82 ctx->restart_handler.priority = 128;
83 err = register_restart_handler(&ctx->restart_handler);
84 if (err)
85 dev_err(dev, "cannot register restart handler (err=%d)\n", err);
82 86
83 return 0; 87 return err;
84} 88}
85 89
86static struct of_device_id xgene_reboot_of_match[] = { 90static struct of_device_id xgene_reboot_of_match[] = {