/*
 *	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");
	emergency_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);
