/*
 * mv64x60_wdt.c - MV64X60 (Marvell Discovery) watchdog userspace interface
 *
 * Author: James Chapman <jchapman@katalix.com>
 *
 * Platform-specific setup code should configure the dog to generate
 * interrupt or reset as required.  This code only enables/disables
 * and services the watchdog.
 *
 * Derived from mpc8xx_wdt.c, with the following copyright.
 * 
 * 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 <linux/platform_device.h>

#include <asm/mv64x60.h>
#include <asm/uaccess.h>
#include <asm/io.h>

/* MV64x60 WDC (config) register access definitions */
#define MV64x60_WDC_CTL1_MASK	(3 << 24)
#define MV64x60_WDC_CTL1(val)	((val & 3) << 24)
#define MV64x60_WDC_CTL2_MASK	(3 << 26)
#define MV64x60_WDC_CTL2(val)	((val & 3) << 26)

/* Flags bits */
#define MV64x60_WDOG_FLAG_OPENED	0
#define MV64x60_WDOG_FLAG_ENABLED	1

static unsigned long wdt_flags;
static int wdt_status;
static void __iomem *mv64x60_regs;
static int mv64x60_wdt_timeout;

static void mv64x60_wdt_reg_write(u32 val)
{
	/* Allow write only to CTL1 / CTL2 fields, retaining values in
	 * other fields.
	 */
	u32 data = readl(mv64x60_regs + MV64x60_WDT_WDC);
	data &= ~(MV64x60_WDC_CTL1_MASK | MV64x60_WDC_CTL2_MASK);
	data |= val;
	writel(data, mv64x60_regs + MV64x60_WDT_WDC);
}

static void mv64x60_wdt_service(void)
{
	/* Write 01 followed by 10 to CTL2 */
	mv64x60_wdt_reg_write(MV64x60_WDC_CTL2(0x01));
	mv64x60_wdt_reg_write(MV64x60_WDC_CTL2(0x02));
}

static void mv64x60_wdt_handler_disable(void)
{
	if (test_and_clear_bit(MV64x60_WDOG_FLAG_ENABLED, &wdt_flags)) {
		/* Write 01 followed by 10 to CTL1 */
		mv64x60_wdt_reg_write(MV64x60_WDC_CTL1(0x01));
		mv64x60_wdt_reg_write(MV64x60_WDC_CTL1(0x02));
		printk(KERN_NOTICE "mv64x60_wdt: watchdog deactivated\n");
	}
}

static void mv64x60_wdt_handler_enable(void)
{
	if (!test_and_set_bit(MV64x60_WDOG_FLAG_ENABLED, &wdt_flags)) {
		/* Write 01 followed by 10 to CTL1 */
		mv64x60_wdt_reg_write(MV64x60_WDC_CTL1(0x01));
		mv64x60_wdt_reg_write(MV64x60_WDC_CTL1(0x02));
		printk(KERN_NOTICE "mv64x60_wdt: watchdog activated\n");
	}
}

static int mv64x60_wdt_open(struct inode *inode, struct file *file)
{
	if (test_and_set_bit(MV64x60_WDOG_FLAG_OPENED, &wdt_flags))
		return -EBUSY;

	mv64x60_wdt_service();
	mv64x60_wdt_handler_enable();

	nonseekable_open(inode, file);

	return 0;
}

static int mv64x60_wdt_release(struct inode *inode, struct file *file)
{
	mv64x60_wdt_service();

#if !defined(CONFIG_WATCHDOG_NOWAYOUT)
	mv64x60_wdt_handler_disable();
#endif

	clear_bit(MV64x60_WDOG_FLAG_OPENED, &wdt_flags);

	return 0;
}

static ssize_t mv64x60_wdt_write(struct file *file, const char __user *data,
				 size_t len, loff_t * ppos)
{
	if (len)
		mv64x60_wdt_service();

	return len;
}

