/*
 *  Copyright (C) 2015 Mans Rullgard <mans@mansr.com>
 *  SMP86xx/SMP87xx Watchdog driver
 *
 *  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.
 */

#include <linux/bitops.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/notifier.h>
#include <linux/platform_device.h>
#include <linux/reboot.h>
#include <linux/watchdog.h>

#define DEFAULT_TIMEOUT 30

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 unsigned int timeout;
module_param(timeout, int, 0);
MODULE_PARM_DESC(timeout, "Watchdog timeout");

/*
 * Counter counts down from programmed value.  Reset asserts when
 * the counter reaches 1.
 */
#define WD_COUNTER		0

#define WD_CONFIG		4
#define WD_CONFIG_XTAL_IN	BIT(0)
#define WD_CONFIG_DISABLE	BIT(31)

struct tangox_wdt_device {
	struct watchdog_device wdt;
	void __iomem *base;
	unsigned long clk_rate;
	struct clk *clk;
	struct notifier_block restart;
};

static int tangox_wdt_set_timeout(struct watchdog_device *wdt,
				  unsigned int new_timeout)
{
	wdt->timeout = new_timeout;

	return 0;
}

static int tangox_wdt_start(struct watchdog_device *wdt)
{
	struct tangox_wdt_device *dev = watchdog_get_drvdata(wdt);
	u32 ticks;

	ticks = 1 + wdt->timeout * dev->clk_rate;
	writel(ticks, dev->base + WD_COUNTER);

	return 0;
}

static int tangox_wdt_stop(struct watchdog_device *wdt)
{
	struct tangox_wdt_device *dev = watchdog_get_drvdata(wdt);

	writel(0, dev->base + WD_COUNTER);

	return 0;
}

static unsigned int tangox_wdt_get_timeleft(struct watchdog_device *wdt)
{
	struct tangox_wdt_device *dev = watchdog_get_drvdata(wdt);
	u32 count;

	count = readl(dev->base + WD_COUNTER);

	if (!count)
		return 0;

	return (count - 1) / dev->clk_rate;
}

static const struct watchdog_info tangox_wdt_info = {
	.options  = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
	.identity = "tangox watchdog",
};

static const struct watchdog_ops tangox_wdt_ops = {
	.start		= tangox_wdt_start,
	.stop		= tangox_wdt_stop,
	.set_timeout	= tangox_wdt_set_timeout,
	.get_timeleft	= tangox_wdt_get_timeleft,
};

static int tangox_wdt_restart(struct notifier_block *nb, unsigned long action,
			      void *data)
{
	struct tangox_wdt_device *dev =
		container_of(nb, struct tangox_wdt_device, restart);

	writel(1, dev->base + WD_COUNTER);

	return NOTIFY_DONE;
}

static int tangox_wdt_probe(struct platform_device *pdev)
{
	struct tangox_wdt_device *dev;
	struct resource *res;
	u32 config;
	int err;

	dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
	if (!dev)
		return -ENOMEM;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	dev->base = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(dev->base))
		return PTR_ERR(dev->base);

	dev->clk = devm_clk_get(&pdev->dev, NULL);
	if (IS_ERR(dev->clk))
		return PTR_ERR(dev->clk);

	err = clk_prepare_enable(dev->clk);
	if (err)
		return err;

	dev->clk_rate = clk_get_rate(dev->clk);
	if (!dev->clk_rate) {
		err = -EINVAL;
		goto err;
	}

	dev->wdt.parent = &pdev->dev;
	dev->wdt.info = &tangox_wdt_info;
	dev->wdt.ops = &tangox_wdt_ops;
	dev->wdt.timeout = DEFAULT_TIMEOUT;
	dev->wdt.min_timeout = 1;
	dev->wdt.max_timeout = (U32_MAX - 1) / dev->clk_rate;

	watchdog_init_timeout(&dev->wdt, timeout, &pdev->dev);
	watchdog_set_nowayout(&dev->wdt, nowayout);
	watchdog_set_drvdata(&dev->wdt, dev);

	/*
	 * Deactivate counter if disable bit is set to avoid
	 * accidental reset.
	 */
	config = readl(dev->base + WD_CONFIG);
	if (config & WD_CONFIG_DISABLE)
		writel(0, dev->base + WD_COUNTER);

	writel(WD_CONFIG_XTAL_IN, dev->base + WD_CONFIG);

	/*
	 * Mark as active and restart with configured timeout if
	 * already running.
	 */
	if (readl(dev->base + WD_COUNTER)) {
		set_bit(WDOG_ACTIVE, &dev->wdt.status);
		tangox_wdt_start(&dev->wdt);
	}

	err = watchdog_register_device(&dev->wdt);
	if (err)
		goto err;

	platform_set_drvdata(pdev, dev);

	dev->restart.notifier_call = tangox_wdt_restart;
	dev->restart.priority = 128;
	err = register_restart_handler(&dev->restart);
	if (err)
		dev_warn(&pdev->dev, "failed to register restart handler\n");

	dev_info(&pdev->dev, "SMP86xx/SMP87xx watchdog registered\n");

	return 0;

 err:
	clk_disable_unprepare(dev->clk);
	return err;
}

static int tangox_wdt_remove(struct platform_device *pdev)
{
	struct tangox_wdt_device *dev = platform_get_drvdata(pdev);

	tangox_wdt_stop(&dev->wdt);
	clk_disable_unprepare(dev->clk);

	unregister_restart_handler(&dev->restart);
	watchdog_unregister_device(&dev->wdt);

	return 0;
}

static const struct of_device_id tangox_wdt_dt_ids[] = {
	{ .compatible = "sigma,smp8642-wdt" },
	{ .compatible = "sigma,smp8759-wdt" },
	{ }
};
MODULE_DEVICE_TABLE(of, tangox_wdt_dt_ids);

static struct platform_driver tangox_wdt_driver = {
	.probe	= tangox_wdt_probe,
	.remove	= tangox_wdt_remove,
	.driver	= {
		.name		= "tangox-wdt",
		.of_match_table	= tangox_wdt_dt_ids,
	},
};

module_platform_driver(tangox_wdt_driver);

MODULE_AUTHOR("Mans Rullgard <mans@mansr.com>");
MODULE_DESCRIPTION("SMP86xx/SMP87xx Watchdog driver");
MODULE_LICENSE("GPL");
