/*
 * Copyright (c) 2009 Nuvoton technology corporation.
 *
 * Wan ZongShun <mcuos.com@gmail.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;version 2 of the License.
 *
 */

#include <linux/bitops.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/io.h>
#include <linux/clk.h>
#include <linux/kernel.h>
#include <linux/miscdevice.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/types.h>
#include <linux/watchdog.h>
#include <linux/uaccess.h>

#define REG_WTCR		0x1c
#define WTCLK			(0x01 << 10)
#define WTE			(0x01 << 7)	/*wdt enable*/
#define WTIS			(0x03 << 4)
#define WTIF			(0x01 << 3)
#define WTRF			(0x01 << 2)
#define WTRE			(0x01 << 1)
#define WTR			(0x01 << 0)
/*
 * The watchdog time interval can be calculated via following formula:
 * WTIS		real time interval (formula)
 * 0x00		((2^ 14 ) * ((external crystal freq) / 256))seconds
 * 0x01		((2^ 16 ) * ((external crystal freq) / 256))seconds
 * 0x02		((2^ 18 ) * ((external crystal freq) / 256))seconds
 * 0x03		((2^ 20 ) * ((external crystal freq) / 256))seconds
 *
 * The external crystal freq is 15Mhz in the nuc900 evaluation board.
 * So 0x00 = +-0.28 seconds, 0x01 = +-1.12 seconds, 0x02 = +-4.48 seconds,
 * 0x03 = +- 16.92 seconds..
 */
#define WDT_HW_TIMEOUT		0x02
#define WDT_TIMEOUT		(HZ/2)
#define WDT_HEARTBEAT		15

static int heartbeat = WDT_HEARTBEAT;
module_param(heartbeat, int, 0);
MODULE_PARM_DESC(heartbeat, "Watchdog heartbeats in seconds. "
	"(default = " __MODULE_STRING(WDT_HEARTBEAT) ")");

static bool nowayout = WATCHDOG_NOWAYOUT;
module_param(nowayout, bool, 0);
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started "
	"(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");

struct nuc900_wdt {
	struct clk	 *wdt_clock;
	struct platform_device *pdev;
	void __iomem	 *wdt_base;
	char		 expect_close;
	struct timer_list timer;
	spinlock_t       wdt_lock;
	unsigned long next_heartbeat;
};

static unsigned long nuc900wdt_busy;
static struct nuc900_wdt *nuc900_wdt;

static inline void nuc900_wdt_keepalive(void)
{
	unsigned int val;

	spin_lock(&nuc900_wdt->wdt_lock);

	val = __raw_readl(nuc900_wdt->wdt_base + REG_WTCR);
	val |= (WTR | WTIF);
	__raw_writel(val, nuc900_wdt->wdt_base + REG_WTCR);

	spin_unlock(&nuc900_wdt->wdt_lock);
}

static inline void nuc900_wdt_start(void)
{
	unsigned int val;

	spin_lock(&nuc900_wdt->wdt_lock);

	val = __raw_readl(nuc900_wdt->wdt_base + REG_WTCR);
	val |= (WTRE | WTE | WTR | WTCLK | WTIF);
	val &= ~WTIS;
	val |= (WDT_HW_TIMEOUT << 0x04);
	__raw_writel(val, nuc900_wdt->wdt_base + REG_WTCR);

	spin_unlock(&nuc900_wdt->wdt_lock);

	nuc900_wdt->next_heartbeat = jiffies + heartbeat * HZ;
	mod_timer(&nuc900_wdt->timer, jiffies + WDT_TIMEOUT);
}

static inline void nuc900_wdt_stop(void)
{
	unsigned int val;

	del_timer(&nuc900_wdt->timer);

	spin_lock(&nuc900_wdt->wdt_lock);

	val = __raw_readl(nuc900_wdt->wdt_base + REG_WTCR);
	val &= ~WTE;
	__raw_writel(val, nuc900_wdt->wdt_base + REG_WTCR);

	spin_unlock(&nuc900_wdt->wdt_lock);
}

static inline void nuc900_wdt_ping(void)
{
	nuc900_wdt->next_heartbeat = jiffies + heartbeat * HZ;
}

static int nuc900_wdt_open(struct inode *inode, struct file *file)
{

	if (test_and_set_bit(0, &nuc900wdt_busy))
		return -EBUSY;

	nuc900_wdt_start();

	return nonseekable_open(inode, file);
}

static int nuc900_wdt_close(struct inode *inode, struct file *file)
{
	if (nuc900_wdt->expect_close == 42)
		nuc900_wdt_stop();
	else {
		dev_crit(&nuc900_wdt->pdev->dev,
			"Unexpected close, not stopping watchdog!\n");
		nuc900_wdt_ping();
	}

	nuc900_wdt->expect_close = 0;
	clear_bit(0, &nuc900wdt_busy);
	return 0;
}

