/*
 *	Eurotech CPU-1220/1410 on board WDT driver
 *
 *	(c) Copyright 2001 Ascensit <support@ascensit.com>
 *	(c) Copyright 2001 Rodolfo Giometti <giometti@ascensit.com>
 *	(c) Copyright 2002 Rob Radez <rob@osinvestor.com>
 *
 *	Based on wdt.c.
 *	Original copyright messages:
 *
 *      (c) Copyright 1996-1997 Alan Cox <alan@redhat.com>, All Rights Reserved.
 *                              http://www.redhat.com
 *
 *      This program is free software; you can redistribute it and/or
 *      modify it under the terms of the GNU General Public License
 *      as published by the Free Software Foundation; either version
 *      2 of the License, or (at your option) any later version.
 *
 *      Neither Alan Cox nor CymruNet Ltd. admit liability nor provide
 *      warranty for any of this software. This material is provided
 *      "AS-IS" and at no charge.
 *
 *      (c) Copyright 1995    Alan Cox <alan@lxorguk.ukuu.org.uk>*
 */

/* Changelog:
 *
 * 2002/04/25 - Rob Radez
 *	clean up #includes
 *	clean up locking
 *	make __setup param unique
 *	proper options in watchdog_info
 *	add WDIOC_GETSTATUS and WDIOC_SETOPTIONS ioctls
 *	add expect_close support
 *
 * 2001 - Rodolfo Giometti
 *	Initial release
 *
 * 2002.05.30 - Joel Becker <joel.becker@oracle.com>
 * 	Added Matt Domsch's nowayout module option.
 */

#include <linux/config.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/types.h>
#include <linux/miscdevice.h>
#include <linux/watchdog.h>
#include <linux/fs.h>
#include <linux/ioport.h>
#include <linux/notifier.h>
#include <linux/reboot.h>
#include <linux/init.h>

#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/system.h>

static unsigned long eurwdt_is_open;
static int eurwdt_timeout;
static char eur_expect_close;

/*
 * You must set these - there is no sane way to probe for this board.
 * You can use eurwdt=x,y to set these now.
 */

static int io = 0x3f0;
static int irq = 10;
static char *ev = "int";

#define WDT_TIMEOUT		60                /* 1 minute */

#ifdef CONFIG_WATCHDOG_NOWAYOUT
static int nowayout = 1;
#else
static int nowayout = 0;
#endif

module_param(nowayout, int, 0);
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");

/*
 * Some symbolic names
 */

#define WDT_CTRL_REG		0x30
#define WDT_OUTPIN_CFG		0xe2
#define WDT_EVENT_INT		0x00
#define WDT_EVENT_REBOOT	0x08
#define WDT_UNIT_SEL		0xf1
#define WDT_UNIT_SECS		0x80
#define WDT_TIMEOUT_VAL		0xf2
#define WDT_TIMER_CFG		0xf3


module_param(io, int, 0);
MODULE_PARM_DESC(io, "Eurotech WDT io port (default=0x3f0)");
module_param(irq, int, 0);
MODULE_PARM_DESC(irq, "Eurotech WDT irq (default=10)");
module_param(ev, charp, 0);
MODULE_PARM_DESC(ev, "Eurotech WDT event type (default is `int')");


/*
 * Programming support
 */

static inline void eurwdt_write_reg(u8 index, u8 data)
{
	outb(index, io);
	outb(data, io+1);
}

static inline void eurwdt_lock_chip(void)
{
	outb(0xaa, io);
}

static inline void eurwdt_unlock_chip(void)
{
	outb(0x55, io);
	eurwdt_write_reg(0x07, 0x08);	/* set the logical device */
}

static inline void eurwdt_set_timeout(int timeout)
{
	eurwdt_write_reg(WDT_TIMEOUT_VAL, (u8) timeout);
}

static inline void eurwdt_disable_timer(void)
{
	eurwdt_set_timeout(0);
}

static void eurwdt_activate_timer(void)
{
	eurwdt_disable_timer();
	eurwdt_write_reg(WDT_CTRL_REG, 0x01);	/* activate the WDT */
	eurwdt_write_reg(WDT_OUTPIN_CFG, !strcmp("int", ev) ? WDT_EVENT_INT : WDT_EVENT_REBOOT);

	/* Setting interrupt line */
	if (irq == 2 || irq > 15 || irq < 0) {
		printk(KERN_ERR ": invalid irq number\n");
		irq = 0;	/* if invalid we disable interrupt */
	}
	if (irq == 0)
		printk(KERN_INFO ": interrupt disabled\n");

	eurwdt_write_reg(WDT_TIMER_CFG, irq<<4);

	eurwdt_write_reg(WDT_UNIT_SEL, WDT_UNIT_SECS);	/* we use seconds */
	eurwdt_set_timeout(0);	/* the default timeout */
}


