/*
 * Psion battery FIQ handler. Copyright 2002 Tony Lindgren <tony@atomide.com>
 *
 * Modeled after Russell King's dma-rpc.c
 */
#include <linux/module.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/delay.h>
#include <linux/proc_fs.h>
#include <linux/sched.h>
#include <linux/miscdevice.h>
#include <linux/spinlock.h>
#include <linux/rwsem.h>
#include <linux/init.h>

#include <asm/hardware/psionw.h>
#include <asm/io.h>
#include <asm/leds.h>
#include <asm/mach-types.h>
#include <asm/system.h>
#include <asm/uaccess.h>

#include <asm/fiq.h>

#include <asm/arch/irqs.h>

static struct fiq_handler extfiq_fh = {
	name:	"extfiq"
};

static struct fiq_handler blint_fh = {
	name:	"blint"
};

/*
 * Sets up a handler for the external fiq
 * NOTE: Not currently in use as Linux does not
 * currently support sharing the fiq vector.
 */
static void extfiq_handler_setup(void)
{
	void *fiqhandler_start;
	unsigned int fiqhandler_length;
	struct pt_regs regs;
	extern unsigned char extfiq_handler_start, extfiq_handler_end;

	printk("FIQ: Setting up handler for external fast interrupt\n");

	fiqhandler_start = &extfiq_handler_start;
	fiqhandler_length = &extfiq_handler_end - &extfiq_handler_start;

	if (claim_fiq(&extfiq_fh)) {
		printk("FIQ: Could not claim fast interrupt\n");
		return;
	}

	set_fiq_handler(fiqhandler_start, fiqhandler_length);
	set_fiq_regs(&regs);
	
	enable_fiq(IRQ_EXTFIQ);
}

/*
 * Sets up a handler for the battery low fiq
 */
static void blint_fiq_handler_setup(void)
{
	void *fiqhandler_start;
	unsigned int fiqhandler_length;
	struct pt_regs regs;
	extern unsigned char blint_fiq_handler_start, blint_fiq_handler_end;

	printk("FIQ: Setting up handler for battery low fast interrupt\n");

	fiqhandler_start = &blint_fiq_handler_start;
	fiqhandler_length = &blint_fiq_handler_end - &blint_fiq_handler_start;

	if (claim_fiq(&blint_fh)) {
		printk("FIQ: Could not claim fast interrupt\n");
		return;
	}

	set_fiq_handler(fiqhandler_start, fiqhandler_length);
	set_fiq_regs(&regs);
	psionw_writel(1, BLEOI);
	enable_fiq(IRQ_BLINT);
}

static int __init psionw_pm_init(void)
{
	printk("FIQ: Initializing Psion fast interrupts\n");
	//extfiq_handler_setup();
	blint_fiq_handler_setup();
}

static void __exit psionw_pm_exit(void)
{
	printk("FIQ: Disabling Psion fast interrupts\n");

	//disable_fiq(IRQ_EXTFIQ);
	//release_fiq(&extfiq_fh);

	disable_fiq(IRQ_BLINT);
	release_fiq(&blint_fh);
}


EXPORT_NO_SYMBOLS;

MODULE_LICENSE("GPL");

module_init(psionw_pm_init);
module_exit(psionw_pm_exit);
