// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * PIC32 deadman timer driver
 *
 * Purna Chandra Mandal <purna.mandal@microchip.com>
 * Copyright (c) 2016, Microchip Technology Inc.
 */
#include <linux/clk.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/watchdog.h>

#include <asm/mach-pic32/pic32.h>

/* Deadman Timer Regs */
#define DMTCON_REG	0x00
#define DMTPRECLR_REG	0x10
#define DMTCLR_REG	0x20
#define DMTSTAT_REG	0x30
#define DMTCNT_REG	0x40
#define DMTPSCNT_REG	0x60
#define DMTPSINTV_REG	0x70

/* Deadman Timer Regs fields */
#define DMT_ON			BIT(15)
#define DMT_STEP1_KEY		BIT(6)
#define DMT_STEP2_KEY		BIT(3)
#define DMTSTAT_WINOPN		BIT(0)
#define DMTSTAT_EVENT		BIT(5)
#define DMTSTAT_BAD2		BIT(6)
#define DMTSTAT_BAD1		BIT(7)

/* Reset Control Register fields for watchdog */
#define RESETCON_DMT_TIMEOUT	BIT(5)

struct pic32_dmt {
	void __iomem	*regs;
	struct clk	*clk;
};

static inline void dmt_enable(struct pic32_dmt *dmt)
{
	writel(DMT_ON, PIC32_SET(dmt->regs + DMTCON_REG));
}

static inline void dmt_disable(struct pic32_dmt *dmt)
{
	writel(DMT_ON, PIC32_CLR(dmt->regs + DMTCON_REG));
	/*
	 * Cannot touch registers in the CPU cycle following clearing the
	 * ON bit.
	 */
	nop();
}

static inline int dmt_bad_status(struct pic32_dmt *dmt)
{
	u32 val;

	val = readl(dmt->regs + DMTSTAT_REG);
	val &= (DMTSTAT_BAD1 | DMTSTAT_BAD2 | DMTSTAT_EVENT);
	if (val)
		return -EAGAIN;

	return 0;
}

static inline int dmt_keepalive(struct pic32_dmt *dmt)
{
	u32 v;
	u32 timeout = 500;

	/* set pre-clear key */
	writel(DMT_STEP1_KEY << 8, dmt->regs + DMTPRECLR_REG);

	/* wait for DMT window to open */
	while (--timeout) {
		v = readl(dmt->regs + DMTSTAT_REG) & DMTSTAT_WINOPN;
		if (v == DMTSTAT_WINOPN)
			break;
	}

	/* apply key2 */
	writel(DMT_STEP2_KEY, dmt->regs + DMTCLR_REG);

	/* check whether keys are latched correctly */
	return dmt_bad_status(dmt);
}

static inline u32 pic32_dmt_get_timeout_secs(struct pic32_dmt *dmt)
{
	unsigned long rate;

	rate = clk_get_rate(dmt->clk);
	if (rate)
		return readl(dmt->regs + DMTPSCNT_REG) / rate;

	return 0;
}

static inline u32 pic32_dmt_bootstatus(struct pic32_dmt *dmt)
{
	u32 v;
	void __iomem *rst_base;

	rst_base = ioremap(PIC32_BASE_RESET, 0x10);
	if (!rst_base)
		return 0;

	v = readl(rst_base);

	writel(RESETCON_DMT_TIMEOUT, PIC32_CLR(rst_base));

	iounmap(rst_base);
	return v & RESETCON_DMT_TIMEOUT;
}

static int pic32_dmt_start(struct watchdog_device *wdd)
{
	struct pic32_dmt *dmt = watchdog_get_drvdata(wdd);

	dmt_enable(dmt);
	return dmt_keepalive(dmt);
}

static int pic32_dmt_stop(struct watchdog_device *wdd)
{
	struct pic32_dmt *dmt = watchdog_get_drvdata(wdd);

	dmt_disable(dmt);

	return 0;
}

static int pic32_dmt_ping(struct watchdog_device *wdd)
{
	struct pic32_dmt *dmt = watchdog_get_drvdata(wdd);

	return dmt_keepalive(dmt);
}

static const struct watchdog_ops pic32_dmt_fops = {
	.owner		= THIS_MODULE,
	.start		= pic32_dmt_start,
	.stop		= pic32_dmt_stop,
	.ping		= pic32_dmt_ping,
};

static const struct watchdog_info pic32_dmt_ident = {
	.options	= WDIOF_KEEPALIVEPING |
			  WDIOF_MAGICCLOSE,
	.identity	= "PIC32 Deadman Timer",
};

static struct watchdog_device pic32_dmt_wdd = {
	.info		= &pic32_dmt_ident,
	.ops		= &pic32_dmt_fops,
};

static int pic32_dmt_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	int ret;
	struct pic32_dmt *dmt;
	struct watchdog_device *wdd = &pic32_dmt_wdd;

	dmt = devm_kzalloc(dev, sizeof(*dmt), GFP_KERNEL);
	if (!dmt)
		return -ENOMEM;

	dmt->regs = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(dmt->regs))
		return PTR_ERR(dmt->regs);

	dmt->clk = devm_clk_get_enabled(dev, NULL);
	if (IS_ERR(dmt->clk)) {
		dev_err(dev, "clk not found\n");
		return PTR_ERR(dmt->clk);
	}

	wdd->timeout = pic32_dmt_get_timeout_secs(dmt);
	if (!wdd->timeout) {
		dev_err(dev, "failed to read watchdog register timeout\n");
		return -EINVAL;
	}

	dev_info(dev, "timeout %d\n", wdd->timeout);

	wdd->bootstatus = pic32_dmt_bootstatus(dmt) ? WDIOF_CARDRESET : 0;

	watchdog_set_nowayout(wdd, WATCHDOG_NOWAYOUT);
	watchdog_set_drvdata(wdd, dmt);

	ret = devm_watchdog_register_device(dev, wdd);
	if (ret)
		return ret;

	platform_set_drvdata(pdev, wdd);
	return 0;
}

static const struct of_device_id pic32_dmt_of_ids[] = {
	{ .compatible = "microchip,pic32mzda-dmt",},
	{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, pic32_dmt_of_ids);

static struct platform_driver pic32_dmt_driver = {
	.probe		= pic32_dmt_probe,
	.driver		= {
		.name		= "pic32-dmt",
		.of_match_table = of_match_ptr(pic32_dmt_of_ids),
	}
};

module_platform_driver(pic32_dmt_driver);

MODULE_AUTHOR("Purna Chandra Mandal <purna.mandal@microchip.com>");
MODULE_DESCRIPTION("Microchip PIC32 DMT Driver");
MODULE_LICENSE("GPL");
