/*
 * drivers/char/watchdog/iop_wdt.c
 *
 * WDT driver for Intel I/O Processors
 * Copyright (C) 2005, Intel Corporation.
 *
 * Based on ixp4xx driver, Copyright 2004 (c) MontaVista, Software, Inc.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 * Place - Suite 330, Boston, MA 02111-1307 USA.
 *
 *	Curt E Bruns <curt.e.bruns@intel.com>
 *	Peter Milne <peter.milne@d-tacq.com>
 *	Dan Williams <dan.j.williams@intel.com>
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/miscdevice.h>
#include <linux/watchdog.h>
#include <linux/uaccess.h>
#include <asm/arch/hardware.h>

static int nowayout = WATCHDOG_NOWAYOUT;
static unsigned long wdt_status;
static unsigned long boot_status;

#define WDT_IN_USE		0
#define WDT_OK_TO_CLOSE		1
#define WDT_ENABLED		2

static unsigned long iop_watchdog_timeout(void)
{
	return (0xffffffffUL / get_iop_tick_rate());
}

/**
 * wdt_supports_disable - determine if we are accessing a iop13xx watchdog
 * or iop3xx by whether it has a disable command
 */
static int wdt_supports_disable(void)
{
	int can_disable;

	if (IOP_WDTCR_EN_ARM != IOP_WDTCR_DIS_ARM)
		can_disable = 1;
	else
		can_disable = 0;

	return can_disable;
}

static void wdt_enable(void)
{
	/* Arm and enable the Timer to starting counting down from 0xFFFF.FFFF
	 * Takes approx. 10.7s to timeout
	 */
	write_wdtcr(IOP_WDTCR_EN_ARM);
	write_wdtcr(IOP_WDTCR_EN);
}

/* returns 0 if the timer was successfully disabled */
static int wdt_disable(void)
{
	/* Stop Counting */
	if (wdt_supports_disable()) {
		write_wdtcr(IOP_WDTCR_DIS_ARM);
		write_wdtcr(IOP_WDTCR_DIS);
		clear_bit(WDT_ENABLED, &wdt_status);
		printk(KERN_INFO "WATCHDOG: Disabled\n");
		return 0;
	} else
		return 1;
}

static int iop_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();

	set_bit(WDT_ENABLED, &wdt_status);

	return nonseekable_open(inode, file);
}

static ssize_t
iop_wdt_write(struct file *file, const char *data, size_t len,
		  loff_t *ppos)
{
	if (len) {
		if (!nowayout) {
			size_t i;

			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);
			}
		}
		wdt_enable();
	}

	return len;
}

static struct watchdog_info ident = {
	.options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING,
	.identity = "iop watchdog",
};

static int
iop_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
		  unsigned long arg)
{
	int options;
	int ret = -ENOTTY;

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

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

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

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

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

	case WDIOC_SETOPTIONS:
		if (get_user(options, (int *)arg))
			return -EFAULT;

		if (options & WDIOS_DISABLECARD) {
			if (!nowayout) {
				if (wdt_disable() == 0) {
					set_bit(WDT_OK_TO_CLOSE, &wdt_status);
					ret = 0;
				} else
					ret = -ENXIO;
			} else
				ret = 0;
		}

		if (options & WDIOS_ENABLECARD) {
			wdt_enable();
			ret = 0;
		}
		break;
	}

	return ret;
}

static int iop_wdt_release(struct inode *inode, struct file *file)
{
	int state = 1;
	if (test_bit(WDT_OK_TO_CLOSE, &wdt_status))
		if (test_bit(WDT_ENABLED, &wdt_status))
			state = wdt_disable();

	/* if the timer is not disbaled reload and notify that we are still
	 * going down
	 */
	if (state != 0) {
		wdt_enable();
		printk(KERN_CRIT "WATCHDOG: Device closed unexpectedly - "
		       "reset in %lu seconds\n", iop_watchdog_timeout());
	}

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

	return 0;
}

static const struct file_operations iop_wdt_fops = {
	.owner = THIS_MODULE,
	.llseek = no_llseek,
	.write = iop_wdt_write,
	.ioctl = iop_wdt_ioctl,
	.open = iop_wdt_open,
	.release = iop_wdt_release,
};

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

static int __init iop_wdt_init(void)
{
	int ret;

	ret = misc_register(&iop_wdt_miscdev);
	if (ret == 0)
		printk("iop watchdog timer: timeout %lu sec\n",
		       iop_watchdog_timeout());

	/* check if the reset was caused by the watchdog timer */
	boot_status = (read_rcsr() & IOP_RCSR_WDT) ? WDIOF_CARDRESET : 0;

	/* Configure Watchdog Timeout to cause an Internal Bus (IB) Reset
	 * NOTE: An IB Reset will Reset both cores in the IOP342
	 */
	write_wdtsr(IOP13XX_WDTCR_IB_RESET);

	return ret;
}

static void __exit iop_wdt_exit(void)
{
	misc_deregister(&iop_wdt_miscdev);
}

module_init(iop_wdt_init);
module_exit(iop_wdt_exit);

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

MODULE_AUTHOR("Curt E Bruns <curt.e.bruns@intel.com>");
MODULE_DESCRIPTION("iop watchdog timer driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
