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 arm_pm_restart(REBOOT_HARD, NULL); 24 } 25 26 static int restart_poweroff_probe(struct platform_device *pdev) 27 { 28 /* If a pm_power_off function has already been added, leave it alone */ 29 if (pm_power_off != NULL) { 30 dev_err(&pdev->dev, 31 "pm_power_off function already registered"); 32 return -EBUSY; 33 } 34 35 pm_power_off = &restart_poweroff_do_poweroff; 36 return 0; 37 } 38 39 static int restart_poweroff_remove(struct platform_device *pdev) 40 { 41 if (pm_power_off == &restart_poweroff_do_poweroff) 42 pm_power_off = NULL; 43 44 return 0; 45 } 46 47 static const struct of_device_id of_restart_poweroff_match[] = { 48 { .compatible = "restart-poweroff", }, 49 {}, 50 }; 51 52 static struct platform_driver restart_poweroff_driver = { 53 .probe = restart_poweroff_probe, 54 .remove = restart_poweroff_remove, 55 .driver = { 56 .name = "poweroff-restart", 57 .owner = THIS_MODULE, 58 .of_match_table = of_restart_poweroff_match, 59 }, 60 }; 61 module_platform_driver(restart_poweroff_driver); 62 63 MODULE_AUTHOR("Andrew Lunn <andrew@lunn.ch"); 64 MODULE_DESCRIPTION("restart poweroff driver"); 65 MODULE_LICENSE("GPLv2"); 66 MODULE_ALIAS("platform:poweroff-restart"); 67