/*
 *	sch311x_wdt.c - Driver for the SCH311x Super-I/O chips
 *			integrated watchdog.
 *
 *	(c) Copyright 2008 Wim Van Sebroeck <wim@iguana.be>.
 *
 *	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; either version
 *	2 of the License, or (at your option) any later version.
 *
 *	Neither Wim Van Sebroeck nor Iguana vzw. admit liability nor
 *	provide warranty for any of this software. This material is
 *	provided "AS-IS" and at no charge.
 */

/*
 *	Includes, defines, variables, module parameters, ...
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

/* Includes */
#include <linux/module.h>		/* For module specific items */
#include <linux/moduleparam.h>		/* For new moduleparam's */
#include <linux/types.h>		/* For standard types (like size_t) */
#include <linux/errno.h>		/* For the -ENODEV/... values */
#include <linux/kernel.h>		/* For printk/... */
#include <linux/miscdevice.h>		/* For MODULE_ALIAS_MISCDEV
							(WATCHDOG_MINOR) */
#include <linux/watchdog.h>		/* For the watchdog specific items */
#include <linux/init.h>			/* For __init/__exit/... */
#include <linux/fs.h>			/* For file operations */
#include <linux/platform_device.h>	/* For platform_driver framework */
#include <linux/ioport.h>		/* For io-port access */
#include <linux/spinlock.h>		/* For spin_lock/spin_unlock/... */
#include <linux/uaccess.h>		/* For copy_to_user/put_user/... */
#include <linux/io.h>			/* For inb/outb/... */

/* Module and version information */
#define DRV_NAME	"sch311x_wdt"

/* Runtime registers */
#define GP60			0x47
#define WDT_TIME_OUT		0x65
#define WDT_VAL			0x66
#define WDT_CFG			0x67
#define WDT_CTRL		0x68

/* internal variables */
static unsigned long sch311x_wdt_is_open;
static char sch311x_wdt_expect_close;
static struct platform_device *sch311x_wdt_pdev;

static int sch311x_ioports[] = { 0x2e, 0x4e, 0x162e, 0x164e, 0x00 };

static struct {	/* The devices private data */
	/* the Runtime Register base address */
	unsigned short runtime_reg;
	/* The card's boot status */
	int boot_status;
	/* the lock for io operations */
	spinlock_t io_lock;
} sch311x_wdt_data;

/* Module load parameters */
static unsigned short force_id;
module_param(force_id, ushort, 0);
MODULE_PARM_DESC(force_id, "Override the detected device ID");

#define WATCHDOG_TIMEOUT 60		/* 60 sec default timeout */
static int timeout = WATCHDOG_TIMEOUT;	/* in seconds */
module_param(timeout, int, 0);
MODULE_PARM_DESC(timeout,
	"Watchdog timeout in seconds. 1<= timeout <=15300, default="
		__MODULE_STRING(WATCHDOG_TIMEOUT) ".");

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) ")");

/*
 *	Super-IO functions
 */

static inline void sch311x_sio_enter(int sio_config_port)
{
	outb(0x55, sio_config_port);
}

static inline void sch311x_sio_exit(int sio_config_port)
{
	outb(0xaa, sio_config_port);
}

static inline int sch311x_sio_inb(int sio_config_port, int reg)
{
	outb(reg, sio_config_port);
	return inb(sio_config_port + 1);
}

static inline void sch311x_sio_outb(int sio_config_port, int reg, int val)
{
	outb(reg, sio_config_port);
	outb(val, sio_config_port + 1);
}

/*
 *	Watchdog Operations
 */

static void sch311x_wdt_set_timeout(int t)
{
	unsigned char timeout_unit = 0x80;

	/* When new timeout is bigger then 255 seconds, we will use minutes */
	if (t > 255) {
		timeout_unit = 0;
		t /= 60;
	}

	/* -- Watchdog Timeout --
	 * Bit 0-6 (Reserved)
	 * Bit 7   WDT Time-out Value Units Select
	 *         (0 = Minutes, 1 = Seconds)
	 */
	outb(timeout_unit, sch311x_wdt_data.runtime_reg + WDT_TIME_OUT);

	/* -- Watchdog Timer Time-out Value --
	 * Bit 0-7 Binary coded units (0=Disabled, 1..255)
	 */
	outb(t, sch311x_wdt_data.runtime_reg + WDT_VAL);
}

