* [PATCH v10 1/5] Documentation: add sbsa-gwdt driver documentation
2016-02-03 17:18 [PATCH v10 0/5] Watchdog: introduce ARM SBSA watchdog driver fu.wei
@ 2016-02-03 17:18 ` fu.wei
2016-02-03 17:18 ` [PATCH v10 2/5] ARM64: add SBSA Generic Watchdog device node in foundation-v8.dts fu.wei
` (3 subsequent siblings)
4 siblings, 0 replies; 46+ messages in thread
From: fu.wei @ 2016-02-03 17:18 UTC (permalink / raw)
To: robh+dt, pawel.moll, mark.rutland, ijc+devicetree, galak, wim,
linux, corbet, catalin.marinas, will.deacon,
Suravee.Suthikulpanit
Cc: linux-kernel, linux-watchdog, linux-doc, devicetree,
linux-arm-kernel, linaro-acpi, rruigrok, harba, cov, timur,
dyoung, panand, graeme.gregory, al.stone, hanjun.guo, jcm, arnd,
leo.duran, sudeep.holla, Fu Wei
From: Fu Wei <fu.wei@linaro.org>
The sbsa-gwdt.txt documentation in devicetree/bindings/watchdog is for
introducing SBSA(Server Base System Architecture) Generic Watchdog
device node info into FDT.
Also add sbsa-gwdt introduction in watchdog-parameters.txt
Acked-by: Arnd Bergmann <arnd@arndb.de>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Fu Wei <fu.wei@linaro.org>
---
.../devicetree/bindings/watchdog/sbsa-gwdt.txt | 35 ++++++++++++++++++++++
Documentation/watchdog/watchdog-parameters.txt | 5 ++++
2 files changed, 40 insertions(+)
diff --git a/Documentation/devicetree/bindings/watchdog/sbsa-gwdt.txt b/Documentation/devicetree/bindings/watchdog/sbsa-gwdt.txt
new file mode 100644
index 0000000..73a5d0d
--- /dev/null
+++ b/Documentation/devicetree/bindings/watchdog/sbsa-gwdt.txt
@@ -0,0 +1,35 @@
+* SBSA (Server Base System Architecture) Generic Watchdog
+
+The SBSA Generic Watchdog Timer is used to force a reset of the system
+after two stages of timeout have elapsed. A detailed definition of the
+watchdog timer can be found in the ARM document: ARM-DEN-0029 - Server
+Base System Architecture (SBSA)
+
+Required properties:
+- compatible: Should at least contain "arm,sbsa-gwdt".
+
+- reg: Each entry specifies the base physical address of a register frame
+ and the length of that frame; currently, two frames must be defined,
+ in this order:
+ 1: Watchdog control frame;
+ 2: Refresh frame.
+
+- interrupts: Should contain the Watchdog Signal 0 (WS0) SPI (Shared
+ Peripheral Interrupt) number of SBSA Generic Watchdog.
+
+Optional properties
+- timeout-sec: Watchdog timeout values (in seconds).
+
+- status: Indicates the device is not available for use. Should be "okay"
+ or "disabled" for available/unavailable. Default is "okay".
+
+Example for FVP Foundation Model v8:
+
+watchdog@2a440000 {
+ compatible = "arm,sbsa-gwdt";
+ reg = <0x0 0x2a440000 0 0x1000>,
+ <0x0 0x2a450000 0 0x1000>;
+ interrupts = <0 27 4>;
+ timeout-sec = <30>;
+ status = "okay";
+};
diff --git a/Documentation/watchdog/watchdog-parameters.txt b/Documentation/watchdog/watchdog-parameters.txt
index 9f9ec9f..300eb4d 100644
--- a/Documentation/watchdog/watchdog-parameters.txt
+++ b/Documentation/watchdog/watchdog-parameters.txt
@@ -284,6 +284,11 @@ sbc_fitpc2_wdt:
margin: Watchdog margin in seconds (default 60s)
nowayout: Watchdog cannot be stopped once started
-------------------------------------------------
+sbsa_gwdt:
+timeout: Watchdog timeout in seconds. (default 20s)
+nowayout: Watchdog cannot be stopped once started
+ (default=kernel config parameter)
+-------------------------------------------------
sc1200wdt:
isapnp: When set to 0 driver ISA PnP support will be disabled (default=1)
io: io port
--
2.5.0
^ permalink raw reply related [flat|nested] 46+ messages in thread
* [PATCH v10 2/5] ARM64: add SBSA Generic Watchdog device node in foundation-v8.dts
2016-02-03 17:18 [PATCH v10 0/5] Watchdog: introduce ARM SBSA watchdog driver fu.wei
2016-02-03 17:18 ` [PATCH v10 1/5] Documentation: add sbsa-gwdt driver documentation fu.wei
@ 2016-02-03 17:18 ` fu.wei
[not found] ` <1454519923-25230-1-git-send-email-fu.wei-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
` (2 subsequent siblings)
4 siblings, 0 replies; 46+ messages in thread
From: fu.wei @ 2016-02-03 17:18 UTC (permalink / raw)
To: robh+dt, pawel.moll, mark.rutland, ijc+devicetree, galak, wim,
linux, corbet, catalin.marinas, will.deacon,
Suravee.Suthikulpanit
Cc: linux-kernel, linux-watchdog, linux-doc, devicetree,
linux-arm-kernel, linaro-acpi, rruigrok, harba, cov, timur,
dyoung, panand, graeme.gregory, al.stone, hanjun.guo, jcm, arnd,
leo.duran, sudeep.holla, Fu Wei
From: Fu Wei <fu.wei@linaro.org>
This can be a example of adding SBSA Generic Watchdog device node
into some dts files for the Soc which contains SBSA Generic Watchdog.
Acked-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Fu Wei <fu.wei@linaro.org>
---
arch/arm64/boot/dts/arm/foundation-v8.dts | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/arch/arm64/boot/dts/arm/foundation-v8.dts b/arch/arm64/boot/dts/arm/foundation-v8.dts
index 4eac8dc..75da16b 100644
--- a/arch/arm64/boot/dts/arm/foundation-v8.dts
+++ b/arch/arm64/boot/dts/arm/foundation-v8.dts
@@ -237,4 +237,12 @@
};
};
};
+ watchdog@2a440000 {
+ compatible = "arm,sbsa-gwdt";
+ reg = <0x0 0x2a440000 0 0x1000>,
+ <0x0 0x2a450000 0 0x1000>;
+ interrupts = <0 27 4>;
+ timeout-sec = <30>;
+ status = "okay";
+ };
};
--
2.5.0
^ permalink raw reply related [flat|nested] 46+ messages in thread
[parent not found: <1454519923-25230-1-git-send-email-fu.wei-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>]
* [PATCH v10 3/5] ARM64: add SBSA Generic Watchdog device node in amd-seattle-soc.dtsi
[not found] ` <1454519923-25230-1-git-send-email-fu.wei-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
@ 2016-02-03 17:18 ` fu.wei-QSEj5FYQhm4dnm+yROfE0A
0 siblings, 0 replies; 46+ messages in thread
From: fu.wei-QSEj5FYQhm4dnm+yROfE0A @ 2016-02-03 17:18 UTC (permalink / raw)
To: robh+dt-DgEjT+Ai2ygdnm+yROfE0A, pawel.moll-5wv7dgnIgG8,
mark.rutland-5wv7dgnIgG8, ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
galak-sgV2jX0FEOL9JmXXK+q4OQ, wim-IQzOog9fTRqzQB+pC5nmwQ,
linux-0h96xk9xTtrk1uMJSBkQmQ, corbet-T1hC0tSOHrs,
catalin.marinas-5wv7dgnIgG8, will.deacon-5wv7dgnIgG8,
Suravee.Suthikulpanit-5C7GfCeVMHo
Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-watchdog-u79uwXL29TY76Z2rM5mHXA,
linux-doc-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linaro-acpi-cunTk1MwBs8s++Sfvej+rw,
rruigrok-sgV2jX0FEOL9JmXXK+q4OQ, harba-sgV2jX0FEOL9JmXXK+q4OQ,
cov-sgV2jX0FEOL9JmXXK+q4OQ, timur-sgV2jX0FEOL9JmXXK+q4OQ,
dyoung-H+wXaHxf7aLQT0dZR+AlfA, panand-H+wXaHxf7aLQT0dZR+AlfA,
graeme.gregory-QSEj5FYQhm4dnm+yROfE0A,
al.stone-QSEj5FYQhm4dnm+yROfE0A,
hanjun.guo-QSEj5FYQhm4dnm+yROfE0A, jcm-H+wXaHxf7aLQT0dZR+AlfA,
arnd-r2nGTMty4D4, leo.duran-5C7GfCeVMHo, sudeep.holla-5wv7dgnIgG8,
Fu Wei
From: Fu Wei <fu.wei-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
This can be a example of adding SBSA Generic Watchdog device node
into some dts files for the Soc which contains SBSA Generic Watchdog.
Acked-by: Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org>
Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit-5C7GfCeVMHo@public.gmane.org>
Signed-off-by: Fu Wei <fu.wei-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi b/arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi
index 2874d92..057e9c0 100644
--- a/arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi
+++ b/arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi
@@ -84,6 +84,15 @@
clock-names = "uartclk", "apb_pclk";
};
+ watchdog0: watchdog@e0bb0000 {
+ compatible = "arm,sbsa-gwdt";
+ reg = <0x0 0xe0bc0000 0 0x1000>,
+ <0x0 0xe0bb0000 0 0x1000>;
+ interrupts = <0 337 4>;
+ timeout-sec = <30>;
+ status = "disabled";
+ };
+
spi0: ssp@e1020000 {
status = "disabled";
compatible = "arm,pl022", "arm,primecell";
--
2.5.0
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 46+ messages in thread
* [PATCH v10 4/5] Watchdog: introduce ARM SBSA watchdog driver
2016-02-03 17:18 [PATCH v10 0/5] Watchdog: introduce ARM SBSA watchdog driver fu.wei
` (2 preceding siblings ...)
[not found] ` <1454519923-25230-1-git-send-email-fu.wei-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
@ 2016-02-03 17:18 ` fu.wei
2016-02-03 17:48 ` Timur Tabi
[not found] ` <1454519923-25230-5-git-send-email-fu.wei-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2016-02-03 17:18 ` [PATCH v10 5/5] Watchdog: ARM SBSA Generic Watchdog half timeout panic support fu.wei
4 siblings, 2 replies; 46+ messages in thread
From: fu.wei @ 2016-02-03 17:18 UTC (permalink / raw)
To: robh+dt, pawel.moll, mark.rutland, ijc+devicetree, galak, wim,
linux, corbet, catalin.marinas, will.deacon,
Suravee.Suthikulpanit
Cc: linux-kernel, linux-watchdog, linux-doc, devicetree,
linux-arm-kernel, linaro-acpi, rruigrok, harba, cov, timur,
dyoung, panand, graeme.gregory, al.stone, hanjun.guo, jcm, arnd,
leo.duran, sudeep.holla, Fu Wei
From: Fu Wei <fu.wei@linaro.org>
According to Server Base System Architecture (SBSA) specification,
the SBSA Generic Watchdog has two stage timeouts: the first signal (WS0)
is for alerting the system by interrupt, the second one (WS1) is a real
hardware reset.
This patch initially implements a simple single stage watchdog driver:
when the timeout is reached, your system will be reset by the second
signal (WS1).
The first signal (WS0) is ignored in this driver.
This driver bases on linux kernel watchdog framework, so it can get
timeout from module parameter and FDT at the driver init stage.
Signed-off-by: Fu Wei <fu.wei@linaro.org>
Reviewed-by: Graeme Gregory <graeme.gregory@linaro.org>
Tested-by: Pratyush Anand <panand@redhat.com>
---
drivers/watchdog/Kconfig | 17 +++
drivers/watchdog/Makefile | 1 +
drivers/watchdog/sbsa_gwdt.c | 322 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 340 insertions(+)
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 4f0e7be..4ab1b05 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -201,6 +201,23 @@ config ARM_SP805_WATCHDOG
ARM Primecell SP805 Watchdog timer. This will reboot your system when
the timeout is reached.
+config ARM_SBSA_WATCHDOG
+ tristate "ARM SBSA Generic Watchdog"
+ depends on ARM64
+ depends on ARM_ARCH_TIMER
+ select WATCHDOG_CORE
+ help
+ ARM SBSA Generic Watchdog has two stage timeouts:
+ the first signal (WS0) is for alerting the system by interrupt,
+ the second one (WS1) is a real hardware reset.
+ More details: ARM DEN0029B - Server Base System Architecture (SBSA)
+
+ This is a simple single stage driver: when the timeout is reached,
+ your system will be reset by WS1. The first signal (WS0) is ignored.
+
+ To compile this driver as module, choose M here: The module
+ will be called sbsa_gwdt.
+
config ASM9260_WATCHDOG
tristate "Alphascale ASM9260 watchdog"
depends on MACH_ASM9260
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index f566753..f9826d4 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -30,6 +30,7 @@ obj-$(CONFIG_USBPCWATCHDOG) += pcwd_usb.o
# ARM Architecture
obj-$(CONFIG_ARM_SP805_WATCHDOG) += sp805_wdt.o
+obj-$(CONFIG_ARM_SBSA_WATCHDOG) += sbsa_gwdt.o
obj-$(CONFIG_ASM9260_WATCHDOG) += asm9260_wdt.o
obj-$(CONFIG_AT91RM9200_WATCHDOG) += at91rm9200_wdt.o
obj-$(CONFIG_AT91SAM9X_WATCHDOG) += at91sam9_wdt.o
diff --git a/drivers/watchdog/sbsa_gwdt.c b/drivers/watchdog/sbsa_gwdt.c
new file mode 100644
index 0000000..5a2dba3
--- /dev/null
+++ b/drivers/watchdog/sbsa_gwdt.c
@@ -0,0 +1,322 @@
+/*
+ * SBSA(Server Base System Architecture) Generic Watchdog driver
+ *
+ * Copyright (c) 2015, Linaro Ltd.
+ * Author: Fu Wei <fu.wei@linaro.org>
+ * Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
+ * Al Stone <al.stone@linaro.org>
+ * Timur Tabi <timur@codeaurora.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License 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.
+ *
+ * This SBSA Generic watchdog driver is a single stage timeout version.
+ * Since this watchdog timer has two stages, and each stage is determined
+ * by WOR. So the timeout is (WOR * 2).
+ * When first timeout is reached, WS0 is triggered, the interrupt
+ * triggered by WS0 will be ignored, then the second watch period starts;
+ * when second timeout is reached, then WS1 is triggered, system reset.
+ *
+ * More details about the hardware specification of this device:
+ * ARM DEN0029B - Server Base System Architecture (SBSA)
+ *
+ * SBSA GWDT: |--------WOR-------WS0--------WOR-------WS1
+ * |----------------timeout----------------reset
+ *
+ */
+
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/uaccess.h>
+#include <linux/watchdog.h>
+#include <asm/arch_timer.h>
+
+/* SBSA Generic Watchdog register definitions */
+/* refresh frame */
+#define SBSA_GWDT_WRR 0x000
+
+/* control frame */
+#define SBSA_GWDT_WCS 0x000
+#define SBSA_GWDT_WOR 0x008
+#define SBSA_GWDT_WCV 0x010
+
+/* refresh/control frame */
+#define SBSA_GWDT_W_IIDR 0xfcc
+#define SBSA_GWDT_IDR 0xfd0
+
+/* Watchdog Control and Status Register */
+#define SBSA_GWDT_WCS_EN BIT(0)
+#define SBSA_GWDT_WCS_WS0 BIT(1)
+#define SBSA_GWDT_WCS_WS1 BIT(2)
+
+/**
+ * struct sbsa_gwdt - Internal representation of the SBSA GWDT
+ * @wdd: kernel watchdog_device structure
+ * @clk: store the System Counter clock frequency, in Hz.
+ * @refresh_base: Virtual address of the watchdog refresh frame
+ * @control_base: Virtual address of the watchdog control frame
+ */
+struct sbsa_gwdt {
+ struct watchdog_device wdd;
+ u32 clk;
+ void __iomem *refresh_base;
+ void __iomem *control_base;
+};
+
+#define to_sbsa_gwdt(e) container_of(e, struct sbsa_gwdt, wdd)
+
+#define DEFAULT_TIMEOUT 20 /* seconds, the 1st + 2nd watch periods*/
+
+static unsigned int timeout;
+module_param(timeout, uint, 0);
+MODULE_PARM_DESC(timeout,
+ "Watchdog timeout in seconds. (>=0, default="
+ __MODULE_STRING(DEFAULT_TIMEOUT) ")");
+
+static bool nowayout = WATCHDOG_NOWAYOUT;
+module_param(nowayout, bool, S_IRUGO);
+MODULE_PARM_DESC(nowayout,
+ "Watchdog cannot be stopped once started (default="
+ __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
+
+/*
+ * watchdog operation functions
+ */
+static int sbsa_gwdt_set_timeout(struct watchdog_device *wdd,
+ unsigned int timeout)
+{
+ struct sbsa_gwdt *gwdt = to_sbsa_gwdt(wdd);
+
+ wdd->timeout = timeout;
+ writel(timeout / 2 * gwdt->clk, gwdt->control_base + SBSA_GWDT_WOR);
+
+ return 0;
+}
+
+static unsigned int sbsa_gwdt_get_timeleft(struct watchdog_device *wdd)
+{
+ struct sbsa_gwdt *gwdt = to_sbsa_gwdt(wdd);
+ u64 timeleft = readq(gwdt->control_base + SBSA_GWDT_WCV) -
+ arch_counter_get_cntvct();
+
+ do_div(timeleft, gwdt->clk);
+
+ if (readl(gwdt->control_base + SBSA_GWDT_WCS) & SBSA_GWDT_WCS_WS0)
+ return timeleft;
+
+ return timeleft + wdd->timeout / 2;
+}
+
+static int sbsa_gwdt_keepalive(struct watchdog_device *wdd)
+{
+ struct sbsa_gwdt *gwdt = to_sbsa_gwdt(wdd);
+
+ /*
+ * Writing WRR for an explicit watchdog refresh.
+ * You can write anyting(like 0xc0ffee).
+ */
+ writel(0xc0ffee, gwdt->refresh_base + SBSA_GWDT_WRR);
+
+ return 0;
+}
+
+static unsigned int sbsa_gwdt_status(struct watchdog_device *wdd)
+{
+ struct sbsa_gwdt *gwdt = to_sbsa_gwdt(wdd);
+ u32 status = readl(gwdt->control_base + SBSA_GWDT_WCS);
+
+ /* is the watchdog timer running? */
+ return (status & SBSA_GWDT_WCS_EN) << WDOG_ACTIVE;
+}
+
+static int sbsa_gwdt_start(struct watchdog_device *wdd)
+{
+ struct sbsa_gwdt *gwdt = to_sbsa_gwdt(wdd);
+
+ /* writing WCS will cause an explicit watchdog refresh */
+ writel(SBSA_GWDT_WCS_EN, gwdt->control_base + SBSA_GWDT_WCS);
+
+ return sbsa_gwdt_keepalive(wdd);
+}
+
+static int sbsa_gwdt_stop(struct watchdog_device *wdd)
+{
+ struct sbsa_gwdt *gwdt = to_sbsa_gwdt(wdd);
+
+ writel(0, gwdt->control_base + SBSA_GWDT_WCS);
+
+ return 0;
+}
+
+static struct watchdog_info sbsa_gwdt_info = {
+ .identity = "SBSA Generic Watchdog",
+ .options = WDIOF_SETTIMEOUT |
+ WDIOF_KEEPALIVEPING |
+ WDIOF_MAGICCLOSE |
+ WDIOF_CARDRESET,
+};
+
+static struct watchdog_ops sbsa_gwdt_ops = {
+ .owner = THIS_MODULE,
+ .start = sbsa_gwdt_start,
+ .stop = sbsa_gwdt_stop,
+ .status = sbsa_gwdt_status,
+ .ping = sbsa_gwdt_keepalive,
+ .set_timeout = sbsa_gwdt_set_timeout,
+ .get_timeleft = sbsa_gwdt_get_timeleft,
+};
+
+static int sbsa_gwdt_probe(struct platform_device *pdev)
+{
+ void __iomem *rf_base, *cf_base;
+ struct device *dev = &pdev->dev;
+ struct watchdog_device *wdd;
+ struct sbsa_gwdt *gwdt;
+ struct resource *res;
+ u32 status;
+ int ret;
+
+ gwdt = devm_kzalloc(dev, sizeof(*gwdt), GFP_KERNEL);
+ if (!gwdt)
+ return -ENOMEM;
+ platform_set_drvdata(pdev, gwdt);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ cf_base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(cf_base))
+ return PTR_ERR(cf_base);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ rf_base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(rf_base))
+ return PTR_ERR(rf_base);
+
+ /*
+ * Get the frequency of system counter from the cp15 interface of ARM
+ * Generic timer. We don't need to check it, because if it returns "0",
+ * system would panic in very early stage.
+ */
+ gwdt->clk = arch_timer_get_cntfrq();
+ gwdt->refresh_base = rf_base;
+ gwdt->control_base = cf_base;
+
+ wdd = &gwdt->wdd;
+ wdd->parent = dev;
+ wdd->info = &sbsa_gwdt_info;
+ wdd->ops = &sbsa_gwdt_ops;
+ watchdog_set_drvdata(wdd, gwdt);
+ watchdog_set_nowayout(wdd, nowayout);
+
+ wdd->min_timeout = 2;
+ wdd->max_timeout = U32_MAX / gwdt->clk * 2;
+ wdd->timeout = DEFAULT_TIMEOUT;
+ watchdog_init_timeout(wdd, timeout, dev);
+
+ status = readl(gwdt->control_base + SBSA_GWDT_WCS);
+ if (status & SBSA_GWDT_WCS_WS1) {
+ dev_warn(dev, "System reset by WDT.\n");
+ wdd->bootstatus |= WDIOF_CARDRESET;
+ }
+
+ ret = watchdog_register_device(wdd);
+ if (ret)
+ return ret;
+
+ /*
+ * Update timeout to WOR.
+ * Because of the explicit watchdog refresh mechanism,
+ * it's also a ping, if watchdog is enabled.
+ */
+ sbsa_gwdt_set_timeout(wdd, wdd->timeout);
+
+ dev_info(dev, "Initialized with %ds timeout @ %u Hz%s\n", wdd->timeout,
+ gwdt->clk, status & SBSA_GWDT_WCS_EN ? " [enabled]" : "");
+
+ return 0;
+}
+
+static void sbsa_gwdt_shutdown(struct platform_device *pdev)
+{
+ struct sbsa_gwdt *gwdt = platform_get_drvdata(pdev);
+
+ sbsa_gwdt_stop(&gwdt->wdd);
+}
+
+static int sbsa_gwdt_remove(struct platform_device *pdev)
+{
+ struct sbsa_gwdt *gwdt = platform_get_drvdata(pdev);
+
+ watchdog_unregister_device(&gwdt->wdd);
+
+ return 0;
+}
+
+/* Disable watchdog if it is active during suspend */
+static int __maybe_unused sbsa_gwdt_suspend(struct device *dev)
+{
+ struct sbsa_gwdt *gwdt = dev_get_drvdata(dev);
+
+ if (watchdog_active(&gwdt->wdd))
+ sbsa_gwdt_stop(&gwdt->wdd);
+
+ return 0;
+}
+
+/* Enable watchdog and configure it if necessary */
+static int __maybe_unused sbsa_gwdt_resume(struct device *dev)
+{
+ struct sbsa_gwdt *gwdt = dev_get_drvdata(dev);
+
+ if (watchdog_active(&gwdt->wdd))
+ sbsa_gwdt_start(&gwdt->wdd);
+
+ return 0;
+}
+
+static const struct dev_pm_ops sbsa_gwdt_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(sbsa_gwdt_suspend, sbsa_gwdt_resume)
+};
+
+static const struct of_device_id sbsa_gwdt_of_match[] = {
+ { .compatible = "arm,sbsa-gwdt", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, sbsa_gwdt_of_match);
+
+static const struct platform_device_id sbsa_gwdt_pdev_match[] = {
+ { .name = "sbsa-gwdt", },
+ {},
+};
+MODULE_DEVICE_TABLE(platform, sbsa_gwdt_pdev_match);
+
+static struct platform_driver sbsa_gwdt_driver = {
+ .driver = {
+ .name = "sbsa-gwdt",
+ .pm = &sbsa_gwdt_pm_ops,
+ .of_match_table = sbsa_gwdt_of_match,
+ },
+ .probe = sbsa_gwdt_probe,
+ .remove = sbsa_gwdt_remove,
+ .shutdown = sbsa_gwdt_shutdown,
+ .id_table = sbsa_gwdt_pdev_match,
+};
+
+module_platform_driver(sbsa_gwdt_driver);
+
+MODULE_DESCRIPTION("SBSA Generic Watchdog Driver");
+MODULE_AUTHOR("Fu Wei <fu.wei@linaro.org>");
+MODULE_AUTHOR("Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>");
+MODULE_AUTHOR("Al Stone <al.stone@linaro.org>");
+MODULE_AUTHOR("Timur Tabi <timur@codeaurora.org>");
+MODULE_LICENSE("GPL v2");
--
2.5.0
^ permalink raw reply related [flat|nested] 46+ messages in thread
* Re: [PATCH v10 4/5] Watchdog: introduce ARM SBSA watchdog driver
2016-02-03 17:18 ` [PATCH v10 4/5] Watchdog: introduce ARM SBSA watchdog driver fu.wei
@ 2016-02-03 17:48 ` Timur Tabi
[not found] ` <56B23D61.2050001-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
[not found] ` <1454519923-25230-5-git-send-email-fu.wei-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
1 sibling, 1 reply; 46+ messages in thread
From: Timur Tabi @ 2016-02-03 17:48 UTC (permalink / raw)
To: fu.wei, robh+dt, pawel.moll, mark.rutland, ijc+devicetree, galak,
wim, linux, corbet, catalin.marinas, will.deacon,
Suravee.Suthikulpanit
Cc: linux-kernel, linux-watchdog, linux-doc, devicetree,
linux-arm-kernel, linaro-acpi, rruigrok, harba, cov, dyoung,
panand, graeme.gregory, al.stone, hanjun.guo, jcm, arnd,
leo.duran, sudeep.holla
fu.wei@linaro.org wrote:
> +static struct platform_driver sbsa_gwdt_driver = {
> + .driver = {
> + .name = "sbsa-gwdt",
> + .pm = &sbsa_gwdt_pm_ops,
> + .of_match_table = sbsa_gwdt_of_match,
> + },
> + .probe = sbsa_gwdt_probe,
> + .remove = sbsa_gwdt_remove,
> + .shutdown = sbsa_gwdt_shutdown,
> + .id_table = sbsa_gwdt_pdev_match,
> +};
I just noticed you dropped ACPI support. Server platforms are supposed
to use ACPI, so that seems like a critical omission to me. You had a
GTDT parser in an older version of this patch. What happened to it?
^ permalink raw reply [flat|nested] 46+ messages in thread
[parent not found: <1454519923-25230-5-git-send-email-fu.wei-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>]
* Re: [PATCH v10 4/5] Watchdog: introduce ARM SBSA watchdog driver
[not found] ` <1454519923-25230-5-git-send-email-fu.wei-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
@ 2016-02-04 16:25 ` Mathieu Poirier
2016-02-05 9:01 ` Fu Wei
2016-02-04 16:31 ` Will Deacon
1 sibling, 1 reply; 46+ messages in thread
From: Mathieu Poirier @ 2016-02-04 16:25 UTC (permalink / raw)
To: fu.wei-QSEj5FYQhm4dnm+yROfE0A
Cc: Rob Herring, Paweł Moll, Mark Rutland, Ian Campbell,
Kumar Gala, wim-IQzOog9fTRqzQB+pC5nmwQ,
linux-0h96xk9xTtrk1uMJSBkQmQ, Jon Corbet, Catalin Marinas,
Will Deacon, Suravee.Suthikulpanit-5C7GfCeVMHo,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-watchdog-u79uwXL29TY76Z2rM5mHXA,
linux-doc-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
linaro-acpi-cunTk1MwBs8s++Sfvej+rw,
rruigrok-sgV2jX0FEOL9JmXXK+q4OQ, harba-sgV2jX0FEOL9JmXXK+q4OQ,
Christopher Covington, timur-sgV2jX0FEOL9JmXXK+q4OQ,
dyoung-H+wXaHxf7aLQT0dZR+AlfA, panand-H+wXaHxf7aLQT0dZR+AlfA,
graeme.gregory-QSEj5FYQhm4dnm+yROfE0A,
al.stone-QSEj5FYQhm4dnm+yROfE0A, hanjun.guo
On 3 February 2016 at 10:18, <fu.wei-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org> wrote:
> From: Fu Wei <fu.wei-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
>
> According to Server Base System Architecture (SBSA) specification,
> the SBSA Generic Watchdog has two stage timeouts: the first signal (WS0)
> is for alerting the system by interrupt, the second one (WS1) is a real
> hardware reset.
>
> This patch initially implements a simple single stage watchdog driver:
> when the timeout is reached, your system will be reset by the second
> signal (WS1).
> The first signal (WS0) is ignored in this driver.
>
> This driver bases on linux kernel watchdog framework, so it can get
> timeout from module parameter and FDT at the driver init stage.
>
> Signed-off-by: Fu Wei <fu.wei-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> Reviewed-by: Graeme Gregory <graeme.gregory-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> Tested-by: Pratyush Anand <panand-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> ---
> drivers/watchdog/Kconfig | 17 +++
> drivers/watchdog/Makefile | 1 +
> drivers/watchdog/sbsa_gwdt.c | 322 +++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 340 insertions(+)
>
> diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
> index 4f0e7be..4ab1b05 100644
> --- a/drivers/watchdog/Kconfig
> +++ b/drivers/watchdog/Kconfig
> @@ -201,6 +201,23 @@ config ARM_SP805_WATCHDOG
> ARM Primecell SP805 Watchdog timer. This will reboot your system when
> the timeout is reached.
>
> +config ARM_SBSA_WATCHDOG
> + tristate "ARM SBSA Generic Watchdog"
> + depends on ARM64
> + depends on ARM_ARCH_TIMER
> + select WATCHDOG_CORE
> + help
> + ARM SBSA Generic Watchdog has two stage timeouts:
> + the first signal (WS0) is for alerting the system by interrupt,
> + the second one (WS1) is a real hardware reset.
> + More details: ARM DEN0029B - Server Base System Architecture (SBSA)
> +
> + This is a simple single stage driver: when the timeout is reached,
> + your system will be reset by WS1. The first signal (WS0) is ignored.
> +
> + To compile this driver as module, choose M here: The module
> + will be called sbsa_gwdt.
> +
> config ASM9260_WATCHDOG
> tristate "Alphascale ASM9260 watchdog"
> depends on MACH_ASM9260
> diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
> index f566753..f9826d4 100644
> --- a/drivers/watchdog/Makefile
> +++ b/drivers/watchdog/Makefile
> @@ -30,6 +30,7 @@ obj-$(CONFIG_USBPCWATCHDOG) += pcwd_usb.o
>
> # ARM Architecture
> obj-$(CONFIG_ARM_SP805_WATCHDOG) += sp805_wdt.o
> +obj-$(CONFIG_ARM_SBSA_WATCHDOG) += sbsa_gwdt.o
> obj-$(CONFIG_ASM9260_WATCHDOG) += asm9260_wdt.o
> obj-$(CONFIG_AT91RM9200_WATCHDOG) += at91rm9200_wdt.o
> obj-$(CONFIG_AT91SAM9X_WATCHDOG) += at91sam9_wdt.o
> diff --git a/drivers/watchdog/sbsa_gwdt.c b/drivers/watchdog/sbsa_gwdt.c
> new file mode 100644
> index 0000000..5a2dba3
> --- /dev/null
> +++ b/drivers/watchdog/sbsa_gwdt.c
> @@ -0,0 +1,322 @@
> +/*
> + * SBSA(Server Base System Architecture) Generic Watchdog driver
> + *
> + * Copyright (c) 2015, Linaro Ltd.
> + * Author: Fu Wei <fu.wei-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> + * Suravee Suthikulpanit <Suravee.Suthikulpanit-5C7GfCeVMHo@public.gmane.org>
> + * Al Stone <al.stone-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> + * Timur Tabi <timur-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License 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.
> + *
> + * This SBSA Generic watchdog driver is a single stage timeout version.
> + * Since this watchdog timer has two stages, and each stage is determined
> + * by WOR. So the timeout is (WOR * 2).
> + * When first timeout is reached, WS0 is triggered, the interrupt
> + * triggered by WS0 will be ignored, then the second watch period starts;
> + * when second timeout is reached, then WS1 is triggered, system reset.
> + *
> + * More details about the hardware specification of this device:
> + * ARM DEN0029B - Server Base System Architecture (SBSA)
> + *
> + * SBSA GWDT: |--------WOR-------WS0--------WOR-------WS1
> + * |----------------timeout----------------reset
> + *
> + */
> +
> +#include <linux/io.h>
> +#include <linux/interrupt.h>
> +#include <linux/module.h>
> +#include <linux/moduleparam.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <linux/uaccess.h>
> +#include <linux/watchdog.h>
> +#include <asm/arch_timer.h>
> +
> +/* SBSA Generic Watchdog register definitions */
> +/* refresh frame */
> +#define SBSA_GWDT_WRR 0x000
> +
> +/* control frame */
> +#define SBSA_GWDT_WCS 0x000
> +#define SBSA_GWDT_WOR 0x008
> +#define SBSA_GWDT_WCV 0x010
> +
> +/* refresh/control frame */
> +#define SBSA_GWDT_W_IIDR 0xfcc
> +#define SBSA_GWDT_IDR 0xfd0
> +
> +/* Watchdog Control and Status Register */
> +#define SBSA_GWDT_WCS_EN BIT(0)
> +#define SBSA_GWDT_WCS_WS0 BIT(1)
> +#define SBSA_GWDT_WCS_WS1 BIT(2)
> +
> +/**
> + * struct sbsa_gwdt - Internal representation of the SBSA GWDT
> + * @wdd: kernel watchdog_device structure
> + * @clk: store the System Counter clock frequency, in Hz.
> + * @refresh_base: Virtual address of the watchdog refresh frame
> + * @control_base: Virtual address of the watchdog control frame
> + */
> +struct sbsa_gwdt {
> + struct watchdog_device wdd;
> + u32 clk;
> + void __iomem *refresh_base;
> + void __iomem *control_base;
> +};
> +
> +#define to_sbsa_gwdt(e) container_of(e, struct sbsa_gwdt, wdd)
> +
> +#define DEFAULT_TIMEOUT 20 /* seconds, the 1st + 2nd watch periods*/
> +
> +static unsigned int timeout;
> +module_param(timeout, uint, 0);
> +MODULE_PARM_DESC(timeout,
> + "Watchdog timeout in seconds. (>=0, default="
> + __MODULE_STRING(DEFAULT_TIMEOUT) ")");
> +
> +static bool nowayout = WATCHDOG_NOWAYOUT;
> +module_param(nowayout, bool, S_IRUGO);
> +MODULE_PARM_DESC(nowayout,
> + "Watchdog cannot be stopped once started (default="
> + __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
> +
> +/*
> + * watchdog operation functions
> + */
> +static int sbsa_gwdt_set_timeout(struct watchdog_device *wdd,
> + unsigned int timeout)
> +{
> + struct sbsa_gwdt *gwdt = to_sbsa_gwdt(wdd);
> +
> + wdd->timeout = timeout;
> + writel(timeout / 2 * gwdt->clk, gwdt->control_base + SBSA_GWDT_WOR);
> +
> + return 0;
> +}
> +
> +static unsigned int sbsa_gwdt_get_timeleft(struct watchdog_device *wdd)
> +{
> + struct sbsa_gwdt *gwdt = to_sbsa_gwdt(wdd);
> + u64 timeleft = readq(gwdt->control_base + SBSA_GWDT_WCV) -
> + arch_counter_get_cntvct();
> +
> + do_div(timeleft, gwdt->clk);
> +
> + if (readl(gwdt->control_base + SBSA_GWDT_WCS) & SBSA_GWDT_WCS_WS0)
> + return timeleft;
> +
> + return timeleft + wdd->timeout / 2;
It would be great to have a comment whenever hard coded values are
used. That way people understand why things were set this way. The
same applies for the rest of this patch.
> +}
> +
> +static int sbsa_gwdt_keepalive(struct watchdog_device *wdd)
> +{
> + struct sbsa_gwdt *gwdt = to_sbsa_gwdt(wdd);
> +
> + /*
> + * Writing WRR for an explicit watchdog refresh.
> + * You can write anyting(like 0xc0ffee).
> + */
> + writel(0xc0ffee, gwdt->refresh_base + SBSA_GWDT_WRR);
> +
> + return 0;
> +}
> +
> +static unsigned int sbsa_gwdt_status(struct watchdog_device *wdd)
> +{
> + struct sbsa_gwdt *gwdt = to_sbsa_gwdt(wdd);
> + u32 status = readl(gwdt->control_base + SBSA_GWDT_WCS);
> +
> + /* is the watchdog timer running? */
> + return (status & SBSA_GWDT_WCS_EN) << WDOG_ACTIVE;
> +}
> +
> +static int sbsa_gwdt_start(struct watchdog_device *wdd)
> +{
> + struct sbsa_gwdt *gwdt = to_sbsa_gwdt(wdd);
> +
> + /* writing WCS will cause an explicit watchdog refresh */
> + writel(SBSA_GWDT_WCS_EN, gwdt->control_base + SBSA_GWDT_WCS);
> +
> + return sbsa_gwdt_keepalive(wdd);
> +}
> +
> +static int sbsa_gwdt_stop(struct watchdog_device *wdd)
> +{
> + struct sbsa_gwdt *gwdt = to_sbsa_gwdt(wdd);
> +
> + writel(0, gwdt->control_base + SBSA_GWDT_WCS);
> +
> + return 0;
> +}
> +
> +static struct watchdog_info sbsa_gwdt_info = {
> + .identity = "SBSA Generic Watchdog",
> + .options = WDIOF_SETTIMEOUT |
> + WDIOF_KEEPALIVEPING |
> + WDIOF_MAGICCLOSE |
> + WDIOF_CARDRESET,
> +};
> +
> +static struct watchdog_ops sbsa_gwdt_ops = {
> + .owner = THIS_MODULE,
> + .start = sbsa_gwdt_start,
> + .stop = sbsa_gwdt_stop,
> + .status = sbsa_gwdt_status,
> + .ping = sbsa_gwdt_keepalive,
> + .set_timeout = sbsa_gwdt_set_timeout,
> + .get_timeleft = sbsa_gwdt_get_timeleft,
> +};
> +
> +static int sbsa_gwdt_probe(struct platform_device *pdev)
> +{
> + void __iomem *rf_base, *cf_base;
> + struct device *dev = &pdev->dev;
> + struct watchdog_device *wdd;
> + struct sbsa_gwdt *gwdt;
> + struct resource *res;
> + u32 status;
> + int ret;
> +
> + gwdt = devm_kzalloc(dev, sizeof(*gwdt), GFP_KERNEL);
> + if (!gwdt)
> + return -ENOMEM;
> + platform_set_drvdata(pdev, gwdt);
> +
> + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + cf_base = devm_ioremap_resource(dev, res);
> + if (IS_ERR(cf_base))
> + return PTR_ERR(cf_base);
> +
> + res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
> + rf_base = devm_ioremap_resource(dev, res);
> + if (IS_ERR(rf_base))
> + return PTR_ERR(rf_base);
> +
> + /*
> + * Get the frequency of system counter from the cp15 interface of ARM
> + * Generic timer. We don't need to check it, because if it returns "0",
> + * system would panic in very early stage.
> + */
> + gwdt->clk = arch_timer_get_cntfrq();
> + gwdt->refresh_base = rf_base;
> + gwdt->control_base = cf_base;
> +
> + wdd = &gwdt->wdd;
> + wdd->parent = dev;
> + wdd->info = &sbsa_gwdt_info;
> + wdd->ops = &sbsa_gwdt_ops;
> + watchdog_set_drvdata(wdd, gwdt);
> + watchdog_set_nowayout(wdd, nowayout);
> +
> + wdd->min_timeout = 2;
> + wdd->max_timeout = U32_MAX / gwdt->clk * 2;
> + wdd->timeout = DEFAULT_TIMEOUT;
> + watchdog_init_timeout(wdd, timeout, dev);
> +
> + status = readl(gwdt->control_base + SBSA_GWDT_WCS);
> + if (status & SBSA_GWDT_WCS_WS1) {
> + dev_warn(dev, "System reset by WDT.\n");
> + wdd->bootstatus |= WDIOF_CARDRESET;
> + }
> +
> + ret = watchdog_register_device(wdd);
> + if (ret)
> + return ret;
> +
> + /*
> + * Update timeout to WOR.
> + * Because of the explicit watchdog refresh mechanism,
> + * it's also a ping, if watchdog is enabled.
> + */
> + sbsa_gwdt_set_timeout(wdd, wdd->timeout);
> +
> + dev_info(dev, "Initialized with %ds timeout @ %u Hz%s\n", wdd->timeout,
> + gwdt->clk, status & SBSA_GWDT_WCS_EN ? " [enabled]" : "");
> +
> + return 0;
> +}
> +
> +static void sbsa_gwdt_shutdown(struct platform_device *pdev)
> +{
> + struct sbsa_gwdt *gwdt = platform_get_drvdata(pdev);
> +
> + sbsa_gwdt_stop(&gwdt->wdd);
> +}
> +
> +static int sbsa_gwdt_remove(struct platform_device *pdev)
> +{
> + struct sbsa_gwdt *gwdt = platform_get_drvdata(pdev);
> +
> + watchdog_unregister_device(&gwdt->wdd);
> +
> + return 0;
> +}
> +
> +/* Disable watchdog if it is active during suspend */
> +static int __maybe_unused sbsa_gwdt_suspend(struct device *dev)
> +{
> + struct sbsa_gwdt *gwdt = dev_get_drvdata(dev);
> +
> + if (watchdog_active(&gwdt->wdd))
> + sbsa_gwdt_stop(&gwdt->wdd);
> +
> + return 0;
> +}
> +
> +/* Enable watchdog and configure it if necessary */
> +static int __maybe_unused sbsa_gwdt_resume(struct device *dev)
> +{
> + struct sbsa_gwdt *gwdt = dev_get_drvdata(dev);
> +
> + if (watchdog_active(&gwdt->wdd))
> + sbsa_gwdt_start(&gwdt->wdd);
> +
> + return 0;
> +}
> +
> +static const struct dev_pm_ops sbsa_gwdt_pm_ops = {
> + SET_SYSTEM_SLEEP_PM_OPS(sbsa_gwdt_suspend, sbsa_gwdt_resume)
> +};
> +
> +static const struct of_device_id sbsa_gwdt_of_match[] = {
> + { .compatible = "arm,sbsa-gwdt", },
> + {},
> +};
> +MODULE_DEVICE_TABLE(of, sbsa_gwdt_of_match);
> +
> +static const struct platform_device_id sbsa_gwdt_pdev_match[] = {
> + { .name = "sbsa-gwdt", },
> + {},
> +};
> +MODULE_DEVICE_TABLE(platform, sbsa_gwdt_pdev_match);
> +
> +static struct platform_driver sbsa_gwdt_driver = {
> + .driver = {
> + .name = "sbsa-gwdt",
> + .pm = &sbsa_gwdt_pm_ops,
> + .of_match_table = sbsa_gwdt_of_match,
> + },
> + .probe = sbsa_gwdt_probe,
> + .remove = sbsa_gwdt_remove,
> + .shutdown = sbsa_gwdt_shutdown,
> + .id_table = sbsa_gwdt_pdev_match,
> +};
> +
> +module_platform_driver(sbsa_gwdt_driver);
> +
> +MODULE_DESCRIPTION("SBSA Generic Watchdog Driver");
> +MODULE_AUTHOR("Fu Wei <fu.wei-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>");
> +MODULE_AUTHOR("Suravee Suthikulpanit <Suravee.Suthikulpanit-5C7GfCeVMHo@public.gmane.org>");
> +MODULE_AUTHOR("Al Stone <al.stone-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>");
> +MODULE_AUTHOR("Timur Tabi <timur-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>");
> +MODULE_LICENSE("GPL v2");
> --
> 2.5.0
>
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [PATCH v10 4/5] Watchdog: introduce ARM SBSA watchdog driver
2016-02-04 16:25 ` Mathieu Poirier
@ 2016-02-05 9:01 ` Fu Wei
0 siblings, 0 replies; 46+ messages in thread
From: Fu Wei @ 2016-02-05 9:01 UTC (permalink / raw)
To: Mathieu Poirier
Cc: Rob Herring, Paweł Moll, Mark Rutland, Ian Campbell,
Kumar Gala, Wim Van Sebroeck, Guenter Roeck, Jon Corbet,
Catalin Marinas, Will Deacon, Suravee Suthikulpanit,
linux-kernel@vger.kernel.org, linux-watchdog, linux-doc,
devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
Linaro ACPI Mailman List, rruigrok, Abdulhamid, Harb,
Christopher Covington
On 5 February 2016 at 00:25, Mathieu Poirier <mathieu.poirier@linaro.org> wrote:
> On 3 February 2016 at 10:18, <fu.wei@linaro.org> wrote:
>> From: Fu Wei <fu.wei@linaro.org>
>>
>> According to Server Base System Architecture (SBSA) specification,
>> the SBSA Generic Watchdog has two stage timeouts: the first signal (WS0)
>> is for alerting the system by interrupt, the second one (WS1) is a real
>> hardware reset.
>>
>> This patch initially implements a simple single stage watchdog driver:
>> when the timeout is reached, your system will be reset by the second
>> signal (WS1).
>> The first signal (WS0) is ignored in this driver.
>>
>> This driver bases on linux kernel watchdog framework, so it can get
>> timeout from module parameter and FDT at the driver init stage.
>>
>> Signed-off-by: Fu Wei <fu.wei@linaro.org>
>> Reviewed-by: Graeme Gregory <graeme.gregory@linaro.org>
>> Tested-by: Pratyush Anand <panand@redhat.com>
>> ---
>> drivers/watchdog/Kconfig | 17 +++
>> drivers/watchdog/Makefile | 1 +
>> drivers/watchdog/sbsa_gwdt.c | 322 +++++++++++++++++++++++++++++++++++++++++++
>> 3 files changed, 340 insertions(+)
>>
>> diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
>> index 4f0e7be..4ab1b05 100644
>> --- a/drivers/watchdog/Kconfig
>> +++ b/drivers/watchdog/Kconfig
>> @@ -201,6 +201,23 @@ config ARM_SP805_WATCHDOG
>> ARM Primecell SP805 Watchdog timer. This will reboot your system when
>> the timeout is reached.
>>
>> +config ARM_SBSA_WATCHDOG
>> + tristate "ARM SBSA Generic Watchdog"
>> + depends on ARM64
>> + depends on ARM_ARCH_TIMER
>> + select WATCHDOG_CORE
>> + help
>> + ARM SBSA Generic Watchdog has two stage timeouts:
>> + the first signal (WS0) is for alerting the system by interrupt,
>> + the second one (WS1) is a real hardware reset.
>> + More details: ARM DEN0029B - Server Base System Architecture (SBSA)
>> +
>> + This is a simple single stage driver: when the timeout is reached,
>> + your system will be reset by WS1. The first signal (WS0) is ignored.
>> +
>> + To compile this driver as module, choose M here: The module
>> + will be called sbsa_gwdt.
>> +
>> config ASM9260_WATCHDOG
>> tristate "Alphascale ASM9260 watchdog"
>> depends on MACH_ASM9260
>> diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
>> index f566753..f9826d4 100644
>> --- a/drivers/watchdog/Makefile
>> +++ b/drivers/watchdog/Makefile
>> @@ -30,6 +30,7 @@ obj-$(CONFIG_USBPCWATCHDOG) += pcwd_usb.o
>>
>> # ARM Architecture
>> obj-$(CONFIG_ARM_SP805_WATCHDOG) += sp805_wdt.o
>> +obj-$(CONFIG_ARM_SBSA_WATCHDOG) += sbsa_gwdt.o
>> obj-$(CONFIG_ASM9260_WATCHDOG) += asm9260_wdt.o
>> obj-$(CONFIG_AT91RM9200_WATCHDOG) += at91rm9200_wdt.o
>> obj-$(CONFIG_AT91SAM9X_WATCHDOG) += at91sam9_wdt.o
>> diff --git a/drivers/watchdog/sbsa_gwdt.c b/drivers/watchdog/sbsa_gwdt.c
>> new file mode 100644
>> index 0000000..5a2dba3
>> --- /dev/null
>> +++ b/drivers/watchdog/sbsa_gwdt.c
>> @@ -0,0 +1,322 @@
>> +/*
>> + * SBSA(Server Base System Architecture) Generic Watchdog driver
>> + *
>> + * Copyright (c) 2015, Linaro Ltd.
>> + * Author: Fu Wei <fu.wei@linaro.org>
>> + * Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
>> + * Al Stone <al.stone@linaro.org>
>> + * Timur Tabi <timur@codeaurora.org>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License 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.
>> + *
>> + * This SBSA Generic watchdog driver is a single stage timeout version.
>> + * Since this watchdog timer has two stages, and each stage is determined
>> + * by WOR. So the timeout is (WOR * 2).
>> + * When first timeout is reached, WS0 is triggered, the interrupt
>> + * triggered by WS0 will be ignored, then the second watch period starts;
>> + * when second timeout is reached, then WS1 is triggered, system reset.
>> + *
>> + * More details about the hardware specification of this device:
>> + * ARM DEN0029B - Server Base System Architecture (SBSA)
>> + *
>> + * SBSA GWDT: |--------WOR-------WS0--------WOR-------WS1
>> + * |----------------timeout----------------reset
>> + *
>> + */
>> +
>> +#include <linux/io.h>
>> +#include <linux/interrupt.h>
>> +#include <linux/module.h>
>> +#include <linux/moduleparam.h>
>> +#include <linux/of.h>
>> +#include <linux/of_device.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/uaccess.h>
>> +#include <linux/watchdog.h>
>> +#include <asm/arch_timer.h>
>> +
>> +/* SBSA Generic Watchdog register definitions */
>> +/* refresh frame */
>> +#define SBSA_GWDT_WRR 0x000
>> +
>> +/* control frame */
>> +#define SBSA_GWDT_WCS 0x000
>> +#define SBSA_GWDT_WOR 0x008
>> +#define SBSA_GWDT_WCV 0x010
>> +
>> +/* refresh/control frame */
>> +#define SBSA_GWDT_W_IIDR 0xfcc
>> +#define SBSA_GWDT_IDR 0xfd0
>> +
>> +/* Watchdog Control and Status Register */
>> +#define SBSA_GWDT_WCS_EN BIT(0)
>> +#define SBSA_GWDT_WCS_WS0 BIT(1)
>> +#define SBSA_GWDT_WCS_WS1 BIT(2)
>> +
>> +/**
>> + * struct sbsa_gwdt - Internal representation of the SBSA GWDT
>> + * @wdd: kernel watchdog_device structure
>> + * @clk: store the System Counter clock frequency, in Hz.
>> + * @refresh_base: Virtual address of the watchdog refresh frame
>> + * @control_base: Virtual address of the watchdog control frame
>> + */
>> +struct sbsa_gwdt {
>> + struct watchdog_device wdd;
>> + u32 clk;
>> + void __iomem *refresh_base;
>> + void __iomem *control_base;
>> +};
>> +
>> +#define to_sbsa_gwdt(e) container_of(e, struct sbsa_gwdt, wdd)
>> +
>> +#define DEFAULT_TIMEOUT 20 /* seconds, the 1st + 2nd watch periods*/
>> +
>> +static unsigned int timeout;
>> +module_param(timeout, uint, 0);
>> +MODULE_PARM_DESC(timeout,
>> + "Watchdog timeout in seconds. (>=0, default="
>> + __MODULE_STRING(DEFAULT_TIMEOUT) ")");
>> +
>> +static bool nowayout = WATCHDOG_NOWAYOUT;
>> +module_param(nowayout, bool, S_IRUGO);
>> +MODULE_PARM_DESC(nowayout,
>> + "Watchdog cannot be stopped once started (default="
>> + __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
>> +
>> +/*
>> + * watchdog operation functions
>> + */
>> +static int sbsa_gwdt_set_timeout(struct watchdog_device *wdd,
>> + unsigned int timeout)
>> +{
>> + struct sbsa_gwdt *gwdt = to_sbsa_gwdt(wdd);
>> +
>> + wdd->timeout = timeout;
>> + writel(timeout / 2 * gwdt->clk, gwdt->control_base + SBSA_GWDT_WOR);
>> +
>> + return 0;
>> +}
>> +
>> +static unsigned int sbsa_gwdt_get_timeleft(struct watchdog_device *wdd)
>> +{
>> + struct sbsa_gwdt *gwdt = to_sbsa_gwdt(wdd);
>> + u64 timeleft = readq(gwdt->control_base + SBSA_GWDT_WCV) -
>> + arch_counter_get_cntvct();
>> +
>> + do_div(timeleft, gwdt->clk);
>> +
>> + if (readl(gwdt->control_base + SBSA_GWDT_WCS) & SBSA_GWDT_WCS_WS0)
>> + return timeleft;
>> +
>> + return timeleft + wdd->timeout / 2;
>
> It would be great to have a comment whenever hard coded values are
> used. That way people understand why things were set this way. The
> same applies for the rest of this patch.
OK, will do , thanks
>
>> +}
>> +
>> +static int sbsa_gwdt_keepalive(struct watchdog_device *wdd)
>> +{
>> + struct sbsa_gwdt *gwdt = to_sbsa_gwdt(wdd);
>> +
>> + /*
>> + * Writing WRR for an explicit watchdog refresh.
>> + * You can write anyting(like 0xc0ffee).
>> + */
>> + writel(0xc0ffee, gwdt->refresh_base + SBSA_GWDT_WRR);
>> +
>> + return 0;
>> +}
>> +
>> +static unsigned int sbsa_gwdt_status(struct watchdog_device *wdd)
>> +{
>> + struct sbsa_gwdt *gwdt = to_sbsa_gwdt(wdd);
>> + u32 status = readl(gwdt->control_base + SBSA_GWDT_WCS);
>> +
>> + /* is the watchdog timer running? */
>> + return (status & SBSA_GWDT_WCS_EN) << WDOG_ACTIVE;
>> +}
>> +
>> +static int sbsa_gwdt_start(struct watchdog_device *wdd)
>> +{
>> + struct sbsa_gwdt *gwdt = to_sbsa_gwdt(wdd);
>> +
>> + /* writing WCS will cause an explicit watchdog refresh */
>> + writel(SBSA_GWDT_WCS_EN, gwdt->control_base + SBSA_GWDT_WCS);
>> +
>> + return sbsa_gwdt_keepalive(wdd);
>> +}
>> +
>> +static int sbsa_gwdt_stop(struct watchdog_device *wdd)
>> +{
>> + struct sbsa_gwdt *gwdt = to_sbsa_gwdt(wdd);
>> +
>> + writel(0, gwdt->control_base + SBSA_GWDT_WCS);
>> +
>> + return 0;
>> +}
>> +
>> +static struct watchdog_info sbsa_gwdt_info = {
>> + .identity = "SBSA Generic Watchdog",
>> + .options = WDIOF_SETTIMEOUT |
>> + WDIOF_KEEPALIVEPING |
>> + WDIOF_MAGICCLOSE |
>> + WDIOF_CARDRESET,
>> +};
>> +
>> +static struct watchdog_ops sbsa_gwdt_ops = {
>> + .owner = THIS_MODULE,
>> + .start = sbsa_gwdt_start,
>> + .stop = sbsa_gwdt_stop,
>> + .status = sbsa_gwdt_status,
>> + .ping = sbsa_gwdt_keepalive,
>> + .set_timeout = sbsa_gwdt_set_timeout,
>> + .get_timeleft = sbsa_gwdt_get_timeleft,
>> +};
>> +
>> +static int sbsa_gwdt_probe(struct platform_device *pdev)
>> +{
>> + void __iomem *rf_base, *cf_base;
>> + struct device *dev = &pdev->dev;
>> + struct watchdog_device *wdd;
>> + struct sbsa_gwdt *gwdt;
>> + struct resource *res;
>> + u32 status;
>> + int ret;
>> +
>> + gwdt = devm_kzalloc(dev, sizeof(*gwdt), GFP_KERNEL);
>> + if (!gwdt)
>> + return -ENOMEM;
>> + platform_set_drvdata(pdev, gwdt);
>> +
>> + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> + cf_base = devm_ioremap_resource(dev, res);
>> + if (IS_ERR(cf_base))
>> + return PTR_ERR(cf_base);
>> +
>> + res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
>> + rf_base = devm_ioremap_resource(dev, res);
>> + if (IS_ERR(rf_base))
>> + return PTR_ERR(rf_base);
>> +
>> + /*
>> + * Get the frequency of system counter from the cp15 interface of ARM
>> + * Generic timer. We don't need to check it, because if it returns "0",
>> + * system would panic in very early stage.
>> + */
>> + gwdt->clk = arch_timer_get_cntfrq();
>> + gwdt->refresh_base = rf_base;
>> + gwdt->control_base = cf_base;
>> +
>> + wdd = &gwdt->wdd;
>> + wdd->parent = dev;
>> + wdd->info = &sbsa_gwdt_info;
>> + wdd->ops = &sbsa_gwdt_ops;
>> + watchdog_set_drvdata(wdd, gwdt);
>> + watchdog_set_nowayout(wdd, nowayout);
>> +
>> + wdd->min_timeout = 2;
>> + wdd->max_timeout = U32_MAX / gwdt->clk * 2;
>> + wdd->timeout = DEFAULT_TIMEOUT;
>> + watchdog_init_timeout(wdd, timeout, dev);
>> +
>> + status = readl(gwdt->control_base + SBSA_GWDT_WCS);
>> + if (status & SBSA_GWDT_WCS_WS1) {
>> + dev_warn(dev, "System reset by WDT.\n");
>> + wdd->bootstatus |= WDIOF_CARDRESET;
>> + }
>> +
>> + ret = watchdog_register_device(wdd);
>> + if (ret)
>> + return ret;
>> +
>> + /*
>> + * Update timeout to WOR.
>> + * Because of the explicit watchdog refresh mechanism,
>> + * it's also a ping, if watchdog is enabled.
>> + */
>> + sbsa_gwdt_set_timeout(wdd, wdd->timeout);
>> +
>> + dev_info(dev, "Initialized with %ds timeout @ %u Hz%s\n", wdd->timeout,
>> + gwdt->clk, status & SBSA_GWDT_WCS_EN ? " [enabled]" : "");
>> +
>> + return 0;
>> +}
>> +
>> +static void sbsa_gwdt_shutdown(struct platform_device *pdev)
>> +{
>> + struct sbsa_gwdt *gwdt = platform_get_drvdata(pdev);
>> +
>> + sbsa_gwdt_stop(&gwdt->wdd);
>> +}
>> +
>> +static int sbsa_gwdt_remove(struct platform_device *pdev)
>> +{
>> + struct sbsa_gwdt *gwdt = platform_get_drvdata(pdev);
>> +
>> + watchdog_unregister_device(&gwdt->wdd);
>> +
>> + return 0;
>> +}
>> +
>> +/* Disable watchdog if it is active during suspend */
>> +static int __maybe_unused sbsa_gwdt_suspend(struct device *dev)
>> +{
>> + struct sbsa_gwdt *gwdt = dev_get_drvdata(dev);
>> +
>> + if (watchdog_active(&gwdt->wdd))
>> + sbsa_gwdt_stop(&gwdt->wdd);
>> +
>> + return 0;
>> +}
>> +
>> +/* Enable watchdog and configure it if necessary */
>> +static int __maybe_unused sbsa_gwdt_resume(struct device *dev)
>> +{
>> + struct sbsa_gwdt *gwdt = dev_get_drvdata(dev);
>> +
>> + if (watchdog_active(&gwdt->wdd))
>> + sbsa_gwdt_start(&gwdt->wdd);
>> +
>> + return 0;
>> +}
>> +
>> +static const struct dev_pm_ops sbsa_gwdt_pm_ops = {
>> + SET_SYSTEM_SLEEP_PM_OPS(sbsa_gwdt_suspend, sbsa_gwdt_resume)
>> +};
>> +
>> +static const struct of_device_id sbsa_gwdt_of_match[] = {
>> + { .compatible = "arm,sbsa-gwdt", },
>> + {},
>> +};
>> +MODULE_DEVICE_TABLE(of, sbsa_gwdt_of_match);
>> +
>> +static const struct platform_device_id sbsa_gwdt_pdev_match[] = {
>> + { .name = "sbsa-gwdt", },
>> + {},
>> +};
>> +MODULE_DEVICE_TABLE(platform, sbsa_gwdt_pdev_match);
>> +
>> +static struct platform_driver sbsa_gwdt_driver = {
>> + .driver = {
>> + .name = "sbsa-gwdt",
>> + .pm = &sbsa_gwdt_pm_ops,
>> + .of_match_table = sbsa_gwdt_of_match,
>> + },
>> + .probe = sbsa_gwdt_probe,
>> + .remove = sbsa_gwdt_remove,
>> + .shutdown = sbsa_gwdt_shutdown,
>> + .id_table = sbsa_gwdt_pdev_match,
>> +};
>> +
>> +module_platform_driver(sbsa_gwdt_driver);
>> +
>> +MODULE_DESCRIPTION("SBSA Generic Watchdog Driver");
>> +MODULE_AUTHOR("Fu Wei <fu.wei@linaro.org>");
>> +MODULE_AUTHOR("Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>");
>> +MODULE_AUTHOR("Al Stone <al.stone@linaro.org>");
>> +MODULE_AUTHOR("Timur Tabi <timur@codeaurora.org>");
>> +MODULE_LICENSE("GPL v2");
>> --
>> 2.5.0
>>
--
Best regards,
Fu Wei
Software Engineer
Red Hat Software (Beijing) Co.,Ltd.Shanghai Branch
Ph: +86 21 61221326(direct)
Ph: +86 186 2020 4684 (mobile)
Room 1512, Regus One Corporate Avenue,Level 15,
One Corporate Avenue,222 Hubin Road,Huangpu District,
Shanghai,China 200021
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [PATCH v10 4/5] Watchdog: introduce ARM SBSA watchdog driver
[not found] ` <1454519923-25230-5-git-send-email-fu.wei-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2016-02-04 16:25 ` Mathieu Poirier
@ 2016-02-04 16:31 ` Will Deacon
[not found] ` <20160204163101.GH17257-5wv7dgnIgG8@public.gmane.org>
1 sibling, 1 reply; 46+ messages in thread
From: Will Deacon @ 2016-02-04 16:31 UTC (permalink / raw)
To: fu.wei-QSEj5FYQhm4dnm+yROfE0A
Cc: robh+dt-DgEjT+Ai2ygdnm+yROfE0A, pawel.moll-5wv7dgnIgG8,
mark.rutland-5wv7dgnIgG8, ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
galak-sgV2jX0FEOL9JmXXK+q4OQ, wim-IQzOog9fTRqzQB+pC5nmwQ,
linux-0h96xk9xTtrk1uMJSBkQmQ, corbet-T1hC0tSOHrs,
catalin.marinas-5wv7dgnIgG8, Suravee.Suthikulpanit-5C7GfCeVMHo,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-watchdog-u79uwXL29TY76Z2rM5mHXA,
linux-doc-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linaro-acpi-cunTk1MwBs8s++Sfvej+rw,
rruigrok-sgV2jX0FEOL9JmXXK+q4OQ, harba-sgV2jX0FEOL9JmXXK+q4OQ,
cov-sgV2jX0FEOL9JmXXK+q4OQ, timur-sgV2jX0FEOL9JmXXK+q4OQ,
dyoung-H+wXaHxf7aLQT0dZR+AlfA, panand-H+wXaHxf7aLQT0dZR+AlfA,
graeme.gregory-QSEj5FYQhm4dnm+yROfE0A,
al.stone-QSEj5FYQhm4dnm+yROfE0A,
hanjun.guo-QSEj5FYQhm4dnm+yROfE0A, jcm-H+wXaHxf7aLQT0dZR+AlfA,
arnd-r2nGTMty4D4, leo.duran-5C7GfCeVMHo, sudeep.holla-5wv7dgnIgG8
On Thu, Feb 04, 2016 at 01:18:42AM +0800, fu.wei-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org wrote:
> +static int sbsa_gwdt_keepalive(struct watchdog_device *wdd)
> +{
> + struct sbsa_gwdt *gwdt = to_sbsa_gwdt(wdd);
> +
> + /*
> + * Writing WRR for an explicit watchdog refresh.
> + * You can write anyting(like 0xc0ffee).
> + */
> + writel(0xc0ffee, gwdt->refresh_base + SBSA_GWDT_WRR);
> +
> + return 0;
> +}
You might get in trouble for that. 0xd09f00d is probably less poisonous.
http://www.petpoisonhelpline.com/poison/caffeine/
Will
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 46+ messages in thread
* [PATCH v10 5/5] Watchdog: ARM SBSA Generic Watchdog half timeout panic support
2016-02-03 17:18 [PATCH v10 0/5] Watchdog: introduce ARM SBSA watchdog driver fu.wei
` (3 preceding siblings ...)
2016-02-03 17:18 ` [PATCH v10 4/5] Watchdog: introduce ARM SBSA watchdog driver fu.wei
@ 2016-02-03 17:18 ` fu.wei
2016-02-03 17:27 ` Timur Tabi
2016-02-04 16:32 ` Mathieu Poirier
4 siblings, 2 replies; 46+ messages in thread
From: fu.wei @ 2016-02-03 17:18 UTC (permalink / raw)
To: robh+dt, pawel.moll, mark.rutland, ijc+devicetree, galak, wim,
linux, corbet, catalin.marinas, will.deacon,
Suravee.Suthikulpanit
Cc: linux-kernel, linux-watchdog, linux-doc, devicetree,
linux-arm-kernel, linaro-acpi, rruigrok, harba, cov, timur,
dyoung, panand, graeme.gregory, al.stone, hanjun.guo, jcm, arnd,
leo.duran, sudeep.holla, Fu Wei
From: Fu Wei <fu.wei@linaro.org>
This patch registers the WS0 interrupt routine to trigger panic,
when the watchdog reachs the first stage (the half timeout).
This function can help administrator to backup the system context
info by panic console output or kdump (if supported), once system
goes wrong (doesn't feed the watchdog in the half timeout).
User also can skip panic by setting panic_enabled (module parameter) as 0
Signed-off-by: Fu Wei <fu.wei@linaro.org>
---
Documentation/watchdog/watchdog-parameters.txt | 1 +
drivers/watchdog/Kconfig | 10 +++++
drivers/watchdog/sbsa_gwdt.c | 54 +++++++++++++++++++++++---
3 files changed, 60 insertions(+), 5 deletions(-)
diff --git a/Documentation/watchdog/watchdog-parameters.txt b/Documentation/watchdog/watchdog-parameters.txt
index 300eb4d..31641e2 100644
--- a/Documentation/watchdog/watchdog-parameters.txt
+++ b/Documentation/watchdog/watchdog-parameters.txt
@@ -286,6 +286,7 @@ nowayout: Watchdog cannot be stopped once started
-------------------------------------------------
sbsa_gwdt:
timeout: Watchdog timeout in seconds. (default 20s)
+panic_enabled: Enable panic at half timeout. (default=true)
nowayout: Watchdog cannot be stopped once started
(default=kernel config parameter)
-------------------------------------------------
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 4ab1b05..42adfdf 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -218,6 +218,16 @@ config ARM_SBSA_WATCHDOG
To compile this driver as module, choose M here: The module
will be called sbsa_gwdt.
+config ARM_SBSA_WATCHDOG_PANIC
+ bool "ARM SBSA Generic Watchdog triggers panic at the half timeout"
+ depends on ARM_SBSA_WATCHDOG
+ help
+ ARM SBSA Generic Watchdog will trigger panic in the first signal
+ (WS0) interrupt routine when the half timeout is reached.
+ This function can help administrator to backup the system context
+ info by panic console output or kdump (if supported).
+ But user can skip panic by setting moduleparam panic_enabled as 0.
+
config ASM9260_WATCHDOG
tristate "Alphascale ASM9260 watchdog"
depends on MACH_ASM9260
diff --git a/drivers/watchdog/sbsa_gwdt.c b/drivers/watchdog/sbsa_gwdt.c
index 5a2dba3..d18cf37 100644
--- a/drivers/watchdog/sbsa_gwdt.c
+++ b/drivers/watchdog/sbsa_gwdt.c
@@ -16,18 +16,22 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * This SBSA Generic watchdog driver is a single stage timeout version.
+ * This SBSA Generic watchdog driver is a two stages version.
* Since this watchdog timer has two stages, and each stage is determined
* by WOR. So the timeout is (WOR * 2).
- * When first timeout is reached, WS0 is triggered, the interrupt
- * triggered by WS0 will be ignored, then the second watch period starts;
- * when second timeout is reached, then WS1 is triggered, system reset.
+ * When the first stage(the half timeout) is reached, WS0 interrupt is
+ * triggered, at this moment the second watch period starts;
+ * In the WS0 interrupt routine, panic will be triggered for saving the
+ * system context.
+ * If the system is getting into trouble and cannot be reset by panic or
+ * restart properly by the kdump kernel(if supported), then the second
+ * stage (the timeout) will be reached, system will be reset by WS1.
*
* More details about the hardware specification of this device:
* ARM DEN0029B - Server Base System Architecture (SBSA)
*
* SBSA GWDT: |--------WOR-------WS0--------WOR-------WS1
- * |----------------timeout----------------reset
+ * |--half_timeout--(panic)--half_timeout--reset
*
*/
@@ -84,6 +88,13 @@ MODULE_PARM_DESC(timeout,
"Watchdog timeout in seconds. (>=0, default="
__MODULE_STRING(DEFAULT_TIMEOUT) ")");
+#ifdef CONFIG_ARM_SBSA_WATCHDOG_PANIC
+static bool panic_enabled = true;
+module_param(panic_enabled, bool, 0);
+MODULE_PARM_DESC(panic_enabled,
+ "enable panic at half timeout. (default=true)");
+#endif
+
static bool nowayout = WATCHDOG_NOWAYOUT;
module_param(nowayout, bool, S_IRUGO);
MODULE_PARM_DESC(nowayout,
@@ -159,6 +170,16 @@ static int sbsa_gwdt_stop(struct watchdog_device *wdd)
return 0;
}
+#ifdef CONFIG_ARM_SBSA_WATCHDOG_PANIC
+static irqreturn_t sbsa_gwdt_interrupt(int irq, void *dev_id)
+{
+ if (panic_enabled)
+ panic("SBSA Watchdog half timeout");
+
+ return IRQ_HANDLED;
+}
+#endif
+
static struct watchdog_info sbsa_gwdt_info = {
.identity = "SBSA Generic Watchdog",
.options = WDIOF_SETTIMEOUT |
@@ -186,6 +207,9 @@ static int sbsa_gwdt_probe(struct platform_device *pdev)
struct resource *res;
u32 status;
int ret;
+#ifdef CONFIG_ARM_SBSA_WATCHDOG_PANIC
+ int irq;
+#endif
gwdt = devm_kzalloc(dev, sizeof(*gwdt), GFP_KERNEL);
if (!gwdt)
@@ -202,6 +226,14 @@ static int sbsa_gwdt_probe(struct platform_device *pdev)
if (IS_ERR(rf_base))
return PTR_ERR(rf_base);
+#ifdef CONFIG_ARM_SBSA_WATCHDOG_PANIC
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ dev_err(dev, "unable to get ws0 interrupt.\n");
+ return irq;
+ }
+#endif
+
/*
* Get the frequency of system counter from the cp15 interface of ARM
* Generic timer. We don't need to check it, because if it returns "0",
@@ -228,6 +260,14 @@ static int sbsa_gwdt_probe(struct platform_device *pdev)
dev_warn(dev, "System reset by WDT.\n");
wdd->bootstatus |= WDIOF_CARDRESET;
}
+#ifdef CONFIG_ARM_SBSA_WATCHDOG_PANIC
+ ret = devm_request_irq(dev, irq, sbsa_gwdt_interrupt, 0,
+ pdev->name, gwdt);
+ if (ret) {
+ dev_err(dev, "unable to request IRQ %d\n", irq);
+ return ret;
+ }
+#endif
ret = watchdog_register_device(wdd);
if (ret)
@@ -242,6 +282,10 @@ static int sbsa_gwdt_probe(struct platform_device *pdev)
dev_info(dev, "Initialized with %ds timeout @ %u Hz%s\n", wdd->timeout,
gwdt->clk, status & SBSA_GWDT_WCS_EN ? " [enabled]" : "");
+#ifdef CONFIG_ARM_SBSA_WATCHDOG_PANIC
+ dev_info(dev, "Half timeout panic %s.\n",
+ panic_enabled ? "enabled" : "disabled");
+#endif
return 0;
}
--
2.5.0
^ permalink raw reply related [flat|nested] 46+ messages in thread
* Re: [PATCH v10 5/5] Watchdog: ARM SBSA Generic Watchdog half timeout panic support
2016-02-03 17:18 ` [PATCH v10 5/5] Watchdog: ARM SBSA Generic Watchdog half timeout panic support fu.wei
@ 2016-02-03 17:27 ` Timur Tabi
2016-02-03 17:49 ` Fu Wei
2016-02-04 16:32 ` Mathieu Poirier
1 sibling, 1 reply; 46+ messages in thread
From: Timur Tabi @ 2016-02-03 17:27 UTC (permalink / raw)
To: fu.wei, robh+dt, pawel.moll, mark.rutland, ijc+devicetree, galak,
wim, linux, corbet, catalin.marinas, will.deacon,
Suravee.Suthikulpanit
Cc: linux-kernel, linux-watchdog, linux-doc, devicetree,
linux-arm-kernel, linaro-acpi, rruigrok, harba, cov, dyoung,
panand, graeme.gregory, al.stone, hanjun.guo, jcm, arnd,
leo.duran, sudeep.holla
fu.wei@linaro.org wrote:
> +#ifdef CONFIG_ARM_SBSA_WATCHDOG_PANIC
> +static bool panic_enabled = true;
I think this should default to 'false', because IMHO, this seems like an
odd feature. I'm not crazy about the fact that there's a Kconfig option
for it either, but I'm not going to NACK this patch.
I personally would prefer to drop this patch, and just wait for
full-blown pre-timeout support. It feels like a debugging feature that
doesn't really belong upstream. But like I said, it's just my opinion,
and I won't complain if I'm outvoted.
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [PATCH v10 5/5] Watchdog: ARM SBSA Generic Watchdog half timeout panic support
2016-02-03 17:27 ` Timur Tabi
@ 2016-02-03 17:49 ` Fu Wei
[not found] ` <CADyBb7sxPg-QUjTbeHFtYkctKc_g7D8O=+jqbXN+DCCoCEnFqA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
0 siblings, 1 reply; 46+ messages in thread
From: Fu Wei @ 2016-02-03 17:49 UTC (permalink / raw)
To: Timur Tabi
Cc: Rob Herring, Paweł Moll, Mark Rutland, Ian Campbell,
Kumar Gala, Wim Van Sebroeck, Guenter Roeck, Jon Corbet,
Catalin Marinas, Will Deacon, Suravee Suthikulpanit, LKML,
linux-watchdog, linux-doc, devicetree, linux-arm-kernel,
Linaro ACPI Mailman List, rruigrok, Abdulhamid, Harb,
Christopher Covington, Dave Young, Pratyush Anand, G Gregory
Hi Timur,
Thanks for your rapid feedback :-)
On 4 February 2016 at 01:27, Timur Tabi <timur@codeaurora.org> wrote:
> fu.wei@linaro.org wrote:
>>
>> +#ifdef CONFIG_ARM_SBSA_WATCHDOG_PANIC
>> +static bool panic_enabled = true;
>
>
> I think this should default to 'false', because IMHO, this seems like an odd
yes, It make sense to make it default to 'false'.
> feature. I'm not crazy about the fact that there's a Kconfig option for it
> either, but I'm not going to NACK this patch.
>
> I personally would prefer to drop this patch, and just wait for full-blown
> pre-timeout support. It feels like a debugging feature that doesn't really
sorry, are you saying : using pre-timeout instead of this half timeout?
But even we have pre-timeout support, pre-timeout == timeout / 2, it
can not be configured without touch timeout.
if you want pre-timeout != timeout / 2, we have to modify WCV in the
interrupt routine.
(because of the explicit watchdog refresh mechanism)
Could you let me know why we need pre-timeout here ?? :-)
> belong upstream. But like I said, it's just my opinion, and I won't
> complain if I'm outvoted.
I think this debugging feature is the purpose of the two-stage
watchdog, if I understand correctly
--
Best regards,
Fu Wei
Software Engineer
Red Hat Software (Beijing) Co.,Ltd.Shanghai Branch
Ph: +86 21 61221326(direct)
Ph: +86 186 2020 4684 (mobile)
Room 1512, Regus One Corporate Avenue,Level 15,
One Corporate Avenue,222 Hubin Road,Huangpu District,
Shanghai,China 200021
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [PATCH v10 5/5] Watchdog: ARM SBSA Generic Watchdog half timeout panic support
2016-02-03 17:18 ` [PATCH v10 5/5] Watchdog: ARM SBSA Generic Watchdog half timeout panic support fu.wei
2016-02-03 17:27 ` Timur Tabi
@ 2016-02-04 16:32 ` Mathieu Poirier
2016-02-04 16:41 ` Guenter Roeck
2016-02-04 16:43 ` Timur Tabi
1 sibling, 2 replies; 46+ messages in thread
From: Mathieu Poirier @ 2016-02-04 16:32 UTC (permalink / raw)
To: fu.wei
Cc: Rob Herring, Paweł Moll, Mark Rutland, Ian Campbell,
Kumar Gala, wim, linux, Jon Corbet, Catalin Marinas, Will Deacon,
Suravee.Suthikulpanit, linux-kernel@vger.kernel.org,
linux-watchdog, linux-doc, devicetree@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, linaro-acpi, rruigrok,
harba, Christopher Covington, timur, dyoung, panand,
graeme.gregory, al.stone, hanjun.guo
On 3 February 2016 at 10:18, <fu.wei@linaro.org> wrote:
> From: Fu Wei <fu.wei@linaro.org>
>
> This patch registers the WS0 interrupt routine to trigger panic,
> when the watchdog reachs the first stage (the half timeout).
> This function can help administrator to backup the system context
> info by panic console output or kdump (if supported), once system
> goes wrong (doesn't feed the watchdog in the half timeout).
>
> User also can skip panic by setting panic_enabled (module parameter) as 0
>
> Signed-off-by: Fu Wei <fu.wei@linaro.org>
> ---
> Documentation/watchdog/watchdog-parameters.txt | 1 +
> drivers/watchdog/Kconfig | 10 +++++
> drivers/watchdog/sbsa_gwdt.c | 54 +++++++++++++++++++++++---
> 3 files changed, 60 insertions(+), 5 deletions(-)
>
> diff --git a/Documentation/watchdog/watchdog-parameters.txt b/Documentation/watchdog/watchdog-parameters.txt
> index 300eb4d..31641e2 100644
> --- a/Documentation/watchdog/watchdog-parameters.txt
> +++ b/Documentation/watchdog/watchdog-parameters.txt
> @@ -286,6 +286,7 @@ nowayout: Watchdog cannot be stopped once started
> -------------------------------------------------
> sbsa_gwdt:
> timeout: Watchdog timeout in seconds. (default 20s)
> +panic_enabled: Enable panic at half timeout. (default=true)
> nowayout: Watchdog cannot be stopped once started
> (default=kernel config parameter)
> -------------------------------------------------
> diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
> index 4ab1b05..42adfdf 100644
> --- a/drivers/watchdog/Kconfig
> +++ b/drivers/watchdog/Kconfig
> @@ -218,6 +218,16 @@ config ARM_SBSA_WATCHDOG
> To compile this driver as module, choose M here: The module
> will be called sbsa_gwdt.
>
> +config ARM_SBSA_WATCHDOG_PANIC
> + bool "ARM SBSA Generic Watchdog triggers panic at the half timeout"
> + depends on ARM_SBSA_WATCHDOG
> + help
> + ARM SBSA Generic Watchdog will trigger panic in the first signal
> + (WS0) interrupt routine when the half timeout is reached.
> + This function can help administrator to backup the system context
> + info by panic console output or kdump (if supported).
> + But user can skip panic by setting moduleparam panic_enabled as 0.
> +
> config ASM9260_WATCHDOG
> tristate "Alphascale ASM9260 watchdog"
> depends on MACH_ASM9260
> diff --git a/drivers/watchdog/sbsa_gwdt.c b/drivers/watchdog/sbsa_gwdt.c
> index 5a2dba3..d18cf37 100644
> --- a/drivers/watchdog/sbsa_gwdt.c
> +++ b/drivers/watchdog/sbsa_gwdt.c
> @@ -16,18 +16,22 @@
> * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> * GNU General Public License for more details.
> *
> - * This SBSA Generic watchdog driver is a single stage timeout version.
> + * This SBSA Generic watchdog driver is a two stages version.
> * Since this watchdog timer has two stages, and each stage is determined
> * by WOR. So the timeout is (WOR * 2).
> - * When first timeout is reached, WS0 is triggered, the interrupt
> - * triggered by WS0 will be ignored, then the second watch period starts;
> - * when second timeout is reached, then WS1 is triggered, system reset.
> + * When the first stage(the half timeout) is reached, WS0 interrupt is
> + * triggered, at this moment the second watch period starts;
> + * In the WS0 interrupt routine, panic will be triggered for saving the
> + * system context.
> + * If the system is getting into trouble and cannot be reset by panic or
> + * restart properly by the kdump kernel(if supported), then the second
> + * stage (the timeout) will be reached, system will be reset by WS1.
> *
> * More details about the hardware specification of this device:
> * ARM DEN0029B - Server Base System Architecture (SBSA)
> *
> * SBSA GWDT: |--------WOR-------WS0--------WOR-------WS1
> - * |----------------timeout----------------reset
> + * |--half_timeout--(panic)--half_timeout--reset
> *
> */
>
> @@ -84,6 +88,13 @@ MODULE_PARM_DESC(timeout,
> "Watchdog timeout in seconds. (>=0, default="
> __MODULE_STRING(DEFAULT_TIMEOUT) ")");
>
> +#ifdef CONFIG_ARM_SBSA_WATCHDOG_PANIC
> +static bool panic_enabled = true;
> +module_param(panic_enabled, bool, 0);
> +MODULE_PARM_DESC(panic_enabled,
> + "enable panic at half timeout. (default=true)");
> +#endif
> +
> static bool nowayout = WATCHDOG_NOWAYOUT;
> module_param(nowayout, bool, S_IRUGO);
> MODULE_PARM_DESC(nowayout,
> @@ -159,6 +170,16 @@ static int sbsa_gwdt_stop(struct watchdog_device *wdd)
> return 0;
> }
>
> +#ifdef CONFIG_ARM_SBSA_WATCHDOG_PANIC
> +static irqreturn_t sbsa_gwdt_interrupt(int irq, void *dev_id)
> +{
> + if (panic_enabled)
> + panic("SBSA Watchdog half timeout");
> +
> + return IRQ_HANDLED;
> +}
> +#endif
> +
> static struct watchdog_info sbsa_gwdt_info = {
> .identity = "SBSA Generic Watchdog",
> .options = WDIOF_SETTIMEOUT |
> @@ -186,6 +207,9 @@ static int sbsa_gwdt_probe(struct platform_device *pdev)
> struct resource *res;
> u32 status;
> int ret;
> +#ifdef CONFIG_ARM_SBSA_WATCHDOG_PANIC
> + int irq;
> +#endif
>
> gwdt = devm_kzalloc(dev, sizeof(*gwdt), GFP_KERNEL);
> if (!gwdt)
> @@ -202,6 +226,14 @@ static int sbsa_gwdt_probe(struct platform_device *pdev)
> if (IS_ERR(rf_base))
> return PTR_ERR(rf_base);
>
> +#ifdef CONFIG_ARM_SBSA_WATCHDOG_PANIC
> + irq = platform_get_irq(pdev, 0);
> + if (irq < 0) {
> + dev_err(dev, "unable to get ws0 interrupt.\n");
> + return irq;
> + }
> +#endif
> +
Can't the driver revert to single stage mode if platform_get_irq()
fails? That way the value of 'irq' can be tested throughout the
_probe() function and the #ifdefs removed.
Thanks,
Mathieu
> /*
> * Get the frequency of system counter from the cp15 interface of ARM
> * Generic timer. We don't need to check it, because if it returns "0",
> @@ -228,6 +260,14 @@ static int sbsa_gwdt_probe(struct platform_device *pdev)
> dev_warn(dev, "System reset by WDT.\n");
> wdd->bootstatus |= WDIOF_CARDRESET;
> }
> +#ifdef CONFIG_ARM_SBSA_WATCHDOG_PANIC
> + ret = devm_request_irq(dev, irq, sbsa_gwdt_interrupt, 0,
> + pdev->name, gwdt);
> + if (ret) {
> + dev_err(dev, "unable to request IRQ %d\n", irq);
> + return ret;
> + }
> +#endif
>
> ret = watchdog_register_device(wdd);
> if (ret)
> @@ -242,6 +282,10 @@ static int sbsa_gwdt_probe(struct platform_device *pdev)
>
> dev_info(dev, "Initialized with %ds timeout @ %u Hz%s\n", wdd->timeout,
> gwdt->clk, status & SBSA_GWDT_WCS_EN ? " [enabled]" : "");
> +#ifdef CONFIG_ARM_SBSA_WATCHDOG_PANIC
> + dev_info(dev, "Half timeout panic %s.\n",
> + panic_enabled ? "enabled" : "disabled");
> +#endif
>
> return 0;
> }
> --
> 2.5.0
>
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [PATCH v10 5/5] Watchdog: ARM SBSA Generic Watchdog half timeout panic support
2016-02-04 16:32 ` Mathieu Poirier
@ 2016-02-04 16:41 ` Guenter Roeck
2016-02-04 16:43 ` Timur Tabi
1 sibling, 0 replies; 46+ messages in thread
From: Guenter Roeck @ 2016-02-04 16:41 UTC (permalink / raw)
To: Mathieu Poirier, fu.wei
Cc: Rob Herring, Paweł Moll, Mark Rutland, Ian Campbell,
Kumar Gala, wim, Jon Corbet, Catalin Marinas, Will Deacon,
Suravee.Suthikulpanit, linux-kernel@vger.kernel.org,
linux-watchdog, linux-doc, devicetree@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, linaro-acpi, rruigrok,
harba, Christopher Covington, timur, dyoung, panand,
graeme.gregory, al.stone, hanjun.guo, jcm
On 02/04/2016 08:32 AM, Mathieu Poirier wrote:
> On 3 February 2016 at 10:18, <fu.wei@linaro.org> wrote:
>> From: Fu Wei <fu.wei@linaro.org>
>>
>> This patch registers the WS0 interrupt routine to trigger panic,
>> when the watchdog reachs the first stage (the half timeout).
>> This function can help administrator to backup the system context
>> info by panic console output or kdump (if supported), once system
>> goes wrong (doesn't feed the watchdog in the half timeout).
>>
>> User also can skip panic by setting panic_enabled (module parameter) as 0
>>
>> Signed-off-by: Fu Wei <fu.wei@linaro.org>
>> ---
>> Documentation/watchdog/watchdog-parameters.txt | 1 +
>> drivers/watchdog/Kconfig | 10 +++++
>> drivers/watchdog/sbsa_gwdt.c | 54 +++++++++++++++++++++++---
>> 3 files changed, 60 insertions(+), 5 deletions(-)
>>
>> diff --git a/Documentation/watchdog/watchdog-parameters.txt b/Documentation/watchdog/watchdog-parameters.txt
>> index 300eb4d..31641e2 100644
>> --- a/Documentation/watchdog/watchdog-parameters.txt
>> +++ b/Documentation/watchdog/watchdog-parameters.txt
>> @@ -286,6 +286,7 @@ nowayout: Watchdog cannot be stopped once started
>> -------------------------------------------------
>> sbsa_gwdt:
>> timeout: Watchdog timeout in seconds. (default 20s)
>> +panic_enabled: Enable panic at half timeout. (default=true)
>> nowayout: Watchdog cannot be stopped once started
>> (default=kernel config parameter)
>> -------------------------------------------------
>> diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
>> index 4ab1b05..42adfdf 100644
>> --- a/drivers/watchdog/Kconfig
>> +++ b/drivers/watchdog/Kconfig
>> @@ -218,6 +218,16 @@ config ARM_SBSA_WATCHDOG
>> To compile this driver as module, choose M here: The module
>> will be called sbsa_gwdt.
>>
>> +config ARM_SBSA_WATCHDOG_PANIC
>> + bool "ARM SBSA Generic Watchdog triggers panic at the half timeout"
>> + depends on ARM_SBSA_WATCHDOG
>> + help
>> + ARM SBSA Generic Watchdog will trigger panic in the first signal
>> + (WS0) interrupt routine when the half timeout is reached.
>> + This function can help administrator to backup the system context
>> + info by panic console output or kdump (if supported).
>> + But user can skip panic by setting moduleparam panic_enabled as 0.
>> +
>> config ASM9260_WATCHDOG
>> tristate "Alphascale ASM9260 watchdog"
>> depends on MACH_ASM9260
>> diff --git a/drivers/watchdog/sbsa_gwdt.c b/drivers/watchdog/sbsa_gwdt.c
>> index 5a2dba3..d18cf37 100644
>> --- a/drivers/watchdog/sbsa_gwdt.c
>> +++ b/drivers/watchdog/sbsa_gwdt.c
>> @@ -16,18 +16,22 @@
>> * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>> * GNU General Public License for more details.
>> *
>> - * This SBSA Generic watchdog driver is a single stage timeout version.
>> + * This SBSA Generic watchdog driver is a two stages version.
>> * Since this watchdog timer has two stages, and each stage is determined
>> * by WOR. So the timeout is (WOR * 2).
>> - * When first timeout is reached, WS0 is triggered, the interrupt
>> - * triggered by WS0 will be ignored, then the second watch period starts;
>> - * when second timeout is reached, then WS1 is triggered, system reset.
>> + * When the first stage(the half timeout) is reached, WS0 interrupt is
>> + * triggered, at this moment the second watch period starts;
>> + * In the WS0 interrupt routine, panic will be triggered for saving the
>> + * system context.
>> + * If the system is getting into trouble and cannot be reset by panic or
>> + * restart properly by the kdump kernel(if supported), then the second
>> + * stage (the timeout) will be reached, system will be reset by WS1.
>> *
>> * More details about the hardware specification of this device:
>> * ARM DEN0029B - Server Base System Architecture (SBSA)
>> *
>> * SBSA GWDT: |--------WOR-------WS0--------WOR-------WS1
>> - * |----------------timeout----------------reset
>> + * |--half_timeout--(panic)--half_timeout--reset
>> *
>> */
>>
>> @@ -84,6 +88,13 @@ MODULE_PARM_DESC(timeout,
>> "Watchdog timeout in seconds. (>=0, default="
>> __MODULE_STRING(DEFAULT_TIMEOUT) ")");
>>
>> +#ifdef CONFIG_ARM_SBSA_WATCHDOG_PANIC
>> +static bool panic_enabled = true;
>> +module_param(panic_enabled, bool, 0);
>> +MODULE_PARM_DESC(panic_enabled,
>> + "enable panic at half timeout. (default=true)");
>> +#endif
>> +
>> static bool nowayout = WATCHDOG_NOWAYOUT;
>> module_param(nowayout, bool, S_IRUGO);
>> MODULE_PARM_DESC(nowayout,
>> @@ -159,6 +170,16 @@ static int sbsa_gwdt_stop(struct watchdog_device *wdd)
>> return 0;
>> }
>>
>> +#ifdef CONFIG_ARM_SBSA_WATCHDOG_PANIC
>> +static irqreturn_t sbsa_gwdt_interrupt(int irq, void *dev_id)
>> +{
>> + if (panic_enabled)
>> + panic("SBSA Watchdog half timeout");
>> +
>> + return IRQ_HANDLED;
>> +}
>> +#endif
>> +
>> static struct watchdog_info sbsa_gwdt_info = {
>> .identity = "SBSA Generic Watchdog",
>> .options = WDIOF_SETTIMEOUT |
>> @@ -186,6 +207,9 @@ static int sbsa_gwdt_probe(struct platform_device *pdev)
>> struct resource *res;
>> u32 status;
>> int ret;
>> +#ifdef CONFIG_ARM_SBSA_WATCHDOG_PANIC
>> + int irq;
>> +#endif
>>
>> gwdt = devm_kzalloc(dev, sizeof(*gwdt), GFP_KERNEL);
>> if (!gwdt)
>> @@ -202,6 +226,14 @@ static int sbsa_gwdt_probe(struct platform_device *pdev)
>> if (IS_ERR(rf_base))
>> return PTR_ERR(rf_base);
>>
>> +#ifdef CONFIG_ARM_SBSA_WATCHDOG_PANIC
>> + irq = platform_get_irq(pdev, 0);
>> + if (irq < 0) {
>> + dev_err(dev, "unable to get ws0 interrupt.\n");
>> + return irq;
>> + }
>> +#endif
>> +
>
> Can't the driver revert to single stage mode if platform_get_irq()
> fails? That way the value of 'irq' can be tested throughout the
> _probe() function and the #ifdefs removed.
>
Good point. Making irq support mandatory on all systems isn't really
a good idea.
Thanks,
Guenter
> Thanks,
> Mathieu
>
>> /*
>> * Get the frequency of system counter from the cp15 interface of ARM
>> * Generic timer. We don't need to check it, because if it returns "0",
>> @@ -228,6 +260,14 @@ static int sbsa_gwdt_probe(struct platform_device *pdev)
>> dev_warn(dev, "System reset by WDT.\n");
>> wdd->bootstatus |= WDIOF_CARDRESET;
>> }
>> +#ifdef CONFIG_ARM_SBSA_WATCHDOG_PANIC
>> + ret = devm_request_irq(dev, irq, sbsa_gwdt_interrupt, 0,
>> + pdev->name, gwdt);
>> + if (ret) {
>> + dev_err(dev, "unable to request IRQ %d\n", irq);
>> + return ret;
>> + }
>> +#endif
>>
>> ret = watchdog_register_device(wdd);
>> if (ret)
>> @@ -242,6 +282,10 @@ static int sbsa_gwdt_probe(struct platform_device *pdev)
>>
>> dev_info(dev, "Initialized with %ds timeout @ %u Hz%s\n", wdd->timeout,
>> gwdt->clk, status & SBSA_GWDT_WCS_EN ? " [enabled]" : "");
>> +#ifdef CONFIG_ARM_SBSA_WATCHDOG_PANIC
>> + dev_info(dev, "Half timeout panic %s.\n",
>> + panic_enabled ? "enabled" : "disabled");
>> +#endif
>>
>> return 0;
>> }
>> --
>> 2.5.0
>>
>
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [PATCH v10 5/5] Watchdog: ARM SBSA Generic Watchdog half timeout panic support
2016-02-04 16:32 ` Mathieu Poirier
2016-02-04 16:41 ` Guenter Roeck
@ 2016-02-04 16:43 ` Timur Tabi
2016-02-05 9:20 ` Fu Wei
1 sibling, 1 reply; 46+ messages in thread
From: Timur Tabi @ 2016-02-04 16:43 UTC (permalink / raw)
To: Mathieu Poirier, fu.wei
Cc: Rob Herring, Paweł Moll, Mark Rutland, Ian Campbell,
Kumar Gala, wim, linux, Jon Corbet, Catalin Marinas, Will Deacon,
Suravee.Suthikulpanit, linux-kernel@vger.kernel.org,
linux-watchdog, linux-doc, devicetree@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, linaro-acpi, rruigrok,
harba, Christopher Covington, dyoung, panand, graeme.gregory,
al.stone, hanjun.guo, jcm
Mathieu Poirier wrote:
>> >+#ifdef CONFIG_ARM_SBSA_WATCHDOG_PANIC
>> >+ irq = platform_get_irq(pdev, 0);
>> >+ if (irq < 0) {
>> >+ dev_err(dev, "unable to get ws0 interrupt.\n");
>> >+ return irq;
>> >+ }
>> >+#endif
>> >+
> Can't the driver revert to single stage mode if platform_get_irq()
> fails? That way the value of 'irq' can be tested throughout the
> _probe() function and the #ifdefs removed.
I like that idea. The same can be done with the devm_request_irq()
call. It should definitely still display a warning if the command-line
option is set but no interrupt is available.
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [PATCH v10 5/5] Watchdog: ARM SBSA Generic Watchdog half timeout panic support
2016-02-04 16:43 ` Timur Tabi
@ 2016-02-05 9:20 ` Fu Wei
0 siblings, 0 replies; 46+ messages in thread
From: Fu Wei @ 2016-02-05 9:20 UTC (permalink / raw)
To: Timur Tabi
Cc: Mathieu Poirier, Rob Herring, Paweł Moll, Mark Rutland,
Ian Campbell, Kumar Gala, Wim Van Sebroeck, Guenter Roeck,
Jon Corbet, Catalin Marinas, Will Deacon, Suravee Suthikulpanit,
linux-kernel@vger.kernel.org, linux-watchdog, linux-doc,
devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
Linaro ACPI Mailman List, rruigrok, Abdulhamid, Harb
On 5 February 2016 at 00:43, Timur Tabi <timur@codeaurora.org> wrote:
> Mathieu Poirier wrote:
>>>
>>> >+#ifdef CONFIG_ARM_SBSA_WATCHDOG_PANIC
>>> >+ irq = platform_get_irq(pdev, 0);
>>> >+ if (irq < 0) {
>>> >+ dev_err(dev, "unable to get ws0 interrupt.\n");
>>> >+ return irq;
>>> >+ }
>>> >+#endif
>>> >+
>>
>> Can't the driver revert to single stage mode if platform_get_irq()
>> fails? That way the value of 'irq' can be tested throughout the
>> _probe() function and the #ifdefs removed.
>
>
> I like that idea. The same can be done with the devm_request_irq() call.
> It should definitely still display a warning if the command-line option is
> set but no interrupt is available.
Yes, I agree with that too, brilliant idea, this will be in v11 patchset
--
Best regards,
Fu Wei
Software Engineer
Red Hat Software (Beijing) Co.,Ltd.Shanghai Branch
Ph: +86 21 61221326(direct)
Ph: +86 186 2020 4684 (mobile)
Room 1512, Regus One Corporate Avenue,Level 15,
One Corporate Avenue,222 Hubin Road,Huangpu District,
Shanghai,China 200021
^ permalink raw reply [flat|nested] 46+ messages in thread