diff options
-rw-r--r-- | Documentation/devicetree/bindings/power_supply/gpio-charger.txt | 27 | ||||
-rw-r--r-- | drivers/power/ds2782_battery.c | 8 | ||||
-rw-r--r-- | drivers/power/gpio-charger.c | 72 | ||||
-rw-r--r-- | drivers/power/reset/axxia-reset.c | 21 | ||||
-rw-r--r-- | drivers/power/reset/brcmstb-reboot.c | 28 | ||||
-rw-r--r-- | drivers/power/reset/hisi-reboot.c | 20 | ||||
-rw-r--r-- | drivers/power/reset/keystone-reset.c | 20 | ||||
-rw-r--r-- | drivers/power/reset/syscon-reboot.c | 2 | ||||
-rw-r--r-- | drivers/power/reset/vexpress-poweroff.c | 40 | ||||
-rw-r--r-- | drivers/power/reset/xgene-reboot.c | 56 |
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 @@ | |||
1 | gpio-charger | ||
2 | |||
3 | Required 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 | |||
17 | Example: | ||
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 | ||
355 | static SIMPLE_DEV_PM_OPS(ds278x_battery_pm_ops, ds278x_suspend, ds278x_resume); | 356 | static 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 | ||
362 | enum ds278x_num_id { | 358 | enum ds278x_num_id { |
363 | DS2782 = 0, | 359 | DS2782 = 0, |
@@ -460,7 +456,7 @@ MODULE_DEVICE_TABLE(i2c, ds278x_id); | |||
460 | static struct i2c_driver ds278x_battery_driver = { | 456 | static 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 | ||
74 | static | ||
75 | struct 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 | |||
72 | static int gpio_charger_probe(struct platform_device *pdev) | 127 | static 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) | |||
189 | static SIMPLE_DEV_PM_OPS(gpio_charger_pm_ops, | 250 | static SIMPLE_DEV_PM_OPS(gpio_charger_pm_ops, |
190 | gpio_charger_suspend, gpio_charger_resume); | 251 | gpio_charger_suspend, gpio_charger_resume); |
191 | 252 | ||
253 | static const struct of_device_id gpio_charger_match[] = { | ||
254 | { .compatible = "gpio-charger" }, | ||
255 | { } | ||
256 | }; | ||
257 | MODULE_DEVICE_TABLE(of, gpio_charger_match); | ||
258 | |||
192 | static struct platform_driver gpio_charger_driver = { | 259 | static 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 | ||
40 | static struct regmap *syscon; | 38 | static struct regmap *syscon; |
41 | 39 | ||
42 | static void do_axxia_restart(enum reboot_mode reboot_mode, const char *cmd) | 40 | static 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 | ||
56 | static struct notifier_block axxia_restart_nb = { | ||
57 | .notifier_call = axxia_restart_handler, | ||
58 | .priority = 128, | ||
59 | }; | ||
60 | |||
55 | static int axxia_reset_probe(struct platform_device *pdev) | 61 | static 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 | ||
70 | static const struct of_device_id of_axxia_reset_match[] = { | 79 | static 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; | |||
35 | static u32 rst_src_en; | 34 | static u32 rst_src_en; |
36 | static u32 sw_mstr_rst; | 35 | static u32 sw_mstr_rst; |
37 | 36 | ||
38 | static void brcmstb_reboot(enum reboot_mode mode, const char *cmd) | 37 | static 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 | ||
73 | static struct notifier_block brcmstb_restart_nb = { | ||
74 | .notifier_call = brcmstb_restart_handler, | ||
75 | .priority = 128, | ||
76 | }; | ||
77 | |||
71 | static int brcmstb_reboot_probe(struct platform_device *pdev) | 78 | static 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 | ||
101 | static const struct of_device_id of_match[] = { | 111 | static 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 | ||
24 | static void __iomem *base; | 24 | static void __iomem *base; |
25 | static u32 reboot_offset; | 25 | static u32 reboot_offset; |
26 | 26 | ||
27 | static void hisi_restart(enum reboot_mode mode, const char *cmd) | 27 | static 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 | ||
38 | static struct notifier_block hisi_restart_nb = { | ||
39 | .notifier_call = hisi_restart_handler, | ||
40 | .priority = 128, | ||
41 | }; | ||
42 | |||
35 | static int hisi_reboot_probe(struct platform_device *pdev) | 43 | static 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 | ||
55 | static struct of_device_id hisi_reboot_of_match[] = { | 67 | static 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 | ||
55 | static void rsctrl_restart(enum reboot_mode mode, const char *cmd) | 55 | static 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 | ||
68 | static struct notifier_block rsctrl_restart_nb = { | ||
69 | .notifier_call = rsctrl_restart_handler, | ||
70 | .priority = 128, | ||
71 | }; | ||
72 | |||
65 | static struct of_device_id rsctrl_of_match[] = { | 73 | static 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 | ||
153 | static struct platform_driver rsctrl_driver = { | 163 | static 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 | |||
23 | static void vexpress_reset_do(struct device *dev, const char *what) | 23 | static 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 | ||
44 | static struct device *vexpress_restart_device; | 44 | static struct device *vexpress_restart_device; |
45 | 45 | ||
46 | static void vexpress_restart(enum reboot_mode reboot_mode, const char *cmd) | 46 | static 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 | ||
54 | static struct notifier_block vexpress_restart_nb = { | ||
55 | .notifier_call = vexpress_restart, | ||
56 | .priority = 128, | ||
57 | }; | ||
58 | |||
51 | static ssize_t vexpress_reset_active_show(struct device *dev, | 59 | static 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 | ||
97 | static 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 | |||
89 | static int vexpress_reset_probe(struct platform_device *pdev) | 112 | static 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 | ||
127 | static const struct platform_device_id vexpress_reset_id_table[] = { | 147 | static 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 | ||
35 | struct xgene_reboot_context { | 37 | struct 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 | ||
41 | static struct xgene_reboot_context *xgene_restart_ctx; | 44 | static int xgene_restart_handler(struct notifier_block *this, |
42 | 45 | unsigned long mode, void *cmd) | |
43 | static 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 | ||
59 | static int xgene_reboot_probe(struct platform_device *pdev) | 61 | static 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 | ||
86 | static struct of_device_id xgene_reboot_of_match[] = { | 90 | static struct of_device_id xgene_reboot_of_match[] = { |