// SPDX-License-Identifier: GPL-2.0-only
/*
 * ACPI Hardware Watchdog (WDAT) driver.
 *
 * Copyright (C) 2016, Intel Corporation
 * Author: Mika Westerberg <mika.westerberg@linux.intel.com>
 */

#include <linux/acpi.h>
#include <linux/ioport.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/watchdog.h>

#define MAX_WDAT_ACTIONS ACPI_WDAT_ACTION_RESERVED

/**
 * struct wdat_instruction - Single ACPI WDAT instruction
 * @entry: Copy of the ACPI table instruction
 * @reg: Register the instruction is accessing
 * @node: Next instruction in action sequence
 */
struct wdat_instruction {
	struct acpi_wdat_entry entry;
	void __iomem *reg;
	struct list_head node;
};

/**
 * struct wdat_wdt - ACPI WDAT watchdog device
 * @pdev: Parent platform device
 * @wdd: Watchdog core device
 * @period: How long is one watchdog period in ms
 * @stopped_in_sleep: Is this watchdog stopped by the firmware in S1-S5
 * @stopped: Was the watchdog stopped by the driver in suspend
 * @actions: An array of instruction lists indexed by an action number from
 *           the WDAT table. There can be %NULL entries for not implemented
 *           actions.
 */
struct wdat_wdt {
	struct platform_device *pdev;
	struct watchdog_device wdd;
	unsigned int period;
	bool stopped_in_sleep;
	bool stopped;
	struct list_head *instructions[MAX_WDAT_ACTIONS];
};

#define to_wdat_wdt(wdd) container_of(wdd, struct wdat_wdt, wdd)

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

static int wdat_wdt_read(struct wdat_wdt *wdat,
	 const struct wdat_instruction *instr, u32 *value)
{
	const struct acpi_generic_address *gas = &instr->entry.register_region;

	switch (gas->access_width) {
	case 1:
		*value = ioread8(instr->reg);
		break;
	case 2:
		*value = ioread16(instr->reg);
		break;
	case 3:
		*value = ioread32(instr->reg);
		break;
	default:
		return -EINVAL;
	}

	dev_dbg(&wdat->pdev->dev, "Read %#x from 0x%08llx\n", *value,
		gas->address);

	return 0;
}

static int wdat_wdt_write(struct wdat_wdt *wdat,
	const struct wdat_instruction *instr, u32 value)
{
	const struct acpi_generic_address *gas = &instr->entry.register_region;

	switch (gas->access_width) {
	case 1:
		iowrite8((u8)value, instr->reg);
		break;
	case 2:
		iowrite16((u16)value, instr->reg);
		break;
	case 3:
		iowrite32(value, instr->reg);
		break;
	default:
		return -EINVAL;
	}

	dev_dbg(&wdat->pdev->dev, "Wrote %#x to 0x%08llx\n", value,
		gas->address);

	return 0;
}

