Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cdb86121 authored by John Crispin's avatar John Crispin Committed by Ralf Baechle
Browse files

watchdog: MIPS: lantiq: implement OF support and minor fixes



Add support for OF. We also apply the following small fixes
* reduce boiler plate by using devm_request_and_ioremap
* sane error path for the clock
* move LTQ_RST_CAUSE_WDTRST to a soc specific header file
* add a message to show that the driver loaded

Signed-off-by: default avatarJohn Crispin <blogic@openwrt.org>
Acked-by: default avatarWim Van Sebroeck <wim@iguana.be>
Cc: linux-watchdog@vger.kernel.org
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/3810/


Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent ceff2676
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -49,7 +49,6 @@ extern struct clk *clk_get_io(void);
extern unsigned char ltq_boot_select(void);
/* find out what caused the last cpu reset */
extern int ltq_reset_cause(void);
#define LTQ_RST_CAUSE_WDTRST	0x20

#define IOPORT_RESOURCE_START	0x10000000
#define IOPORT_RESOURCE_END	0xffffffff
+2 −0
Original line number Diff line number Diff line
@@ -133,6 +133,8 @@ extern __iomem void *ltq_cgu_membase;
#define LTQ_WDT_BASE_ADDR	0x1F8803F0
#define LTQ_WDT_SIZE		0x10

#define LTQ_RST_CAUSE_WDTRST	0x20

/* STP - serial to parallel conversion unit */
#define LTQ_STP_BASE_ADDR	0x1E100BB0
#define LTQ_STP_SIZE		0x40
+25 −31
Original line number Diff line number Diff line
@@ -13,14 +13,15 @@
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <linux/watchdog.h>
#include <linux/platform_device.h>
#include <linux/of_platform.h>
#include <linux/uaccess.h>
#include <linux/clk.h>
#include <linux/io.h>

#include <lantiq.h>
#include <lantiq_soc.h>

/* Section 3.4 of the datasheet
/*
 * Section 3.4 of the datasheet
 * The password sequence protects the WDT control register from unintended
 * write actions, which might cause malfunction of the WDT.
 *
@@ -70,7 +71,8 @@ ltq_wdt_disable(void)
{
	/* write the first password magic */
	ltq_w32(LTQ_WDT_PW1, ltq_wdt_membase + LTQ_WDT_CR);
	/* write the second password magic with no config
	/*
	 * write the second password magic with no config
	 * this turns the watchdog off
	 */
	ltq_w32(LTQ_WDT_PW2, ltq_wdt_membase + LTQ_WDT_CR);
@@ -184,7 +186,7 @@ static struct miscdevice ltq_wdt_miscdev = {
	.fops	= &ltq_wdt_fops,
};

static int __init
static int __devinit
ltq_wdt_probe(struct platform_device *pdev)
{
	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -194,28 +196,27 @@ ltq_wdt_probe(struct platform_device *pdev)
		dev_err(&pdev->dev, "cannot obtain I/O memory region");
		return -ENOENT;
	}
	res = devm_request_mem_region(&pdev->dev, res->start,
		resource_size(res), dev_name(&pdev->dev));
	if (!res) {
		dev_err(&pdev->dev, "cannot request I/O memory region");
		return -EBUSY;
	}
	ltq_wdt_membase = devm_ioremap_nocache(&pdev->dev, res->start,
		resource_size(res));

	ltq_wdt_membase = devm_request_and_ioremap(&pdev->dev, res);
	if (!ltq_wdt_membase) {
		dev_err(&pdev->dev, "cannot remap I/O memory region\n");
		return -ENOMEM;
	}

	/* we do not need to enable the clock as it is always running */
	clk = clk_get(&pdev->dev, "io");
	WARN_ON(!clk);
	clk = clk_get_io();
	if (IS_ERR(clk)) {
		dev_err(&pdev->dev, "Failed to get clock\n");
		return -ENOENT;
	}
	ltq_io_region_clk_rate = clk_get_rate(clk);
	clk_put(clk);

	/* find out if the watchdog caused the last reboot */
	if (ltq_reset_cause() == LTQ_RST_CAUSE_WDTRST)
		ltq_wdt_bootstatus = WDIOF_CARDRESET;

	dev_info(&pdev->dev, "Init done\n");
	return misc_register(&ltq_wdt_miscdev);
}

@@ -227,33 +228,26 @@ ltq_wdt_remove(struct platform_device *pdev)
	return 0;
}

static const struct of_device_id ltq_wdt_match[] = {
	{ .compatible = "lantiq,wdt" },
	{},
};
MODULE_DEVICE_TABLE(of, ltq_wdt_match);

static struct platform_driver ltq_wdt_driver = {
	.probe = ltq_wdt_probe,
	.remove = __devexit_p(ltq_wdt_remove),
	.driver = {
		.name = "ltq_wdt",
		.name = "wdt",
		.owner = THIS_MODULE,
		.of_match_table = ltq_wdt_match,
	},
};

static int __init
init_ltq_wdt(void)
{
	return platform_driver_probe(&ltq_wdt_driver, ltq_wdt_probe);
}

static void __exit
exit_ltq_wdt(void)
{
	return platform_driver_unregister(&ltq_wdt_driver);
}

module_init(init_ltq_wdt);
module_exit(exit_ltq_wdt);
module_platform_driver(ltq_wdt_driver);

module_param(nowayout, bool, 0);
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started");

MODULE_AUTHOR("John Crispin <blogic@openwrt.org>");
MODULE_DESCRIPTION("Lantiq SoC Watchdog");
MODULE_LICENSE("GPL");