/*
 * PIKA FPGA based Watchdog Timer
 *
 * Copyright (c) 2008 PIKA Technologies
 *   Sean MacLennan <smaclennan@pikatech.com>
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/init.h>
#include <linux/errno.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <linux/watchdog.h>
#include <linux/reboot.h>
#include <linux/jiffies.h>
#include <linux/timer.h>
#include <linux/bitops.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>

#define DRV_NAME "PIKA-WDT"

/* Hardware timeout in seconds */
#define WDT_HW_TIMEOUT 2

/* Timer heartbeat (500ms) */
#define WDT_TIMEOUT	(HZ/2)

/* User land timeout */
#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) ")");

static struct {
	void __iomem *fpga;
	unsigned long next_heartbeat;	/* the next_heartbeat for the timer */
	unsigned long open;
	char expect_close;
	int bootstatus;
	struct timer_list timer;	/* The timer that pings the watchdog */
} pikawdt_private;

static struct watchdog_info ident __ro_after_init = {
	.identity	= DRV_NAME,
	.options	= WDIOF_CARDRESET |
			  WDIOF_SETTIMEOUT |
			  WDIOF_KEEPALIVEPING |
			  WDIOF_MAGICCLOSE,
};

/*
 * Reload the watchdog timer.  (ie, pat the watchdog)
 */
static inline void pikawdt_reset(void)
{
	/* -- FPGA: Reset Control Register (32bit R/W) (Offset: 0x14) --
	 * Bit 7,    WTCHDG_EN: When set to 1, the watchdog timer is enabled.
	 *           Once enabled, it cannot be disabled. The watchdog can be
	 *           kicked by performing any write access to the reset
	 *           control register (this register).
	 * Bit 8-11, WTCHDG_TIMEOUT_SEC: Sets the watchdog timeout value in
	 *           seconds. Valid ranges are 1 to 15 seconds. The value can
	 *           be modified dynamically.
	 */
	unsigned reset = in_be32(pikawdt_private.fpga + 0x14);
	/* enable with max timeout - 15 seconds */
	reset |= (1 << 7) + (WDT_HW_TIMEOUT << 8);
	out_be32(pikawdt_private.fpga + 0x14, reset);
}

/*
 * Timer tick
 */
static void pikawdt_ping(unsigned long data)
{
	if (time_before(jiffies, pikawdt_private.next_heartbeat) ||
			(!nowayout && !pikawdt_private.open)) {
		pikawdt_reset();
		mod_timer(&pikawdt_private.timer, jiffies + WDT_TIMEOUT);
	} else
		pr_crit("I will reset your machine !\n");
}


static void pikawdt_keepalive(void)
{
	pikawdt_private.next_heartbeat = jiffies + heartbeat * HZ;
}

static void pikawdt_start(void)
{
	pikawdt_keepalive();
	mod_timer(&pikawdt_private.timer, jiffies + WDT_TIMEOUT);
}

/*
 * Watchdog device is opened, and watchdog starts running.
 */
static int pikawdt_open(struct inode *inode, struct file *file)
{
	/* /dev/watchdog can only be opened once */
	if (test_and_set_bit(0, &pikawdt_private.open))
		return -EBUSY;

	pikawdt_start();

	return nonseekable_open(inode, file);
}

/*
 * Close the watchdog device.
 */
static int pikawdt_release(struct inode *inode, struct file *file)
{
	/* stop internal ping */
	if (!pikawdt_private.expect_close)
		del_timer(&pikawdt_private.timer);

	clear_bit(0, &pikawdt_private.open);
	pikawdt_private.expect_close = 0;
	return 0;
}

/*
 * Pat the watchdog whenever device is written to.
 */
static ssize_t pikawdt_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;

		pikawdt_private.expect_close = 0;

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

	pikawdt_keepalive();

	return len;
}

/*
 * Handle commands from user-space.
 */
static long pikawdt_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, &ident, sizeof(ident)) ? -EFAULT : 0;

	case WDIOC_GETSTATUS:
		return put_user(0, p);

	case WDIOC_GETBOOTSTATUS:
		return put_user(pikawdt_private.bootstatus, p);

	case WDIOC_KEEPALIVE:
		pikawdt_keepalive();
		return 0;

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

		heartbeat = new_value;
		pikawdt_keepalive();

		return put_user(new_value, p);  /* return current value */

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


static const struct file_operations pikawdt_fops = {
	.owner		= THIS_MODULE,
	.llseek		= no_llseek,
	.open		= pikawdt_open,
	.release	= pikawdt_release,
	.write		= pikawdt_write,
	.unlocked_ioctl	= pikawdt_ioctl,
};

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

static int __init pikawdt_init(void)
{
	struct device_node *np;
	void __iomem *fpga;
	static u32 post1;
	int ret;

	np = of_find_compatible_node(NULL, NULL, "pika,fpga");
	if (np == NULL) {
		pr_err("Unable to find fpga\n");
		return -ENOENT;
	}

	pikawdt_private.fpga = of_iomap(np, 0);
	of_node_put(np);
	if (pikawdt_private.fpga == NULL) {
		pr_err("Unable to map fpga\n");
		return -ENOMEM;
	}

	ident.firmware_version = in_be32(pikawdt_private.fpga + 0x1c) & 0xffff;

	/* POST information is in the sd area. */
	np = of_find_compatible_node(NULL, NULL, "pika,fpga-sd");
	if (np == NULL) {
		pr_err("Unable to find fpga-sd\n");
		ret = -ENOENT;
		goto out;
	}

	fpga = of_iomap(np, 0);
	of_node_put(np);
	if (fpga == NULL) {
		pr_err("Unable to map fpga-sd\n");
		ret = -ENOMEM;
		goto out;
	}

	/* -- FPGA: POST Test Results Register 1 (32bit R/W) (Offset: 0x4040) --
	 * Bit 31,   WDOG: Set to 1 when the last reset was caused by a watchdog
	 *           timeout.
	 */
	post1 = in_be32(fpga + 0x40);
	if (post1 & 0x80000000)
		pikawdt_private.bootstatus = WDIOF_CARDRESET;

	iounmap(fpga);

	setup_timer(&pikawdt_private.timer, pikawdt_ping, 0);

	ret = misc_register(&pikawdt_miscdev);
	if (ret) {
		pr_err("Unable to register miscdev\n");
		goto out;
	}

	pr_info("initialized. heartbeat=%d sec (nowayout=%d)\n",
		heartbeat, nowayout);
	return 0;

out:
	iounmap(pikawdt_private.fpga);
	return ret;
}

static void __exit pikawdt_exit(void)
{
	misc_deregister(&pikawdt_miscdev);

	iounmap(pikawdt_private.fpga);
}

module_init(pikawdt_init);
module_exit(pikawdt_exit);

MODULE_AUTHOR("Sean MacLennan <smaclennan@pikatech.com>");
MODULE_DESCRIPTION("PIKA FPGA based Watchdog Timer");
MODULE_LICENSE("GPL");