static int wdat_wdt_run_action(struct wdat_wdt *wdat, unsigned int action,
			       u32 param, u32 *retval)
{
	struct wdat_instruction *instr;

	if (action >= ARRAY_SIZE(wdat->instructions))
		return -EINVAL;

	if (!wdat->instructions[action])
		return -EOPNOTSUPP;

	dev_dbg(&wdat->pdev->dev, "Running action %#x\n", action);

	/* Run each instruction sequentially */
	list_for_each_entry(instr, wdat->instructions[action], node) {
		const struct acpi_wdat_entry *entry = &instr->entry;
		const struct acpi_generic_address *gas;
		u32 flags, value, mask, x, y;
		bool preserve;
		int ret;

		gas = &entry->register_region;

		preserve = entry->instruction & ACPI_WDAT_PRESERVE_REGISTER;
		flags = entry->instruction & ~ACPI_WDAT_PRESERVE_REGISTER;
		value = entry->value;
		mask = entry->mask;

		switch (flags) {
		case ACPI_WDAT_READ_VALUE:
			ret = wdat_wdt_read(wdat, instr, &x);
			if (ret)
				return ret;
			x >>= gas->bit_offset;
			x &= mask;
			if (retval)
				*retval = x == value;
			break;

		case ACPI_WDAT_READ_COUNTDOWN:
			ret = wdat_wdt_read(wdat, instr, &x);
			if (ret)
				return ret;
			x >>= gas->bit_offset;
			x &= mask;
			if (retval)
				*retval = x;
			break;

		case ACPI_WDAT_WRITE_VALUE:
			x = value & mask;
			x <<= gas->bit_offset;
			if (preserve) {
				ret = wdat_wdt_read(wdat, instr, &y);
				if (ret)
					return ret;
				y = y & ~(mask << gas->bit_offset);
				x |= y;
			}
			ret = wdat_wdt_write(wdat, instr, x);
			if (ret)
				return ret;
			break;

		case ACPI_WDAT_WRITE_COUNTDOWN:
			x = param;
			x &= mask;
			x <<= gas->bit_offset;
			if (preserve) {
				ret = wdat_wdt_read(wdat, instr, &y);
				if (ret)
					return ret;
				y = y & ~(mask << gas->bit_offset);
				x |= y;
			}
			ret = wdat_wdt_write(wdat, instr, x);
			if (ret)
				return ret;
			break;

		default:
			dev_err(&wdat->pdev->dev, "Unknown instruction: %u\n",
				flags);
			return -EINVAL;
		}
	}

	return 0;
}

static int wdat_wdt_enable_reboot(struct wdat_wdt *wdat)
{
	int ret;

	/*
	 * WDAT specification says that the watchdog is required to reboot
	 * the system when it fires. However, it also states that it is
	 * recommeded to make it configurable through hardware register. We
	 * enable reboot now if it is configrable, just in case.
	 */
	ret = wdat_wdt_run_action(wdat, ACPI_WDAT_SET_REBOOT, 0, NULL);
	if (ret && ret != -EOPNOTSUPP) {
		dev_err(&wdat->pdev->dev,
			"Failed to enable reboot when watchdog triggers\n");
		return ret;
	}

	return 0;
}

static void wdat_wdt_boot_status(struct wdat_wdt *wdat)
{
	u32 boot_status = 0;
	int ret;

	ret = wdat_wdt_run_action(wdat, ACPI_WDAT_GET_STATUS, 0, &boot_status);
	if (ret && ret != -EOPNOTSUPP) {
		dev_err(&wdat->pdev->dev, "Failed to read boot status\n");
		return;
	}

	if (boot_status)
		wdat->wdd.bootstatus = WDIOF_CARDRESET;

	/* Clear the boot status in case BIOS did not do it */
	ret = wdat_wdt_run_action(wdat, ACPI_WDAT_SET_STATUS, 0, NULL);
	if (ret && ret != -EOPNOTSUPP)
		dev_err(&wdat->pdev->dev, "Failed to clear boot status\n");
}

static void wdat_wdt_set_running(struct wdat_wdt *wdat)
{
	u32 running = 0;
	int ret;

	ret = wdat_wdt_run_action(wdat, ACPI_WDAT_GET_RUNNING_STATE, 0,
				  &running);
	if (ret && ret != -EOPNOTSUPP)
		dev_err(&wdat->pdev->dev, "Failed to read running state\n");

	if (running)
		set_bit(WDOG_HW_RUNNING, &wdat->wdd.status);
}

static int wdat_wdt_start(struct watchdog_device *wdd)
{
	return wdat_wdt_run_action(to_wdat_wdt(wdd),
				   ACPI_WDAT_SET_RUNNING_STATE, 0, NULL);
}

static int wdat_wdt_stop(struct watchdog_device *wdd)
{
	return wdat_wdt_run_action(to_wdat_wdt(wdd),
				   ACPI_WDAT_SET_STOPPED_STATE, 0, NULL);
}

