/*
 *  Watchdog driver for Broadcom BCM47XX
 *
 *  Copyright (C) 2008 Aleksandar Radovanovic <biblbroks@sezampro.rs>
 *  Copyright (C) 2009 Matthieu CASTET <castet.matthieu@free.fr>
 *
 *  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.
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/bitops.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/miscdevice.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/reboot.h>
#include <linux/types.h>
#include <linux/uaccess.h>
#include <linux/watchdog.h>
#include <linux/timer.h>
#include <linux/jiffies.h>
#include <linux/ssb/ssb_embedded.h>
#include <asm/mach-bcm47xx/bcm47xx.h>

#define DRV_NAME		"bcm47xx_wdt"

#define WDT_DEFAULT_TIME	30	/* seconds */
#define WDT_MAX_TIME		255	/* seconds */

static int wdt_time = WDT_DEFAULT_TIME;
static bool nowayout = WATCHDOG_NOWAYOUT;

module_param(wdt_time, int, 0);
MODULE_PARM_DESC(wdt_time, "Watchdog time in seconds. (default="
				__MODULE_STRING(WDT_DEFAULT_TIME) ")");

#ifdef CONFIG_WATCHDOG_NOWAYOUT
module_param(nowayout, bool, 0);
MODULE_PARM_DESC(nowayout,
		"Watchdog cannot be stopped once started (default="
				__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
#endif

static unsigned long bcm47xx_wdt_busy;
static char expect_release;
static struct timer_list wdt_timer;
static atomic_t ticks;

static inline void bcm47xx_wdt_hw_start(void)
{
	/* this is 2,5s on 100Mhz clock  and 2s on 133 Mhz */
	switch (bcm47xx_bus_type) {
#ifdef CONFIG_BCM47XX_SSB
	case BCM47XX_BUS_TYPE_SSB:
		ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 0xfffffff);
		break;
#endif
#ifdef CONFIG_BCM47XX_BCMA
	case BCM47XX_BUS_TYPE_BCMA:
		bcma_chipco_watchdog_timer_set(&bcm47xx_bus.bcma.bus.drv_cc,
					       0xfffffff);
		break;
#endif
	}
}

static inline int bcm47xx_wdt_hw_stop(void)
{
	switch (bcm47xx_bus_type) {
#ifdef CONFIG_BCM47XX_SSB
	case BCM47XX_BUS_TYPE_SSB:
		return ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 0);
#endif
#ifdef CONFIG_BCM47XX_BCMA
	case BCM47XX_BUS_TYPE_BCMA:
		bcma_chipco_watchdog_timer_set(&bcm47xx_bus.bcma.bus.drv_cc, 0);
		return 0;
#endif
	}
	return -EINVAL;
}

static void bcm47xx_timer_tick(unsigned long unused)
{
	if (!atomic_dec_and_test(&ticks)) {
		bcm47xx_wdt_hw_start();
		mod_timer(&wdt_timer, jiffies + HZ);
	} else {
		pr_crit("Watchdog will fire soon!!!\n");
	}
}

static inline void bcm47xx_wdt_pet(void)
{
	atomic_set(&ticks, wdt_time);
}

static void bcm47xx_wdt_start(void)
{
	bcm47xx_wdt_pet();
	bcm47xx_timer_tick(0);
}

static void bcm47xx_wdt_pause(void)
{
	del_timer_sync(&wdt_timer);
	bcm47xx_wdt_hw_stop();
}

static void bcm47xx_wdt_stop(void)
{
	bcm47xx_wdt_pause();
}

static int bcm47xx_wdt_settimeout(int new_time)
{
	if ((new_time <= 0) || (new_time > WDT_MAX_TIME))
		return -EINVAL;

	wdt_time = new_time;
	return 0;
}

static int bcm47xx_wdt_open(struct inode *inode, struct file *file)
{
	if (test_and_set_bit(0, &bcm47xx_wdt_busy))
		return -EBUSY;

	bcm47xx_wdt_start();
	return nonseekable_open(inode, file);
}

