/*
 * Copyright (C) ST-Ericsson SA 2011-2013
 *
 * License Terms: GNU General Public License v2
 *
 * Author: Mathieu Poirier <mathieu.poirier@linaro.org> for ST-Ericsson
 * Author: Jonas Aaberg <jonas.aberg@stericsson.com> for ST-Ericsson
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/moduleparam.h>
#include <linux/err.h>
#include <linux/uaccess.h>
#include <linux/watchdog.h>
#include <linux/platform_device.h>
#include <linux/platform_data/ux500_wdt.h>

#include <linux/mfd/dbx500-prcmu.h>

#define WATCHDOG_TIMEOUT 600 /* 10 minutes */

#define WATCHDOG_MIN	0
#define WATCHDOG_MAX28	268435  /* 28 bit resolution in ms == 268435.455 s */
#define WATCHDOG_MAX32	4294967 /* 32 bit resolution in ms == 4294967.295 s */

static unsigned int timeout = WATCHDOG_TIMEOUT;
module_param(timeout, uint, 0);
MODULE_PARM_DESC(timeout,
	"Watchdog timeout in seconds. 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) ")");

static int ux500_wdt_start(struct watchdog_device *wdd)
{
	return prcmu_enable_a9wdog(PRCMU_WDOG_ALL);
}

static int ux500_wdt_stop(struct watchdog_device *wdd)
{
	return prcmu_disable_a9wdog(PRCMU_WDOG_ALL);
}

static int ux500_wdt_keepalive(struct watchdog_device *wdd)
{
	return prcmu_kick_a9wdog(PRCMU_WDOG_ALL);
}

static int ux500_wdt_set_timeout(struct watchdog_device *wdd,
				 unsigned int timeout)
{
	ux500_wdt_stop(wdd);
	prcmu_load_a9wdog(PRCMU_WDOG_ALL, timeout * 1000);
	ux500_wdt_start(wdd);

	return 0;
}

static const struct watchdog_info ux500_wdt_info = {
	.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
	.identity = "Ux500 WDT",
	.firmware_version = 1,
};

static const struct watchdog_ops ux500_wdt_ops = {
	.owner = THIS_MODULE,
	.start = ux500_wdt_start,
	.stop  = ux500_wdt_stop,
	.ping  = ux500_wdt_keepalive,
	.set_timeout = ux500_wdt_set_timeout,
};

static struct watchdog_device ux500_wdt = {
	.info = &ux500_wdt_info,
	.ops = &ux500_wdt_ops,
	.min_timeout = WATCHDOG_MIN,
	.max_timeout = WATCHDOG_MAX32,
};

static int ux500_wdt_probe(struct platform_device *pdev)
{
	int ret;
	struct ux500_wdt_data *pdata = dev_get_platdata(&pdev->dev);

	if (pdata) {
		if (pdata->timeout > 0)
			timeout = pdata->timeout;
		if (pdata->has_28_bits_resolution)
			ux500_wdt.max_timeout = WATCHDOG_MAX28;
	}

	ux500_wdt.parent = &pdev->dev;
	watchdog_set_nowayout(&ux500_wdt, nowayout);

	/* disable auto off on sleep */
	prcmu_config_a9wdog(PRCMU_WDOG_CPU1, false);

	/* set HW initial value */
	prcmu_load_a9wdog(PRCMU_WDOG_ALL, timeout * 1000);

	ret = watchdog_register_device(&ux500_wdt);
	if (ret)
		return ret;

	dev_info(&pdev->dev, "initialized\n");

	return 0;
}

static int ux500_wdt_remove(struct platform_device *dev)
{
	watchdog_unregister_device(&ux500_wdt);

	return 0;
}

#ifdef CONFIG_PM
static int ux500_wdt_suspend(struct platform_device *pdev,
			     pm_message_t state)
{
	if (watchdog_active(&ux500_wdt)) {
		ux500_wdt_stop(&ux500_wdt);
		prcmu_config_a9wdog(PRCMU_WDOG_CPU1, true);

		prcmu_load_a9wdog(PRCMU_WDOG_ALL, timeout * 1000);
		ux500_wdt_start(&ux500_wdt);
	}
	return 0;
}

static int ux500_wdt_resume(struct platform_device *pdev)
{
	if (watchdog_active(&ux500_wdt)) {
		ux500_wdt_stop(&ux500_wdt);
		prcmu_config_a9wdog(PRCMU_WDOG_CPU1, false);

		prcmu_load_a9wdog(PRCMU_WDOG_ALL, timeout * 1000);
		ux500_wdt_start(&ux500_wdt);
	}
	return 0;
}
#else
#define ux500_wdt_suspend NULL
#define ux500_wdt_resume NULL
#endif

static struct platform_driver ux500_wdt_driver = {
	.probe		= ux500_wdt_probe,
	.remove		= ux500_wdt_remove,
	.suspend	= ux500_wdt_suspend,
	.resume		= ux500_wdt_resume,
	.driver		= {
		.name	= "ux500_wdt",
	},
};

module_platform_driver(ux500_wdt_driver);

MODULE_AUTHOR("Jonas Aaberg <jonas.aberg@stericsson.com>");
MODULE_DESCRIPTION("Ux500 Watchdog Driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:ux500_wdt");