static int wdat_wdt_ping(struct watchdog_device *wdd)
{
	return wdat_wdt_run_action(to_wdat_wdt(wdd), ACPI_WDAT_RESET, 0, NULL);
}

static int wdat_wdt_set_timeout(struct watchdog_device *wdd,
				unsigned int timeout)
{
	struct wdat_wdt *wdat = to_wdat_wdt(wdd);
	unsigned int periods;
	int ret;

	periods = timeout * 1000 / wdat->period;
	ret = wdat_wdt_run_action(wdat, ACPI_WDAT_SET_COUNTDOWN, periods, NULL);
	if (!ret)
		wdd->timeout = timeout;
	return ret;
}

static unsigned int wdat_wdt_get_timeleft(struct watchdog_device *wdd)
{
	struct wdat_wdt *wdat = to_wdat_wdt(wdd);
	u32 periods = 0;

	wdat_wdt_run_action(wdat, ACPI_WDAT_GET_CURRENT_COUNTDOWN, 0, &periods);
	return periods * wdat->period / 1000;
}

static const struct watchdog_info wdat_wdt_info = {
	.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
	.firmware_version = 0,
	.identity = "wdat_wdt",
};

static const struct watchdog_ops wdat_wdt_ops = {
	.owner = THIS_MODULE,
	.start = wdat_wdt_start,
	.stop = wdat_wdt_stop,
	.ping = wdat_wdt_ping,
	.set_timeout = wdat_wdt_set_timeout,
	.get_timeleft = wdat_wdt_get_timeleft,
};

static int wdat_wdt_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	const struct acpi_wdat_entry *entries;
	const struct acpi_table_wdat *tbl;
	struct wdat_wdt *wdat;
	struct resource *res;
	void __iomem **regs;
	acpi_status status;
	int i, ret;

	status = acpi_get_table(ACPI_SIG_WDAT, 0,
				(struct acpi_table_header **)&tbl);
	if (ACPI_FAILURE(status))
		return -ENODEV;

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

	regs = devm_kcalloc(dev, pdev->num_resources, sizeof(*regs),
			    GFP_KERNEL);
	if (!regs)
		return -ENOMEM;

	/* WDAT specification wants to have >= 1ms period */
	if (tbl->timer_period < 1)
		return -EINVAL;
	if (tbl->min_count > tbl->max_count)
		return -EINVAL;

	wdat->period = tbl->timer_period;
	wdat->wdd.min_hw_heartbeat_ms = wdat->period * tbl->min_count;
	wdat->wdd.max_hw_heartbeat_ms = wdat->period * tbl->max_count;
	wdat->stopped_in_sleep = tbl->flags & ACPI_WDAT_STOPPED;
	wdat->wdd.info = &wdat_wdt_info;
	wdat->wdd.ops = &wdat_wdt_ops;
	wdat->pdev = pdev;

	/* Request and map all resources */
	for (i = 0; i < pdev->num_resources; i++) {
		void __iomem *reg;

		res = &pdev->resource[i];
		if (resource_type(res) == IORESOURCE_MEM) {
			reg = devm_ioremap_resource(dev, res);
			if (IS_ERR(reg))
				return PTR_ERR(reg);
		} else if (resource_type(res) == IORESOURCE_IO) {
			reg = devm_ioport_map(dev, res->start, 1);
			if (!reg)
				return -ENOMEM;
		} else {
			dev_err(dev, "Unsupported resource\n");
			return -EINVAL;
		}

		regs[i] = reg;
	}

	entries = (struct acpi_wdat_entry *)(tbl + 1);
	for (i = 0; i < tbl->entries; i++) {
		const struct acpi_generic_address *gas;
		struct wdat_instruction *instr;
		struct list_head *instructions;
		unsigned int action;
		struct resource r;
		int j;

		action = entries[i].action;
		if (action >= MAX_WDAT_ACTIONS) {
			dev_dbg(dev, "Skipping unknown action: %u\n", action);
			continue;
		}

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

		INIT_LIST_HEAD(&instr->node);
		instr->entry = entries[i];

		gas = &entries[i].register_region;

		memset(&r, 0, sizeof(r));
		r.start = gas->address;
		r.end = r.start + gas->access_width - 1;
		if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
			r.flags = IORESOURCE_MEM;
		} else if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_IO) {
			r.flags = IORESOURCE_IO;
		} else {
			dev_dbg(dev, "Unsupported address space: %d\n",
				gas->space_id);
			continue;
		}

		/* Find the matching resource */
		for (j = 0; j < pdev->num_resources; j++) {
			res = &pdev->resource[j];
			if (resource_contains(res, &r)) {
				instr->reg = regs[j] + r.start - res->start;
				break;
			}
		}

		if (!instr->reg) {
			dev_err(dev, "I/O resource not found\n");
			return -EINVAL;
		}

		instructions = wdat->instructions[action];
		if (!instructions) {
			instructions = devm_kzalloc(dev,
						    sizeof(*instructions),
						    GFP_KERNEL);
			if (!instructions)
				return -ENOMEM;

			INIT_LIST_HEAD(instructions);
			wdat->instructions[action] = instructions;
		}

		list_add_tail(&instr->node, instructions);
	}

	wdat_wdt_boot_status(wdat);
	wdat_wdt_set_running(wdat);

	ret = wdat_wdt_enable_reboot(wdat);
	if (ret)
		return ret;

	platform_set_drvdata(pdev, wdat);

	watchdog_set_nowayout(&wdat->wdd, nowayout);
	return devm_watchdog_register_device(dev, &wdat->wdd);
}

