/*
 * linux/drivers/parisc/power.c
 * HP PARISC soft power switch support driver
 *
 * Copyright (c) 2001-2007 Helge Deller <deller@gmx.de>
 * All rights reserved.
 *
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions, and the following disclaimer,
 *    without modification.
 * 2. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * Alternatively, this software may be distributed under the terms of the
 * GNU General Public License ("GPL").
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 *
 *
 *  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,
};


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 = 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");
