/*
 * Watchdog timer driver for the WinSystems EBC-C384
 * Copyright (C) 2016 William Breathitt Gray
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License, version 2, as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 */
#include <linux/device.h>
#include <linux/dmi.h>
#include <linux/errno.h>
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/isa.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/types.h>
#include <linux/watchdog.h>

#define MODULE_NAME		"ebc-c384_wdt"
#define WATCHDOG_TIMEOUT	60
/*
 * The timeout value in minutes must fit in a single byte when sent to the
 * watchdog timer; the maximum timeout possible is 15300 (255 * 60) seconds.
 */
#define WATCHDOG_MAX_TIMEOUT	15300
#define BASE_ADDR		0x564
#define ADDR_EXTENT		5
#define CFG_ADDR		(BASE_ADDR + 1)
#define PET_ADDR		(BASE_ADDR + 2)

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 unsigned timeout;
module_param(timeout, uint, 0);
MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds (default="
	__MODULE_STRING(WATCHDOG_TIMEOUT) ")");

static int ebc_c384_wdt_start(struct watchdog_device *wdev)
{
	unsigned t = wdev->timeout;

	/* resolution is in minutes for timeouts greater than 255 seconds */
	if (t > 255)
		t = DIV_ROUND_UP(t, 60);

	outb(t, PET_ADDR);

	return 0;
}

static int ebc_c384_wdt_stop(struct watchdog_device *wdev)
{
	outb(0x00, PET_ADDR);

	return 0;
}

static int ebc_c384_wdt_set_timeout(struct watchdog_device *wdev, unsigned t)
{
	/* resolution is in minutes for timeouts greater than 255 seconds */
	if (t > 255) {
		/* round second resolution up to minute granularity */
		wdev->timeout = roundup(t, 60);

		/* set watchdog timer for minutes */
		outb(0x00, CFG_ADDR);
	} else {
		wdev->timeout = t;

		/* set watchdog timer for seconds */
		outb(0x80, CFG_ADDR);
	}

	return 0;
}

static const struct watchdog_ops ebc_c384_wdt_ops = {
	.start = ebc_c384_wdt_start,
	.stop = ebc_c384_wdt_stop,
	.set_timeout = ebc_c384_wdt_set_timeout
};

static const struct watchdog_info ebc_c384_wdt_info = {
	.options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT,
	.identity = MODULE_NAME
};

static int ebc_c384_wdt_probe(struct device *dev, unsigned int id)
{
	struct watchdog_device *wdd;

	if (!devm_request_region(dev, BASE_ADDR, ADDR_EXTENT, dev_name(dev))) {
		dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n",
			BASE_ADDR, BASE_ADDR + ADDR_EXTENT);
		return -EBUSY;
	}

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

	wdd->info = &ebc_c384_wdt_info;
	wdd->ops = &ebc_c384_wdt_ops;
	wdd->timeout = WATCHDOG_TIMEOUT;
	wdd->min_timeout = 1;
	wdd->max_timeout = WATCHDOG_MAX_TIMEOUT;

	watchdog_set_nowayout(wdd, nowayout);

	if (watchdog_init_timeout(wdd, timeout, dev))
		dev_warn(dev, "Invalid timeout (%u seconds), using default (%u seconds)\n",
			timeout, WATCHDOG_TIMEOUT);

	dev_set_drvdata(dev, wdd);

	return watchdog_register_device(wdd);
}

static int ebc_c384_wdt_remove(struct device *dev, unsigned int id)
{
	struct watchdog_device *wdd = dev_get_drvdata(dev);

	watchdog_unregister_device(wdd);

	return 0;
}

static struct isa_driver ebc_c384_wdt_driver = {
	.probe = ebc_c384_wdt_probe,
	.driver = {
		.name = MODULE_NAME
	},
	.remove = ebc_c384_wdt_remove
};

static int __init ebc_c384_wdt_init(void)
{
	if (!dmi_match(DMI_BOARD_NAME, "EBC-C384 SBC"))
		return -ENODEV;

	return isa_register_driver(&ebc_c384_wdt_driver, 1);
}

static void __exit ebc_c384_wdt_exit(void)
{
	isa_unregister_driver(&ebc_c384_wdt_driver);
}

module_init(ebc_c384_wdt_init);
module_exit(ebc_c384_wdt_exit);

MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>");
MODULE_DESCRIPTION("WinSystems EBC-C384 watchdog timer driver");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("isa:" MODULE_NAME);
