/*
 * linux/drivers/parisc/power.c
 * HP PARISC soft power switch support driver
 *
 * Copyright (c) 2001-2005 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/string.h>
#include <linux/notifier.h>
#include <linux/reboot.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/workqueue.h>

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


#ifdef DEBUG
# define DPRINTK(x...) printk(x)
#else
# define DPRINTK(x...)
#endif


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


#define DIAG_CODE(code)		(0x14000000 + ((code)<<5))

/* this will go to processor.h or any other place... */
/* taken from PCXL ERS page 82 */
#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\n nop\n" : "=&r" (__res) : "i" (MFCPU_T(dr,28)) \
	);					\
	__res;					\
} )


static void deferred_poweroff(void *dummy)
{
	if (kill_cad_pid(SIGINT, 1)) {
		/* just in case killing init process failed */
		machine_power_off();
	}
}

/*
 * This function gets called from interrupt context.
 * As it's called within an interrupt, it wouldn't sync if we don't
 * use schedule_work().
 */

static DECLARE_WORK(poweroff_work, deferred_poweroff, NULL);

static void poweroff(void)
{
	static int powering_off __read_mostly;

	if (powering_off)
		return;

	powering_off++;
	schedule_work(&poweroff_work);
}


/* local time-counter for shutdown */
static int shutdown_timer __read_mostly;

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

	shutdown_timer++;
	
	/* wait until the button was pressed for 1 second */
	if (shutdown_timer == HZ) {
#if defined (DEBUG) || defined(CONFIG_CHASSIS_LCD_LED)
		static char msg[] = "Shutting down...";
#endif
		DPRINTK(KERN_INFO "%s\n", msg);
		lcd_print(msg);
		poweroff();
	}
}


/* main power switch tasklet struct (scheduled from time.c) */
DECLARE_TASKLET_DISABLED(power_tasklet, NULL, 0);

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

/*
 * 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.
 * 
 */
static void gecko_tasklet_func(unsigned long unused)
{
	if (unlikely(!pwrsw_enabled))
		return;

	if (__getDIAG(25) & 0x80000000) {
		/* power switch button not pressed or released again */
		/* Warning: Some machines do never reset this DIAG flag! */
		shutdown_timer = 0;
	} else {
		process_shutdown();
	}
}



/*
 * 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.
 */

static void polling_tasklet_func(unsigned long soft_power_reg)
{
        unsigned long current_status;
	
	if (unlikely(!pwrsw_enabled))
		return;

	current_status = gsc_readl(soft_power_reg);
	if (current_status & 0x1) {
		/* power switch button not pressed */
		shutdown_timer = 0;
	} else {
		process_shutdown();
	}
}


/*
 * 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
 */
static int parisc_panic_event(struct notifier_block *this,
		unsigned long event, void *ptr)
{
	/* re-enable the soft-power switch */
	pdc_soft_power_button(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 = 0;

#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 "Gecko-style soft power switch enabled.\n");
			power_tasklet.func = gecko_tasklet_func;
			break;
			
	case -1UL:	printk(KERN_INFO "Soft power switch support not available.\n");
			return -ENODEV;
	
	default:	printk(KERN_INFO "Soft power switch enabled, polling @ 0x%08lx.\n",
				soft_power_reg);
			power_tasklet.data = soft_power_reg;
			power_tasklet.func = polling_tasklet_func;
	}

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

	tasklet_enable(&power_tasklet);

	return 0;
}

static void __exit power_exit(void)
{
	if (!power_tasklet.func)
		return;

	tasklet_disable(&power_tasklet);
	atomic_notifier_chain_unregister(&panic_notifier_list,
			&parisc_panic_block);
	power_tasklet.func = NULL;
	pdc_soft_power_button(0);
}

module_init(power_init);
module_exit(power_exit);


MODULE_AUTHOR("Helge Deller");
MODULE_DESCRIPTION("Soft power switch driver");
MODULE_LICENSE("Dual BSD/GPL");
