/* $Id: riowatchdog.c,v 1.3.2.2 2002/01/23 18:48:02 davem Exp $
 * riowatchdog.c - driver for hw watchdog inside Super I/O of RIO
 *
 * Copyright (C) 2001 David S. Miller (davem@redhat.com)
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/miscdevice.h>
#include <linux/smp_lock.h>

#include <asm/io.h>
#include <asm/ebus.h>
#include <asm/bbc.h>
#include <asm/oplib.h>
#include <asm/uaccess.h>

#include <asm/watchdog.h>

/* RIO uses the NatSemi Super I/O power management logical device
 * as its' watchdog.
 *
 * When the watchdog triggers, it asserts a line to the BBC (Boot Bus
 * Controller) of the machine.  The BBC can only be configured to
 * trigger a power-on reset when the signal is asserted.  The BBC
 * can be configured to ignore the signal entirely as well.
 *
 * The only Super I/O device register we care about is at index
 * 0x05 (WDTO_INDEX) which is the watchdog time-out in minutes (1-255).
 * If set to zero, this disables the watchdog.  When set, the system
 * must periodically (before watchdog expires) clear (set to zero) and
 * re-set the watchdog else it will trigger.
 *
 * There are two other indexed watchdog registers inside this Super I/O
 * logical device, but they are unused.  The first, at index 0x06 is
 * the watchdog control and can be used to make the watchdog timer re-set
 * when the PS/2 mouse or serial lines show activity.  The second, at
 * index 0x07 is merely a sampling of the line from the watchdog to the
 * BBC.
 *
 * The watchdog device generates no interrupts.
 */

MODULE_AUTHOR("David S. Miller <davem@redhat.com>");
MODULE_DESCRIPTION("Hardware watchdog driver for Sun RIO");
MODULE_SUPPORTED_DEVICE("watchdog");
MODULE_LICENSE("GPL");

#define RIOWD_NAME	"pmc"
#define RIOWD_MINOR	215

static DEFINE_SPINLOCK(riowd_lock);

static void __iomem *bbc_regs;
static void __iomem *riowd_regs;
#define WDTO_INDEX	0x05

static int riowd_timeout = 1;		/* in minutes */
module_param(riowd_timeout, int, 0);
MODULE_PARM_DESC(riowd_timeout, "Watchdog timeout in minutes");

#if 0 /* Currently unused. */
static u8 riowd_readreg(int index)
{
	unsigned long flags;
	u8 ret;

	spin_lock_irqsave(&riowd_lock, flags);
	writeb(index, riowd_regs + 0);
	ret = readb(riowd_regs + 1);
	spin_unlock_irqrestore(&riowd_lock, flags);

	return ret;
}
#endif

static void riowd_writereg(u8 val, int index)
{
	unsigned long flags;

	spin_lock_irqsave(&riowd_lock, flags);
	writeb(index, riowd_regs + 0);
	writeb(val, riowd_regs + 1);
	spin_unlock_irqrestore(&riowd_lock, flags);
}

static void riowd_pingtimer(void)
{
	riowd_writereg(riowd_timeout, WDTO_INDEX);
}

static void riowd_stoptimer(void)
{
	u8 val;

	riowd_writereg(0, WDTO_INDEX);

	val = readb(bbc_regs + BBC_WDACTION);
	val &= ~BBC_WDACTION_RST;
	writeb(val, bbc_regs + BBC_WDACTION);
}

static void riowd_starttimer(void)
{
	u8 val;

	riowd_writereg(riowd_timeout, WDTO_INDEX);

	val = readb(bbc_regs + BBC_WDACTION);
	val |= BBC_WDACTION_RST;
	writeb(val, bbc_regs + BBC_WDACTION);
}

static int riowd_open(struct inode *inode, struct file *filp)
{
	cycle_kernel_lock();
	nonseekable_open(inode, filp);
	return 0;
}

static int riowd_release(struct inode *inode, struct file *filp)
{
	return 0;
}

