/* riowd.c - driver for hw watchdog inside Super I/O of RIO
 *
 * Copyright (C) 2001, 2008 David S. Miller (davem@davemloft.net)
 */

#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 <linux/watchdog.h>
#include <linux/of.h>
#include <linux/of_device.h>

#include <asm/io.h>
#include <asm/uaccess.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@davemloft.net>");
MODULE_DESCRIPTION("Hardware watchdog driver for Sun RIO");
MODULE_SUPPORTED_DEVICE("watchdog");
MODULE_LICENSE("GPL");

#define DRIVER_NAME	"riowd"
#define PFX		DRIVER_NAME ": "

struct riowd {
	void __iomem		*regs;
	spinlock_t		lock;
};

static struct riowd *riowd_device;

#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");

static void riowd_writereg(struct riowd *p, u8 val, int index)
{
	unsigned long flags;

	spin_lock_irqsave(&p->lock, flags);
	writeb(index, p->regs + 0);
	writeb(val, p->regs + 1);
	spin_unlock_irqrestore(&p->lock, flags);
}

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 = {
		.options		= WDIOF_SETTIMEOUT,
		.firmware_version	= 1,
		.identity		= DRIVER_NAME,
	};
	void __user *argp = (void __user *)arg;
	struct riowd *p = riowd_device;
	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_writereg(p, riowd_timeout, WDTO_INDEX);
		break;

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

		if (options & WDIOS_DISABLECARD)
			riowd_writereg(p, 0, WDTO_INDEX);
		else if (options & WDIOS_ENABLECARD)
			riowd_writereg(p, riowd_timeout, WDTO_INDEX);
		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_writereg(p, riowd_timeout, WDTO_INDEX);
		/* 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)
{
	struct riowd *p = riowd_device;

	if (count) {
		riowd_writereg(p, riowd_timeout, WDTO_INDEX);
		return 1;
	}

	return 0;
}

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

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

static int __devinit riowd_probe(struct of_device *op,
				 const struct of_device_id *match)
{
	struct riowd *p;
	int err = -EINVAL;

	if (riowd_device)
		goto out;

	err = -ENOMEM;
	p = kzalloc(sizeof(*p), GFP_KERNEL);
	if (!p)
		goto out;

	spin_lock_init(&p->lock);

	p->regs = of_ioremap(&op->resource[0], 0, 2, DRIVER_NAME);
	if (!p->regs) {
		printk(KERN_ERR PFX "Cannot map registers.\n");
		goto out_free;
	}

	err = misc_register(&riowd_miscdev);
	if (err) {
		printk(KERN_ERR PFX "Cannot register watchdog misc device.\n");
		goto out_iounmap;
	}

	printk(KERN_INFO PFX "Hardware watchdog [%i minutes], "
	       "regs at %p\n", riowd_timeout, p->regs);

	dev_set_drvdata(&op->dev, p);
	riowd_device = p;
	err = 0;

out_iounmap:
	of_iounmap(&op->resource[0], p->regs, 2);

out_free:
	kfree(p);

out:
	return err;
}

static int __devexit riowd_remove(struct of_device *op)
{
	struct riowd *p = dev_get_drvdata(&op->dev);

	misc_deregister(&riowd_miscdev);
	of_iounmap(&op->resource[0], p->regs, 2);
	kfree(p);

	return 0;
}

static const struct of_device_id riowd_match[] = {
	{
		.name = "pmc",
	},
	{},
};
MODULE_DEVICE_TABLE(of, riowd_match);

static struct of_platform_driver riowd_driver = {
	.name		= DRIVER_NAME,
	.match_table	= riowd_match,
	.probe		= riowd_probe,
	.remove		= __devexit_p(riowd_remove),
};

static int __init riowd_init(void)
{
	return of_register_driver(&riowd_driver, &of_bus_type);
}

static void __exit riowd_exit(void)
{
	of_unregister_driver(&riowd_driver);
}

module_init(riowd_init);
module_exit(riowd_exit);