static void sch311x_wdt_start(void)
{
	unsigned char t;

	spin_lock(&sch311x_wdt_data.io_lock);

	/* set watchdog's timeout */
	sch311x_wdt_set_timeout(timeout);
	/* enable the watchdog */
	/* -- General Purpose I/O Bit 6.0 --
	 * Bit 0,   In/Out: 0 = Output, 1 = Input
	 * Bit 1,   Polarity: 0 = No Invert, 1 = Invert
	 * Bit 2-3, Function select: 00 = GPI/O, 01 = LED1, 11 = WDT,
	 *                           10 = Either Edge Triggered Intr.4
	 * Bit 4-6  (Reserved)
	 * Bit 7,   Output Type: 0 = Push Pull Bit, 1 = Open Drain
	 */
	t = inb(sch311x_wdt_data.runtime_reg + GP60);
	outb((t & ~0x0d) | 0x0c, sch311x_wdt_data.runtime_reg + GP60);

	spin_unlock(&sch311x_wdt_data.io_lock);

}

static void sch311x_wdt_stop(void)
{
	unsigned char t;

	spin_lock(&sch311x_wdt_data.io_lock);

	/* stop the watchdog */
	t = inb(sch311x_wdt_data.runtime_reg + GP60);
	outb((t & ~0x0d) | 0x01, sch311x_wdt_data.runtime_reg + GP60);
	/* disable timeout by setting it to 0 */
	sch311x_wdt_set_timeout(0);

	spin_unlock(&sch311x_wdt_data.io_lock);
}

static void sch311x_wdt_keepalive(void)
{
	spin_lock(&sch311x_wdt_data.io_lock);
	sch311x_wdt_set_timeout(timeout);
	spin_unlock(&sch311x_wdt_data.io_lock);
}

static int sch311x_wdt_set_heartbeat(int t)
{
	if (t < 1 || t > (255*60))
		return -EINVAL;

	/* When new timeout is bigger then 255 seconds,
	 * we will round up to minutes (with a max of 255) */
	if (t > 255)
		t = (((t - 1) / 60) + 1) * 60;

	timeout = t;
	return 0;
}

static void sch311x_wdt_get_status(int *status)
{
	unsigned char new_status;

	*status = 0;

	spin_lock(&sch311x_wdt_data.io_lock);

	/* -- Watchdog timer control --
	 * Bit 0   Status Bit: 0 = Timer counting, 1 = Timeout occurred
	 * Bit 1   Reserved
	 * Bit 2   Force Timeout: 1 = Forces WD timeout event (self-cleaning)
	 * Bit 3   P20 Force Timeout enabled:
	 *          0 = P20 activity does not generate the WD timeout event
	 *          1 = P20 Allows rising edge of P20, from the keyboard
	 *              controller, to force the WD timeout event.
	 * Bit 4-7 Reserved
	 */
	new_status = inb(sch311x_wdt_data.runtime_reg + WDT_CTRL);
	if (new_status & 0x01)
		*status |= WDIOF_CARDRESET;

	spin_unlock(&sch311x_wdt_data.io_lock);
}

/*
 *	/dev/watchdog handling
 */

static ssize_t sch311x_wdt_write(struct file *file, const char __user *buf,
						size_t count, loff_t *ppos)
{
	if (count) {
		if (!nowayout) {
			size_t i;

			sch311x_wdt_expect_close = 0;

			for (i = 0; i != count; i++) {
				char c;
				if (get_user(c, buf + i))
					return -EFAULT;
				if (c == 'V')
					sch311x_wdt_expect_close = 42;
			}
		}
		sch311x_wdt_keepalive();
	}
	return count;
}

