blob: 562aa0e450ed65cff1182f5def30106bda7ec880 [file] [log] [blame]
Thomas Gleixner8092f732019-06-03 07:45:04 +02001// SPDX-License-Identifier: GPL-2.0-only
Linus Torvalds1da177e2005-04-16 15:20:36 -07002/*
3 * poweroff.c - sysrq handler to gracefully power down machine.
Linus Torvalds1da177e2005-04-16 15:20:36 -07004 */
5
6#include <linux/kernel.h>
7#include <linux/sysrq.h>
8#include <linux/init.h>
9#include <linux/pm.h>
10#include <linux/workqueue.h>
Eric W. Biedermanff319772005-07-26 11:47:32 -060011#include <linux/reboot.h>
Zhang Rui2f15fc42008-07-23 21:28:40 -070012#include <linux/cpumask.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070013
14/*
15 * When the user hits Sys-Rq o to power down the machine this is the
16 * callback we use.
17 */
18
David Howells65f27f32006-11-22 14:55:48 +000019static void do_poweroff(struct work_struct *dummy)
Linus Torvalds1da177e2005-04-16 15:20:36 -070020{
Eric W. Biedermanff319772005-07-26 11:47:32 -060021 kernel_power_off();
Linus Torvalds1da177e2005-04-16 15:20:36 -070022}
23
David Howells65f27f32006-11-22 14:55:48 +000024static DECLARE_WORK(poweroff_work, do_poweroff);
Linus Torvalds1da177e2005-04-16 15:20:36 -070025
Dmitry Torokhov1495cc92010-08-17 21:15:46 -070026static void handle_poweroff(int key)
Linus Torvalds1da177e2005-04-16 15:20:36 -070027{
Zhang Rui2f15fc42008-07-23 21:28:40 -070028 /* run sysrq poweroff on boot cpu */
Rusty Russell41c7bb92009-01-01 10:12:28 +103029 schedule_work_on(cpumask_first(cpu_online_mask), &poweroff_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -070030}
31
Emil Velikov6400b5a2020-05-13 22:43:50 +010032static const struct sysrq_key_op sysrq_poweroff_op = {
Linus Torvalds1da177e2005-04-16 15:20:36 -070033 .handler = handle_poweroff,
zhangwei(Jovi)28ad5852013-04-30 15:28:52 -070034 .help_msg = "poweroff(o)",
Linus Torvalds1da177e2005-04-16 15:20:36 -070035 .action_msg = "Power Off",
Manish Katiyar1dc492a2009-02-22 10:24:27 +053036 .enable_mask = SYSRQ_ENABLE_BOOT,
Linus Torvalds1da177e2005-04-16 15:20:36 -070037};
38
Jan Beulichbbdc18a2012-09-10 12:05:18 +000039static int __init pm_sysrq_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -070040{
41 register_sysrq_key('o', &sysrq_poweroff_op);
42 return 0;
43}
44
45subsys_initcall(pm_sysrq_init);