1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * Power off by restarting and let u-boot keep hold of the machine |
4 | * until the user presses a button for example. |
5 | * |
6 | * Andrew Lunn <andrew@lunn.ch> |
7 | * |
8 | * Copyright (C) 2012 Andrew Lunn |
9 | */ |
10 | #include <linux/kernel.h> |
11 | #include <linux/init.h> |
12 | #include <linux/platform_device.h> |
13 | #include <linux/of_platform.h> |
14 | #include <linux/module.h> |
15 | #include <linux/reboot.h> |
16 | |
17 | static void restart_poweroff_do_poweroff(void) |
18 | { |
19 | reboot_mode = REBOOT_HARD; |
20 | machine_restart(NULL); |
21 | } |
22 | |
23 | static int restart_poweroff_probe(struct platform_device *pdev) |
24 | { |
25 | /* If a pm_power_off function has already been added, leave it alone */ |
26 | if (pm_power_off != NULL) { |
27 | dev_err(&pdev->dev, |
28 | "pm_power_off function already registered" ); |
29 | return -EBUSY; |
30 | } |
31 | |
32 | pm_power_off = &restart_poweroff_do_poweroff; |
33 | return 0; |
34 | } |
35 | |
36 | static int restart_poweroff_remove(struct platform_device *pdev) |
37 | { |
38 | if (pm_power_off == &restart_poweroff_do_poweroff) |
39 | pm_power_off = NULL; |
40 | |
41 | return 0; |
42 | } |
43 | |
44 | static const struct of_device_id of_restart_poweroff_match[] = { |
45 | { .compatible = "restart-poweroff" , }, |
46 | {}, |
47 | }; |
48 | MODULE_DEVICE_TABLE(of, of_restart_poweroff_match); |
49 | |
50 | static struct platform_driver restart_poweroff_driver = { |
51 | .probe = restart_poweroff_probe, |
52 | .remove = restart_poweroff_remove, |
53 | .driver = { |
54 | .name = "poweroff-restart" , |
55 | .of_match_table = of_restart_poweroff_match, |
56 | }, |
57 | }; |
58 | module_platform_driver(restart_poweroff_driver); |
59 | |
60 | MODULE_AUTHOR("Andrew Lunn <andrew@lunn.ch" ); |
61 | MODULE_DESCRIPTION("restart poweroff driver" ); |
62 | MODULE_ALIAS("platform:poweroff-restart" ); |
63 | |