/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
 * HP PARISC soft power switch driver
 *
 * Copyright (c) 2001-2023 Helge Deller <deller@gmx.de>
 *
 *  HINT:
 *  Support of the soft power switch button may be enabled or disabled at
 *  runtime through the "/proc/sys/kernel/power" procfs entry.
 */

#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/panic_notifier.h>
#include <linux/reboot.h>
#include <linux/sched/signal.h>
#include <linux/kthread.h>
#include <linux/pm.h>

#include <asm/pdc.h>
#include <asm/io.h>
#include <asm/led.h>

#define DRIVER_NAME  "powersw"
#define KTHREAD_NAME "kpowerswd"

/* how often should the power button be polled ? */
#define POWERSWITCH_POLL_PER_SEC 2

/* how long does the power button needs to be down until we react ? */
#define POWERSWITCH_DOWN_SEC 2

/* assembly code to access special registers */
/* taken from PCXL ERS page 82 */
#define DIAG_CODE(code)		(0x14000000 + ((code)<<5))

#define MFCPU_X(rDiagReg, t_ch, t_th, code) \
	(DIAG_CODE(code) + ((rDiagReg)<<21) + ((t_ch)<<16) + ((t_th)<<0) )

#define MTCPU(dr, gr)		MFCPU_X(dr, gr,  0, 0x12)       /* move value of gr to dr[dr] */
#define MFCPU_C(dr, gr)		MFCPU_X(dr, gr,  0, 0x30)	/* for dr0 and dr8 only ! */
#define MFCPU_T(dr, gr)		MFCPU_X(dr,  0, gr, 0xa0)	/* all dr except dr0 and dr8 */

#define __getDIAG(dr) ( {			\
        register unsigned long __res asm("r28");\
	 __asm__ __volatile__ (			\
		".word %1" : "=&r" (__res) : "i" (MFCPU_T(dr,28) ) \
	);					\
	__res;					\
} )

/* local shutdown counter */
static int shutdown_timer __read_mostly;

/* check, give feedback and start shutdown after one second */
static void process_shutdown(void)
{
	if (shutdown_timer == 0)
		printk(KERN_ALERT KTHREAD_NAME ": Shutdown requested...\n");

	shutdown_timer++;

	/* wait until the button was pressed for 1 second */
	if (shutdown_timer == (POWERSWITCH_DOWN_SEC*POWERSWITCH_POLL_PER_SEC)) {
		static const char msg[] = "Shutting down...";
		printk(KERN_INFO KTHREAD_NAME ": %s\n", msg);
		lcd_print(msg);

		/* send kill signal */
		if (kill_cad_pid(SIGINT, 1)) {
			/* just in case killing init process failed */
			machine_power_off();
		}
	}
}


/* main power switch task struct */
static struct task_struct *power_task;

/* filename in /proc which can be used to enable/disable the power switch */
#define SYSCTL_FILENAME	"sys/kernel/power"

/* soft power switch enabled/disabled */
int pwrsw_enabled __read_mostly = 1;

/* main kernel thread worker. It polls the button state */
static int kpowerswd(void *param)
{
	__set_current_state(TASK_RUNNING);

	do {
		int button_not_pressed;
		unsigned long soft_power_reg = (unsigned long) param;

		schedule_timeout_interruptible(pwrsw_enabled ? HZ : HZ/POWERSWITCH_POLL_PER_SEC);

		if (unlikely(!pwrsw_enabled))
			continue;

		if (soft_power_reg) {
			/*
			 * Non-Gecko-style machines:
			 * Check the power switch status which is read from the
			 * real I/O location at soft_power_reg.
			 * Bit 31 ("the lowest bit) is the status of the power switch.
			 * This bit is "1" if the button is NOT pressed.
			 */
			button_not_pressed = (gsc_readl(soft_power_reg) & 0x1);
		} else {
			/*
			 * On gecko style machines (e.g. 712/xx and 715/xx)
			 * the power switch status is stored in Bit 0 ("the highest bit")
			 * of CPU diagnose register 25.
			 * Warning: Some machines never reset the DIAG flag, even if
			 * the button has been released again.
			 */
			button_not_pressed = (__getDIAG(25) & 0x80000000);
		}

		if (likely(button_not_pressed)) {
			if (unlikely(shutdown_timer && /* avoid writing if not necessary */
				shutdown_timer < (POWERSWITCH_DOWN_SEC*POWERSWITCH_POLL_PER_SEC))) {
				shutdown_timer = 0;
				printk(KERN_INFO KTHREAD_NAME ": Shutdown request aborted.\n");
			}
		} else
			process_shutdown();


	} while (!kthread_should_stop());

	return 0;
}