static int mv64x60_wdt_ioctl(struct inode *inode, struct file *file,
			     unsigned int cmd, unsigned long arg)
{
	int timeout;
	void __user *argp = (void __user *)arg;
	static struct watchdog_info info = {
		.options = WDIOF_KEEPALIVEPING,
		.firmware_version = 0,
		.identity = "MV64x60 watchdog",
	};

	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(wdt_status, (int __user *)argp))
			return -EFAULT;
		wdt_status &= ~WDIOF_KEEPALIVEPING;
		break;

	case WDIOC_GETTEMP:
		return -EOPNOTSUPP;

	case WDIOC_SETOPTIONS:
		return -EOPNOTSUPP;

	case WDIOC_KEEPALIVE:
		mv64x60_wdt_service();
		wdt_status |= WDIOF_KEEPALIVEPING;
		break;

	case WDIOC_SETTIMEOUT:
		return -EOPNOTSUPP;

	case WDIOC_GETTIMEOUT:
		timeout = mv64x60_wdt_timeout * HZ;
		if (put_user(timeout, (int __user *)argp))
			return -EFAULT;
		break;

	default:
		return -ENOTTY;
	}

	return 0;
}

static const struct file_operations mv64x60_wdt_fops = {
	.owner = THIS_MODULE,
	.llseek = no_llseek,
	.write = mv64x60_wdt_write,
	.ioctl = mv64x60_wdt_ioctl,
	.open = mv64x60_wdt_open,
	.release = mv64x60_wdt_release,
};

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

static int __devinit mv64x60_wdt_probe(struct platform_device *dev)
{
	struct mv64x60_wdt_pdata *pdata = dev->dev.platform_data;
	int bus_clk = 133;

	mv64x60_wdt_timeout = 10;
	if (pdata) {
		mv64x60_wdt_timeout = pdata->timeout;
		bus_clk = pdata->bus_clk;
	}

	mv64x60_regs = mv64x60_get_bridge_vbase();

	writel((mv64x60_wdt_timeout * (bus_clk * 1000000)) >> 8,
	       mv64x60_regs + MV64x60_WDT_WDC);

	return misc_register(&mv64x60_wdt_miscdev);
}

static int __devexit mv64x60_wdt_remove(struct platform_device *dev)
{
	misc_deregister(&mv64x60_wdt_miscdev);

	mv64x60_wdt_service();
	mv64x60_wdt_handler_disable();

	return 0;
}

static struct platform_driver mv64x60_wdt_driver = {
	.probe = mv64x60_wdt_probe,
	.remove = __devexit_p(mv64x60_wdt_remove),
	.driver = {
		.owner = THIS_MODULE,
		.name = MV64x60_WDT_NAME,
	},
};

static struct platform_device *mv64x60_wdt_dev;

static int __init mv64x60_wdt_init(void)
{
	int ret;

	printk(KERN_INFO "MV64x60 watchdog driver\n");

	mv64x60_wdt_dev = platform_device_alloc(MV64x60_WDT_NAME, -1);
	if (!mv64x60_wdt_dev) {
		ret = -ENOMEM;
		goto out;
	}

	ret = platform_device_add(mv64x60_wdt_dev);
	if (ret) {
		platform_device_put(mv64x60_wdt_dev);
		goto out;
	}

	ret = platform_driver_register(&mv64x60_wdt_driver);
	if (ret) {
		platform_device_unregister(mv64x60_wdt_dev);
		goto out;
	}

 out:
	return ret;
}

static void __exit mv64x60_wdt_exit(void)
{
	platform_driver_unregister(&mv64x60_wdt_driver);
	platform_device_unregister(mv64x60_wdt_dev);
}

module_init(mv64x60_wdt_init);
module_exit(mv64x60_wdt_exit);

MODULE_AUTHOR("James Chapman <jchapman@katalix.com>");
MODULE_DESCRIPTION("MV64x60 watchdog driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
