// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2019 Synaptics Incorporated
 *
 * Author: Jisheng Zhang <jszhang@kernel.org>
 */

#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/reset.h>
#include <linux/watchdog.h>

#define CONTROL			0x00
#define WD_CONTROL		0x04
#define INT_STAT		0x08
#define TERMINAL_COUNT		0x0c
#define RESET_TERMINAL_COUNT	0x10
#define WD_CMD_WINDOWN		0x14
#define CURRENT_COUNT		0x18

struct as390_wdt {
	void __iomem		*base;
	unsigned long		rate;
	struct watchdog_device	wdd;
	struct reset_control	*rst;
	struct clk		*clk;
};

static inline u32 rdl(struct as390_wdt *wdt, u32 offset)
{
	return readl_relaxed(wdt->base + offset);
}

static inline void wrl(struct as390_wdt *wdt, u32 offset, u32 data)
{
	writel_relaxed(data, wdt->base + offset);
}

static int as390_wdt_ping(struct watchdog_device *wdog)
{
	struct as390_wdt *wdt = watchdog_get_drvdata(wdog);

	local_irq_disable();
	wrl(wdt, WD_CONTROL, 0xA5FF3210);
	wrl(wdt, WD_CONTROL, 0x44BB77DD);
	local_irq_enable();

	return 0;
}

static int as390_wdt_stop(struct watchdog_device *wdog)
{
	struct as390_wdt *wdt = watchdog_get_drvdata(wdog);

	local_irq_disable();
	writel_relaxed(0x0123a5ff, wdt->base + WD_CONTROL);
	writel_relaxed(0xccee6699, wdt->base + WD_CONTROL);
	local_irq_enable();

	return 0;
}

static void as390_wdt_set(struct as390_wdt *wdt, u32 ticks)
{
	u32 val;

	val = rdl(wdt, CONTROL);
	if (val & (1 << 1)) {
		as390_wdt_stop(&wdt->wdd);
		reset_control_reset(wdt->rst);
	}

	val = 1 << 0;
	wrl(wdt, CONTROL, val);

	if (ticks <= 5000)
		ticks = 5000 + 1;
	wrl(wdt, TERMINAL_COUNT, ticks);

	val |= (1 << 27);
	val |= (1 << 6);
	val |= (1 << 5);
	val |= (1 << 4);
	wrl(wdt, CONTROL, val); 
	wrl(wdt, RESET_TERMINAL_COUNT, 5000);
	wrl(wdt, WD_CMD_WINDOWN, 0xffff);

	val |= (1 << 1);
	wrl(wdt, CONTROL, val); 
}

static int as390_wdt_restart(struct watchdog_device *wdog, unsigned long action,
			  void *data)
{
	struct as390_wdt *wdt = watchdog_get_drvdata(wdog);

	as390_wdt_set(wdt, 1);
	/* wait for reset to assert... */
	mdelay(500);

	return 0;
}

static int as390_wdt_start(struct watchdog_device *wdog)
{
	struct as390_wdt *wdt = watchdog_get_drvdata(wdog);

	as390_wdt_set(wdt, wdog->timeout * wdt->rate);

	return 0;
}

static int as390_wdt_set_timeout(struct watchdog_device *wdog, unsigned int t)
{
	struct as390_wdt *wdt = watchdog_get_drvdata(wdog);

	as390_wdt_set(wdt, t * wdt->rate);
	wdog->timeout = t;

	return 0;
}

static unsigned int as390_wdt_get_timeleft(struct watchdog_device *wdog)
{
	struct as390_wdt *wdt = watchdog_get_drvdata(wdog);
	u32 count = rdl(wdt, TERMINAL_COUNT) - rdl(wdt, CURRENT_COUNT);

	return count / wdt->rate;
}

static irqreturn_t as390_wdt_irq_handler(int irq, void *dev_id)
{
	return IRQ_HANDLED;
}

static const struct watchdog_ops as390_wdt_ops = {
	.owner		= THIS_MODULE,
	.start		= as390_wdt_start,
	.stop		= as390_wdt_stop,
	.ping		= as390_wdt_ping,
	.set_timeout	= as390_wdt_set_timeout,
	.get_timeleft	= as390_wdt_get_timeleft,
	.restart        = as390_wdt_restart,
};

static const struct watchdog_info as390_wdt_info = {
	.options	= WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE
			| WDIOF_KEEPALIVEPING,
	.identity	= "Synaptics AS390 Watchdog",
};

static int as390_wdt_probe(struct platform_device *pdev)
{
	int ret, irq;
	struct resource *res;
	struct as390_wdt *wdt;
	struct watchdog_device *wdd;
	struct device *dev = &pdev->dev;

	wdt = devm_kzalloc(dev, sizeof(struct as390_wdt), GFP_KERNEL);
	if (!wdt)
		return -ENOMEM;

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

	wdt->rst = devm_reset_control_get_optional(&pdev->dev, NULL);
	if (IS_ERR(wdt->rst))
		return PTR_ERR(wdt->rst);

	wdt->clk = devm_clk_get(dev, NULL);
	if (IS_ERR(wdt->clk))
		return PTR_ERR(wdt->clk);
	clk_prepare_enable(wdt->clk);

	wdd = &wdt->wdd;
	wdd->info = &as390_wdt_info;
	wdd->ops = &as390_wdt_ops;
	wdt->rate = clk_get_rate(wdt->clk);
	wdd->max_timeout = U32_MAX / wdt->rate;
	wdd->timeout = wdd->max_timeout;
	wdd->parent = dev;
	wdd->min_timeout = 1;

	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
		ret = irq;
		goto out_disable_clk;
	}
	ret = devm_request_irq(dev, irq, as390_wdt_irq_handler, 0,
			       pdev->name, wdt);
	if (ret)
		goto out_disable_clk;

	watchdog_set_drvdata(wdd, wdt);
	watchdog_set_restart_priority(wdd, 128);
	ret = devm_watchdog_register_device(dev, wdd);
	if (ret)
		goto out_disable_clk;

	return 0;

out_disable_clk:
	clk_disable_unprepare(wdt->clk);
	return ret;
}

static const struct of_device_id as390_wdt_of_match[] = {
	{ .compatible = "syna,as390-wdt", },
	{},
};
MODULE_DEVICE_TABLE(of, as390_wdt_of_match);

static struct platform_driver as390_wdt_driver = {
	.probe		= as390_wdt_probe,
	.driver = {
		.name =		"as390_wdt",
		.of_match_table = as390_wdt_of_match,
	},
};
module_platform_driver(as390_wdt_driver);

MODULE_AUTHOR("Jisheng Zhang<jszhang@kernel.org>");
MODULE_DESCRIPTION("Synaptics AS390 Watchdog Driver");
MODULE_LICENSE("GPL v2");
