/*
 * Kontron PLD watchdog driver
 *
 * Copyright (c) 2010-2013 Kontron Europe GmbH
 * Author: Michael Brunner <michael.brunner@kontron.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License 2 as published
 * by the Free Software Foundation.
 *
 * This program is distributed in the hope that 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.
 *
 * Note: From the PLD watchdog point of view timeout and pretimeout are
 *       defined differently than in the kernel.
 *       First the pretimeout stage runs out before the timeout stage gets
 *       active.
 *
 * Kernel/API:                     P-----| pretimeout
 *               |-----------------------T timeout
 * Watchdog:     |-----------------P       pretimeout_stage
 *                                 |-----T timeout_stage
 */

#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/miscdevice.h>
#include <linux/uaccess.h>
#include <linux/watchdog.h>
#include <linux/platform_device.h>
#include <linux/mfd/kempld.h>

#define KEMPLD_WDT_STAGE_TIMEOUT(x)	(0x1b + (x) * 4)
#define KEMPLD_WDT_STAGE_CFG(x)		(0x18 + (x))
#define STAGE_CFG_GET_PRESCALER(x)	(((x) & 0x30) >> 4)
#define STAGE_CFG_SET_PRESCALER(x)	(((x) & 0x3) << 4)
#define STAGE_CFG_PRESCALER_MASK	0x30
#define STAGE_CFG_ACTION_MASK		0x7
#define STAGE_CFG_ASSERT		(1 << 3)

#define KEMPLD_WDT_MAX_STAGES		2
#define KEMPLD_WDT_KICK			0x16
#define KEMPLD_WDT_CFG			0x17
#define KEMPLD_WDT_CFG_ENABLE		0x10
#define KEMPLD_WDT_CFG_ENABLE_LOCK	0x8
#define KEMPLD_WDT_CFG_GLOBAL_LOCK	0x80

enum {
	ACTION_NONE = 0,
	ACTION_RESET,
	ACTION_NMI,
	ACTION_SMI,
	ACTION_SCI,
	ACTION_DELAY,
};

enum {
	STAGE_TIMEOUT = 0,
	STAGE_PRETIMEOUT,
};

enum {
	PRESCALER_21 = 0,
	PRESCALER_17,
	PRESCALER_12,
};

const u32 kempld_prescaler[] = {
	[PRESCALER_21] = (1 << 21) - 1,
	[PRESCALER_17] = (1 << 17) - 1,
	[PRESCALER_12] = (1 << 12) - 1,
	0,
};

struct kempld_wdt_stage {
	unsigned int	id;
	u32		mask;
};

struct kempld_wdt_data {
	struct kempld_device_data	*pld;
	struct watchdog_device		wdd;
	unsigned int			pretimeout;
	struct kempld_wdt_stage		stage[KEMPLD_WDT_MAX_STAGES];
#ifdef CONFIG_PM
	u8				pm_status_store;
#endif
};

#define DEFAULT_TIMEOUT		30 /* seconds */
#define DEFAULT_PRETIMEOUT	0

static unsigned int timeout = DEFAULT_TIMEOUT;
module_param(timeout, uint, 0);
MODULE_PARM_DESC(timeout,
	"Watchdog timeout in seconds. (>=0, default="
	__MODULE_STRING(DEFAULT_TIMEOUT) ")");

static unsigned int pretimeout = DEFAULT_PRETIMEOUT;
module_param(pretimeout, uint, 0);
MODULE_PARM_DESC(pretimeout,
	"Watchdog pretimeout in seconds. (>=0, default="
	__MODULE_STRING(DEFAULT_PRETIMEOUT) ")");

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

