/*
 * Copyright (C) 2016 Freescale Semiconductor, Inc.
 *
 * 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/io.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/reboot.h>
#include <linux/watchdog.h>

#define WDOG_CS			0x0
#define WDOG_CS_CMD32EN		(1 << 13)
#define WDOG_CS_ULK		(1 << 11)
#define WDOG_CS_RCS		(1 << 10)
#define WDOG_CS_EN		(1 << 7)
#define WDOG_CS_UPDATE		(1 << 5)

#define WDOG_CNT	0x4
#define WDOG_TOVAL	0x8

#define REFRESH_SEQ0	0xA602
#define REFRESH_SEQ1	0xB480
#define REFRESH		((REFRESH_SEQ1 << 16) | (REFRESH_SEQ0))

#define UNLOCK_SEQ0	0xC520
#define UNLOCK_SEQ1	0xD928
#define UNLOCK		((UNLOCK_SEQ1 << 16) | (UNLOCK_SEQ0))

struct imx7ulp_wdt {
	void __iomem *base;
	int rate;
	struct watchdog_device wdd;
	struct notifier_block restart_handler;
};

static inline void imx7ulp_wdt_enable(void __iomem *base, bool enable)
{
	u32 val = readl(base + WDOG_CS);

	local_irq_disable();

	writel(UNLOCK, base + WDOG_CNT);
	if (enable)
		writel(val | WDOG_CS_EN, base + WDOG_CS);
	else
		writel(val & ~WDOG_CS_EN, base + WDOG_CS);

	local_irq_enable();
}

static inline bool imx7ulp_wdt_is_enabled(void __iomem *base)
{
	u32 val = readl(base + WDOG_CS);

	return val & WDOG_CS_EN;
}

static int imx7ulp_wdt_ping(struct watchdog_device *wdog)
{
	/* refresh the wdt counter to keepalive */
	struct imx7ulp_wdt *wdt = watchdog_get_drvdata(wdog);
	local_irq_disable();
	writel(REFRESH, wdt->base + WDOG_CNT);
	local_irq_enable();
	return 0;
}

static int imx7ulp_wdt_start(struct watchdog_device *wdog)
{
	struct imx7ulp_wdt *wdt = watchdog_get_drvdata(wdog);
	imx7ulp_wdt_enable(wdt->base, true);

	return 0;
}

static int imx7ulp_wdt_stop(struct watchdog_device *wdog)
{
	struct imx7ulp_wdt *wdt = watchdog_get_drvdata(wdog);
	imx7ulp_wdt_enable(wdt->base, false);

	return 0;
}

static int imx7ulp_wdt_set_timeout(struct watchdog_device *wdog, unsigned int timeout)
{
	struct imx7ulp_wdt *wdt = watchdog_get_drvdata(wdog);
	u32 val = wdt->rate * timeout;

	local_irq_disable();

	writel(UNLOCK, wdt->base + WDOG_CNT);
	writel(val, wdt->base + WDOG_TOVAL);

	local_irq_enable();

	wdog->timeout = timeout;

	imx7ulp_wdt_ping(wdog);

	return 0;
}

static const struct watchdog_ops imx7ulp_wdt_ops = {
	.owner = THIS_MODULE,
	.start = imx7ulp_wdt_start,
	.stop  = imx7ulp_wdt_stop,
	.ping  = imx7ulp_wdt_ping,
	.set_timeout = imx7ulp_wdt_set_timeout,
};

static const struct watchdog_info imx7ulp_wdt_info = {
	.identity	= "i.MX7ULP watchdog timer",
	.options	= WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING
			 | WDIOF_MAGICCLOSE,
};

static int imx7ulp_wdt_restart_handler(struct notifier_block *this,
			 unsigned long action, void *data)
{
	struct imx7ulp_wdt *wdt = container_of(this, struct imx7ulp_wdt, restart_handler);

	local_irq_disable();

	imx7ulp_wdt_enable(wdt->base, true);
	imx7ulp_wdt_set_timeout(&wdt->wdd, 1);

	local_irq_enable();

	/* wait for wdog to fire */
	while(true)
		;

	return NOTIFY_DONE;
}

static inline void imx7ulp_wdt_init(void __iomem *base, unsigned int timeout)
{
	u32 val;

	local_irq_disable();

	/* unlock the wdog for reconfiguration */
	writel_relaxed(UNLOCK_SEQ0, base + WDOG_CNT);
	writel_relaxed(UNLOCK_SEQ1, base + WDOG_CNT);

	/*set an initial timeout value in TOVAL */
	writel(timeout, base + WDOG_TOVAL);
	/* enable 32bit command sequence and reconfigure */
	val = (1 << 13) | (1 << 8) | (1 << 5);
	writel(val, base + WDOG_CS);

	local_irq_enable();
}

