diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:49:45 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:49:45 +0000 |
commit | 2c3c1048746a4622d8c89a29670120dc8fab93c4 (patch) | |
tree | 848558de17fb3008cdf4d861b01ac7781903ce39 /drivers/s390/char/sclp_quiesce.c | |
parent | Initial commit. (diff) | |
download | linux-2c3c1048746a4622d8c89a29670120dc8fab93c4.tar.xz linux-2c3c1048746a4622d8c89a29670120dc8fab93c4.zip |
Adding upstream version 6.1.76.upstream/6.1.76
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'drivers/s390/char/sclp_quiesce.c')
-rw-r--r-- | drivers/s390/char/sclp_quiesce.c | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/drivers/s390/char/sclp_quiesce.c b/drivers/s390/char/sclp_quiesce.c new file mode 100644 index 000000000..ade721467 --- /dev/null +++ b/drivers/s390/char/sclp_quiesce.c @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * signal quiesce handler + * + * Copyright IBM Corp. 1999, 2004 + * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com> + * Peter Oberparleiter <peter.oberparleiter@de.ibm.com> + */ + +#include <linux/types.h> +#include <linux/cpumask.h> +#include <linux/smp.h> +#include <linux/init.h> +#include <linux/reboot.h> +#include <linux/atomic.h> +#include <asm/ptrace.h> +#include <asm/smp.h> + +#include "sclp.h" + +/* Shutdown handler. Signal completion of shutdown by loading special PSW. */ +static void do_machine_quiesce(void) +{ + psw_t quiesce_psw; + + smp_send_stop(); + quiesce_psw.mask = + PSW_MASK_BASE | PSW_MASK_EA | PSW_MASK_BA | PSW_MASK_WAIT; + quiesce_psw.addr = 0xfff; + __load_psw(quiesce_psw); +} + +/* Handler for quiesce event. Start shutdown procedure. */ +static void sclp_quiesce_handler(struct evbuf_header *evbuf) +{ + _machine_restart = (void *) do_machine_quiesce; + _machine_halt = do_machine_quiesce; + _machine_power_off = do_machine_quiesce; + ctrl_alt_del(); +} + +static struct sclp_register sclp_quiesce_event = { + .receive_mask = EVTYP_SIGQUIESCE_MASK, + .receiver_fn = sclp_quiesce_handler, +}; + +/* Initialize quiesce driver. */ +static int __init sclp_quiesce_init(void) +{ + return sclp_register(&sclp_quiesce_event); +} +device_initcall(sclp_quiesce_init); |