#ifdef CONFIG_PM_SLEEP
static int wdat_wdt_suspend_noirq(struct device *dev)
{
	struct wdat_wdt *wdat = dev_get_drvdata(dev);
	int ret;

	if (!watchdog_active(&wdat->wdd))
		return 0;

	/*
	 * We need to stop the watchdog if firmare is not doing it or if we
	 * are going suspend to idle (where firmware is not involved). If
	 * firmware is stopping the watchdog we kick it here one more time
	 * to give it some time.
	 */
	wdat->stopped = false;
	if (acpi_target_system_state() == ACPI_STATE_S0 ||
	    !wdat->stopped_in_sleep) {
		ret = wdat_wdt_stop(&wdat->wdd);
		if (!ret)
			wdat->stopped = true;
	} else {
		ret = wdat_wdt_ping(&wdat->wdd);
	}

	return ret;
}

static int wdat_wdt_resume_noirq(struct device *dev)
{
	struct wdat_wdt *wdat = dev_get_drvdata(dev);
	int ret;

	if (!watchdog_active(&wdat->wdd))
		return 0;

	if (!wdat->stopped) {
		/*
		 * Looks like the boot firmware reinitializes the watchdog
		 * before it hands off to the OS on resume from sleep so we
		 * stop and reprogram the watchdog here.
		 */
		ret = wdat_wdt_stop(&wdat->wdd);
		if (ret)
			return ret;

		ret = wdat_wdt_set_timeout(&wdat->wdd, wdat->wdd.timeout);
		if (ret)
			return ret;

		ret = wdat_wdt_enable_reboot(wdat);
		if (ret)
			return ret;

		ret = wdat_wdt_ping(&wdat->wdd);
		if (ret)
			return ret;
	}

	return wdat_wdt_start(&wdat->wdd);
}
#endif

static const struct dev_pm_ops wdat_wdt_pm_ops = {
	SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(wdat_wdt_suspend_noirq,
				      wdat_wdt_resume_noirq)
};

static struct platform_driver wdat_wdt_driver = {
	.probe = wdat_wdt_probe,
	.driver = {
		.name = "wdat_wdt",
		.pm = &wdat_wdt_pm_ops,
	},
};

module_platform_driver(wdat_wdt_driver);

MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>");
MODULE_DESCRIPTION("ACPI Hardware Watchdog (WDAT) driver");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:wdat_wdt");