static const struct watchdog_info nuc900_wdt_info = {
	.identity	= "nuc900 watchdog",
	.options	= WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING |
						WDIOF_MAGICCLOSE,
};

static long nuc900_wdt_ioctl(struct file *file,
					unsigned int cmd, unsigned long arg)
{
	void __user *argp = (void __user *)arg;
	int __user *p = argp;
	int new_value;

	switch (cmd) {
	case WDIOC_GETSUPPORT:
		return copy_to_user(argp, &nuc900_wdt_info,
				sizeof(nuc900_wdt_info)) ? -EFAULT : 0;
	case WDIOC_GETSTATUS:
	case WDIOC_GETBOOTSTATUS:
		return put_user(0, p);

	case WDIOC_KEEPALIVE:
		nuc900_wdt_ping();
		return 0;

	case WDIOC_SETTIMEOUT:
		if (get_user(new_value, p))
			return -EFAULT;

		heartbeat = new_value;
		nuc900_wdt_ping();

		return put_user(new_value, p);
	case WDIOC_GETTIMEOUT:
		return put_user(heartbeat, p);
	default:
		return -ENOTTY;
	}
}

static ssize_t nuc900_wdt_write(struct file *file, const char __user *data,
						size_t len, loff_t *ppos)
{
	if (!len)
		return 0;

	/* Scan for magic character */
	if (!nowayout) {
		size_t i;

		nuc900_wdt->expect_close = 0;

		for (i = 0; i < len; i++) {
			char c;
			if (get_user(c, data + i))
				return -EFAULT;
			if (c == 'V') {
				nuc900_wdt->expect_close = 42;
				break;
			}
		}
	}

	nuc900_wdt_ping();
	return len;
}

static void nuc900_wdt_timer_ping(struct timer_list *unused)
{
	if (time_before(jiffies, nuc900_wdt->next_heartbeat)) {
		nuc900_wdt_keepalive();
		mod_timer(&nuc900_wdt->timer, jiffies + WDT_TIMEOUT);
	} else
		dev_warn(&nuc900_wdt->pdev->dev, "Will reset the machine !\n");
}

static const struct file_operations nuc900wdt_fops = {
	.owner		= THIS_MODULE,
	.llseek		= no_llseek,
	.unlocked_ioctl	= nuc900_wdt_ioctl,
	.open		= nuc900_wdt_open,
	.release	= nuc900_wdt_close,
	.write		= nuc900_wdt_write,
};

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

static int nuc900wdt_probe(struct platform_device *pdev)
{
	struct resource *res;
	int ret = 0;

	nuc900_wdt = devm_kzalloc(&pdev->dev, sizeof(*nuc900_wdt),
				GFP_KERNEL);
	if (!nuc900_wdt)
		return -ENOMEM;

	nuc900_wdt->pdev = pdev;

	spin_lock_init(&nuc900_wdt->wdt_lock);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	nuc900_wdt->wdt_base = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(nuc900_wdt->wdt_base))
		return PTR_ERR(nuc900_wdt->wdt_base);

	nuc900_wdt->wdt_clock = devm_clk_get(&pdev->dev, NULL);
	if (IS_ERR(nuc900_wdt->wdt_clock)) {
		dev_err(&pdev->dev, "failed to find watchdog clock source\n");
		return PTR_ERR(nuc900_wdt->wdt_clock);
	}

	clk_enable(nuc900_wdt->wdt_clock);

	timer_setup(&nuc900_wdt->timer, nuc900_wdt_timer_ping, 0);

	ret = misc_register(&nuc900wdt_miscdev);
	if (ret) {
		dev_err(&pdev->dev, "err register miscdev on minor=%d (%d)\n",
			WATCHDOG_MINOR, ret);
		goto err_clk;
	}

	return 0;

err_clk:
	clk_disable(nuc900_wdt->wdt_clock);
	return ret;
}

static int nuc900wdt_remove(struct platform_device *pdev)
{
	misc_deregister(&nuc900wdt_miscdev);

	clk_disable(nuc900_wdt->wdt_clock);

	return 0;
}

static struct platform_driver nuc900wdt_driver = {
	.probe		= nuc900wdt_probe,
	.remove		= nuc900wdt_remove,
	.driver		= {
		.name	= "nuc900-wdt",
	},
};

module_platform_driver(nuc900wdt_driver);

MODULE_AUTHOR("Wan ZongShun <mcuos.com@gmail.com>");
MODULE_DESCRIPTION("Watchdog driver for NUC900");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:nuc900-wdt");