static int kempld_wdt_set_stage_action(struct kempld_wdt_data *wdt_data,
					struct kempld_wdt_stage *stage,
					u8 action)
{
	struct kempld_device_data *pld = wdt_data->pld;
	u8 stage_cfg;

	if (!stage || !stage->mask)
		return -EINVAL;

	kempld_get_mutex(pld);
	stage_cfg = kempld_read8(pld, KEMPLD_WDT_STAGE_CFG(stage->id));
	stage_cfg &= ~STAGE_CFG_ACTION_MASK;
	stage_cfg |= (action & STAGE_CFG_ACTION_MASK);

	if (action == ACTION_RESET)
		stage_cfg |= STAGE_CFG_ASSERT;
	else
		stage_cfg &= ~STAGE_CFG_ASSERT;

	kempld_write8(pld, KEMPLD_WDT_STAGE_CFG(stage->id), stage_cfg);
	kempld_release_mutex(pld);

	return 0;
}

static int kempld_wdt_set_stage_timeout(struct kempld_wdt_data *wdt_data,
					struct kempld_wdt_stage *stage,
					unsigned int timeout)
{
	struct kempld_device_data *pld = wdt_data->pld;
	u32 prescaler = kempld_prescaler[PRESCALER_21];
	u64 stage_timeout64;
	u32 stage_timeout;
	u32 remainder;
	u8 stage_cfg;

	if (!stage)
		return -EINVAL;

	stage_timeout64 = (u64)timeout * pld->pld_clock;
	remainder = do_div(stage_timeout64, prescaler);
	if (remainder)
		stage_timeout64++;

	if (stage_timeout64 > stage->mask)
		return -EINVAL;

	stage_timeout = stage_timeout64 & stage->mask;

	kempld_get_mutex(pld);
	stage_cfg = kempld_read8(pld, KEMPLD_WDT_STAGE_CFG(stage->id));
	stage_cfg &= ~STAGE_CFG_PRESCALER_MASK;
	stage_cfg |= STAGE_CFG_SET_PRESCALER(prescaler);
	kempld_write8(pld, KEMPLD_WDT_STAGE_CFG(stage->id), stage_cfg);
	kempld_write32(pld, KEMPLD_WDT_STAGE_TIMEOUT(stage->id),
			stage_timeout);
	kempld_release_mutex(pld);

	return 0;
}

/*
 * kempld_get_mutex must be called prior to calling this function.
 */
static unsigned int kempld_wdt_get_timeout(struct kempld_wdt_data *wdt_data,
						struct kempld_wdt_stage *stage)
{
	struct kempld_device_data *pld = wdt_data->pld;
	unsigned int timeout;
	u64 stage_timeout;
	u32 prescaler;
	u32 remainder;
	u8 stage_cfg;

	if (!stage->mask)
		return 0;

	stage_cfg = kempld_read8(pld, KEMPLD_WDT_STAGE_CFG(stage->id));
	stage_timeout = kempld_read32(pld, KEMPLD_WDT_STAGE_TIMEOUT(stage->id));
	prescaler = kempld_prescaler[STAGE_CFG_GET_PRESCALER(stage_cfg)];

	stage_timeout = (stage_timeout & stage->mask) * prescaler;
	remainder = do_div(stage_timeout, pld->pld_clock);
	if (remainder)
		stage_timeout++;

	timeout = stage_timeout;
	WARN_ON_ONCE(timeout != stage_timeout);

	return timeout;
}

static int kempld_wdt_set_timeout(struct watchdog_device *wdd,
					unsigned int timeout)
{
	struct kempld_wdt_data *wdt_data = watchdog_get_drvdata(wdd);
	struct kempld_wdt_stage *pretimeout_stage;
	struct kempld_wdt_stage *timeout_stage;
	int ret;

	timeout_stage = &wdt_data->stage[STAGE_TIMEOUT];
	pretimeout_stage = &wdt_data->stage[STAGE_PRETIMEOUT];

	if (pretimeout_stage->mask && wdt_data->pretimeout > 0)
		timeout = wdt_data->pretimeout;

	ret = kempld_wdt_set_stage_action(wdt_data, timeout_stage,
						ACTION_RESET);
	if (ret)
		return ret;
	ret = kempld_wdt_set_stage_timeout(wdt_data, timeout_stage,
						timeout);
	if (ret)
		return ret;

	wdd->timeout = timeout;
	return 0;
}

