// SPDX-License-Identifier: GPL-2.0
/*
 * drivers/char/watchdog/pnx4008_wdt.c
 *
 * Watchdog driver for PNX4008 board
 *
 * Authors: Dmitry Chigirev <source@mvista.com>,
 *	    Vitaly Wool <vitalywool@gmail.com>
 * Based on sa1100 driver,
 * Copyright (C) 2000 Oleg Drokin <green@crimea.edu>
 *
 * 2005-2006 (c) MontaVista Software, Inc.
 *
 * (C) 2012 Wolfram Sang, Pengutronix
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/watchdog.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/spinlock.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/of.h>
#include <linux/delay.h>
#include <linux/reboot.h>

/* WatchDog Timer - Chapter 23 Page 207 */

#define DEFAULT_HEARTBEAT 19
#define MAX_HEARTBEAT     60

/* Watchdog timer register set definition */
#define WDTIM_INT(p)     ((p) + 0x0)
#define WDTIM_CTRL(p)    ((p) + 0x4)
#define WDTIM_COUNTER(p) ((p) + 0x8)
#define WDTIM_MCTRL(p)   ((p) + 0xC)
#define WDTIM_MATCH0(p)  ((p) + 0x10)
#define WDTIM_EMR(p)     ((p) + 0x14)
#define WDTIM_PULSE(p)   ((p) + 0x18)
#define WDTIM_RES(p)     ((p) + 0x1C)

/* WDTIM_INT bit definitions */
#define MATCH_INT      1

/* WDTIM_CTRL bit definitions */
#define COUNT_ENAB     1
#define RESET_COUNT    (1 << 1)
#define DEBUG_EN       (1 << 2)

/* WDTIM_MCTRL bit definitions */
#define MR0_INT        1
#undef  RESET_COUNT0
#define RESET_COUNT0   (1 << 2)
#define STOP_COUNT0    (1 << 2)
#define M_RES1         (1 << 3)
#define M_RES2         (1 << 4)
#define RESFRC1        (1 << 5)
#define RESFRC2        (1 << 6)

/* WDTIM_EMR bit definitions */
#define EXT_MATCH0      1
#define MATCH_OUTPUT_HIGH (2 << 4)	/*a MATCH_CTRL setting */

/* WDTIM_RES bit definitions */
#define WDOG_RESET      1	/* read only */

#define WDOG_COUNTER_RATE 13000000	/*the counter clock is 13 MHz fixed */

static bool nowayout = WATCHDOG_NOWAYOUT;
static unsigned int heartbeat;

static DEFINE_SPINLOCK(io_lock);
static void __iomem	*wdt_base;
static struct clk	*wdt_clk;

static int pnx4008_wdt_start(struct watchdog_device *wdd)
{
	spin_lock(&io_lock);

	/* stop counter, initiate counter reset */
	writel(RESET_COUNT, WDTIM_CTRL(wdt_base));
	/*wait for reset to complete. 100% guarantee event */
	while (readl(WDTIM_COUNTER(wdt_base)))
		cpu_relax();
	/* internal and external reset, stop after that */
	writel(M_RES2 | STOP_COUNT0 | RESET_COUNT0, WDTIM_MCTRL(wdt_base));
	/* configure match output */
	writel(MATCH_OUTPUT_HIGH, WDTIM_EMR(wdt_base));
	/* clear interrupt, just in case */
	writel(MATCH_INT, WDTIM_INT(wdt_base));
	/* the longest pulse period 65541/(13*10^6) seconds ~ 5 ms. */
	writel(0xFFFF, WDTIM_PULSE(wdt_base));
	writel(wdd->timeout * WDOG_COUNTER_RATE, WDTIM_MATCH0(wdt_base));
	/*enable counter, stop when debugger active */
	writel(COUNT_ENAB | DEBUG_EN, WDTIM_CTRL(wdt_base));

	spin_unlock(&io_lock);
	return 0;
}

static int pnx4008_wdt_stop(struct watchdog_device *wdd)
{
	spin_lock(&io_lock);

	writel(0, WDTIM_CTRL(wdt_base));	/*stop counter */

	spin_unlock(&io_lock);
	return 0;
}

static int pnx4008_wdt_set_timeout(struct watchdog_device *wdd,
				    unsigned int new_timeout)
{
	wdd->timeout = new_timeout;
	return 0;
}