/*
 * Kernel methods.
 */

static irqreturn_t eurwdt_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
	printk(KERN_CRIT "timeout WDT timeout\n");

#ifdef ONLY_TESTING
	printk(KERN_CRIT "Would Reboot.\n");
#else
	printk(KERN_CRIT "Initiating system reboot.\n");
	machine_restart(NULL);
#endif
	return IRQ_HANDLED;
}


/**
 * eurwdt_ping:
 *
 * Reload counter one with the watchdog timeout.
 */

static void eurwdt_ping(void)
{
	/* Write the watchdog default value */
	eurwdt_set_timeout(eurwdt_timeout);
}

/**
 * eurwdt_write:
 * @file: file handle to the watchdog
 * @buf: buffer to write (unused as data does not matter here
 * @count: count of bytes
 * @ppos: pointer to the position to write. No seeks allowed
 *
 * A write to a watchdog device is defined as a keepalive signal. Any
 * write of data will do, as we we don't define content meaning.
 */

static ssize_t eurwdt_write(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
	if (count) 	{
		if (!nowayout) {
			size_t i;

			eur_expect_close = 0;

			for (i = 0; i != count; i++) {
				char c;
				if(get_user(c, buf+i))
					return -EFAULT;
				if (c == 'V')
					eur_expect_close = 42;
			}
		}
		eurwdt_ping();	/* the default timeout */
	}

	return count;
}

/**
 * eurwdt_ioctl:
 * @inode: inode of the device
 * @file: file handle to the device
 * @cmd: watchdog command
 * @arg: argument pointer
 *
 * The watchdog API defines a common set of functions for all watchdogs
 * according to their available features.
 */

static int eurwdt_ioctl(struct inode *inode, struct file *file,
	unsigned int cmd, unsigned long arg)
{
	void __user *argp = (void __user *)arg;
	int __user *p = argp;
	static struct watchdog_info ident = {
		.options	  = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE,
		.firmware_version = 1,
		.identity	  = "WDT Eurotech CPU-1220/1410",
	};

	int time;
	int options, retval = -EINVAL;

	switch(cmd) {
	default:
		return -ENOIOCTLCMD;

	case WDIOC_GETSUPPORT:
		return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;

	case WDIOC_GETSTATUS:
	case WDIOC_GETBOOTSTATUS:
		return put_user(0, p);

	case WDIOC_KEEPALIVE:
		eurwdt_ping();
		return 0;

	case WDIOC_SETTIMEOUT:
		if (copy_from_user(&time, p, sizeof(int)))
			return -EFAULT;

		/* Sanity check */
		if (time < 0 || time > 255)
			return -EINVAL;

		eurwdt_timeout = time;
		eurwdt_set_timeout(time);
		/* Fall */

	case WDIOC_GETTIMEOUT:
		return put_user(eurwdt_timeout, p);

	case WDIOC_SETOPTIONS:
		if (get_user(options, p))
			return -EFAULT;
		if (options & WDIOS_DISABLECARD) {
			eurwdt_disable_timer();
			retval = 0;
		}
		if (options & WDIOS_ENABLECARD) {
			eurwdt_activate_timer();
			eurwdt_ping();
			retval = 0;
		}
		return retval;
	}
}

/**
 * eurwdt_open:
 * @inode: inode of device
 * @file: file handle to device
 *
 * The misc device has been opened. The watchdog device is single
 * open and on opening we load the counter.
 */

static int eurwdt_open(struct inode *inode, struct file *file)
{
	if (test_and_set_bit(0, &eurwdt_is_open))
		return -EBUSY;
	eurwdt_timeout = WDT_TIMEOUT;	/* initial timeout */
	/* Activate the WDT */
	eurwdt_activate_timer();
	return nonseekable_open(inode, file);
}

/**
 * eurwdt_release:
 * @inode: inode to board
 * @file: file handle to board
 *
 * The watchdog has a configurable API. There is a religious dispute
 * between people who want their watchdog to be able to shut down and
 * those who want to be sure if the watchdog manager dies the machine
 * reboots. In the former case we disable the counters, in the latter
 * case you have to open it again very soon.
 */

