// SPDX-License-Identifier: GPL-2.0-only
/*
 *      Intel_SCU 0.2:  An Intel SCU IOH Based Watchdog Device
 *			for Intel part #(s):
 *				- AF82MP20 PCH
 *
 *      Copyright (C) 2009-2010 Intel Corporation. All rights reserved.
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/compiler.h>
#include <linux/kernel.h>
#include <linux/moduleparam.h>
#include <linux/types.h>
#include <linux/miscdevice.h>
#include <linux/watchdog.h>
#include <linux/fs.h>
#include <linux/notifier.h>
#include <linux/reboot.h>
#include <linux/init.h>
#include <linux/jiffies.h>
#include <linux/uaccess.h>
#include <linux/slab.h>
#include <linux/io.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/sched.h>
#include <linux/signal.h>
#include <linux/sfi.h>
#include <asm/irq.h>
#include <linux/atomic.h>
#include <asm/intel_scu_ipc.h>
#include <asm/apb_timer.h>
#include <asm/intel-mid.h>

#include "intel_scu_watchdog.h"

/* Bounds number of times we will retry loading time count */
/* This retry is a work around for a silicon bug.	   */
#define MAX_RETRY 16

#define IPC_SET_WATCHDOG_TIMER	0xF8

static int timer_margin = DEFAULT_SOFT_TO_HARD_MARGIN;
module_param(timer_margin, int, 0);
MODULE_PARM_DESC(timer_margin,
		"Watchdog timer margin"
		"Time between interrupt and resetting the system"
		"The range is from 1 to 160"
		"This is the time for all keep alives to arrive");

static int timer_set = DEFAULT_TIME;
module_param(timer_set, int, 0);
MODULE_PARM_DESC(timer_set,
		"Default Watchdog timer setting"
		"Complete cycle time"
		"The range is from 1 to 170"
		"This is the time for all keep alives to arrive");

/* After watchdog device is closed, check force_boot. If:
 * force_boot == 0, then force boot on next watchdog interrupt after close,
 * force_boot == 1, then force boot immediately when device is closed.
 */
static int force_boot;
module_param(force_boot, int, 0);
MODULE_PARM_DESC(force_boot,
		"A value of 1 means that the driver will reboot"
		"the system immediately if the /dev/watchdog device is closed"
		"A value of 0 means that when /dev/watchdog device is closed"
		"the watchdog timer will be refreshed for one more interval"
		"of length: timer_set. At the end of this interval, the"
		"watchdog timer will reset the system."
		);

/* there is only one device in the system now; this can be made into
 * an array in the future if we have more than one device */

static struct intel_scu_watchdog_dev watchdog_device;

/* Forces restart, if force_reboot is set */
static void watchdog_fire(void)
{
	if (force_boot) {
		pr_crit("Initiating system reboot\n");
		emergency_restart();
		pr_crit("Reboot didn't ?????\n");
	}

	else {
		pr_crit("Immediate Reboot Disabled\n");
		pr_crit("System will reset when watchdog timer times out!\n");
	}
}

static int check_timer_margin(int new_margin)
{
	if ((new_margin < MIN_TIME_CYCLE) ||
	    (new_margin > MAX_TIME - timer_set)) {
		pr_debug("value of new_margin %d is out of the range %d to %d\n",
			 new_margin, MIN_TIME_CYCLE, MAX_TIME - timer_set);
		return -EINVAL;
	}
	return 0;
}

/*
 * IPC operations
 */
static int watchdog_set_ipc(int soft_threshold, int threshold)
{
	u32	*ipc_wbuf;
	u8	 cbuf[16] = { '\0' };
	int	 ipc_ret = 0;

	ipc_wbuf = (u32 *)&cbuf;
	ipc_wbuf[0] = soft_threshold;
	ipc_wbuf[1] = threshold;

	ipc_ret = intel_scu_ipc_command(
			IPC_SET_WATCHDOG_TIMER,
			0,
			ipc_wbuf,
			2,
			NULL,
			0);

	if (ipc_ret != 0)
		pr_err("Error setting SCU watchdog timer: %x\n", ipc_ret);

	return ipc_ret;
};

/*
 *      Intel_SCU operations
 */

