// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *  PNX833x Hardware Watchdog Driver
 *  Copyright 2008 NXP Semiconductors
 *  Daniel Laird <daniel.j.laird@nxp.com>
 *  Andre McCurdy <andre.mccurdy@nxp.com>
 *
 *  Heavily based upon - IndyDog	0.3
 *  A Hardware Watchdog Device for SGI IP22
 *
 * (c) Copyright 2002 Guido Guenther <agx@sigxcpu.org>, All Rights Reserved.
 *
 * based on softdog.c by Alan Cox <alan@redhat.com>
 */

#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/fs.h>
#include <linux/mm.h>
#include <linux/miscdevice.h>
#include <linux/watchdog.h>
#include <linux/notifier.h>
#include <linux/reboot.h>
#include <linux/init.h>
#include <asm/mach-pnx833x/pnx833x.h>

#define WATCHDOG_TIMEOUT 30		/* 30 sec Maximum timeout */
#define WATCHDOG_COUNT_FREQUENCY 68000000U /* Watchdog counts at 68MHZ. */
#define	PNX_WATCHDOG_TIMEOUT	(WATCHDOG_TIMEOUT * WATCHDOG_COUNT_FREQUENCY)
#define PNX_TIMEOUT_VALUE	2040000000U

/** CONFIG block */
#define PNX833X_CONFIG                      (0x07000U)
#define PNX833X_CONFIG_CPU_WATCHDOG         (0x54)
#define PNX833X_CONFIG_CPU_WATCHDOG_COMPARE (0x58)
#define PNX833X_CONFIG_CPU_COUNTERS_CONTROL (0x1c)

/** RESET block */
#define PNX833X_RESET                       (0x08000U)
#define PNX833X_RESET_CONFIG                (0x08)

static int pnx833x_wdt_alive;

/* Set default timeout in MHZ.*/
static int pnx833x_wdt_timeout = PNX_WATCHDOG_TIMEOUT;
module_param(pnx833x_wdt_timeout, int, 0);
MODULE_PARM_DESC(timeout, "Watchdog timeout in Mhz. (68Mhz clock), default="
			__MODULE_STRING(PNX_TIMEOUT_VALUE) "(30 seconds).");

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) ")");

#define START_DEFAULT	1
static int start_enabled = START_DEFAULT;
module_param(start_enabled, int, 0);
MODULE_PARM_DESC(start_enabled, "Watchdog is started on module insertion "
				"(default=" __MODULE_STRING(START_DEFAULT) ")");

static void pnx833x_wdt_start(void)
{
	/* Enable watchdog causing reset. */
	PNX833X_REG(PNX833X_RESET + PNX833X_RESET_CONFIG) |= 0x1;
	/* Set timeout.*/
	PNX833X_REG(PNX833X_CONFIG +
		PNX833X_CONFIG_CPU_WATCHDOG_COMPARE) = pnx833x_wdt_timeout;
	/* Enable watchdog. */
	PNX833X_REG(PNX833X_CONFIG +
				PNX833X_CONFIG_CPU_COUNTERS_CONTROL) |= 0x1;

	pr_info("Started watchdog timer\n");
}

static void pnx833x_wdt_stop(void)
{
	/* Disable watchdog causing reset. */
	PNX833X_REG(PNX833X_RESET + PNX833X_CONFIG) &= 0xFFFFFFFE;
	/* Disable watchdog.*/
	PNX833X_REG(PNX833X_CONFIG +
			PNX833X_CONFIG_CPU_COUNTERS_CONTROL) &= 0xFFFFFFFE;

	pr_info("Stopped watchdog timer\n");
}

static void pnx833x_wdt_ping(void)
{
	PNX833X_REG(PNX833X_CONFIG +
		PNX833X_CONFIG_CPU_WATCHDOG_COMPARE) = pnx833x_wdt_timeout;
}

/*
 *	Allow only one person to hold it open
 */
static int pnx833x_wdt_open(struct inode *inode, struct file *file)
{
	if (test_and_set_bit(0, &pnx833x_wdt_alive))
		return -EBUSY;

	if (nowayout)
		__module_get(THIS_MODULE);

	/* Activate timer */
	if (!start_enabled)
		pnx833x_wdt_start();

	pnx833x_wdt_ping();

	pr_info("Started watchdog timer\n");

	return stream_open(inode, file);
}

static int pnx833x_wdt_release(struct inode *inode, struct file *file)
{
	/* Shut off the timer.
	 * Lock it in if it's a module and we defined ...NOWAYOUT */
	if (!nowayout)
		pnx833x_wdt_stop(); /* Turn the WDT off */

	clear_bit(0, &pnx833x_wdt_alive);
	return 0;
}