static int bcm47xx_wdt_release(struct inode *inode, struct file *file)
{
	if (expect_release == 42) {
		bcm47xx_wdt_stop();
	} else {
		pr_crit("Unexpected close, not stopping watchdog!\n");
		bcm47xx_wdt_start();
	}

	clear_bit(0, &bcm47xx_wdt_busy);
	expect_release = 0;
	return 0;
}

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

			expect_release = 0;

			for (i = 0; i != len; i++) {
				char c;
				if (get_user(c, data + i))
					return -EFAULT;
				if (c == 'V')
					expect_release = 42;
			}
		}
		bcm47xx_wdt_pet();
	}
	return len;
}

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

static long bcm47xx_wdt_ioctl(struct file *file,
					unsigned int cmd, unsigned long arg)
{
	void __user *argp = (void __user *)arg;
	int __user *p = argp;
	int new_value, retval = -EINVAL;

	switch (cmd) {
	case WDIOC_GETSUPPORT:
		return copy_to_user(argp, &bcm47xx_wdt_info,
				sizeof(bcm47xx_wdt_info)) ? -EFAULT : 0;

	case WDIOC_GETSTATUS:
	case WDIOC_GETBOOTSTATUS:
		return put_user(0, p);

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

		if (new_value & WDIOS_DISABLECARD) {
			bcm47xx_wdt_stop();
			retval = 0;
		}

		if (new_value & WDIOS_ENABLECARD) {
			bcm47xx_wdt_start();
			retval = 0;
		}

		return retval;

	case WDIOC_KEEPALIVE:
		bcm47xx_wdt_pet();
		return 0;

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

		if (bcm47xx_wdt_settimeout(new_value))
			return -EINVAL;

		bcm47xx_wdt_pet();

	case WDIOC_GETTIMEOUT:
		return put_user(wdt_time, p);

	default:
		return -ENOTTY;
	}
}

static int bcm47xx_wdt_notify_sys(struct notifier_block *this,
	unsigned long code, void *unused)
{
	if (code == SYS_DOWN || code == SYS_HALT)
		bcm47xx_wdt_stop();
	return NOTIFY_DONE;
}

static const struct file_operations bcm47xx_wdt_fops = {
	.owner		= THIS_MODULE,
	.llseek		= no_llseek,
	.unlocked_ioctl	= bcm47xx_wdt_ioctl,
	.open		= bcm47xx_wdt_open,
	.release	= bcm47xx_wdt_release,
	.write		= bcm47xx_wdt_write,
};

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

static struct notifier_block bcm47xx_wdt_notifier = {
	.notifier_call = bcm47xx_wdt_notify_sys,
};

static int __init bcm47xx_wdt_init(void)
{
	int ret;

	if (bcm47xx_wdt_hw_stop() < 0)
		return -ENODEV;

	setup_timer(&wdt_timer, bcm47xx_timer_tick, 0L);

	if (bcm47xx_wdt_settimeout(wdt_time)) {
		bcm47xx_wdt_settimeout(WDT_DEFAULT_TIME);
		pr_info("wdt_time value must be 0 < wdt_time < %d, using %d\n",
			(WDT_MAX_TIME + 1), wdt_time);
	}

	ret = register_reboot_notifier(&bcm47xx_wdt_notifier);
	if (ret)
		return ret;

	ret = misc_register(&bcm47xx_wdt_miscdev);
	if (ret) {
		unregister_reboot_notifier(&bcm47xx_wdt_notifier);
		return ret;
	}

	pr_info("BCM47xx Watchdog Timer enabled (%d seconds%s)\n",
		wdt_time, nowayout ? ", nowayout" : "");
	return 0;
}

static void __exit bcm47xx_wdt_exit(void)
{
	if (!nowayout)
		bcm47xx_wdt_stop();

	misc_deregister(&bcm47xx_wdt_miscdev);

	unregister_reboot_notifier(&bcm47xx_wdt_notifier);
}

module_init(bcm47xx_wdt_init);
module_exit(bcm47xx_wdt_exit);

MODULE_AUTHOR("Aleksandar Radovanovic");
MODULE_DESCRIPTION("Watchdog driver for Broadcom BCM47xx");
MODULE_LICENSE("GPL");
MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