/*
 * powerfail interruption handler (irq IRQ_FROM_REGION(CPU_IRQ_REGION)+2)
 */
#if 0
static void powerfail_interrupt(int code, void *x)
{
	printk(KERN_CRIT "POWERFAIL INTERRUPTION !\n");
	poweroff();
}
#endif




/*
 * parisc_panic_event() is called by the panic handler.
 *
 * As soon as a panic occurs, our tasklets above will not
 * be executed any longer. This function then re-enables
 * the soft-power switch and allows the user to switch off
 * the system. We rely in pdc_soft_power_button_panic()
 * since this version spin_trylocks (instead of regular
 * spinlock), preventing deadlocks on panic path.
 */
static int parisc_panic_event(struct notifier_block *this,
		unsigned long event, void *ptr)
{
	/* re-enable the soft-power switch */
	pdc_soft_power_button_panic(0);
	return NOTIFY_DONE;
}

static struct notifier_block parisc_panic_block = {
	.notifier_call	= parisc_panic_event,
	.priority	= INT_MAX,
};

/* qemu soft power-off function */
static int qemu_power_off(struct sys_off_data *data)
{
	/* this turns the system off via SeaBIOS */
	gsc_writel(0, (unsigned long) data->cb_data);
	pdc_soft_power_button(1);
	return NOTIFY_DONE;
}

static int __init power_init(void)
{
	unsigned long ret;
	unsigned long soft_power_reg;

#if 0
	request_irq( IRQ_FROM_REGION(CPU_IRQ_REGION)+2, &powerfail_interrupt,
		0, "powerfail", NULL);
#endif

	/* enable the soft power switch if possible */
	ret = pdc_soft_power_info(&soft_power_reg);
	if (ret == PDC_OK)
		ret = pdc_soft_power_button(1);
	if (ret != PDC_OK)
		soft_power_reg = -1UL;

	switch (soft_power_reg) {
	case 0:		printk(KERN_INFO DRIVER_NAME ": Gecko-style soft power switch enabled.\n");
			break;

	case -1UL:	printk(KERN_INFO DRIVER_NAME ": Soft power switch support not available.\n");
			return -ENODEV;

	default:	printk(KERN_INFO DRIVER_NAME ": Soft power switch at 0x%08lx enabled.\n",
				soft_power_reg);
	}

	power_task = NULL;
	if (running_on_qemu && soft_power_reg)
		register_sys_off_handler(SYS_OFF_MODE_POWER_OFF, SYS_OFF_PRIO_DEFAULT,
					qemu_power_off, (void *)soft_power_reg);
	if (!running_on_qemu || soft_power_reg)
		power_task = kthread_run(kpowerswd, (void*)soft_power_reg,
					KTHREAD_NAME);
	if (IS_ERR(power_task)) {
		printk(KERN_ERR DRIVER_NAME ": thread creation failed.  Driver not loaded.\n");
		pdc_soft_power_button(0);
		return -EIO;
	}

	/* Register a call for panic conditions. */
	atomic_notifier_chain_register(&panic_notifier_list,
			&parisc_panic_block);

	return 0;
}

static void __exit power_exit(void)
{
	kthread_stop(power_task);

	atomic_notifier_chain_unregister(&panic_notifier_list,
			&parisc_panic_block);

	pdc_soft_power_button(0);
}

arch_initcall(power_init);
module_exit(power_exit);


MODULE_AUTHOR("Helge Deller <deller@gmx.de>");
MODULE_DESCRIPTION("Soft power switch driver");
MODULE_LICENSE("Dual BSD/GPL");