static ssize_t pnx833x_wdt_write(struct file *file, const char *data, size_t len, loff_t *ppos)
{
	/* Refresh the timer. */
	if (len)
		pnx833x_wdt_ping();

	return len;
}

static long pnx833x_wdt_ioctl(struct file *file, unsigned int cmd,
							unsigned long arg)
{
	int options, new_timeout = 0;
	uint32_t timeout, timeout_left = 0;

	static const struct watchdog_info ident = {
		.options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT,
		.firmware_version = 0,
		.identity = "Hardware Watchdog for PNX833x",
	};

	switch (cmd) {
	default:
		return -ENOTTY;

	case WDIOC_GETSUPPORT:
		if (copy_to_user((struct watchdog_info *)arg,
				 &ident, sizeof(ident)))
			return -EFAULT;
		return 0;

	case WDIOC_GETSTATUS:
	case WDIOC_GETBOOTSTATUS:
		return put_user(0, (int *)arg);

	case WDIOC_SETOPTIONS:
		if (get_user(options, (int *)arg))
			return -EFAULT;

		if (options & WDIOS_DISABLECARD)
			pnx833x_wdt_stop();

		if (options & WDIOS_ENABLECARD)
			pnx833x_wdt_start();

		return 0;

	case WDIOC_KEEPALIVE:
		pnx833x_wdt_ping();
		return 0;

	case WDIOC_SETTIMEOUT:
	{
		if (get_user(new_timeout, (int *)arg))
			return -EFAULT;

		pnx833x_wdt_timeout = new_timeout;
		PNX833X_REG(PNX833X_CONFIG +
			PNX833X_CONFIG_CPU_WATCHDOG_COMPARE) = new_timeout;
		return put_user(new_timeout, (int *)arg);
	}

	case WDIOC_GETTIMEOUT:
		timeout = PNX833X_REG(PNX833X_CONFIG +
					PNX833X_CONFIG_CPU_WATCHDOG_COMPARE);
		return put_user(timeout, (int *)arg);

	case WDIOC_GETTIMELEFT:
		timeout_left = PNX833X_REG(PNX833X_CONFIG +
						PNX833X_CONFIG_CPU_WATCHDOG);
		return put_user(timeout_left, (int *)arg);

	}
}

static int pnx833x_wdt_notify_sys(struct notifier_block *this,
					unsigned long code, void *unused)
{
	if (code == SYS_DOWN || code == SYS_HALT)
		pnx833x_wdt_stop(); /* Turn the WDT off */

	return NOTIFY_DONE;
}

static const struct file_operations pnx833x_wdt_fops = {
	.owner		= THIS_MODULE,
	.llseek		= no_llseek,
	.write		= pnx833x_wdt_write,
	.unlocked_ioctl	= pnx833x_wdt_ioctl,
	.open		= pnx833x_wdt_open,
	.release	= pnx833x_wdt_release,
};

static struct miscdevice pnx833x_wdt_miscdev = {
	.minor		= WATCHDOG_MINOR,
	.name		= "watchdog",
	.fops		= &pnx833x_wdt_fops,
};

static struct notifier_block pnx833x_wdt_notifier = {
	.notifier_call = pnx833x_wdt_notify_sys,
};

static int __init watchdog_init(void)
{
	int ret, cause;

	/* Lets check the reason for the reset.*/
	cause = PNX833X_REG(PNX833X_RESET);
	/*If bit 31 is set then watchdog was cause of reset.*/
	if (cause & 0x80000000) {
		pr_info("The system was previously reset due to the watchdog firing - please investigate...\n");
	}

	ret = register_reboot_notifier(&pnx833x_wdt_notifier);
	if (ret) {
		pr_err("cannot register reboot notifier (err=%d)\n", ret);
		return ret;
	}

	ret = misc_register(&pnx833x_wdt_miscdev);
	if (ret) {
		pr_err("cannot register miscdev on minor=%d (err=%d)\n",
		       WATCHDOG_MINOR, ret);
		unregister_reboot_notifier(&pnx833x_wdt_notifier);
		return ret;
	}

	pr_info("Hardware Watchdog Timer for PNX833x: Version 0.1\n");

	if (start_enabled)
		pnx833x_wdt_start();

	return 0;
}

static void __exit watchdog_exit(void)
{
	misc_deregister(&pnx833x_wdt_miscdev);
	unregister_reboot_notifier(&pnx833x_wdt_notifier);
}

module_init(watchdog_init);
module_exit(watchdog_exit);

MODULE_AUTHOR("Daniel Laird/Andre McCurdy");
MODULE_DESCRIPTION("Hardware Watchdog Device for PNX833x");
MODULE_LICENSE("GPL");
