blob: ade7214678042629a37ce880a85e1d955c80a436 [file] [log] [blame]
Greg Kroah-Hartmanb2441312017-11-01 15:07:57 +01001// SPDX-License-Identifier: GPL-2.0
Linus Torvalds1da177e2005-04-16 15:20:36 -07002/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07003 * signal quiesce handler
4 *
Heiko Carstensa53c8fa2012-07-20 11:15:04 +02005 * Copyright IBM Corp. 1999, 2004
Linus Torvalds1da177e2005-04-16 15:20:36 -07006 * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
7 * Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
8 */
9
Linus Torvalds1da177e2005-04-16 15:20:36 -070010#include <linux/types.h>
11#include <linux/cpumask.h>
12#include <linux/smp.h>
13#include <linux/init.h>
Adrian Bunk83cc5ed2006-06-25 05:47:41 -070014#include <linux/reboot.h>
Arun Sharma600634972011-07-26 16:09:06 -070015#include <linux/atomic.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070016#include <asm/ptrace.h>
Jan Glauber188596f2007-02-21 10:55:03 +010017#include <asm/smp.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070018
19#include "sclp.h"
20
Linus Torvalds1da177e2005-04-16 15:20:36 -070021/* Shutdown handler. Signal completion of shutdown by loading special PSW. */
Martin Schwidefsky8b94c1e2009-11-13 15:43:53 +010022static void do_machine_quiesce(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -070023{
24 psw_t quiesce_psw;
25
Heiko Carstensc6b5b842006-12-04 15:40:33 +010026 smp_send_stop();
Martin Schwidefskyb50511e2011-10-30 15:16:50 +010027 quiesce_psw.mask =
28 PSW_MASK_BASE | PSW_MASK_EA | PSW_MASK_BA | PSW_MASK_WAIT;
Linus Torvalds1da177e2005-04-16 15:20:36 -070029 quiesce_psw.addr = 0xfff;
30 __load_psw(quiesce_psw);
31}
Linus Torvalds1da177e2005-04-16 15:20:36 -070032
Linus Torvalds1da177e2005-04-16 15:20:36 -070033/* Handler for quiesce event. Start shutdown procedure. */
Martin Schwidefsky8b94c1e2009-11-13 15:43:53 +010034static void sclp_quiesce_handler(struct evbuf_header *evbuf)
Linus Torvalds1da177e2005-04-16 15:20:36 -070035{
Peter Oberparleiter9b357cc2021-06-11 11:13:40 +020036 _machine_restart = (void *) do_machine_quiesce;
37 _machine_halt = do_machine_quiesce;
38 _machine_power_off = do_machine_quiesce;
Linus Torvalds1da177e2005-04-16 15:20:36 -070039 ctrl_alt_del();
40}
41
42static struct sclp_register sclp_quiesce_event = {
Stefan Haberland6d4740c2007-04-27 16:01:53 +020043 .receive_mask = EVTYP_SIGQUIESCE_MASK,
Martin Schwidefsky8b94c1e2009-11-13 15:43:53 +010044 .receiver_fn = sclp_quiesce_handler,
Linus Torvalds1da177e2005-04-16 15:20:36 -070045};
46
47/* Initialize quiesce driver. */
Martin Schwidefsky8b94c1e2009-11-13 15:43:53 +010048static int __init sclp_quiesce_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -070049{
Martin Schwidefskya12c53f2008-07-14 09:59:28 +020050 return sclp_register(&sclp_quiesce_event);
Linus Torvalds1da177e2005-04-16 15:20:36 -070051}
Paul Gortmakeraae175d2016-10-30 16:37:28 -040052device_initcall(sclp_quiesce_init);