static long sch311x_wdt_ioctl(struct file *file, unsigned int cmd,
							unsigned long arg)
{
	int status;
	int new_timeout;
	void __user *argp = (void __user *)arg;
	int __user *p = argp;
	static const struct watchdog_info ident = {
		.options		= WDIOF_KEEPALIVEPING |
					  WDIOF_SETTIMEOUT |
					  WDIOF_MAGICCLOSE,
		.firmware_version	= 1,
		.identity		= DRV_NAME,
	};

	switch (cmd) {
	case WDIOC_GETSUPPORT:
		if (copy_to_user(argp, &ident, sizeof(ident)))
			return -EFAULT;
		break;

	case WDIOC_GETSTATUS:
	{
		sch311x_wdt_get_status(&status);
		return put_user(status, p);
	}
	case WDIOC_GETBOOTSTATUS:
		return put_user(sch311x_wdt_data.boot_status, p);

	case WDIOC_SETOPTIONS:
	{
		int options, retval = -EINVAL;

		if (get_user(options, p))
			return -EFAULT;
		if (options & WDIOS_DISABLECARD) {
			sch311x_wdt_stop();
			retval = 0;
		}
		if (options & WDIOS_ENABLECARD) {
			sch311x_wdt_start();
			retval = 0;
		}
		return retval;
	}
	case WDIOC_KEEPALIVE:
		sch311x_wdt_keepalive();
		break;

	case WDIOC_SETTIMEOUT:
		if (get_user(new_timeout, p))
			return -EFAULT;
		if (sch311x_wdt_set_heartbeat(new_timeout))
			return -EINVAL;
		sch311x_wdt_keepalive();
		/* Fall */
	case WDIOC_GETTIMEOUT:
		return put_user(timeout, p);
	default:
		return -ENOTTY;
	}
	return 0;
}

static int sch311x_wdt_open(struct inode *inode, struct file *file)
{
	if (test_and_set_bit(0, &sch311x_wdt_is_open))
		return -EBUSY;
	/*
	 *	Activate
	 */
	sch311x_wdt_start();
	return nonseekable_open(inode, file);
}

static int sch311x_wdt_close(struct inode *inode, struct file *file)
{
	if (sch311x_wdt_expect_close == 42) {
		sch311x_wdt_stop();
	} else {
		pr_crit("Unexpected close, not stopping watchdog!\n");
		sch311x_wdt_keepalive();
	}
	clear_bit(0, &sch311x_wdt_is_open);
	sch311x_wdt_expect_close = 0;
	return 0;
}

/*
 *	Kernel Interfaces
 */

static const struct file_operations sch311x_wdt_fops = {
	.owner		= THIS_MODULE,
	.llseek		= no_llseek,
	.write		= sch311x_wdt_write,
	.unlocked_ioctl	= sch311x_wdt_ioctl,
	.open		= sch311x_wdt_open,
	.release	= sch311x_wdt_close,
};

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

/*
 *	Init & exit routines
 */

static int sch311x_wdt_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	int err;

	spin_lock_init(&sch311x_wdt_data.io_lock);

	if (!request_region(sch311x_wdt_data.runtime_reg + GP60, 1, DRV_NAME)) {
		dev_err(dev, "Failed to request region 0x%04x-0x%04x.\n",
			sch311x_wdt_data.runtime_reg + GP60,
			sch311x_wdt_data.runtime_reg + GP60);
		err = -EBUSY;
		goto exit;
	}

	if (!request_region(sch311x_wdt_data.runtime_reg + WDT_TIME_OUT, 4,
								DRV_NAME)) {
		dev_err(dev, "Failed to request region 0x%04x-0x%04x.\n",
			sch311x_wdt_data.runtime_reg + WDT_TIME_OUT,
			sch311x_wdt_data.runtime_reg + WDT_CTRL);
		err = -EBUSY;
		goto exit_release_region;
	}

	/* Make sure that the watchdog is not running */
	sch311x_wdt_stop();

	/* Disable keyboard and mouse interaction and interrupt */
	/* -- Watchdog timer configuration --
	 * Bit 0   Reserved
	 * Bit 1   Keyboard enable: 0* = No Reset, 1 = Reset WDT upon KBD Intr.
	 * Bit 2   Mouse enable: 0* = No Reset, 1 = Reset WDT upon Mouse Intr
	 * Bit 3   Reserved
	 * Bit 4-7 WDT Interrupt Mapping: (0000* = Disabled,
	 *            0001=IRQ1, 0010=(Invalid), 0011=IRQ3 to 1111=IRQ15)
	 */
	outb(0, sch311x_wdt_data.runtime_reg + WDT_CFG);

	/* Check that the heartbeat value is within it's range ;
	 * if not reset to the default */
	if (sch311x_wdt_set_heartbeat(timeout)) {
		sch311x_wdt_set_heartbeat(WATCHDOG_TIMEOUT);
		dev_info(dev, "timeout value must be 1<=x<=15300, using %d\n",
			timeout);
	}

	/* Get status at boot */
	sch311x_wdt_get_status(&sch311x_wdt_data.boot_status);

	sch311x_wdt_miscdev.parent = dev;

	err = misc_register(&sch311x_wdt_miscdev);
	if (err != 0) {
		dev_err(dev, "cannot register miscdev on minor=%d (err=%d)\n",
							WATCHDOG_MINOR, err);
		goto exit_release_region2;
	}

	dev_info(dev,
		"SMSC SCH311x WDT initialized. timeout=%d sec (nowayout=%d)\n",
		timeout, nowayout);

	return 0;

