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

Commit e97662e1 authored by Ezequiel Garcia's avatar Ezequiel Garcia Committed by Jason Cooper
Browse files

watchdog: orion: Handle the interrupt so it's properly acked



DT-enabled plaforms, where the irqchip driver for the brigde interrupt
controller is available, can handle the watchdog IRQ properly. Therefore,
request the interrupt and add a dummy handler that merely calls panic().

This is done in order to have an initial 'ack' of the interruption,
which clears the watchdog state.

Furthermore, since some platforms don't have such IRQ, this commit
makes the interrupt specification optional.

Tested-by: default avatarSebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
Tested-by: default avatarWilly Tarreau <w@1wt.eu>
Signed-off-by: default avatarEzequiel Garcia <ezequiel.garcia@free-electrons.com>
Acked-by: default avatarWim Van Sebroeck <wim@iguana.be>
Tested-By: default avatarJason Gunthorpe <jgunthorpe@obsidianresearch.com>
Signed-off-by: default avatarJason Cooper <jason@lakedaemon.net>
parent d9d0c53d
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -7,6 +7,7 @@ Required Properties:


Optional properties:
Optional properties:


- interrupts	: Contains the IRQ for watchdog expiration
- timeout-sec	: Contains the watchdog timeout in seconds
- timeout-sec	: Contains the watchdog timeout in seconds


Example:
Example:
@@ -14,6 +15,7 @@ Example:
	wdt@20300 {
	wdt@20300 {
		compatible = "marvell,orion-wdt";
		compatible = "marvell,orion-wdt";
		reg = <0x20300 0x28>;
		reg = <0x20300 0x28>;
		interrupts = <3>;
		timeout-sec = <10>;
		timeout-sec = <10>;
		status = "okay";
		status = "okay";
	};
	};
+23 −1
Original line number Original line Diff line number Diff line
@@ -19,6 +19,7 @@
#include <linux/platform_device.h>
#include <linux/platform_device.h>
#include <linux/watchdog.h>
#include <linux/watchdog.h>
#include <linux/init.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/io.h>
#include <linux/clk.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/err.h>
@@ -119,10 +120,16 @@ static struct watchdog_device orion_wdt = {
	.min_timeout = 1,
	.min_timeout = 1,
};
};


static irqreturn_t orion_wdt_irq(int irq, void *devid)
{
	panic("Watchdog Timeout");
	return IRQ_HANDLED;
}

static int orion_wdt_probe(struct platform_device *pdev)
static int orion_wdt_probe(struct platform_device *pdev)
{
{
	struct resource *res;
	struct resource *res;
	int ret;
	int ret, irq;


	clk = devm_clk_get(&pdev->dev, NULL);
	clk = devm_clk_get(&pdev->dev, NULL);
	if (IS_ERR(clk)) {
	if (IS_ERR(clk)) {
@@ -161,6 +168,21 @@ static int orion_wdt_probe(struct platform_device *pdev)
	if (!orion_wdt_enabled())
	if (!orion_wdt_enabled())
		orion_wdt_stop(&orion_wdt);
		orion_wdt_stop(&orion_wdt);


	/* Request the IRQ only after the watchdog is disabled */
	irq = platform_get_irq(pdev, 0);
	if (irq > 0) {
		/*
		 * Not all supported platforms specify an interrupt for the
		 * watchdog, so let's make it optional.
		 */
		ret = devm_request_irq(&pdev->dev, irq, orion_wdt_irq, 0,
				       pdev->name, &orion_wdt);
		if (ret < 0) {
			dev_err(&pdev->dev, "failed to request IRQ\n");
			goto disable_clk;
		}
	}

	watchdog_set_nowayout(&orion_wdt, nowayout);
	watchdog_set_nowayout(&orion_wdt, nowayout);
	ret = watchdog_register_device(&orion_wdt);
	ret = watchdog_register_device(&orion_wdt);
	if (ret)
	if (ret)