static int riowd_ioctl(struct inode *inode, struct file *filp,
		       unsigned int cmd, unsigned long arg)
{
	static struct watchdog_info info = {
	       	WDIOF_SETTIMEOUT, 0, "Natl. Semiconductor PC97317"
	};
	void __user *argp = (void __user *)arg;
	unsigned int options;
	int new_margin;

	switch (cmd) {
	case WDIOC_GETSUPPORT:
		if (copy_to_user(argp, &info, sizeof(info)))
			return -EFAULT;
		break;

	case WDIOC_GETSTATUS:
	case WDIOC_GETBOOTSTATUS:
		if (put_user(0, (int __user *)argp))
			return -EFAULT;
		break;

	case WDIOC_KEEPALIVE:
		riowd_pingtimer();
		break;

	case WDIOC_SETOPTIONS:
		if (copy_from_user(&options, argp, sizeof(options)))
			return -EFAULT;

		if (options & WDIOS_DISABLECARD)
			riowd_stoptimer();
		else if (options & WDIOS_ENABLECARD)
			riowd_starttimer();
		else
			return -EINVAL;

		break;

	case WDIOC_SETTIMEOUT:
		if (get_user(new_margin, (int __user *)argp))
			return -EFAULT;
		if ((new_margin < 60) || (new_margin > (255 * 60)))
		    return -EINVAL;
		riowd_timeout = (new_margin + 59) / 60;
		riowd_pingtimer();
		/* Fall */

	case WDIOC_GETTIMEOUT:
		return put_user(riowd_timeout * 60, (int __user *)argp);

	default:
		return -EINVAL;
	};

	return 0;
}

static ssize_t riowd_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
{
	if (count) {
		riowd_pingtimer();
		return 1;
	}

	return 0;
}

static const struct file_operations riowd_fops = {
	.owner =	THIS_MODULE,
	.ioctl =	riowd_ioctl,
	.open =		riowd_open,
	.write =	riowd_write,
	.release =	riowd_release,
};

static struct miscdevice riowd_miscdev = { RIOWD_MINOR, RIOWD_NAME, &riowd_fops };

static int __init riowd_bbc_init(void)
{
	struct 	linux_ebus *ebus = NULL;
	struct 	linux_ebus_device *edev = NULL;
	u8 val;

	for_each_ebus(ebus) {
		for_each_ebusdev(edev, ebus) {
			if (!strcmp(edev->ofdev.node->name, "bbc"))
				goto found_bbc;
		}
	}

found_bbc:
	if (!edev)
		return -ENODEV;
	bbc_regs = ioremap(edev->resource[0].start, BBC_REGS_SIZE);
	if (!bbc_regs)
		return -ENODEV;

	/* Turn it off. */
	val = readb(bbc_regs + BBC_WDACTION);
	val &= ~BBC_WDACTION_RST;
	writeb(val, bbc_regs + BBC_WDACTION);

	return 0;
}

static int __init riowd_init(void)
{
	struct 	linux_ebus *ebus = NULL;
	struct 	linux_ebus_device *edev = NULL;

	for_each_ebus(ebus) {
		for_each_ebusdev(edev, ebus) {
			if (!strcmp(edev->ofdev.node->name, RIOWD_NAME))
				goto ebus_done;
		}
	}

ebus_done:
	if (!edev)
		goto fail;

	riowd_regs = ioremap(edev->resource[0].start, 2);
	if (riowd_regs == NULL) {
		printk(KERN_ERR "pmc: Cannot map registers.\n");
		return -ENODEV;
	}

	if (riowd_bbc_init()) {
		printk(KERN_ERR "pmc: Failure initializing BBC config.\n");
		goto fail;
	}

	if (misc_register(&riowd_miscdev)) {
		printk(KERN_ERR "pmc: Cannot register watchdog misc device.\n");
		goto fail;
	}

	printk(KERN_INFO "pmc: Hardware watchdog [%i minutes], "
	       "regs at %p\n", riowd_timeout, riowd_regs);

	return 0;

fail:
	if (riowd_regs) {
		iounmap(riowd_regs);
		riowd_regs = NULL;
	}
	if (bbc_regs) {
		iounmap(bbc_regs);
		bbc_regs = NULL;
	}
	return -ENODEV;
}

static void __exit riowd_cleanup(void)
{
	misc_deregister(&riowd_miscdev);
	iounmap(riowd_regs);
	riowd_regs = NULL;
	iounmap(bbc_regs);
	bbc_regs = NULL;
}

module_init(riowd_init);
module_exit(riowd_cleanup);
