/*
 * mpc8xx_wdt.c - MPC8xx watchdog userspace interface
 *
 * Author: Florian Schirmer <jolt@tuxbox.org>
 *
 * 2002 (c) Florian Schirmer <jolt@tuxbox.org> This file is licensed under
 * the terms of the GNU General Public License version 2. This program
 * is licensed "as is" without any warranty of any kind, whether express
 * or implied.
 */

#include <linux/fs.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/miscdevice.h>
#include <linux/module.h>
#include <linux/watchdog.h>
#include <asm/8xx_immap.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include <syslib/m8xx_wdt.h>

static unsigned long wdt_opened;
static int wdt_status;
static spinlock_t wdt_lock;

static void mpc8xx_wdt_handler_disable(void)
{
	volatile uint __iomem *piscr;
	piscr = (uint *)&((immap_t *)IMAP_ADDR)->im_sit.sit_piscr;

	if (!m8xx_has_internal_rtc)
		m8xx_wdt_stop_timer();
	else
		out_be32(piscr, in_be32(piscr) & ~(PISCR_PIE | PISCR_PTE));
	printk(KERN_NOTICE "mpc8xx_wdt: keep-alive handler deactivated\n");
}

static void mpc8xx_wdt_handler_enable(void)
{
	volatile uint __iomem *piscr;
	piscr = (uint *)&((immap_t *)IMAP_ADDR)->im_sit.sit_piscr;

	if (!m8xx_has_internal_rtc)
		m8xx_wdt_install_timer();
	else
		out_be32(piscr, in_be32(piscr) | PISCR_PIE | PISCR_PTE);
	printk(KERN_NOTICE "mpc8xx_wdt: keep-alive handler activated\n");
}

static int mpc8xx_wdt_open(struct inode *inode, struct file *file)
{
	if (test_and_set_bit(0, &wdt_opened))
		return -EBUSY;
	m8xx_wdt_reset();
	mpc8xx_wdt_handler_disable();
	return nonseekable_open(inode, file);
}

static int mpc8xx_wdt_release(struct inode *inode, struct file *file)
{
	m8xx_wdt_reset();
#if !defined(CONFIG_WATCHDOG_NOWAYOUT)
	mpc8xx_wdt_handler_enable();
#endif
	clear_bit(0, &wdt_opened);
	return 0;
}

static ssize_t mpc8xx_wdt_write(struct file *file, const char *data,
						size_t len, loff_t *ppos)
{
	if (len) {
		spin_lock(&wdt_lock);
		m8xx_wdt_reset();
		spin_unlock(&wdt_lock);
	}
	return len;
}

static long mpc8xx_wdt_ioctl(struct file *file,
					unsigned int cmd, unsigned long arg)
{
	int timeout;
	static struct watchdog_info info = {
		.options = WDIOF_KEEPALIVEPING,
		.firmware_version = 0,
		.identity = "MPC8xx watchdog",
	};

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

	case WDIOC_GETSTATUS:
	case WDIOC_GETBOOTSTATUS:
		if (put_user(wdt_status, (int *)arg))
			return -EFAULT;
		wdt_status &= ~WDIOF_KEEPALIVEPING;
		break;

	case WDIOC_GETTEMP:
		return -EOPNOTSUPP;

	case WDIOC_SETOPTIONS:
		return -EOPNOTSUPP;

	case WDIOC_KEEPALIVE:
		spin_lock(&wdt_lock);
		m8xx_wdt_reset();
		wdt_status |= WDIOF_KEEPALIVEPING;
		spin_unlock(&wdt_lock);
		break;

	case WDIOC_SETTIMEOUT:
		return -EOPNOTSUPP;

	case WDIOC_GETTIMEOUT:
		spin_lock(&wdt_lock);
		timeout = m8xx_wdt_get_timeout();
		spin_unlock(&wdt_lock);
		if (put_user(timeout, (int *)arg))
			return -EFAULT;
		break;

	default:
		return -ENOTTY;
	}

	return 0;
}

static const struct file_operations mpc8xx_wdt_fops = {
	.owner = THIS_MODULE,
	.llseek = no_llseek,
	.write = mpc8xx_wdt_write,
	.unlocked_ioctl = mpc8xx_wdt_ioctl,
	.open = mpc8xx_wdt_open,
	.release = mpc8xx_wdt_release,
};

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

static int __init mpc8xx_wdt_init(void)
{
	spin_lock_init(&wdt_lock);
	return misc_register(&mpc8xx_wdt_miscdev);
}

static void __exit mpc8xx_wdt_exit(void)
{
	misc_deregister(&mpc8xx_wdt_miscdev);

	m8xx_wdt_reset();
	mpc8xx_wdt_handler_enable();
}

module_init(mpc8xx_wdt_init);
module_exit(mpc8xx_wdt_exit);

MODULE_AUTHOR("Florian Schirmer <jolt@tuxbox.org>");
MODULE_DESCRIPTION("MPC8xx watchdog driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
