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

static int nowayout = WATCHDOG_NOWAYOUT;
module_param(nowayout, int, 0);
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(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)
{
	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();
#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 -ENOTTY;

	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 const 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, IRQF_DISABLED, "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);