/* timer interrupt handler */
static irqreturn_t watchdog_timer_interrupt(int irq, void *dev_id)
{
	int int_status;
	int_status = ioread32(watchdog_device.timer_interrupt_status_addr);

	pr_debug("irq, int_status: %x\n", int_status);

	if (int_status != 0)
		return IRQ_NONE;

	/* has the timer been started? If not, then this is spurious */
	if (watchdog_device.timer_started == 0) {
		pr_debug("spurious interrupt received\n");
		return IRQ_HANDLED;
	}

	/* temporarily disable the timer */
	iowrite32(0x00000002, watchdog_device.timer_control_addr);

	/* set the timer to the threshold */
	iowrite32(watchdog_device.threshold,
		  watchdog_device.timer_load_count_addr);

	/* allow the timer to run */
	iowrite32(0x00000003, watchdog_device.timer_control_addr);

	return IRQ_HANDLED;
}

static int intel_scu_keepalive(void)
{

	/* read eoi register - clears interrupt */
	ioread32(watchdog_device.timer_clear_interrupt_addr);

	/* temporarily disable the timer */
	iowrite32(0x00000002, watchdog_device.timer_control_addr);

	/* set the timer to the soft_threshold */
	iowrite32(watchdog_device.soft_threshold,
		  watchdog_device.timer_load_count_addr);

	/* allow the timer to run */
	iowrite32(0x00000003, watchdog_device.timer_control_addr);

	return 0;
}

static int intel_scu_stop(void)
{
	iowrite32(0, watchdog_device.timer_control_addr);
	return 0;
}

static int intel_scu_set_heartbeat(u32 t)
{
	int			 ipc_ret;
	int			 retry_count;
	u32			 soft_value;
	u32			 hw_value;

	watchdog_device.timer_set = t;
	watchdog_device.threshold =
		timer_margin * watchdog_device.timer_tbl_ptr->freq_hz;
	watchdog_device.soft_threshold =
		(watchdog_device.timer_set - timer_margin)
		* watchdog_device.timer_tbl_ptr->freq_hz;

	pr_debug("set_heartbeat: timer freq is %d\n",
		 watchdog_device.timer_tbl_ptr->freq_hz);
	pr_debug("set_heartbeat: timer_set is %x (hex)\n",
		 watchdog_device.timer_set);
	pr_debug("set_heartbeat: timer_margin is %x (hex)\n", timer_margin);
	pr_debug("set_heartbeat: threshold is %x (hex)\n",
		 watchdog_device.threshold);
	pr_debug("set_heartbeat: soft_threshold is %x (hex)\n",
		 watchdog_device.soft_threshold);

	/* Adjust thresholds by FREQ_ADJUSTMENT factor, to make the */
	/* watchdog timing come out right. */
	watchdog_device.threshold =
		watchdog_device.threshold / FREQ_ADJUSTMENT;
	watchdog_device.soft_threshold =
		watchdog_device.soft_threshold / FREQ_ADJUSTMENT;

	/* temporarily disable the timer */
	iowrite32(0x00000002, watchdog_device.timer_control_addr);

	/* send the threshold and soft_threshold via IPC to the processor */
	ipc_ret = watchdog_set_ipc(watchdog_device.soft_threshold,
				   watchdog_device.threshold);

	if (ipc_ret != 0) {
		/* Make sure the watchdog timer is stopped */
		intel_scu_stop();
		return ipc_ret;
	}

	/* Soft Threshold set loop. Early versions of silicon did */
	/* not always set this count correctly.  This loop checks */
	/* the value and retries if it was not set correctly.     */

	retry_count = 0;
	soft_value = watchdog_device.soft_threshold & 0xFFFF0000;
	do {

		/* Make sure timer is stopped */
		intel_scu_stop();

		if (MAX_RETRY < retry_count++) {
			/* Unable to set timer value */
			pr_err("Unable to set timer\n");
			return -ENODEV;
		}

		/* set the timer to the soft threshold */
		iowrite32(watchdog_device.soft_threshold,
			watchdog_device.timer_load_count_addr);

		/* read count value before starting timer */
		ioread32(watchdog_device.timer_load_count_addr);

		/* Start the timer */
		iowrite32(0x00000003, watchdog_device.timer_control_addr);

		/* read the value the time loaded into its count reg */
		hw_value = ioread32(watchdog_device.timer_load_count_addr);
		hw_value = hw_value & 0xFFFF0000;


	} while (soft_value != hw_value);

	watchdog_device.timer_started = 1;

	return 0;
}

