/*
 * linux/drivers/char/watchdog/omap_wdt.c
 *
 * Watchdog driver for the TI OMAP 16xx & 24xx 32KHz (non-secure) watchdog
 *
 * Author: MontaVista Software, Inc.
 *	 <gdavis@mvista.com> or <source@mvista.com>
 *
 * 2003 (c) MontaVista Software, Inc. 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.
 *
 * History:
 *
 * 20030527: George G. Davis <gdavis@mvista.com>
 *	Initially based on linux-2.4.19-rmk7-pxa1/drivers/char/sa1100_wdt.c
 *	(c) Copyright 2000 Oleg Drokin <green@crimea.edu>
 *	Based on SoftDog driver by Alan Cox <alan@redhat.com>
 *
 * Copyright (c) 2004 Texas Instruments.
 *	1. Modified to support OMAP1610 32-KHz watchdog timer
 *	2. Ported to 2.6 kernel
 *
 * Copyright (c) 2005 David Brownell
 *	Use the driver model and standard identifiers; handle bigger timeouts.
 */

#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/miscdevice.h>
#include <linux/watchdog.h>
#include <linux/reboot.h>
#include <linux/init.h>
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/moduleparam.h>
#include <linux/clk.h>
#include <linux/bitops.h>

#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/hardware.h>

#include <asm/arch/prcm.h>

#include "omap_wdt.h"

static unsigned timer_margin;
module_param(timer_margin, uint, 0);
MODULE_PARM_DESC(timer_margin, "initial watchdog timeout (in seconds)");

static int omap_wdt_users;
static struct clk *armwdt_ck = NULL;
static struct clk *mpu_wdt_ick = NULL;
static struct clk *mpu_wdt_fck = NULL;

static unsigned int wdt_trgr_pattern = 0x1234;

static void omap_wdt_ping(void)
{
	/* wait for posted write to complete */
	while ((omap_readl(OMAP_WATCHDOG_WPS)) & 0x08)
		cpu_relax();
	wdt_trgr_pattern = ~wdt_trgr_pattern;
	omap_writel(wdt_trgr_pattern, (OMAP_WATCHDOG_TGR));
	/* wait for posted write to complete */
	while ((omap_readl(OMAP_WATCHDOG_WPS)) & 0x08)
		cpu_relax();
	/* reloaded WCRR from WLDR */
}

static void omap_wdt_enable(void)
{
	/* Sequence to enable the watchdog */
	omap_writel(0xBBBB, OMAP_WATCHDOG_SPR);
	while ((omap_readl(OMAP_WATCHDOG_WPS)) & 0x10)
		cpu_relax();
	omap_writel(0x4444, OMAP_WATCHDOG_SPR);
	while ((omap_readl(OMAP_WATCHDOG_WPS)) & 0x10)
		cpu_relax();
}

static void omap_wdt_disable(void)
{
	/* sequence required to disable watchdog */
	omap_writel(0xAAAA, OMAP_WATCHDOG_SPR);	/* TIMER_MODE */
	while (omap_readl(OMAP_WATCHDOG_WPS) & 0x10)
		cpu_relax();
	omap_writel(0x5555, OMAP_WATCHDOG_SPR);	/* TIMER_MODE */
	while (omap_readl(OMAP_WATCHDOG_WPS) & 0x10)
		cpu_relax();
}

static void omap_wdt_adjust_timeout(unsigned new_timeout)
{
	if (new_timeout < TIMER_MARGIN_MIN)
		new_timeout = TIMER_MARGIN_DEFAULT;
	if (new_timeout > TIMER_MARGIN_MAX)
		new_timeout = TIMER_MARGIN_MAX;
	timer_margin = new_timeout;
}

static void omap_wdt_set_timeout(void)
{
	u32 pre_margin = GET_WLDR_VAL(timer_margin);

	/* just count up at 32 KHz */
	while (omap_readl(OMAP_WATCHDOG_WPS) & 0x04)
		cpu_relax();
	omap_writel(pre_margin, OMAP_WATCHDOG_LDR);
	while (omap_readl(OMAP_WATCHDOG_WPS) & 0x04)
		cpu_relax();
}

