162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * signal quiesce handler 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright IBM Corp. 1999, 2004 662306a36Sopenharmony_ci * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com> 762306a36Sopenharmony_ci * Peter Oberparleiter <peter.oberparleiter@de.ibm.com> 862306a36Sopenharmony_ci */ 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#include <linux/types.h> 1162306a36Sopenharmony_ci#include <linux/cpumask.h> 1262306a36Sopenharmony_ci#include <linux/smp.h> 1362306a36Sopenharmony_ci#include <linux/init.h> 1462306a36Sopenharmony_ci#include <linux/reboot.h> 1562306a36Sopenharmony_ci#include <linux/atomic.h> 1662306a36Sopenharmony_ci#include <asm/ptrace.h> 1762306a36Sopenharmony_ci#include <asm/smp.h> 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci#include "sclp.h" 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci/* Shutdown handler. Signal completion of shutdown by loading special PSW. */ 2262306a36Sopenharmony_cistatic void do_machine_quiesce(void) 2362306a36Sopenharmony_ci{ 2462306a36Sopenharmony_ci psw_t quiesce_psw; 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ci smp_send_stop(); 2762306a36Sopenharmony_ci quiesce_psw.mask = 2862306a36Sopenharmony_ci PSW_MASK_BASE | PSW_MASK_EA | PSW_MASK_BA | PSW_MASK_WAIT; 2962306a36Sopenharmony_ci quiesce_psw.addr = 0xfff; 3062306a36Sopenharmony_ci __load_psw(quiesce_psw); 3162306a36Sopenharmony_ci} 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci/* Handler for quiesce event. Start shutdown procedure. */ 3462306a36Sopenharmony_cistatic void sclp_quiesce_handler(struct evbuf_header *evbuf) 3562306a36Sopenharmony_ci{ 3662306a36Sopenharmony_ci _machine_restart = (void *) do_machine_quiesce; 3762306a36Sopenharmony_ci _machine_halt = do_machine_quiesce; 3862306a36Sopenharmony_ci _machine_power_off = do_machine_quiesce; 3962306a36Sopenharmony_ci ctrl_alt_del(); 4062306a36Sopenharmony_ci} 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_cistatic struct sclp_register sclp_quiesce_event = { 4362306a36Sopenharmony_ci .receive_mask = EVTYP_SIGQUIESCE_MASK, 4462306a36Sopenharmony_ci .receiver_fn = sclp_quiesce_handler, 4562306a36Sopenharmony_ci}; 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci/* Initialize quiesce driver. */ 4862306a36Sopenharmony_cistatic int __init sclp_quiesce_init(void) 4962306a36Sopenharmony_ci{ 5062306a36Sopenharmony_ci return sclp_register(&sclp_quiesce_event); 5162306a36Sopenharmony_ci} 5262306a36Sopenharmony_cidevice_initcall(sclp_quiesce_init); 53