/*
 * Watchdog driver for SBC-FITPC2 board
 *
 * Author: Denis Turischev <denis@compulab.co.il>
 *
 * Adapted from the IXP2000 watchdog driver by Deepak Saxena.
 *
 * 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.
 */

#define pr_fmt(fmt) KBUILD_MODNAME " WATCHDOG: " fmt

#include <linux/module.h>
#include <linux/types.h>
#include <linux/miscdevice.h>
#include <linux/watchdog.h>
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/moduleparam.h>
#include <linux/dmi.h>
#include <linux/io.h>
#include <linux/uaccess.h>

#include <asm/system.h>

static int nowayout = WATCHDOG_NOWAYOUT;
static unsigned int margin = 60;	/* (secs) Default is 1 minute */
static unsigned long wdt_status;
static DEFINE_MUTEX(wdt_lock);

#define WDT_IN_USE		0
#define WDT_OK_TO_CLOSE		1

#define COMMAND_PORT		0x4c
#define DATA_PORT		0x48

#define IFACE_ON_COMMAND	1
#define REBOOT_COMMAND		2

#define WATCHDOG_NAME 		"SBC-FITPC2 Watchdog"

static void wdt_send_data(unsigned char command, unsigned char data)
{
	outb(data, DATA_PORT);
	msleep(200);
	outb(command, COMMAND_PORT);
	msleep(100);
}

static void wdt_enable(void)
{
	mutex_lock(&wdt_lock);
	wdt_send_data(IFACE_ON_COMMAND, 1);
	wdt_send_data(REBOOT_COMMAND, margin);
	mutex_unlock(&wdt_lock);
}

static void wdt_disable(void)
{
	mutex_lock(&wdt_lock);
	wdt_send_data(IFACE_ON_COMMAND, 0);
	wdt_send_data(REBOOT_COMMAND, 0);
	mutex_unlock(&wdt_lock);
}

static int fitpc2_wdt_open(struct inode *inode, struct file *file)
{
	if (test_and_set_bit(WDT_IN_USE, &wdt_status))
		return -EBUSY;

	clear_bit(WDT_OK_TO_CLOSE, &wdt_status);

	wdt_enable();

	return nonseekable_open(inode, file);
}

static ssize_t fitpc2_wdt_write(struct file *file, const char *data,
						size_t len, loff_t *ppos)
{
	size_t i;

	if (!len)
		return 0;

	if (nowayout) {
		len = 0;
		goto out;
	}

	clear_bit(WDT_OK_TO_CLOSE, &wdt_status);

	for (i = 0; i != len; i++) {
		char c;

		if (get_user(c, data + i))
			return -EFAULT;

		if (c == 'V')
			set_bit(WDT_OK_TO_CLOSE, &wdt_status);
	}

out:
	wdt_enable();

	return len;
}


static const struct watchdog_info ident = {
	.options	= WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT |
				WDIOF_KEEPALIVEPING,
	.identity	= WATCHDOG_NAME,
};


static long fitpc2_wdt_ioctl(struct file *file, unsigned int cmd,
							unsigned long arg)
{
	int ret = -ENOTTY;
	int time;

	switch (cmd) {
	case WDIOC_GETSUPPORT:
		ret = copy_to_user((struct watchdog_info *)arg, &ident,
				   sizeof(ident)) ? -EFAULT : 0;
		break;

	case WDIOC_GETSTATUS:
		ret = put_user(0, (int *)arg);
		break;

	case WDIOC_GETBOOTSTATUS:
		ret = put_user(0, (int *)arg);
		break;

	case WDIOC_KEEPALIVE:
		wdt_enable();
		ret = 0;
		break;

	case WDIOC_SETTIMEOUT:
		ret = get_user(time, (int *)arg);
		if (ret)
			break;

		if (time < 31 || time > 255) {
			ret = -EINVAL;
			break;
		}

		margin = time;
		wdt_enable();
		/* Fall through */

	case WDIOC_GETTIMEOUT:
		ret = put_user(margin, (int *)arg);
		break;
	}

	return ret;
}

static int fitpc2_wdt_release(struct inode *inode, struct file *file)
{
	if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) {
		wdt_disable();
		pr_info("Device disabled\n");
	} else {
		pr_warning("Device closed unexpectedly -"
			" timer will not stop\n");
		wdt_enable();
	}

	clear_bit(WDT_IN_USE, &wdt_status);
	clear_bit(WDT_OK_TO_CLOSE, &wdt_status);

	return 0;
}


static const struct file_operations fitpc2_wdt_fops = {
	.owner		= THIS_MODULE,
	.llseek		= no_llseek,
	.write		= fitpc2_wdt_write,
	.unlocked_ioctl	= fitpc2_wdt_ioctl,
	.open		= fitpc2_wdt_open,
	.release	= fitpc2_wdt_release,
};

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

static int __init fitpc2_wdt_init(void)
{
	int err;
	const char *brd_name;

	brd_name = dmi_get_system_info(DMI_BOARD_NAME);

	if (!brd_name || !strstr(brd_name, "SBC-FITPC2"))
		return -ENODEV;

	pr_info("%s found\n", brd_name);

	if (!request_region(COMMAND_PORT, 1, WATCHDOG_NAME)) {
		pr_err("I/O address 0x%04x already in use\n", COMMAND_PORT);
		return -EIO;
	}

	if (!request_region(DATA_PORT, 1, WATCHDOG_NAME)) {
		pr_err("I/O address 0x%04x already in use\n", DATA_PORT);
		err = -EIO;
		goto err_data_port;
	}

	if (margin < 31 || margin > 255) {
		pr_err("margin must be in range 31 - 255"
		       " seconds, you tried to set %d\n", margin);
		err = -EINVAL;
		goto err_margin;
	}

	err = misc_register(&fitpc2_wdt_miscdev);
	if (err) {
		pr_err("cannot register miscdev on minor=%d (err=%d)\n",
							WATCHDOG_MINOR, err);
		goto err_margin;
	}

	return 0;

err_margin:
	release_region(DATA_PORT, 1);
err_data_port:
	release_region(COMMAND_PORT, 1);

	return err;
}

static void __exit fitpc2_wdt_exit(void)
{
	misc_deregister(&fitpc2_wdt_miscdev);
	release_region(DATA_PORT, 1);
	release_region(COMMAND_PORT, 1);
}

module_init(fitpc2_wdt_init);
module_exit(fitpc2_wdt_exit);

MODULE_AUTHOR("Denis Turischev <denis@compulab.co.il>");
MODULE_DESCRIPTION("SBC-FITPC2 Watchdog");

module_param(margin, int, 0);
MODULE_PARM_DESC(margin, "Watchdog margin in seconds (default 60s)");

module_param(nowayout, int, 0);
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started");

MODULE_LICENSE("GPL");
MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);