/*
 *	Allow only one task to hold it open
 */

static int omap_wdt_open(struct inode *inode, struct file *file)
{
	if (test_and_set_bit(1, (unsigned long *)&omap_wdt_users))
		return -EBUSY;

	if (cpu_is_omap16xx())
		clk_enable(armwdt_ck);	/* Enable the clock */

	if (cpu_is_omap24xx()) {
		clk_enable(mpu_wdt_ick);    /* Enable the interface clock */
		clk_enable(mpu_wdt_fck);    /* Enable the functional clock */
	}

	/* initialize prescaler */
	while (omap_readl(OMAP_WATCHDOG_WPS) & 0x01)
		cpu_relax();
	omap_writel((1 << 5) | (PTV << 2), OMAP_WATCHDOG_CNTRL);
	while (omap_readl(OMAP_WATCHDOG_WPS) & 0x01)
		cpu_relax();

	omap_wdt_set_timeout();
	omap_wdt_enable();
	return nonseekable_open(inode, file);
}

static int omap_wdt_release(struct inode *inode, struct file *file)
{
	/*
	 *      Shut off the timer unless NOWAYOUT is defined.
	 */
#ifndef CONFIG_WATCHDOG_NOWAYOUT
	omap_wdt_disable();

	if (cpu_is_omap16xx()) {
		clk_disable(armwdt_ck);	/* Disable the clock */
		clk_put(armwdt_ck);
		armwdt_ck = NULL;
	}

	if (cpu_is_omap24xx()) {
		clk_disable(mpu_wdt_ick);	/* Disable the clock */
		clk_disable(mpu_wdt_fck);	/* Disable the clock */
		clk_put(mpu_wdt_ick);
		clk_put(mpu_wdt_fck);
		mpu_wdt_ick = NULL;
		mpu_wdt_fck = NULL;
	}
#else
	printk(KERN_CRIT "omap_wdt: Unexpected close, not stopping!\n");
#endif
	omap_wdt_users = 0;
	return 0;
}

static ssize_t
omap_wdt_write(struct file *file, const char __user *data,
		size_t len, loff_t *ppos)
{
	/* Refresh LOAD_TIME. */
	if (len)
		omap_wdt_ping();
	return len;
}

static int
omap_wdt_ioctl(struct inode *inode, struct file *file,
	unsigned int cmd, unsigned long arg)
{
	int new_margin;
	static struct watchdog_info ident = {
		.identity = "OMAP Watchdog",
		.options = WDIOF_SETTIMEOUT,
		.firmware_version = 0,
	};

	switch (cmd) {
	default:
		return -ENOTTY;
	case WDIOC_GETSUPPORT:
		return copy_to_user((struct watchdog_info __user *)arg, &ident,
				sizeof(ident));
	case WDIOC_GETSTATUS:
		return put_user(0, (int __user *)arg);
	case WDIOC_GETBOOTSTATUS:
		if (cpu_is_omap16xx())
			return put_user(omap_readw(ARM_SYSST),
					(int __user *)arg);
		if (cpu_is_omap24xx())
			return put_user(omap_prcm_get_reset_sources(),
					(int __user *)arg);
	case WDIOC_KEEPALIVE:
		omap_wdt_ping();
		return 0;
	case WDIOC_SETTIMEOUT:
		if (get_user(new_margin, (int __user *)arg))
			return -EFAULT;
		omap_wdt_adjust_timeout(new_margin);

		omap_wdt_disable();
		omap_wdt_set_timeout();
		omap_wdt_enable();

		omap_wdt_ping();
		/* Fall */
	case WDIOC_GETTIMEOUT:
		return put_user(timer_margin, (int __user *)arg);
	}
}

static const struct file_operations omap_wdt_fops = {
	.owner = THIS_MODULE,
	.write = omap_wdt_write,
	.ioctl = omap_wdt_ioctl,
	.open = omap_wdt_open,
	.release = omap_wdt_release,
};

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