static int imx7ulp_wdt_probe(struct platform_device *pdev)
{
	struct imx7ulp_wdt *wdt;
	struct resource *res;
	int err;
	u32 timeout;

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

	platform_set_drvdata(pdev, wdt);

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

	/* use the 1KHz LPO as the counter clock */
	wdt->rate = 1000;

	/* init the wdd */
	wdt->wdd.info = &imx7ulp_wdt_info;
	wdt->wdd.ops = &imx7ulp_wdt_ops;
	wdt->wdd.min_timeout = 1;
	wdt->wdd.max_timeout = 60;
	wdt->wdd.parent = &pdev->dev;
	watchdog_set_drvdata(&wdt->wdd, wdt);
	/*
	 * set the timeout_parm to 0 to get the timeout
	 * from 'timeout-sec' property in dtb.
	 */
	err = watchdog_init_timeout(&wdt->wdd, 0, &pdev->dev);
	if (err) {
		dev_err(&pdev->dev, "Failed to init the wdog timeout\n");
		return err;
	}

	timeout = wdt->wdd.timeout * wdt->rate;
	/* reconfigure the watchdog timer.*/
	imx7ulp_wdt_init(wdt->base, timeout);

	err = watchdog_register_device(&wdt->wdd);
	if (err) {
		dev_err(&pdev->dev, "Failed to register watchdog device\n");
		return err;
	}

	wdt->restart_handler.notifier_call = imx7ulp_wdt_restart_handler;
	wdt->restart_handler.priority = 128;
	err = register_restart_handler(&wdt->restart_handler);
	if (err) {
		dev_err(&pdev->dev, "cannot register restart handler\n");
		watchdog_unregister_device(&wdt->wdd);
		return err;
	}

	return 0;
}

static int imx7ulp_wdt_remove(struct platform_device *pdev)
{
	struct imx7ulp_wdt *wdt = platform_get_drvdata(pdev);

	imx7ulp_wdt_stop(&wdt->wdd);

	watchdog_unregister_device(&wdt->wdd);

	return 0;
}

static void imx7ulp_wdt_shutdown(struct platform_device *pdev)
{
	struct imx7ulp_wdt *wdt = platform_get_drvdata(pdev);

	if (watchdog_active(&wdt->wdd))
		imx7ulp_wdt_stop(&wdt->wdd);
}

#ifdef CONFIG_PM_SLEEP
/* Disable watchdog before suspend */
static int imx7ulp_wdt_suspend(struct device *dev)
{
	struct imx7ulp_wdt *wdt = dev_get_drvdata(dev);

	imx7ulp_wdt_enable(wdt->base, false);

	return 0;
}

static int imx7ulp_wdt_resume(struct device *dev)
{
	struct imx7ulp_wdt *wdt = dev_get_drvdata(dev);
	u32 timeout = wdt->wdd.timeout * wdt->rate;

	if (imx7ulp_wdt_is_enabled(wdt->base))
		imx7ulp_wdt_init(wdt->base, timeout);

	if (watchdog_active(&wdt->wdd))
		imx7ulp_wdt_enable(wdt->base, true);

	return 0;
}
#endif

static SIMPLE_DEV_PM_OPS(imx7ulp_wdt_pm_ops, imx7ulp_wdt_suspend,
			 imx7ulp_wdt_resume);

static const struct of_device_id imx7ulp_wdt_dt_ids[] = {
	{ .compatible = "fsl,imx7ulp-wdt", },
	{ /*sentinel */ }
};
MODULE_DEVICE_TABLE(of, imx7ulp_wdt_dt_ids);

static struct platform_driver imx7ulp_wdt_driver = {
	.probe		= imx7ulp_wdt_probe,
	.remove		= imx7ulp_wdt_remove,
	.shutdown	= imx7ulp_wdt_shutdown,
	.driver		= {
		.name	= "imx7ulp-wdt",
		.pm	= &imx7ulp_wdt_pm_ops,
		.of_match_table = imx7ulp_wdt_dt_ids,
	},
};

module_platform_driver(imx7ulp_wdt_driver);

MODULE_AUTHOR("Bai Ping <ping.bai@nxp.com>");
MODULE_DESCRIPTION("Freescale i.MX7ULP watchdog driver");
MODULE_LICENSE("GPL v2");