static int kempld_wdt_set_pretimeout(struct watchdog_device *wdd,
					unsigned int pretimeout)
{
	struct kempld_wdt_data *wdt_data = watchdog_get_drvdata(wdd);
	struct kempld_wdt_stage *pretimeout_stage;
	u8 action = ACTION_NONE;
	int ret;

	pretimeout_stage = &wdt_data->stage[STAGE_PRETIMEOUT];

	if (!pretimeout_stage->mask)
		return -ENXIO;

	if (pretimeout > wdd->timeout)
		return -EINVAL;

	if (pretimeout > 0)
		action = ACTION_NMI;

	ret = kempld_wdt_set_stage_action(wdt_data, pretimeout_stage,
						action);
	if (ret)
		return ret;
	ret = kempld_wdt_set_stage_timeout(wdt_data, pretimeout_stage,
						wdd->timeout - pretimeout);
	if (ret)
		return ret;

	wdt_data->pretimeout = pretimeout;
	return 0;
}

static void kempld_wdt_update_timeouts(struct kempld_wdt_data *wdt_data)
{
	struct kempld_device_data *pld = wdt_data->pld;
	struct kempld_wdt_stage *pretimeout_stage;
	struct kempld_wdt_stage *timeout_stage;
	unsigned int pretimeout, timeout;

	pretimeout_stage = &wdt_data->stage[STAGE_PRETIMEOUT];
	timeout_stage = &wdt_data->stage[STAGE_TIMEOUT];

	kempld_get_mutex(pld);
	pretimeout = kempld_wdt_get_timeout(wdt_data, pretimeout_stage);
	timeout = kempld_wdt_get_timeout(wdt_data, timeout_stage);
	kempld_release_mutex(pld);

	if (pretimeout)
		wdt_data->pretimeout = timeout;
	else
		wdt_data->pretimeout = 0;

	wdt_data->wdd.timeout = pretimeout + timeout;
}

static int kempld_wdt_start(struct watchdog_device *wdd)
{
	struct kempld_wdt_data *wdt_data = watchdog_get_drvdata(wdd);
	struct kempld_device_data *pld = wdt_data->pld;
	u8 status;
	int ret;

	ret = kempld_wdt_set_timeout(wdd, wdd->timeout);
	if (ret)
		return ret;

	kempld_get_mutex(pld);
	status = kempld_read8(pld, KEMPLD_WDT_CFG);
	status |= KEMPLD_WDT_CFG_ENABLE;
	kempld_write8(pld, KEMPLD_WDT_CFG, status);
	status = kempld_read8(pld, KEMPLD_WDT_CFG);
	kempld_release_mutex(pld);

	/* Check if the watchdog was enabled */
	if (!(status & KEMPLD_WDT_CFG_ENABLE))
		return -EACCES;

	return 0;
}

static int kempld_wdt_stop(struct watchdog_device *wdd)
{
	struct kempld_wdt_data *wdt_data = watchdog_get_drvdata(wdd);
	struct kempld_device_data *pld = wdt_data->pld;
	u8 status;

	kempld_get_mutex(pld);
	status = kempld_read8(pld, KEMPLD_WDT_CFG);
	status &= ~KEMPLD_WDT_CFG_ENABLE;
	kempld_write8(pld, KEMPLD_WDT_CFG, status);
	status = kempld_read8(pld, KEMPLD_WDT_CFG);
	kempld_release_mutex(pld);

	/* Check if the watchdog was disabled */
	if (status & KEMPLD_WDT_CFG_ENABLE)
		return -EACCES;

	return 0;
}

static int kempld_wdt_keepalive(struct watchdog_device *wdd)
{
	struct kempld_wdt_data *wdt_data = watchdog_get_drvdata(wdd);
	struct kempld_device_data *pld = wdt_data->pld;

	kempld_get_mutex(pld);
	kempld_write8(pld, KEMPLD_WDT_KICK, 'K');
	kempld_release_mutex(pld);

	return 0;
}