static int __init omap_wdt_probe(struct platform_device *pdev)
{
	struct resource *res, *mem;
	int ret;

	/* reserve static register mappings */
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res)
		return -ENOENT;

	mem = request_mem_region(res->start, res->end - res->start + 1,
				 pdev->name);
	if (mem == NULL)
		return -EBUSY;

	platform_set_drvdata(pdev, mem);

	omap_wdt_users = 0;

	if (cpu_is_omap16xx()) {
		armwdt_ck = clk_get(&pdev->dev, "armwdt_ck");
		if (IS_ERR(armwdt_ck)) {
			ret = PTR_ERR(armwdt_ck);
			armwdt_ck = NULL;
			goto fail;
		}
	}

	if (cpu_is_omap24xx()) {
		mpu_wdt_ick = clk_get(&pdev->dev, "mpu_wdt_ick");
		if (IS_ERR(mpu_wdt_ick)) {
			ret = PTR_ERR(mpu_wdt_ick);
			mpu_wdt_ick = NULL;
			goto fail;
		}
		mpu_wdt_fck = clk_get(&pdev->dev, "mpu_wdt_fck");
		if (IS_ERR(mpu_wdt_fck)) {
			ret = PTR_ERR(mpu_wdt_fck);
			mpu_wdt_fck = NULL;
			goto fail;
		}
	}

	omap_wdt_disable();
	omap_wdt_adjust_timeout(timer_margin);

	omap_wdt_miscdev.parent = &pdev->dev;
	ret = misc_register(&omap_wdt_miscdev);
	if (ret)
		goto fail;

	pr_info("OMAP Watchdog Timer: initial timeout %d sec\n", timer_margin);

	/* autogate OCP interface clock */
	omap_writel(0x01, OMAP_WATCHDOG_SYS_CONFIG);
	return 0;

fail:
	if (armwdt_ck)
		clk_put(armwdt_ck);
	if (mpu_wdt_ick)
		clk_put(mpu_wdt_ick);
	if (mpu_wdt_fck)
		clk_put(mpu_wdt_fck);
	release_resource(mem);
	return ret;
}

static void omap_wdt_shutdown(struct platform_device *pdev)
{
	omap_wdt_disable();
}

static int omap_wdt_remove(struct platform_device *pdev)
{
	struct resource *mem = platform_get_drvdata(pdev);
	misc_deregister(&omap_wdt_miscdev);
	release_resource(mem);
	if (armwdt_ck)
		clk_put(armwdt_ck);
	if (mpu_wdt_ick)
		clk_put(mpu_wdt_ick);
	if (mpu_wdt_fck)
		clk_put(mpu_wdt_fck);
	return 0;
}

#ifdef	CONFIG_PM

/* REVISIT ... not clear this is the best way to handle system suspend; and
 * it's very inappropriate for selective device suspend (e.g. suspending this
 * through sysfs rather than by stopping the watchdog daemon).  Also, this
 * may not play well enough with NOWAYOUT...
 */

static int omap_wdt_suspend(struct platform_device *pdev, pm_message_t state)
{
	if (omap_wdt_users)
		omap_wdt_disable();
	return 0;
}

static int omap_wdt_resume(struct platform_device *pdev)
{
	if (omap_wdt_users) {
		omap_wdt_enable();
		omap_wdt_ping();
	}
	return 0;
}

#else
#define	omap_wdt_suspend	NULL
#define	omap_wdt_resume		NULL
#endif

static struct platform_driver omap_wdt_driver = {
	.probe		= omap_wdt_probe,
	.remove		= omap_wdt_remove,
	.shutdown	= omap_wdt_shutdown,
	.suspend	= omap_wdt_suspend,
	.resume		= omap_wdt_resume,
	.driver		= {
		.owner	= THIS_MODULE,
		.name	= "omap_wdt",
	},
};

static int __init omap_wdt_init(void)
{
	return platform_driver_register(&omap_wdt_driver);
}

static void __exit omap_wdt_exit(void)
{
	platform_driver_unregister(&omap_wdt_driver);
}

module_init(omap_wdt_init);
module_exit(omap_wdt_exit);

MODULE_AUTHOR("George G. Davis");
MODULE_LICENSE("GPL");
MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
MODULE_ALIAS("platform:omap_wdt");
