/*
 * Watchdog driver for TS-4800 based boards
 *
 * Copyright (c) 2015 - Savoir-faire Linux
 *
 * 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.
 */

#include <linux/kernel.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/watchdog.h>

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

/* possible feed values */
#define TS4800_WDT_FEED_2S       0x1
#define TS4800_WDT_FEED_10S      0x2
#define TS4800_WDT_DISABLE       0x3

struct ts4800_wdt {
	struct watchdog_device  wdd;
	struct regmap           *regmap;
	u32                     feed_offset;
	u32                     feed_val;
};

/*
 * TS-4800 supports the following timeout values:
 *
 *   value desc
 *   ---------------------
 *     0    feed for 338ms
 *     1    feed for 2.706s
 *     2    feed for 10.824s
 *     3    disable watchdog
 *
 * Keep the regmap/timeout map ordered by timeout
 */
static const struct {
	const int timeout;
	const int regval;
} ts4800_wdt_map[] = {
	{ 2,  TS4800_WDT_FEED_2S },
	{ 10, TS4800_WDT_FEED_10S },
};

#define MAX_TIMEOUT_INDEX       (ARRAY_SIZE(ts4800_wdt_map) - 1)

static void ts4800_write_feed(struct ts4800_wdt *wdt, u32 val)
{
	regmap_write(wdt->regmap, wdt->feed_offset, val);
}

static int ts4800_wdt_start(struct watchdog_device *wdd)
{
	struct ts4800_wdt *wdt = watchdog_get_drvdata(wdd);

	ts4800_write_feed(wdt, wdt->feed_val);
	return 0;
}

static int ts4800_wdt_stop(struct watchdog_device *wdd)
{
	struct ts4800_wdt *wdt = watchdog_get_drvdata(wdd);

	ts4800_write_feed(wdt, TS4800_WDT_DISABLE);
	return 0;
}

static int ts4800_wdt_set_timeout(struct watchdog_device *wdd,
				  unsigned int timeout)
{
	struct ts4800_wdt *wdt = watchdog_get_drvdata(wdd);
	int i;

	for (i = 0; i < MAX_TIMEOUT_INDEX; i++) {
		if (ts4800_wdt_map[i].timeout >= timeout)
			break;
	}

	wdd->timeout = ts4800_wdt_map[i].timeout;
	wdt->feed_val = ts4800_wdt_map[i].regval;

	return 0;
}

static const struct watchdog_ops ts4800_wdt_ops = {
	.owner = THIS_MODULE,
	.start = ts4800_wdt_start,
	.stop = ts4800_wdt_stop,
	.set_timeout = ts4800_wdt_set_timeout,
};

static const struct watchdog_info ts4800_wdt_info = {
	.options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING,
	.identity = "TS-4800 Watchdog",
};

static int ts4800_wdt_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct device_node *np = dev->of_node;
	struct device_node *syscon_np;
	struct watchdog_device *wdd;
	struct ts4800_wdt *wdt;
	u32 reg;
	int ret;

	syscon_np = of_parse_phandle(np, "syscon", 0);
	if (!syscon_np) {
		dev_err(dev, "no syscon property\n");
		return -ENODEV;
	}

	ret = of_property_read_u32_index(np, "syscon", 1, &reg);
	if (ret < 0) {
		dev_err(dev, "no offset in syscon\n");
		return ret;
	}

	/* allocate memory for watchdog struct */
	wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
	if (!wdt)
		return -ENOMEM;

	/* set regmap and offset to know where to write */
	wdt->feed_offset = reg;
	wdt->regmap = syscon_node_to_regmap(syscon_np);
	of_node_put(syscon_np);
	if (IS_ERR(wdt->regmap)) {
		dev_err(dev, "cannot get parent's regmap\n");
		return PTR_ERR(wdt->regmap);
	}

	/* Initialize struct watchdog_device */
	wdd = &wdt->wdd;
	wdd->parent = dev;
	wdd->info = &ts4800_wdt_info;
	wdd->ops = &ts4800_wdt_ops;
	wdd->min_timeout = ts4800_wdt_map[0].timeout;
	wdd->max_timeout = ts4800_wdt_map[MAX_TIMEOUT_INDEX].timeout;

	watchdog_set_drvdata(wdd, wdt);
	watchdog_set_nowayout(wdd, nowayout);
	watchdog_init_timeout(wdd, 0, dev);

	/*
	 * As this watchdog supports only a few values, ts4800_wdt_set_timeout
	 * must be called to initialize timeout and feed_val with valid values.
	 * Default to maximum timeout if none, or an invalid one, is provided in
	 * device tree.
	 */
	if (!wdd->timeout)
		wdd->timeout = wdd->max_timeout;
	ts4800_wdt_set_timeout(wdd, wdd->timeout);

	/*
	 * The feed register is write-only, so it is not possible to determine
	 * watchdog's state. Disable it to be in a known state.
	 */
	ts4800_wdt_stop(wdd);

	ret = devm_watchdog_register_device(dev, wdd);
	if (ret) {
		dev_err(dev, "failed to register watchdog device\n");
		return ret;
	}

	platform_set_drvdata(pdev, wdt);

	dev_info(dev, "initialized (timeout = %d sec, nowayout = %d)\n",
		 wdd->timeout, nowayout);

	return 0;
}

static const struct of_device_id ts4800_wdt_of_match[] = {
	{ .compatible = "technologic,ts4800-wdt", },
	{ },
};
MODULE_DEVICE_TABLE(of, ts4800_wdt_of_match);

static struct platform_driver ts4800_wdt_driver = {
	.probe		= ts4800_wdt_probe,
	.driver		= {
		.name	= "ts4800_wdt",
		.of_match_table = ts4800_wdt_of_match,
	},
};

module_platform_driver(ts4800_wdt_driver);

MODULE_AUTHOR("Damien Riegel <damien.riegel@savoirfairelinux.com>");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:ts4800_wdt");