static long kempld_wdt_ioctl(struct watchdog_device *wdd, unsigned int cmd,
				unsigned long arg)
{
	struct kempld_wdt_data *wdt_data = watchdog_get_drvdata(wdd);
	void __user *argp = (void __user *)arg;
	int ret = -ENOIOCTLCMD;
	int __user *p = argp;
	int new_value;

	switch (cmd) {
	case WDIOC_SETPRETIMEOUT:
		if (get_user(new_value, p))
			return -EFAULT;
		ret = kempld_wdt_set_pretimeout(wdd, new_value);
		if (ret)
			return ret;
		ret = kempld_wdt_keepalive(wdd);
		break;
	case WDIOC_GETPRETIMEOUT:
		ret = put_user(wdt_data->pretimeout, (int *)arg);
		break;
	}

	return ret;
}

static int kempld_wdt_probe_stages(struct watchdog_device *wdd)
{
	struct kempld_wdt_data *wdt_data = watchdog_get_drvdata(wdd);
	struct kempld_device_data *pld = wdt_data->pld;
	struct kempld_wdt_stage *pretimeout_stage;
	struct kempld_wdt_stage *timeout_stage;
	u8 index, data, data_orig;
	u32 mask;
	int i, j;

	pretimeout_stage = &wdt_data->stage[STAGE_PRETIMEOUT];
	timeout_stage = &wdt_data->stage[STAGE_TIMEOUT];

	pretimeout_stage->mask = 0;
	timeout_stage->mask = 0;

	for (i = 0; i < 3; i++) {
		index = KEMPLD_WDT_STAGE_TIMEOUT(i);
		mask = 0;

		kempld_get_mutex(pld);
		/* Probe each byte individually. */
		for (j = 0; j < 4; j++) {
			data_orig = kempld_read8(pld, index + j);
			kempld_write8(pld, index + j, 0x00);
			data = kempld_read8(pld, index + j);
			/* A failed write means this byte is reserved */
			if (data != 0x00)
				break;
			kempld_write8(pld, index + j, data_orig);
			mask |= 0xff << (j * 8);
		}
		kempld_release_mutex(pld);

		/* Assign available stages to timeout and pretimeout */
		if (!timeout_stage->mask) {
			timeout_stage->mask = mask;
			timeout_stage->id = i;
		} else {
			if (pld->feature_mask & KEMPLD_FEATURE_BIT_NMI) {
				pretimeout_stage->mask = timeout_stage->mask;
				timeout_stage->mask = mask;
				pretimeout_stage->id = timeout_stage->id;
				timeout_stage->id = i;
			}
			break;
		}
	}

	if (!timeout_stage->mask)
		return -ENODEV;

	return 0;
}

static struct watchdog_info kempld_wdt_info = {
	.identity	= "KEMPLD Watchdog",
	.options	= WDIOF_SETTIMEOUT |
			WDIOF_KEEPALIVEPING |
			WDIOF_MAGICCLOSE |
			WDIOF_PRETIMEOUT
};

static struct watchdog_ops kempld_wdt_ops = {
	.owner		= THIS_MODULE,
	.start		= kempld_wdt_start,
	.stop		= kempld_wdt_stop,
	.ping		= kempld_wdt_keepalive,
	.set_timeout	= kempld_wdt_set_timeout,
	.ioctl		= kempld_wdt_ioctl,
};