static int pnx4008_restart_handler(struct watchdog_device *wdd,
				   unsigned long mode, void *cmd)
{
	const char *boot_cmd = cmd;

	/*
	 * Verify if a "cmd" passed from the userspace program rebooting
	 * the system; if available, handle it.
	 * - For details, see the 'reboot' syscall in kernel/reboot.c
	 * - If the received "cmd" is not supported, use the default mode.
	 */
	if (boot_cmd) {
		if (boot_cmd[0] == 'h')
			mode = REBOOT_HARD;
		else if (boot_cmd[0] == 's')
			mode = REBOOT_SOFT;
	}

	if (mode == REBOOT_SOFT) {
		/* Force match output active */
		writel(EXT_MATCH0, WDTIM_EMR(wdt_base));
		/* Internal reset on match output (RESOUT_N not asserted) */
		writel(M_RES1, WDTIM_MCTRL(wdt_base));
	} else {
		/* Instant assert of RESETOUT_N with pulse length 1mS */
		writel(13000, WDTIM_PULSE(wdt_base));
		writel(M_RES2 | RESFRC1 | RESFRC2, WDTIM_MCTRL(wdt_base));
	}

	/* Wait for watchdog to reset system */
	mdelay(1000);

	return NOTIFY_DONE;
}

static const struct watchdog_info pnx4008_wdt_ident = {
	.options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE |
	    WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
	.identity = "PNX4008 Watchdog",
};

static const struct watchdog_ops pnx4008_wdt_ops = {
	.owner = THIS_MODULE,
	.start = pnx4008_wdt_start,
	.stop = pnx4008_wdt_stop,
	.set_timeout = pnx4008_wdt_set_timeout,
	.restart = pnx4008_restart_handler,
};

static struct watchdog_device pnx4008_wdd = {
	.info = &pnx4008_wdt_ident,
	.ops = &pnx4008_wdt_ops,
	.timeout = DEFAULT_HEARTBEAT,
	.min_timeout = 1,
	.max_timeout = MAX_HEARTBEAT,
};

static void pnx4008_clk_disable_unprepare(void *data)
{
	clk_disable_unprepare(data);
}

static int pnx4008_wdt_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	int ret = 0;

	watchdog_init_timeout(&pnx4008_wdd, heartbeat, dev);

	wdt_base = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(wdt_base))
		return PTR_ERR(wdt_base);

	wdt_clk = devm_clk_get(dev, NULL);
	if (IS_ERR(wdt_clk))
		return PTR_ERR(wdt_clk);

	ret = clk_prepare_enable(wdt_clk);
	if (ret)
		return ret;
	ret = devm_add_action_or_reset(dev, pnx4008_clk_disable_unprepare,
				       wdt_clk);
	if (ret)
		return ret;

	pnx4008_wdd.bootstatus = (readl(WDTIM_RES(wdt_base)) & WDOG_RESET) ?
			WDIOF_CARDRESET : 0;
	pnx4008_wdd.parent = dev;
	watchdog_set_nowayout(&pnx4008_wdd, nowayout);
	watchdog_set_restart_priority(&pnx4008_wdd, 128);

	if (readl(WDTIM_CTRL(wdt_base)) & COUNT_ENAB)
		set_bit(WDOG_HW_RUNNING, &pnx4008_wdd.status);

	ret = devm_watchdog_register_device(dev, &pnx4008_wdd);
	if (ret < 0)
		return ret;

	dev_info(dev, "heartbeat %d sec\n", pnx4008_wdd.timeout);

	return 0;
}

#ifdef CONFIG_OF
static const struct of_device_id pnx4008_wdt_match[] = {
	{ .compatible = "nxp,pnx4008-wdt" },
	{ }
};
MODULE_DEVICE_TABLE(of, pnx4008_wdt_match);
#endif

static struct platform_driver platform_wdt_driver = {
	.driver = {
		.name = "pnx4008-watchdog",
		.of_match_table = of_match_ptr(pnx4008_wdt_match),
	},
	.probe = pnx4008_wdt_probe,
};

module_platform_driver(platform_wdt_driver);

MODULE_AUTHOR("MontaVista Software, Inc. <source@mvista.com>");
MODULE_AUTHOR("Wolfram Sang <kernel@pengutronix.de>");
MODULE_DESCRIPTION("PNX4008 Watchdog Driver");

module_param(heartbeat, uint, 0);
MODULE_PARM_DESC(heartbeat,
		 "Watchdog heartbeat period in seconds from 1 to "
		 __MODULE_STRING(MAX_HEARTBEAT) ", default "
		 __MODULE_STRING(DEFAULT_HEARTBEAT));

module_param(nowayout, bool, 0);
MODULE_PARM_DESC(nowayout,
		 "Set to 1 to keep watchdog running after device release");

MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:pnx4008-watchdog");