/*
 * /dev/watchdog handling
 */

static int intel_scu_open(struct inode *inode, struct file *file)
{

	/* Set flag to indicate that watchdog device is open */
	if (test_and_set_bit(0, &watchdog_device.driver_open))
		return -EBUSY;

	/* Check for reopen of driver. Reopens are not allowed */
	if (watchdog_device.driver_closed)
		return -EPERM;

	return stream_open(inode, file);
}

static int intel_scu_release(struct inode *inode, struct file *file)
{
	/*
	 * This watchdog should not be closed, after the timer
	 * is started with the WDIPC_SETTIMEOUT ioctl
	 * If force_boot is set watchdog_fire() will cause an
	 * immediate reset. If force_boot is not set, the watchdog
	 * timer is refreshed for one more interval. At the end
	 * of that interval, the watchdog timer will reset the system.
	 */

	if (!test_and_clear_bit(0, &watchdog_device.driver_open)) {
		pr_debug("intel_scu_release, without open\n");
		return -ENOTTY;
	}

	if (!watchdog_device.timer_started) {
		/* Just close, since timer has not been started */
		pr_debug("closed, without starting timer\n");
		return 0;
	}

	pr_crit("Unexpected close of /dev/watchdog!\n");

	/* Since the timer was started, prevent future reopens */
	watchdog_device.driver_closed = 1;

	/* Refresh the timer for one more interval */
	intel_scu_keepalive();

	/* Reboot system (if force_boot is set) */
	watchdog_fire();

	/* We should only reach this point if force_boot is not set */
	return 0;
}

static ssize_t intel_scu_write(struct file *file,
			      char const *data,
			      size_t len,
			      loff_t *ppos)
{

	if (watchdog_device.timer_started)
		/* Watchdog already started, keep it alive */
		intel_scu_keepalive();
	else
		/* Start watchdog with timer value set by init */
		intel_scu_set_heartbeat(watchdog_device.timer_set);

	return len;
}

static long intel_scu_ioctl(struct file *file,
			   unsigned int cmd,
			   unsigned long arg)
{
	void __user *argp = (void __user *)arg;
	u32 __user *p = argp;
	u32 new_margin;


	static const struct watchdog_info ident = {
		.options =          WDIOF_SETTIMEOUT
				    | WDIOF_KEEPALIVEPING,
		.firmware_version = 0,  /* @todo Get from SCU via
						 ipc_get_scu_fw_version()? */
		.identity =         "Intel_SCU IOH Watchdog"  /* len < 32 */
	};

	switch (cmd) {
	case WDIOC_GETSUPPORT:
		return copy_to_user(argp,
				    &ident,
				    sizeof(ident)) ? -EFAULT : 0;
	case WDIOC_GETSTATUS:
	case WDIOC_GETBOOTSTATUS:
		return put_user(0, p);
	case WDIOC_KEEPALIVE:
		intel_scu_keepalive();

		return 0;
	case WDIOC_SETTIMEOUT:
		if (get_user(new_margin, p))
			return -EFAULT;

		if (check_timer_margin(new_margin))
			return -EINVAL;

		if (intel_scu_set_heartbeat(new_margin))
			return -EINVAL;
		return 0;
	case WDIOC_GETTIMEOUT:
		return put_user(watchdog_device.soft_threshold, p);

	default:
		return -ENOTTY;
	}
}

/*
 *      Notifier for system down
 */
static int intel_scu_notify_sys(struct notifier_block *this,
			       unsigned long code,
			       void *another_unused)
{
	if (code == SYS_DOWN || code == SYS_HALT)
		/* Turn off the watchdog timer. */
		intel_scu_stop();
	return NOTIFY_DONE;
}

/*
 *      Kernel Interfaces
 */
static const struct file_operations intel_scu_fops = {
	.owner          = THIS_MODULE,
	.llseek         = no_llseek,
	.write          = intel_scu_write,
	.unlocked_ioctl = intel_scu_ioctl,
	.compat_ioctl	= compat_ptr_ioctl,
	.open           = intel_scu_open,
	.release        = intel_scu_release,
};

