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