static int kempld_wdt_probe(struct platform_device *pdev)
{
	struct kempld_device_data *pld = dev_get_drvdata(pdev->dev.parent);
	struct kempld_wdt_data *wdt_data;
	struct device *dev = &pdev->dev;
	struct watchdog_device *wdd;
	u8 status;
	int ret = 0;

	wdt_data = devm_kzalloc(dev, sizeof(*wdt_data), GFP_KERNEL);
	if (!wdt_data)
		return -ENOMEM;

	wdt_data->pld = pld;
	wdd = &wdt_data->wdd;
	wdd->parent = dev;

	kempld_get_mutex(pld);
	status = kempld_read8(pld, KEMPLD_WDT_CFG);
	kempld_release_mutex(pld);

	/* Enable nowayout if watchdog is already locked */
	if (status & (KEMPLD_WDT_CFG_ENABLE_LOCK |
			KEMPLD_WDT_CFG_GLOBAL_LOCK)) {
		if (!nowayout)
			dev_warn(dev,
				"Forcing nowayout - watchdog lock enabled!\n");
		nowayout = true;
	}

	wdd->info = &kempld_wdt_info;
	wdd->ops = &kempld_wdt_ops;

	watchdog_set_drvdata(wdd, wdt_data);
	watchdog_set_nowayout(wdd, nowayout);

	ret = kempld_wdt_probe_stages(wdd);
	if (ret)
		return ret;

	kempld_wdt_set_timeout(wdd, timeout);
	kempld_wdt_set_pretimeout(wdd, pretimeout);

	/* Check if watchdog is already enabled */
	if (status & KEMPLD_WDT_CFG_ENABLE) {
		/* Get current watchdog settings */
		kempld_wdt_update_timeouts(wdt_data);
		dev_info(dev, "Watchdog was already enabled\n");
	}

	platform_set_drvdata(pdev, wdt_data);
	ret = watchdog_register_device(wdd);
	if (ret)
		return ret;

	dev_info(dev, "Watchdog registered with %ds timeout\n", wdd->timeout);

	return 0;
}

static void kempld_wdt_shutdown(struct platform_device *pdev)
{
	struct kempld_wdt_data *wdt_data = platform_get_drvdata(pdev);

	kempld_wdt_stop(&wdt_data->wdd);
}

static int kempld_wdt_remove(struct platform_device *pdev)
{
	struct kempld_wdt_data *wdt_data = platform_get_drvdata(pdev);
	struct watchdog_device *wdd = &wdt_data->wdd;
	int ret = 0;

	if (!nowayout)
		ret = kempld_wdt_stop(wdd);
	watchdog_unregister_device(wdd);

	return ret;
}

#ifdef CONFIG_PM
/* Disable watchdog if it is active during suspend */
static int kempld_wdt_suspend(struct platform_device *pdev,
				pm_message_t message)
{
	struct kempld_wdt_data *wdt_data = platform_get_drvdata(pdev);
	struct kempld_device_data *pld = wdt_data->pld;
	struct watchdog_device *wdd = &wdt_data->wdd;

	kempld_get_mutex(pld);
	wdt_data->pm_status_store = kempld_read8(pld, KEMPLD_WDT_CFG);
	kempld_release_mutex(pld);

	kempld_wdt_update_timeouts(wdt_data);

	if (wdt_data->pm_status_store & KEMPLD_WDT_CFG_ENABLE)
		return kempld_wdt_stop(wdd);

	return 0;
}

/* Enable watchdog and configure it if necessary */
static int kempld_wdt_resume(struct platform_device *pdev)
{
	struct kempld_wdt_data *wdt_data = platform_get_drvdata(pdev);
	struct watchdog_device *wdd = &wdt_data->wdd;

	/*
	 * If watchdog was stopped before suspend be sure it gets disabled
	 * again, for the case BIOS has enabled it during resume
	 */
	if (wdt_data->pm_status_store & KEMPLD_WDT_CFG_ENABLE)
		return kempld_wdt_start(wdd);
	else
		return kempld_wdt_stop(wdd);
}
#else
#define kempld_wdt_suspend	NULL
#define kempld_wdt_resume	NULL
#endif

static struct platform_driver kempld_wdt_driver = {
	.driver		= {
		.name	= "kempld-wdt",
		.owner	= THIS_MODULE,
	},
	.probe		= kempld_wdt_probe,
	.remove		= kempld_wdt_remove,
	.shutdown	= kempld_wdt_shutdown,
	.suspend	= kempld_wdt_suspend,
	.resume		= kempld_wdt_resume,
};

module_platform_driver(kempld_wdt_driver);

MODULE_DESCRIPTION("KEM PLD Watchdog Driver");
MODULE_AUTHOR("Michael Brunner <michael.brunner@kontron.com>");
MODULE_LICENSE("GPL");
MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