exit_release_region2:
	release_region(sch311x_wdt_data.runtime_reg + WDT_TIME_OUT, 4);
exit_release_region:
	release_region(sch311x_wdt_data.runtime_reg + GP60, 1);
	sch311x_wdt_data.runtime_reg = 0;
exit:
	return err;
}

static int __devexit sch311x_wdt_remove(struct platform_device *pdev)
{
	/* Stop the timer before we leave */
	if (!nowayout)
		sch311x_wdt_stop();

	/* Deregister */
	misc_deregister(&sch311x_wdt_miscdev);
	release_region(sch311x_wdt_data.runtime_reg + WDT_TIME_OUT, 4);
	release_region(sch311x_wdt_data.runtime_reg + GP60, 1);
	sch311x_wdt_data.runtime_reg = 0;
	return 0;
}

static void sch311x_wdt_shutdown(struct platform_device *dev)
{
	/* Turn the WDT off if we have a soft shutdown */
	sch311x_wdt_stop();
}

static struct platform_driver sch311x_wdt_driver = {
	.probe		= sch311x_wdt_probe,
	.remove		= sch311x_wdt_remove,
	.shutdown	= sch311x_wdt_shutdown,
	.driver		= {
		.owner = THIS_MODULE,
		.name = DRV_NAME,
	},
};

static int __init sch311x_detect(int sio_config_port, unsigned short *addr)
{
	int err = 0, reg;
	unsigned short base_addr;
	unsigned char dev_id;

	sch311x_sio_enter(sio_config_port);

	/* Check device ID. We currently know about:
	 * SCH3112 (0x7c), SCH3114 (0x7d), and SCH3116 (0x7f). */
	reg = force_id ? force_id : sch311x_sio_inb(sio_config_port, 0x20);
	if (!(reg == 0x7c || reg == 0x7d || reg == 0x7f)) {
		err = -ENODEV;
		goto exit;
	}
	dev_id = reg == 0x7c ? 2 : reg == 0x7d ? 4 : 6;

	/* Select logical device A (runtime registers) */
	sch311x_sio_outb(sio_config_port, 0x07, 0x0a);

	/* Check if Logical Device Register is currently active */
	if ((sch311x_sio_inb(sio_config_port, 0x30) & 0x01) == 0)
		pr_info("Seems that LDN 0x0a is not active...\n");

	/* Get the base address of the runtime registers */
	base_addr = (sch311x_sio_inb(sio_config_port, 0x60) << 8) |
			   sch311x_sio_inb(sio_config_port, 0x61);
	if (!base_addr) {
		pr_err("Base address not set\n");
		err = -ENODEV;
		goto exit;
	}
	*addr = base_addr;

	pr_info("Found an SMSC SCH311%d chip at 0x%04x\n", dev_id, base_addr);

exit:
	sch311x_sio_exit(sio_config_port);
	return err;
}

static int __init sch311x_wdt_init(void)
{
	int err, i, found = 0;
	unsigned short addr = 0;

	for (i = 0; !found && sch311x_ioports[i]; i++)
		if (sch311x_detect(sch311x_ioports[i], &addr) == 0)
			found++;

	if (!found)
		return -ENODEV;

	sch311x_wdt_data.runtime_reg = addr;

	err = platform_driver_register(&sch311x_wdt_driver);
	if (err)
		return err;

	sch311x_wdt_pdev = platform_device_register_simple(DRV_NAME, addr,
								NULL, 0);

	if (IS_ERR(sch311x_wdt_pdev)) {
		err = PTR_ERR(sch311x_wdt_pdev);
		goto unreg_platform_driver;
	}

	return 0;

unreg_platform_driver:
	platform_driver_unregister(&sch311x_wdt_driver);
	return err;
}

static void __exit sch311x_wdt_exit(void)
{
	platform_device_unregister(sch311x_wdt_pdev);
	platform_driver_unregister(&sch311x_wdt_driver);
}

module_init(sch311x_wdt_init);
module_exit(sch311x_wdt_exit);

MODULE_AUTHOR("Wim Van Sebroeck <wim@iguana.be>");
MODULE_DESCRIPTION("SMSC SCH311x WatchDog Timer Driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);