static int eurwdt_release(struct inode *inode, struct file *file)
{
	if (eur_expect_close == 42) {
		eurwdt_disable_timer();
	} else {
		printk(KERN_CRIT "eurwdt: Unexpected close, not stopping watchdog!\n");
		eurwdt_ping();
	}
	clear_bit(0, &eurwdt_is_open);
	eur_expect_close = 0;
	return 0;
}

/**
 * eurwdt_notify_sys:
 * @this: our notifier block
 * @code: the event being reported
 * @unused: unused
 *
 * Our notifier is called on system shutdowns. We want to turn the card
 * off at reboot otherwise the machine will reboot again during memory
 * test or worse yet during the following fsck. This would suck, in fact
 * trust me - if it happens it does suck.
 */

static int eurwdt_notify_sys(struct notifier_block *this, unsigned long code,
	void *unused)
{
	if (code == SYS_DOWN || code == SYS_HALT) {
		/* Turn the card off */
		eurwdt_disable_timer();
	}

	return NOTIFY_DONE;
}

/*
 * Kernel Interfaces
 */


static struct file_operations eurwdt_fops = {
	.owner	= THIS_MODULE,
	.llseek	= no_llseek,
	.write	= eurwdt_write,
	.ioctl	= eurwdt_ioctl,
	.open	= eurwdt_open,
	.release	= eurwdt_release,
};

static struct miscdevice eurwdt_miscdev = {
	.minor	= WATCHDOG_MINOR,
	.name	= "watchdog",
	.fops	= &eurwdt_fops,
};

/*
 * The WDT card needs to learn about soft shutdowns in order to
 * turn the timebomb registers off.
 */

static struct notifier_block eurwdt_notifier = {
	.notifier_call = eurwdt_notify_sys,
};

/**
 * cleanup_module:
 *
 * Unload the watchdog. You cannot do this with any file handles open.
 * If your watchdog is set to continue ticking on close and you unload
 * it, well it keeps ticking. We won't get the interrupt but the board
 * will not touch PC memory so all is fine. You just have to load a new
 * module in 60 seconds or reboot.
 */

static void __exit eurwdt_exit(void)
{
	eurwdt_lock_chip();

	misc_deregister(&eurwdt_miscdev);

	unregister_reboot_notifier(&eurwdt_notifier);
	release_region(io, 2);
	free_irq(irq, NULL);
}

/**
 * eurwdt_init:
 *
 * Set up the WDT watchdog board. After grabbing the resources
 * we require we need also to unlock the device.
 * The open() function will actually kick the board off.
 */

static int __init eurwdt_init(void)
{
	int ret;

	ret = misc_register(&eurwdt_miscdev);
	if (ret) {
		printk(KERN_ERR "eurwdt: can't misc_register on minor=%d\n",
		WATCHDOG_MINOR);
		goto out;
	}

	ret = request_irq(irq, eurwdt_interrupt, SA_INTERRUPT, "eurwdt", NULL);
	if(ret) {
		printk(KERN_ERR "eurwdt: IRQ %d is not free.\n", irq);
		goto outmisc;
	}

	if (!request_region(io, 2, "eurwdt")) {
		printk(KERN_ERR "eurwdt: IO %X is not free.\n", io);
		ret = -EBUSY;
		goto outirq;
	}

	ret = register_reboot_notifier(&eurwdt_notifier);
	if (ret) {
		printk(KERN_ERR "eurwdt: can't register reboot notifier (err=%d)\n", ret);
		goto outreg;
	}

	eurwdt_unlock_chip();

	ret = 0;
	printk(KERN_INFO "Eurotech WDT driver 0.01 at %X (Interrupt %d)"
		" - timeout event: %s\n",
		io, irq, (!strcmp("int", ev) ? "int" : "reboot"));

out:
	return ret;

outreg:
	release_region(io, 2);

outirq:
	free_irq(irq, NULL);

outmisc:
	misc_deregister(&eurwdt_miscdev);
	goto out;
}

module_init(eurwdt_init);
module_exit(eurwdt_exit);

MODULE_AUTHOR("Rodolfo Giometti");
MODULE_DESCRIPTION("Driver for Eurotech CPU-1220/1410 on board watchdog");
MODULE_LICENSE("GPL");
MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