static int __init intel_scu_watchdog_init(void)
{
	int ret;
	u32 __iomem *tmp_addr;

	/*
	 * We don't really need to check this as the SFI timer get will fail
	 * but if we do so we can exit with a clearer reason and no noise.
	 *
	 * If it isn't an intel MID device then it doesn't have this watchdog
	 */
	if (!intel_mid_identify_cpu())
		return -ENODEV;

	/* Check boot parameters to verify that their initial values */
	/* are in range. */
	/* Check value of timer_set boot parameter */
	if ((timer_set < MIN_TIME_CYCLE) ||
	    (timer_set > MAX_TIME - MIN_TIME_CYCLE)) {
		pr_err("value of timer_set %x (hex) is out of range from %x to %x (hex)\n",
		       timer_set, MIN_TIME_CYCLE, MAX_TIME - MIN_TIME_CYCLE);
		return -EINVAL;
	}

	/* Check value of timer_margin boot parameter */
	if (check_timer_margin(timer_margin))
		return -EINVAL;

	watchdog_device.timer_tbl_ptr = sfi_get_mtmr(sfi_mtimer_num-1);

	if (watchdog_device.timer_tbl_ptr == NULL) {
		pr_debug("timer is not available\n");
		return -ENODEV;
	}
	/* make sure the timer exists */
	if (watchdog_device.timer_tbl_ptr->phys_addr == 0) {
		pr_debug("timer %d does not have valid physical memory\n",
			 sfi_mtimer_num);
		return -ENODEV;
	}

	if (watchdog_device.timer_tbl_ptr->irq == 0) {
		pr_debug("timer %d invalid irq\n", sfi_mtimer_num);
		return -ENODEV;
	}

	tmp_addr = ioremap(watchdog_device.timer_tbl_ptr->phys_addr,
			20);

	if (tmp_addr == NULL) {
		pr_debug("timer unable to ioremap\n");
		return -ENOMEM;
	}

	watchdog_device.timer_load_count_addr = tmp_addr++;
	watchdog_device.timer_current_value_addr = tmp_addr++;
	watchdog_device.timer_control_addr = tmp_addr++;
	watchdog_device.timer_clear_interrupt_addr = tmp_addr++;
	watchdog_device.timer_interrupt_status_addr = tmp_addr++;

	/* Set the default time values in device structure */

	watchdog_device.timer_set = timer_set;
	watchdog_device.threshold =
		timer_margin * watchdog_device.timer_tbl_ptr->freq_hz;
	watchdog_device.soft_threshold =
		(watchdog_device.timer_set - timer_margin)
		* watchdog_device.timer_tbl_ptr->freq_hz;


	watchdog_device.intel_scu_notifier.notifier_call =
		intel_scu_notify_sys;

	ret = register_reboot_notifier(&watchdog_device.intel_scu_notifier);
	if (ret) {
		pr_err("cannot register notifier %d)\n", ret);
		goto register_reboot_error;
	}

	watchdog_device.miscdev.minor = WATCHDOG_MINOR;
	watchdog_device.miscdev.name = "watchdog";
	watchdog_device.miscdev.fops = &intel_scu_fops;

	ret = misc_register(&watchdog_device.miscdev);
	if (ret) {
		pr_err("cannot register miscdev %d err =%d\n",
		       WATCHDOG_MINOR, ret);
		goto misc_register_error;
	}

	ret = request_irq((unsigned int)watchdog_device.timer_tbl_ptr->irq,
		watchdog_timer_interrupt,
		IRQF_SHARED, "watchdog",
		&watchdog_device.timer_load_count_addr);
	if (ret) {
		pr_err("error requesting irq %d\n", ret);
		goto request_irq_error;
	}
	/* Make sure timer is disabled before returning */
	intel_scu_stop();
	return 0;

/* error cleanup */

request_irq_error:
	misc_deregister(&watchdog_device.miscdev);
misc_register_error:
	unregister_reboot_notifier(&watchdog_device.intel_scu_notifier);
register_reboot_error:
	intel_scu_stop();
	iounmap(watchdog_device.timer_load_count_addr);
	return ret;
}
late_initcall(intel_scu_watchdog_init);
