Watchdog: introdouce ARM SBSA watchdog driver
Subsystems (12)
A message that is not in the archive (sent off-list or not yet received): [email protected]
cover Watchdog: introdouce ARM SBSA watchdog driver
From: Fu Wei <[email protected]>
This patchset:
(1)Introdouces Documentation/devicetree/bindings/watchdog/sbsa-gwdt.txt for FDT info of SBSA Generic Watchdog, and give two examples of adding SBSA Generic Watchdog device node into the dts files:
foundation-v8.dts and amd-seattle-soc.dtsi
(2)Introdouce "pretimeout" into the watchdog framework
(3)Introdouces ARM SBSA watchdog driver
a.Use linux kernel watchdog framework
b.Work with FDT on ARM64
c.Use "pretimeout" in watchdog framework
d.In first timeout(WS0), do panic to save system context e.Support geting timeout and pretimeout from
parameter and FDT at the driver init stage
(4)Parse SBSA Generic Watchdog Structure in GTDT table of ACPI,
and create a platform device with that information This platform device can be used by This Watchdog driver
This patchset has been tested with watchdog daemon (ACPI/FDT, module/build-in) on the following platforms:
(1)ARM Foundation v8 model
(2)AMD Seattle B0
Fu Wei (6):
Documentation: add sbsa-gwdt.txt documentation
ARM64: add SBSA Generic Watchdog device node in foundation-v8.dts
ARM64: add SBSA Generic Watchdog device node in amd-seattle-soc.dtsi
Watchdog: introdouce "pretimeout" into framework
Watchdog: introdouce ARM SBSA watchdog driver
ACPI: import watchdog info of GTDT into platform device
.../devicetree/bindings/watchdog/sbsa-gwdt.txt | 36 ++ arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi | 11 + arch/arm64/boot/dts/arm/foundation-v8.dts | 10 + arch/arm64/kernel/acpi.c | 136 +++++ drivers/watchdog/Kconfig | 10 + drivers/watchdog/Makefile | 1 + drivers/watchdog/sbsa_gwdt.c | 553 +++++++++++++++++++++ drivers/watchdog/watchdog_core.c | 66 +++ drivers/watchdog/watchdog_dev.c | 48 ++ include/linux/watchdog.h | 19 + 10 files changed, 890 insertions(+) create mode 100644 Documentation/devicetree/bindings/watchdog/sbsa-gwdt.txt create mode 100644 drivers/watchdog/sbsa_gwdt.c
Signature · 1 line
1.9.1
PATCH 1/6 Documentation: add sbsa-gwdt.txt documentation
From: Fu Wei <[email protected]>
The sbsa-gwdt.txt documentation in devicetree/bindings/watchdog is for introducing SBSA(Server Base System Architecture) Generic Watchdog device node info into FDT
--- .../devicetree/bindings/watchdog/sbsa-gwdt.txt | 36 ++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 Documentation/devicetree/bindings/watchdog/sbsa-gwdt.txt
Documentation/devicetree/bindings/watchdog/sbsa-gwdt.txt new file +36 -0
@@ -0,0 +1,36 @@ +* SBSA(Server Base System Architecture) Generic Watchdog + +The SBSA Generic Watchdog Timer is used for resetting the system after +two stages of timeout. +More details: ARM-DEN-0029 - Server Base System Architecture (SBSA) + +Required properties: +- compatible : Should at least contain "arm,sbsa-gwdt". + +- reg : base physical address of the frames and length of memory mapped region. + +- reg-names : Should contain the resource reg names to show the order of + the values in "reg". + Must include the following entries : "refresh", "control". + +- interrupts : Should at least contain WS0 interrupt, + the WS1 Signal is optional. + +- interrupt-names : Should contain the resource interrupt names. + Must include the following entries : "ws0". "ws1" is optional. + +Optional properties +- timeout-sec : Watchdog pre-timeout and timeout values (in seconds). + The first is timeout values, then pre-timeout. + +Example for FVP Foundation Model v8: + +watchdog@2a450000 { + compatible = "arm,sbsa-gwdt"; + reg = <0x0 0x2a450000 0 0x10000>, + <0x0 0x2a440000 0 0x10000>; + reg-names = "refresh", "control"; + interrupts = <0 27 4>; + interrupt-names = "ws0"; + timeout-sec = <10 5>; +};
Signature · 1 line
1.9.1
Re: [PATCH 1/6] Documentation: add sbsa-gwdt.txt documentation
Quoted 7 lines · On Friday 15 May 2015 19:08:05 [email protected]…
From: Fu Wei <[email protected]>
The sbsa-gwdt.txt documentation in devicetree/bindings/watchdog is for introducing SBSA(Server Base System Architecture) Generic Watchdog device node info into FDT
Signed-off-by Fu Wei <[email protected]>
Looks good, just one minor comment:
Documentation/devicetree/bindings/watchdog/sbsa-gwdt.txt line 24
Quoted 3 lines
Documentation/devicetree/bindings/watchdog/sbsa-gwdt.txt new file +3
-0+Optional properties +- timeout-sec : Watchdog pre-timeout and timeout values (in seconds). + The first is timeout values, then pre-timeout.
Please update Documentation/watchdog/watchdog-kernel-api.txt as well, to mention the second number in the timeout-sec property.
Arnd
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/6] Documentation: add sbsa-gwdt.txt documentation
Hi Arnd,
Great thanks, np, will do so
Quoted 24 lines · Arnd Bergmann
Quoted 7 lines · On Friday 15 May 2015 19:08:05 [email protected]…
From: Fu Wei <[email protected]>
The sbsa-gwdt.txt documentation in devicetree/bindings/watchdog is for introducing SBSA(Server Base System Architecture) Generic Watchdog device node info into FDT
Signed-off-by Fu Wei <[email protected]>Looks good, just one minor comment:
Documentation/devicetree/bindings/watchdog/sbsa-gwdt.txt line 24
Quoted 3 lines
Documentation/devicetree/bindings/watchdog/sbsa-gwdt.txt new file +3
-0+Optional properties +- timeout-sec : Watchdog pre-timeout and timeout values (in seconds). + The first is timeout values, then pre-timeout.Please update
Documentation/watchdog/watchdog-kernel-api.txtas well, to mention the second number in the timeout-sec property.Arnd
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Signature · 14 lines
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 -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/6] Documentation: add sbsa-gwdt.txt documentation
In reply to Arnd BergmannHi Arnd,
Great thanks for reminding, I should do it earlier. You will see it in next patchset.
Quoted 25 lines · Arnd Bergmann
Quoted 7 lines · On Friday 15 May 2015 19:08:05 [email protected]…
From: Fu Wei <[email protected]>
The sbsa-gwdt.txt documentation in devicetree/bindings/watchdog is for introducing SBSA(Server Base System Architecture) Generic Watchdog device node info into FDT
Signed-off-by Fu Wei <[email protected]>Looks good, just one minor comment:
Documentation/devicetree/bindings/watchdog/sbsa-gwdt.txt line 24
Quoted 3 lines
Documentation/devicetree/bindings/watchdog/sbsa-gwdt.txt new file +3
-0+Optional properties +- timeout-sec : Watchdog pre-timeout and timeout values (in seconds). + The first is timeout values, then pre-timeout.Please update
Documentation/watchdog/watchdog-kernel-api.txtas well, to mention the second number in the timeout-sec property.Arnd
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Signature · 16 lines
Best regards, Fu Wei Software Engineer From Red Hat LEG Team Linaro.org | Open source software for ARM SoCs Ph: +86 186 2020 4684 (mobile) IRC: fuwei Skype: tekkamanninja Room 1512, Regus One Corporate Avenue,Level 15, One Corporate Avenue,222 Hubin Road,Huangpu District, Shanghai,China 200021 -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 2/6 ARM64: add SBSA Generic Watchdog device node in foundation-v8.dts
In reply to [email protected]From: Fu Wei <[email protected]>
This can be a example of adding SBSA Generic Watchdog device node into some dts files for the Soc which contains SBSA Generic Watchdog
--- arch/arm64/boot/dts/arm/foundation-v8.dts | 10 ++++++++++ 1 file changed, 10 insertions(+)
arch/arm64/boot/dts/arm/foundation-v8.dts +10 -0
@@ -237,4 +237,14 @@ }; }; }; + watchdog0: watchdog@2a450000 { + compatible = "arm,sbsa-gwdt"; + reg = <0x0 0x2a450000 0 0x10000>, + <0x0 0x2a440000 0 0x10000>; + reg-names = "refresh", + "control"; + interrupts = <0 27 4>; + interrupt-names = "ws0"; + timeout-sec = <10 5>; + }; };
Signature · 1 line
1.9.1
PATCH 3/6 ARM64: add SBSA Generic Watchdog device node in amd-seattle-soc.dtsi
In reply to [email protected]From: Fu Wei <[email protected]>
This can be a example of adding SBSA Generic Watchdog device node into some dts files for the Soc which contains SBSA Generic Watchdog
--- arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi | 11 +++++++++++ 1 file changed, 11 insertions(+)
arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi +11 -0
@@ -84,6 +84,17 @@ clock-names = "uartclk", "apb_pclk"; }; + watchdog0: watchdog@e0bb0000 { + compatible = "arm,sbsa-gwdt"; + reg = <0x0 0xe0bb0000 0 0x10000>, + <0x0 0xe0bc0000 0 0x10000>; + reg-names = "refresh", + "control"; + interrupts = <0 337 4>; + interrupt-names = "ws0"; + timeout-sec = <10 5>; + }; + spi0: ssp@e1020000 { status = "disabled"; compatible = "arm,pl022", "arm,primecell";
Signature · 6 lines
1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Quoted 19 lines · On Friday 15 May 2015 19:08:04 [email protected]…
From: Fu Wei <[email protected]>
This patchset:
(1)Introdouces
Documentation/devicetree/bindings/watchdog/sbsa-gwdt.txtfor FDT info of SBSA Generic Watchdog, and give two examples of adding SBSA Generic Watchdog device node into the dts files:
foundation-v8.dtsandamd-seattle-soc.dtsi(2)Introdouce "pretimeout" into the watchdog framework
(3)Introdouces ARM SBSA watchdog driver
a.Use linux kernel watchdog framework
b.Work with FDT on ARM64
c.Use "pretimeout" in watchdog framework
d.In first timeout(WS0), do panic to save system context e.Support geting timeout and pretimeout from
parameter and FDT at the driver init stage
Quoted 10 lines
(4)Parse SBSA Generic Watchdog Structure in GTDT table of ACPI,
and create a platform device with that information This platform device can be used by This Watchdog driverThis patchset has been tested with watchdog daemon (ACPI/FDT, module/build-in) on the following platforms:
(1)ARM Foundation v8 model
(2)AMD Seattle B0
I've had a few very minor comments to the individual patches, otherwise looks good. I have not reviewed the ACPI part of the series, as I have no knowledge of that.
Arnd
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Hi Arnd,
OK, Thanks, Will reply those comments soon.
Quoted 37 lines · Arnd Bergmann
Quoted 19 lines · On Friday 15 May 2015 19:08:04 [email protected]…
From: Fu Wei <[email protected]>
This patchset:
(1)Introdouces
Documentation/devicetree/bindings/watchdog/sbsa-gwdt.txtfor FDT info of SBSA Generic Watchdog, and give two examples of adding SBSA Generic Watchdog device node into the dts files:
foundation-v8.dtsandamd-seattle-soc.dtsi(2)Introdouce "pretimeout" into the watchdog framework
(3)Introdouces ARM SBSA watchdog driver
a.Use linux kernel watchdog framework
b.Work with FDT on ARM64
c.Use "pretimeout" in watchdog framework
d.In first timeout(WS0), do panic to save system context e.Support geting timeout and pretimeout from
parameter and FDT at the driver init stageQuoted 10 lines
(4)Parse SBSA Generic Watchdog Structure in GTDT table of ACPI,
and create a platform device with that information This platform device can be used by This Watchdog driverThis patchset has been tested with watchdog daemon (ACPI/FDT, module/build-in) on the following platforms:
(1)ARM Foundation v8 model
(2)AMD Seattle B0I've had a few very minor comments to the individual patches, otherwise looks good. I have not reviewed the ACPI part of the series, as I have no knowledge of that.
Arnd
Signature · 16 lines
Best regards, Fu Wei Software Engineer From Red Hat LEG Team Linaro.org | Open source software for ARM SoCs Ph: +86 186 2020 4684 (mobile) IRC: fuwei Skype: tekkamanninja Room 1512, Regus One Corporate Avenue,Level 15, One Corporate Avenue,222 Hubin Road,Huangpu District, Shanghai,China 200021 -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 4/6 Watchdog: introdouce "pretimeout" into framework
In reply to a message not in the archiveFrom: Fu Wei <[email protected]>
Reasons:
(1)kernel already has two watchdog drivers are using "pretimeout":
drivers/char/ipmi/ipmi_watchdog.c drivers/watchdog/kempld_wdt.c(but the definition is different)
(2)some other dirvers are going to use this: ARM SBSA Generic Watchdog
--- drivers/watchdog/watchdog_core.c | 66 ++++++++++++++++++++++++++++++++++++++++ drivers/watchdog/watchdog_dev.c | 48 +++++++++++++++++++++++++++++ include/linux/watchdog.h | 19 ++++++++++++ 3 files changed, 133 insertions(+)
drivers/watchdog/watchdog_core.c +66 -0
@@ -54,6 +54,14 @@ static void watchdog_check_min_max_timeout(struct watchdog_device *wdd) wdd->min_timeout =0 ; wdd->max_timeout =0 ; } +if (wdd->min_pretimeout && wdd->min_timeout < wdd->min_pretimeout) { +pr_info ("Invalid min timeout, resetting to min pretimeout!\n" ); + wdd->min_timeout = wdd->min_pretimeout; + } +if (wdd->max_pretimeout && wdd->max_timeout < wdd->max_pretimeout) { +pr_info ("Invalid max timeout, resetting to max pretimeout!\n" ); + wdd->max_timeout = wdd->max_pretimeout; + } }/**
@@ -98,6 +106,63 @@ int watchdog_init_timeout(struct watchdog_device *wdd, }EXPORT_SYMBOL_GPL (watchdog_init_timeout); +static void watchdog_check_min_max_pretimeout (struct watchdog_device *wdd) +{ +/* +* Check that we have valid min and max pretimeout values, if +* not reset them both to 0 (=not used or unknown) +*/ +if (wdd->min_pretimeout > wdd->max_pretimeout) { +pr_info ("Invalid min and max pretimeout, resetting to 0!\n" ); + wdd->min_pretimeout =0 ; + wdd->max_pretimeout =0 ; + } +} + +/** +* watchdog_init_pretimeout() - initialize the pretimeout field +* @pretimeout_parm: pretimeout module parameter +* @dev: Device that stores the timeout-sec property +* +* Initialize the pretimeout field of the watchdog_device struct with either +* the pretimeout module parameter (if it is valid value) or the timeout-sec +* property (only if it is a valid value and the timeout_parm is out of bounds). +* If none of them are valid then we keep the old value (which should normally +* be the default pretimeout value. +* +* A zero is returned on success and -EINVAL for failure. +*/ +int watchdog_init_pretimeout (struct watchdog_device *wdd, +unsigned int pretimeout_parm,struct device *dev) +{ +int ret =0 ; +u32 timeouts[2 ]; + +watchdog_check_min_max_pretimeout (wdd); + +/* try to get the timeout module parameter first */ +if (!watchdog_pretimeout_invalid (wdd, pretimeout_parm) && + pretimeout_parm) { + wdd->pretimeout = pretimeout_parm; +return ret; + } +if (pretimeout_parm) + ret = -EINVAL ; + +/* try to get the timeout_sec property */ +if (!dev || !dev->of_node) +return ret; + ret =of_property_read_u32_array (dev->of_node, +"timeout-sec" , timeouts,2 ); +if (!watchdog_pretimeout_invalid (wdd, timeouts[1 ]) && timeouts[1 ]) + wdd->pretimeout = timeouts[1 ]; +else + ret = -EINVAL ; + +return ret; +} +EXPORT_SYMBOL_GPL (watchdog_init_pretimeout); +/** * watchdog_register_device() - register a watchdog device * @wdd: watchdog device
@@ -119,6 +184,7 @@ int watchdog_register_device(struct watchdog_device *wdd)if (wdd->ops->start ==NULL || wdd->ops->stop ==NULL )return -EINVAL ; +watchdog_check_min_max_pretimeout (wdd);watchdog_check_min_max_timeout (wdd);/*
drivers/watchdog/watchdog_dev.c +48 -0
60 lines not on this page · raw message
include/linux/watchdog.h +19 -0
@@ -25,6 +25,7 @@ struct watchdog_device;* @ping: The routine that sends a keepalive ping to the watchdog device. * @status: The routine that shows the status of the watchdog device. * @set_timeout:The routine for setting the watchdog devices timeout value. +* @set_pretimeout:The routine for setting the watchdog devices pretimeout value * @get_timeleft:The routine that get's the time that's left before a reset. * @ref: The ref operation for dyn. allocated watchdog_device structs * @unref: The unref operation for dyn. allocated watchdog_device structs
@@ -44,6 +45,7 @@ struct watchdog_ops {int (*ping)(struct watchdog_device *);unsigned int (*status)(struct watchdog_device *);int (*set_timeout)(struct watchdog_device *,unsigned int ); +int (*set_pretimeout)(struct watchdog_device *,unsigned int );unsigned int (*get_timeleft)(struct watchdog_device *);void (*ref)(struct watchdog_device *);void (*unref)(struct watchdog_device *);
@@ -62,6 +64,9 @@ struct watchdog_ops {* @timeout: The watchdog devices timeout value. * @min_timeout:The watchdog devices minimum timeout value. * @max_timeout:The watchdog devices maximum timeout value. +* @pretimeout: The watchdog devices pretimeout value. +* @min_pretimeout:The watchdog devices minimum pretimeout value. +* @max_pretimeout:The watchdog devices maximum pretimeout value. * @driver-data:Pointer to the drivers private data. * @lock: Lock for watchdog core internal use only. * @status: Field that contains the devices internal status bits.
@@ -86,6 +91,9 @@ struct watchdog_device {unsigned int timeout;unsigned int min_timeout;unsigned int max_timeout; +unsigned int pretimeout; +unsigned int min_pretimeout; +unsigned int max_pretimeout;void *driver_data;struct mutex lock;unsigned long status;
@@ -120,6 +128,14 @@ static inline bool watchdog_timeout_invalid(struct watchdog_device *wdd, unsigne (t < wdd->min_timeout || t > wdd->max_timeout)); } +/* Use the following function to check if a pretimeout value is invalid */ +static inline bool watchdog_pretimeout_invalid (struct watchdog_device *wdd, +unsigned int t) +{ +return ((wdd->max_pretimeout !=0 ) && + (t < wdd->min_pretimeout || t > wdd->max_pretimeout)); +} +/* Use the following functions to manipulate watchdog driver specific data */ static inline void watchdog_set_drvdata (struct watchdog_device *wdd,void *data) {
@@ -134,6 +150,9 @@ static inline void *watchdog_get_drvdata(struct watchdog_device *wdd)/* drivers/watchdog/watchdog_core.c */ extern int watchdog_init_timeout (struct watchdog_device *wdd,unsigned int timeout_parm,struct device *dev); +extern int watchdog_init_pretimeout (struct watchdog_device *wdd, +unsigned int pretimeout_parm, +struct device *dev);extern int watchdog_register_device (struct watchdog_device *);extern void watchdog_unregister_device (struct watchdog_device *);
Signature · 1 line
1.9.1
PATCH 5/6 Watchdog: introdouce ARM SBSA watchdog driver
From: Fu Wei <[email protected]>
(1)Use linux kernel watchdog framework
(2)Work with FDT on ARM64
(3)Use "pretimeout" in watchdog framework
(4)In first timeout(WS0), do panic to save system context (5)support geting timeout and pretimeout from
parameter and FDT at the driver init stage.
--- drivers/watchdog/Kconfig | 10 + drivers/watchdog/Makefile | 1 + drivers/watchdog/sbsa_gwdt.c | 553 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 564 insertions(+) create mode 100644 drivers/watchdog/sbsa_gwdt.c
drivers/watchdog/Kconfig +10 -0
@@ -152,6 +152,16 @@ 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 ARM || ARM64 || COMPILE_TEST + select WATCHDOG_CORE + help + ARM SBSA Generic Watchdog timer. This has two Watchdog Signal(WS0/WS1), + will trigger a warnning interrupt(do panic) in the first timeout(WS0); + will reboot your system when the second timeout(WS1) is reached. + More details: DEN0029B - Server Base System Architecture (SBSA) + config AT91RM9200_WATCHDOG tristate "AT91RM9200 watchdog" depends on SOC_AT91RM9200 && MFD_SYSCON
drivers/watchdog/Makefile +1 -0
@@ -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_AT91RM9200_WATCHDOG) += at91rm9200_wdt.o obj-$(CONFIG_AT91SAM9X_WATCHDOG) += at91sam9_wdt.o obj-$(CONFIG_CADENCE_WATCHDOG) += cadence_wdt.o
drivers/watchdog/sbsa_gwdt.c new file +553 -0
553 lines not on this page · raw message
Signature · 1 line
1.9.1
Quoted 10 lines · On Friday 15 May 2015 19:24:49 [email protected] wrote:
From: Fu Wei <[email protected]>
(1)Use linux kernel watchdog framework
(2)Work with FDT on ARM64
(3)Use "pretimeout" in watchdog framework
(4)In first timeout(WS0), do panic to save system context (5)support geting timeout and pretimeout from
parameter and FDT at the driver init stage.Signed-off-by Fu Wei <[email protected]>
The patch looks good overall. Please try to describe in the patch in full sentences in the changelog, as we normally do.
A few tiny details that I'd do differently, but don't have to change if the watchdog maintainer is fine with your version:
drivers/watchdog/sbsa_gwdt.c line 99
Quoted 10 lines
drivers/watchdog/sbsa_gwdt.c new file +10
-0+struct sbsa_gwdt { +struct watchdog_device wdd; +u32 clk; +void __iomem *refresh_base; +void __iomem *control_base; +#ifdef CONFIG_PM_SLEEP +spinlock_t lock; +u8 pm_status_store; +#endif +};
I would drop the #ifdef here, and favor readability over saving a few bytes.
drivers/watchdog/sbsa_gwdt.c line 364
Quoted 8 lines
drivers/watchdog/sbsa_gwdt.c new file +8
-0+/* +* Try to determine the frequency from the cp15 interface +*/ + clk =arch_timer_get_cntfrq (); +if (!clk) { +dev_err (dev,"System Counter frequency not available\n" ); +return -EINVAL ; + }
Is it guaranteed that the same clock feeds the arch timer and the watchdog? Maybe it would be better to use the clk API to read the frequency, so we can avoid this dependency.
drivers/watchdog/sbsa_gwdt.c line 386
Quoted 13 lines
drivers/watchdog/sbsa_gwdt.c new file +13
-0+ +pr_debug ("sbsa_gwdt: ioremap %s frame 0x%llx(size: %llu)-->%p.\n" , + res->name, (unsigned long long )res->start, + (unsigned long long )(res->end - res->start +1 ), rf_base); + + res =platform_get_resource_byname (pdev,IORESOURCE_MEM ,"control" ); + cf_base =devm_ioremap_resource (dev, res); +if (IS_ERR (rf_base)) +return PTR_ERR (rf_base); + +pr_debug ("sbsa_gwdt: ioremap %s frame 0x%llx(size: %llu)-->%p.\n" , + res->name, (unsigned long long )res->start, + (unsigned long long )(res->end - res->start +1 ), cf_base);
I would probably drop the various pr_debug() calls here. Once the driver works fine, they are normally not that useful any more.
Arnd
Hi Arnd,
Great thanks for your review,
The feedback is inline below:
Quoted 10 lines · Arnd Bergmann
Quoted 9 lines · On Friday 15 May 2015 19:24:49 [email protected]…
From: Fu Wei <[email protected]>
(1)Use linux kernel watchdog framework
(2)Work with FDT on ARM64
(3)Use "pretimeout" in watchdog framework
(4)In first timeout(WS0), do panic to save system context (5)support geting timeout and pretimeout from
parameter and FDT at the driver init stage.
Quoted 4 lines
Quoted 1 line
Signed-off-by Fu Wei <[email protected]>The patch looks good overall. Please try to describe in the patch in full sentences in the changelog, as we normally do.
Sure, you will see changelog in the next version.
Quoted 4 lines
A few tiny details that I'd do differently, but don't have to change if the watchdog maintainer is fine with your version:
Quoted 13 lines
drivers/watchdog/sbsa_gwdt.c line 99
Quoted 10 lines
drivers/watchdog/sbsa_gwdt.c new file +10
-0+struct sbsa_gwdt { +struct watchdog_device wdd; +u32 clk; +void __iomem *refresh_base; +void __iomem *control_base; +#ifdef CONFIG_PM_SLEEP +spinlock_t lock; +u8 pm_status_store; +#endif +};I would drop the #ifdef here, and favor readability over saving a few bytes.
yes, that make sense :-)
Quoted 13 lines
drivers/watchdog/sbsa_gwdt.c line 364
Quoted 9 lines
drivers/watchdog/sbsa_gwdt.c new file +8
-0+/* +* Try to determine the frequency from the cp15 interface +*/ + clk =arch_timer_get_cntfrq (); +if (!clk) { +dev_err (dev,"System Counter frequency not available\n" ); +return -EINVAL ; + }Is it guaranteed that the same clock feeds the arch timer and the watchdog? Maybe it would be better to use the clk API to read the frequency, so we can avoid this dependency.
yes. you are right. According to SBSA doc, the clocksource of SBSA watchdog is System Counter. And System Counter is in (arm_)arch_timer. So I think we should do
depends on ARM_ARCH_TIMER
and use the relevant interface :
clk = arch_timer_get_rate();
will improve it, thanks for your suggestion!
Quoted 17 lines
Quoted 4 lines
drivers/watchdog/sbsa_gwdt.c new file +3
-0+ + pr_debug("sbsa_gwdt: ioremap %s frame 0x%llx(size: %llu)-->%p.\n", + res->name, (unsigned long long)res->start,drivers/watchdog/sbsa_gwdt.c line 386
Quoted 10 lines
drivers/watchdog/sbsa_gwdt.c new file +10
-0+ (unsigned long long)(res->end - res->start + 1), rf_base); + + res =platform_get_resource_byname (pdev,IORESOURCE_MEM ,"control" ); + cf_base =devm_ioremap_resource (dev, res); +if (IS_ERR (rf_base)) +return PTR_ERR (rf_base); + +pr_debug ("sbsa_gwdt: ioremap %s frame 0x%llx(size: %llu)-->%p.\n" , + res->name, (unsigned long long )res->start, + (unsigned long long )(res->end - res->start +1 ), cf_base);I would probably drop the various
pr_debug()calls here. Once the driver works fine, they are normally not that useful any more.
yes, for this drive, if it works fine, we can drop it, but I keep these info for some reason:
(1)they can help engineer debug GTDT table or DTS, if the info of watchdog goes wrong. (2)check the memory map
(3)if DEBUG is disable, all pr_debug are no_printk, it won't increase Image size or output any through console.
Quoted 3 lines
Arnd
Signature · 16 lines
Best regards, Fu Wei Software Engineer From Red Hat LEG Team Linaro.org | Open source software for ARM SoCs Ph: +86 186 2020 4684 (mobile) IRC: fuwei Skype: tekkamanninja Room 1512, Regus One Corporate Avenue,Level 15, One Corporate Avenue,222 Hubin Road,Huangpu District, Shanghai,China 200021 -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Quoted 10 lines · Fu Wei
yes. you are right. According to SBSA doc, the clocksource of SBSA watchdog is System Counter. And System Counter is in (arm_)arch_timer. So I think we should do
depends on
ARM_ARCH_TIMERand use the relevant interface :
clk = arch_timer_get_rate();will improve it, thanks for your suggestion!
If you use arch_timer_get_rate(), then you will not be able to compile the driver as a module.
The clock API doesn't work for me, either, because no clocks are defined (clk_get_sys() always fails).
That's why I use arch_timer_get_cntfrq().
Quoted 5 lines
Quoted 2 lines
I would probably drop the various
pr_debug()calls here. Once the driver works fine, they are normally not that useful any more.yes, for this drive, if it works fine, we can drop it, but I keep these info for some reason:
(1)they can help engineer debug GTDT table or DTS, if the info of watchdog goes wrong.
Any engineer will add his own printks when debugging. You don't need to do that job for someone else. You just have too many pr_debug() statements.
Signature · 3 lines
Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation.
Guenter Roeck
maintainerQuoted 7 lines · On 05/15/2015 04:24 AM, [email protected] wrote:
From: Fu Wei <[email protected]>
(1)Use linux kernel watchdog framework
(2)Work with FDT on ARM64
(3)Use "pretimeout" in watchdog framework
(4)In first timeout(WS0), do panic to save system context (5)support geting timeout and pretimeout from
getting
Quoted 1 line
parameter and FDT at the driver init stage.
Subject: s/introdouce/introduce/
Please find a better description.
Also, please provide revisions numbers for your patch sets, and list the changes from one revision to the next.
Quoted 14 lines
Signed-off-by Fu Wei <[email protected]>--- drivers/watchdog/Kconfig | 10 + drivers/watchdog/Makefile | 1 + drivers/watchdog/sbsa_gwdt.c | 553 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 564 insertions(+)create mode 100644
drivers/watchdog/sbsa_gwdt.cdrivers/watchdog/Kconfig +0
-0
drivers/watchdog/Kconfig config ARM_SP805_WATCHDOG · line 160
Quoted 9 lines
drivers/watchdog/Kconfig +6
-0@@ -152,6 +152,16 @@ 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 ARM || ARM64 || COMPILE_TEST + select WATCHDOG_CORE + help + ARM SBSA Generic Watchdog timer. This has two Watchdog Signal(WS0/WS1),
signals
drivers/watchdog/Kconfig config ARM_SP805_WATCHDOG · line 161
Quoted 1 line
drivers/watchdog/Kconfig +1
-0+ will trigger a warnning interrupt(do panic) in the first timeout(WS0);
warning
Quoted 33 lines
drivers/watchdog/Kconfig +3
-0+ will reboot your system when the second timeout(WS1) is reached. + More details: DEN0029B - Server Base System Architecture (SBSA) + config AT91RM9200_WATCHDOG tristate "AT91RM9200 watchdog" depends on SOC_AT91RM9200 && MFD_SYSCONdrivers/watchdog/Makefile +1
-0@@ -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_AT91RM9200_WATCHDOG) += at91rm9200_wdt.o obj-$(CONFIG_AT91SAM9X_WATCHDOG) += at91sam9_wdt.o obj-$(CONFIG_CADENCE_WATCHDOG) += cadence_wdt.odrivers/watchdog/sbsa_gwdt.c new file +9
-0@@ -0,0 +1,553 @@ +/* +* SBSA(Server Base System Architecture) Generic Watchdog driver +* +* Copyright (c) 2015, Linaro Ltd. +* Author: Fu Wei <[email protected]> +* Suravee Suthikulpanit <[email protected]> +* +* 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
drivers/watchdog/sbsa_gwdt.c line 19
Quoted 10 lines
drivers/watchdog/sbsa_gwdt.c new file +10
-0+* 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. +* +* Note: This SBSA Generic watchdog driver is compatible with +* the pretimeout concept of Linux kernel. +* But timeout and pretimeout are set by the different REGs.
Why "But" ?
drivers/watchdog/sbsa_gwdt.c line 23
Quoted 4 lines
drivers/watchdog/sbsa_gwdt.c new file +4
-0+* The first watch period is set by writing WCV directly, +* that can support more than 10s timeout at the maximum +* system counter frequency. +* And the second watch period is set by WOR(32bit) which will be loaded
s/And the/The/
Quoted 47 lines
drivers/watchdog/sbsa_gwdt.c new file +47
-0+* automatically by hardware, when WS0 is triggered. +* This gives a maximum watch period of around 10s at the maximum +* system counter frequency. +* The System Counter shall run at maximum of 400MHz. +* More details: DEN0029B - Server Base System Architecture (SBSA) +* +* Kernel/API: P---------| pretimeout +* |-------------------------------T timeout +* SBSA GWDT: P--WOR---WS1 pretimeout +* |-------WCV----------WS0~~~~~~~~T timeout +*/ + +#include <asm/arch_timer.h> + +#include <linux/acpi.h> +#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/spinlock.h> +#include <linux/uaccess.h> +#include <linux/watchdog.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_LO 0x010 +#define SBSA_GWDT_WCV_HI 0x014 + +/* 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) + +/* Watchdog Interface Identification Register */ +#define SBSA_GWDT_W_IIDR_PID (x) ((x >> 20) & 0xfff)
drivers/watchdog/sbsa_gwdt.c line 80
Quoted 10 lines
drivers/watchdog/sbsa_gwdt.c new file +10
-0+#define SBSA_GWDT_W_IIDR_ARCH_VER (x) ((x >> 16) & 0xf) +#define SBSA_GWDT_W_IIDR_REV (x) ((x >> 12) & 0xf) +#define SBSA_GWDT_W_IIDR_IMPLEMENTER (x) (x & 0xfff) +#define SBSA_GWDT_W_IIDR_VID_BANK (x) ((x >> 8) & 0xf) +#define SBSA_GWDT_W_IIDR_VID (x) (x & 0x7f) + +/* Watchdog Identification Register */ +#define SBSA_GWDT_IDR_W_PIDR2 0xfe8 +#define SBSA_GWDT_IDR_W_PIDR2_ARCH_VER (x) ((x >> 4) & 0xf) +
(x) for all the above macros, please.
drivers/watchdog/sbsa_gwdt.c line 86
Quoted 6 lines
drivers/watchdog/sbsa_gwdt.c new file +6
-0+/** +* 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: VA of the watchdog refresh frame +* @control_base: VA of the watchdog control frame
Please spell out "Virtual address".
drivers/watchdog/sbsa_gwdt.c line 98
Quoted 12 lines
drivers/watchdog/sbsa_gwdt.c new file +12
-0+* @lock: struct sbsa_gwdt spinlock +* @pm_status_store: store the PM info of WDT +*/ +struct sbsa_gwdt { +struct watchdog_device wdd; +u32 clk; +void __iomem *refresh_base; +void __iomem *control_base; +#ifdef CONFIG_PM_SLEEP +spinlock_t lock; +u8 pm_status_store; +#endif
Please avoid the #ifdef.
Quoted 81 lines
drivers/watchdog/sbsa_gwdt.c new file +81
-0+}; + +#define to_sbsa_gwdt (e) container_of(e, struct sbsa_gwdt, wdd) + +#define DEFAULT_TIMEOUT_WS0 10/* seconds, the 1st watch period*/ +#define DEFAULT_PRETIMEOUT 5/* seconds, the 2nd watch period*/ + +static unsigned int timeout; +module_param (timeout, uint,0 ); +MODULE_PARM_DESC (timeout, + "Watchdog timeout in seconds. (>=0, default=" + __MODULE_STRING(DEFAULT_TIMEOUT_WS0 + DEFAULT_PRETIMEOUT) ")"); + +static unsigned int max_timeout =UINT_MAX ; +module_param (max_timeout, uint,0 ); +MODULE_PARM_DESC (max_timeout, + "Watchdog max timeout in seconds. (>=0, default=" + __MODULE_STRING(UINT_MAX) ")"); + +static unsigned int max_pretimeout =U32_MAX ; +module_param (max_pretimeout, uint,0 ); +MODULE_PARM_DESC (max_pretimeout, + "Watchdog max pretimeout in seconds. (>=0, default=" + __MODULE_STRING(U32_MAX) ")"); + +static unsigned int pretimeout; +module_param (pretimeout, uint,0 ); +MODULE_PARM_DESC (pretimeout, + "Watchdog pretimeout in seconds. (>=0, default=" + __MODULE_STRING(DEFAULT_PRETIMEOUT) ")"); + +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) ")"); + +/* +* Architected system timer support. +*/ +static void sbsa_gwdt_cf_write (unsigned int reg,u32 val, +struct watchdog_device *wdd) +{ +struct sbsa_gwdt *gwdt =to_sbsa_gwdt (wdd); + +writel_relaxed (val, gwdt->control_base + reg); +} + +static void sbsa_gwdt_rf_write (unsigned int reg,u32 val, +struct watchdog_device *wdd) +{ +struct sbsa_gwdt *gwdt =to_sbsa_gwdt (wdd); + +writel_relaxed (val, gwdt->refresh_base + reg); +} + +static u32 sbsa_gwdt_cf_read (unsigned int reg,struct watchdog_device *wdd) +{ +struct sbsa_gwdt *gwdt =to_sbsa_gwdt (wdd); + +return readl_relaxed (gwdt->control_base + reg); +} + +/* +* help founctions for accessing 64bit WCV register +* mutex_lock must be called prior to calling this function. +*/ +static u64 sbsa_gwdt_get_wcv (struct watchdog_device *wdd) +{ +u32 wcv_lo, wcv_hi; + +do { + wcv_hi =sbsa_gwdt_cf_read (SBSA_GWDT_WCV_HI , wdd); + wcv_lo =sbsa_gwdt_cf_read (SBSA_GWDT_WCV_LO , wdd); + }while (wcv_hi !=sbsa_gwdt_cf_read (SBSA_GWDT_WCV_HI , wdd)); + +return (((u64 )wcv_hi <<32 ) | wcv_lo); +} + +static void sbsa_gwdt_set_wcv (struct watchdog_device *wdd,u64 value) +{
drivers/watchdog/sbsa_gwdt.c line 189
Quoted 10 lines
drivers/watchdog/sbsa_gwdt.c new file +10
-0+u32 wcv_lo, wcv_hi; + + wcv_lo = value &U32_MAX ; + wcv_hi = (value >>32 ) &U32_MAX ; + +sbsa_gwdt_cf_write (SBSA_GWDT_WCV_HI , wcv_hi, wdd); +sbsa_gwdt_cf_write (SBSA_GWDT_WCV_LO , wcv_lo, wdd); + +pr_debug ("sbsa_gwdt: set WCV to %llu, result: %llu\n" , + value,sbsa_gwdt_get_wcv (wdd));
Is this pr_debug still necessary ?
Quoted 18 lines
drivers/watchdog/sbsa_gwdt.c new file +18
-0+} + +static void reload_timeout_to_wcv (struct watchdog_device *wdd) +{ +struct sbsa_gwdt *gwdt =to_sbsa_gwdt (wdd); +u64 wcv; + + wcv =arch_counter_get_cntvct () + + (u64)(wdd->timeout - wdd->pretimeout) * gwdt->clk; + +sbsa_gwdt_set_wcv (wdd, wcv); +} + +/* +* Use the following function to set the limit of timeout +* after updating pretimeout +*/ +static void sbsa_gwdt_set_timeout_limits (struct sbsa_gwdt *gwdt)
drivers/watchdog/sbsa_gwdt.c line 217
Quoted 10 lines
drivers/watchdog/sbsa_gwdt.c new file +10
-0+{ +unsigned int first_period_max = (U64_MAX / gwdt->clk); +struct watchdog_device *wdd = &gwdt->wdd; + + wdd->min_timeout = wdd->pretimeout +1 ; + wdd->max_timeout =min (wdd->pretimeout + first_period_max, max_timeout); + +pr_debug ("sbsa_gwdt: timeout (%u-%u), pretimeout (%u-%u)\n" , + wdd->min_timeout, wdd->max_timeout, + wdd->min_pretimeout, wdd->max_pretimeout);
Is this still necessary ?
drivers/watchdog/sbsa_gwdt.c line 226
Quoted 9 lines
drivers/watchdog/sbsa_gwdt.c new file +9
-0+} + +static int sbsa_gwdt_set_timeout (struct watchdog_device *wdd, +unsigned int timeout) +{ + wdd->timeout = timeout; + +return 0 ; +/* watchdog framework will trigger a ping, after this call */
Unnecessary comment.
Quoted 12 lines
drivers/watchdog/sbsa_gwdt.c new file +12
-0+} + +static int sbsa_gwdt_set_pretimeout (struct watchdog_device *wdd, +unsigned int pretimeout) +{ +struct sbsa_gwdt *gwdt =to_sbsa_gwdt (wdd); +u32 wor; + + wdd->pretimeout = pretimeout; +sbsa_gwdt_set_timeout_limits (gwdt); + +if (!pretimeout)
drivers/watchdog/sbsa_gwdt.c line 248
Quoted 10 lines
drivers/watchdog/sbsa_gwdt.c new file +10
-0+/* gives sbsa_gwdt_start a chance to setup timeout */ + wor = gwdt->clk; + else + wor = pretimeout * gwdt->clk; + +/* refresh the WOR, that will cause an explicit watchdog refresh */ +sbsa_gwdt_cf_write (SBSA_GWDT_WOR , wor, wdd); + +pr_debug ("sbsa_gwdt: set WOR to %x(%us), result: %x\n" , + wor, pretimeout,sbsa_gwdt_cf_read (SBSA_GWDT_WOR , wdd));
Is this still necessary ?
drivers/watchdog/sbsa_gwdt.c line 226
Quoted 3 lines
drivers/watchdog/sbsa_gwdt.c new file +3
-0+ +return 0 ; +/* watchdog framework will trigger a ping, after this call */
Unnecessary comment.
drivers/watchdog/sbsa_gwdt.c line 259
Quoted 8 lines
drivers/watchdog/sbsa_gwdt.c new file +8
-0+} + +static unsigned int sbsa_gwdt_get_timeleft (struct watchdog_device *wdd) +{ +struct sbsa_gwdt *gwdt =to_sbsa_gwdt (wdd); +u64 timeleft =sbsa_gwdt_get_wcv (wdd) -arch_counter_get_cntvct (); + +return timeleft / gwdt->clk;
Will this ever be built on a 32 bit target ? That may cause a link error due to the 64 bit divide operation.
drivers/watchdog/sbsa_gwdt.c line 272
Quoted 13 lines
drivers/watchdog/sbsa_gwdt.c new file +13
-0+} + +static int sbsa_gwdt_start (struct watchdog_device *wdd) +{ +/* Force refresh */ +sbsa_gwdt_rf_write (SBSA_GWDT_WRR ,0xc0ffee , wdd); +/* writing WCS will cause an explicit watchdog refresh */ +sbsa_gwdt_cf_write (SBSA_GWDT_WCS ,SBSA_GWDT_WCS_EN , wdd); + +reload_timeout_to_wcv (wdd); + +pr_debug ("sbsa_gwdt: WCS is %x(%s)\n" , +sbsa_gwdt_cf_read (SBSA_GWDT_WCS , wdd), __func__);
Another one. If you think you need to keep those, can you at least use dev_dbg ? I won't comment on the debug messages further, but I really think that even for debug messages this is a bit noisy.
Quoted 73 lines
drivers/watchdog/sbsa_gwdt.c new file +73
-0+ +return 0 ; +} + +static int sbsa_gwdt_stop (struct watchdog_device *wdd) +{ +/* Force refresh */ +sbsa_gwdt_rf_write (SBSA_GWDT_WRR ,0xc0ffee , wdd); +/* writing WCS will cause an explicit watchdog refresh */ +sbsa_gwdt_cf_write (SBSA_GWDT_WCS ,0 , wdd); + +pr_debug ("sbsa_gwdt: WCS is %x(%s)\n" , +sbsa_gwdt_cf_read (SBSA_GWDT_WCS , wdd), __func__); + +return 0 ; +} + +static int sbsa_gwdt_keepalive (struct watchdog_device *wdd) +{ +/* +* Writing WRR for an explicit watchdog refresh +* You can write anyting(like 0xc0ffee) +*/ +sbsa_gwdt_rf_write (SBSA_GWDT_WRR ,0xc0ffee , wdd); + +reload_timeout_to_wcv (wdd); + +pr_debug ("sbsa_gwdt: ping, %us left.\n" ,sbsa_gwdt_get_timeleft (wdd)); + +return 0 ; +} + +static irqreturn_t sbsa_gwdt_interrupt (int irq,void *dev_id) +{ +struct sbsa_gwdt *gwdt = (struct sbsa_gwdt *)dev_id; +struct watchdog_device *wdd = &gwdt->wdd; +u32 status; + + status =sbsa_gwdt_cf_read (SBSA_GWDT_WCS , wdd); + +pr_debug ("sbsa_gwdt: interrupt routine, WCS@%x\n" , status); + +if (status &SBSA_GWDT_WCS_WS0 ) { +pr_debug ("sbsa_gwdt WS0: trigger WS1 in %ds!\n" , +sbsa_gwdt_get_timeleft (wdd)); +panic ("SBSA Watchdog pre-timeout" ); + } + +return IRQ_HANDLED ; +} + +static struct watchdog_info sbsa_gwdt_info = { + .identity ="SBSA Generic Watchdog" , + .options =WDIOF_SETTIMEOUT | +WDIOF_KEEPALIVEPING | +WDIOF_MAGICCLOSE | +WDIOF_PRETIMEOUT | +WDIOF_CARDRESET , +}; + +static struct watchdog_ops sbsa_gwdt_ops = { + .owner =THIS_MODULE , + .start = sbsa_gwdt_start, + .stop = sbsa_gwdt_stop, + .ping = sbsa_gwdt_keepalive, + .set_timeout = sbsa_gwdt_set_timeout, + .set_pretimeout = sbsa_gwdt_set_pretimeout, + .get_timeleft = sbsa_gwdt_get_timeleft, +}; + +static int sbsa_gwdt_probe (struct platform_device *pdev) +{ +struct device *dev = &pdev->dev;
drivers/watchdog/sbsa_gwdt.c line 355
Quoted 10 lines
drivers/watchdog/sbsa_gwdt.c new file +10
-0+ +struct sbsa_gwdt *gwdt; +struct watchdog_device *wdd; + +struct resource *res; +void *rf_base, *cf_base; +int irq; +u32 clk, status, w_iidr; + +int ret =0 ;
Please drop the empty lines above.
Quoted 12 lines
drivers/watchdog/sbsa_gwdt.c new file +12
-0+ +/* +* Try to determine the frequency from the cp15 interface +*/ + clk =arch_timer_get_cntfrq (); +if (!clk) { +dev_err (dev,"System Counter frequency not available\n" ); +return -EINVAL ; + } + + gwdt =devm_kzalloc (dev,sizeof (*gwdt),GFP_KERNEL ); +if (!gwdt)
drivers/watchdog/sbsa_gwdt.c line 377
Quoted 10 lines
drivers/watchdog/sbsa_gwdt.c new file +10
-0+return -ENOMEM ; + + res =platform_get_resource_byname (pdev,IORESOURCE_MEM ,"refresh" ); + rf_base =devm_ioremap_resource (dev, res); +if (IS_ERR (rf_base)) +return PTR_ERR (rf_base); + +pr_debug ("sbsa_gwdt: ioremap %s frame 0x%llx(size: %llu)-->%p.\n" , + res->name, (unsigned long long )res->start, + (unsigned long long )(res->end - res->start +1 ), rf_base);
If you think you need to keep those messages, please at least use %pR.
Quoted 29 lines
drivers/watchdog/sbsa_gwdt.c new file +29
-0+ + res =platform_get_resource_byname (pdev,IORESOURCE_MEM ,"control" ); + cf_base =devm_ioremap_resource (dev, res); +if (IS_ERR (rf_base)) +return PTR_ERR (rf_base); + +pr_debug ("sbsa_gwdt: ioremap %s frame 0x%llx(size: %llu)-->%p.\n" , + res->name, (unsigned long long )res->start, + (unsigned long long )(res->end - res->start +1 ), cf_base); + + irq =platform_get_irq_byname (pdev,"ws0" ); +if (irq <0 ) { +dev_err (dev,"unable to get ws0 interrupt.\n" ); +return irq; + } + +pr_debug ("sbsa_gwdt: ws0 irq %d.\n" , irq); + + gwdt->refresh_base = rf_base; + gwdt->control_base = cf_base; + gwdt->clk = clk; +#ifdef CONFIG_PM_SLEEP +spin_lock_init (&gwdt->lock); +#endif +platform_set_drvdata (pdev, gwdt); + +pr_debug ("sbsa_gwdt: hw clk: %uHz--> WOR(32bit) max timeout is %us.\n" , + gwdt->clk,U32_MAX / clk); +
drivers/watchdog/sbsa_gwdt.c line 416
Quoted 10 lines
drivers/watchdog/sbsa_gwdt.c new file +10
-0+ 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); + + status =sbsa_gwdt_cf_read (SBSA_GWDT_WCS , wdd); +if (status &SBSA_GWDT_WCS_WS1 ) { + dev_warn(dev, "System was reseted by WDT(WCS: %x, WCV: %llx)\n",
"was reseted" is kind of odd. Can you use just "reset" or maybe "restarted" ?
Quoted 10 lines
drivers/watchdog/sbsa_gwdt.c new file +10
-0+ status, sbsa_gwdt_get_wcv(wdd)); + wdd->bootstatus |=WDIOF_CARDRESET ; + } +/* Check if watchdog is already enabled */ +if (status &SBSA_GWDT_WCS_EN ) { +dev_warn (dev,"already enabled!\n" ); +sbsa_gwdt_keepalive (wdd); + } + +pr_debug ("sbsa_gwdt: WCS: %x(%s)\n" , status, __func__);
drivers/watchdog/sbsa_gwdt.c line 436
Quoted 10 lines
drivers/watchdog/sbsa_gwdt.c new file +10
-0+ + wdd->min_pretimeout =0 ; + wdd->max_pretimeout =min (U32_MAX / clk, max_timeout -1 ); +sbsa_gwdt_set_timeout_limits (gwdt); + +watchdog_init_pretimeout (wdd, pretimeout, dev); +if (!wdd->pretimeout) { + wdd->pretimeout =DEFAULT_PRETIMEOUT ; +dev_info (dev,"can't get pretimeout param, set default %us.\n" , + wdd->pretimeout);
Unnecessary message. The pretimeout is printed again below.
drivers/watchdog/sbsa_gwdt.c line 444
Quoted 8 lines
drivers/watchdog/sbsa_gwdt.c new file +8
-0+ } +sbsa_gwdt_set_pretimeout (wdd, wdd->pretimeout); + +watchdog_init_timeout (wdd, timeout, dev); +if (!wdd->timeout) { + wdd->timeout = wdd->pretimeout +DEFAULT_TIMEOUT_WS0 ; +dev_info (dev,"can't get timeout param, set default: %us.\n" , + wdd->timeout);
Same here.
Quoted 12 lines
drivers/watchdog/sbsa_gwdt.c new file +12
-0+ } +sbsa_gwdt_set_timeout (wdd, wdd->timeout); + + ret =devm_request_irq (dev, irq, sbsa_gwdt_interrupt,IRQF_TIMER , + pdev->name, gwdt); +if (ret) { +dev_err (dev,"unable to request IRQ %d\n" , irq); +return ret; + } + + ret =watchdog_register_device (wdd); +if (ret)
drivers/watchdog/sbsa_gwdt.c line 466
Quoted 10 lines
drivers/watchdog/sbsa_gwdt.c new file +10
-0+return ret; + +/* get device information from control frame and display */ + w_iidr =sbsa_gwdt_cf_read (SBSA_GWDT_W_IIDR , &gwdt->wdd); +dev_info (dev,"PID:%u(JEP106 %u-%u), Arch v%u Rev %u." , +SBSA_GWDT_W_IIDR_PID (w_iidr), +SBSA_GWDT_W_IIDR_VID_BANK (w_iidr), +SBSA_GWDT_W_IIDR_VID (w_iidr), +SBSA_GWDT_W_IIDR_ARCH_VER (w_iidr), +SBSA_GWDT_W_IIDR_REV (w_iidr));
Is this valuable information ?
Quoted 18 lines
drivers/watchdog/sbsa_gwdt.c new file +18
-0+ +dev_info (dev,"Initialized with %ds timeout, %ds pretimeout @ %uHz\n" , + wdd->timeout, wdd->pretimeout, gwdt->clk); + +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); +int ret =0 ;
drivers/watchdog/sbsa_gwdt.c line 494
Quoted 10 lines
drivers/watchdog/sbsa_gwdt.c new file +10
-0+ +if (!nowayout) + ret =sbsa_gwdt_stop (&gwdt->wdd); + +watchdog_unregister_device (&gwdt->wdd); + +return ret; +} + +#ifdef CONFIG_PM_SLEEP
You don't need the #ifdef if you use __maybe_unused with the function declarations.
drivers/watchdog/sbsa_gwdt.c line 506
Quoted 12 lines
drivers/watchdog/sbsa_gwdt.c new file +12
-0+/* Disable watchdog if it is active during suspend */ +static int sbsa_gwdt_suspend (struct device *dev) +{ +struct sbsa_gwdt *gwdt =dev_get_drvdata (dev); +struct watchdog_device *wdd = &gwdt->wdd; + +spin_lock (&gwdt->lock); + gwdt->pm_status_store =sbsa_gwdt_cf_read (SBSA_GWDT_WCS , wdd); + +if (gwdt->pm_status_store &SBSA_GWDT_WCS_EN ) +sbsa_gwdt_stop (wdd); +spin_unlock (&gwdt->lock);
Wonder what this lock is protecting against. Can you explain ? I would assume that suspend and resume are mutually exclusive and don't require locking against each other.
Quoted 5 lines
drivers/watchdog/sbsa_gwdt.c new file +5
-0+ +return 0 ; +} + +/* Enable watchdog and configure it if necessary */
drivers/watchdog/sbsa_gwdt.c line 521
Quoted 10 lines
drivers/watchdog/sbsa_gwdt.c new file +10
-0+static int sbsa_gwdt_resume (struct device *dev) +{ +struct sbsa_gwdt *gwdt =dev_get_drvdata (dev); +struct watchdog_device *wdd = &gwdt->wdd; + +spin_lock (&gwdt->lock); +if (gwdt->pm_status_store &SBSA_GWDT_WCS_EN ) +sbsa_gwdt_start (wdd); +else +sbsa_gwdt_stop (wdd);
What is the stop here for ?
Quoted 23 lines
drivers/watchdog/sbsa_gwdt.c new file +22
-0+spin_unlock (&gwdt->lock); + +return 0 ; +} +#endif + +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 dev_pm_ops sbsa_gwdt_pm_ops = { +SET_SYSTEM_SLEEP_PM_OPS (sbsa_gwdt_suspend, sbsa_gwdt_resume) +}; + +static struct platform_driver sbsa_gwdt_driver = { + .driver = { + .name ="sbsa-gwdt" , + .pm = &sbsa_gwdt_pm_ops, + .of_match_table = sbsa_gwdt_of_match, + },
drivers/watchdog/sbsa_gwdt.c line 553
Quoted 10 lines
drivers/watchdog/sbsa_gwdt.c new file +10
-0+ .probe = sbsa_gwdt_probe, + .remove = sbsa_gwdt_remove, + .shutdown = sbsa_gwdt_shutdown, +}; + +module_platform_driver (sbsa_gwdt_driver); + +MODULE_DESCRIPTION ("SBSA Generic Watchdog Driver" ); +MODULE_AUTHOR ("Fu Wei <[email protected]>" ); +MODULE_LICENSE ("GPL v2" );
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Hi Grenter,
Great thanks for your review,
Quoted 16 lines · Guenter Roeck
Quoted 8 lines · On 05/15/2015 04:24 AM, [email protected] wrote:
From: Fu Wei <[email protected]>
(1)Use linux kernel watchdog framework
(2)Work with FDT on ARM64
(3)Use "pretimeout" in watchdog framework
(4)In first timeout(WS0), do panic to save system context (5)support geting timeout and pretimeout fromgetting
Quoted 1 line
parameter and FDT at the driver init stage.
Quoted 6 lines
Subject: s/introdouce/introduce/
Please find a better description.
Also, please provide revisions numbers for your patch sets, and list the changes from one revision to the next.
sorry for those typo, I have fixed them,
and will provide revisions numbers and changelog in next patch
Quoted 31 lines
Quoted 26 lines
Signed-off-by Fu Wei <[email protected]>--- drivers/watchdog/Kconfig | 10 + drivers/watchdog/Makefile | 1 + drivers/watchdog/sbsa_gwdt.c | 553 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 564 insertions(+)create mode 100644
drivers/watchdog/sbsa_gwdt.cdrivers/watchdog/Kconfig +0
-0@@ -152,6 +152,16 @@ config ARM_SP805_WATCHDOG ARM Primecell SP805 Watchdog timer. This will reboot your systemwhen
the timeout is reached.drivers/watchdog/Kconfig +6
-0+config ARM_SBSA_WATCHDOG + tristate "ARM SBSA Generic Watchdog" + depends on ARM || ARM64 || COMPILE_TEST + select WATCHDOG_CORE + help + ARM SBSA Generic Watchdog timer. This has two WatchdogQuoted 1 line
Signal(WS0/WS1),
signals
Quoted 5 lines
Quoted 2 lines
+ will trigger a warnning interrupt(do panic) in the first
timeout(WS0);warning
sorry for these typoes, I have fixed them,
Quoted 40 lines
Quoted 40 lines
drivers/watchdog/Kconfig +3
-0+ will reboot your system when the second timeout(WS1) is reached. + More details: DEN0029B - Server Base System Architecture (SBSA) + config AT91RM9200_WATCHDOG tristate "AT91RM9200 watchdog" depends on SOC_AT91RM9200 && MFD_SYSCONdrivers/watchdog/Makefile +1
-0@@ -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_AT91RM9200_WATCHDOG) += at91rm9200_wdt.o obj-$(CONFIG_AT91SAM9X_WATCHDOG) += at91sam9_wdt.o obj-$(CONFIG_CADENCE_WATCHDOG) += cadence_wdt.odrivers/watchdog/sbsa_gwdt.c new file +14
-0@@ -0,0 +1,553 @@ +/* +* SBSA(Server Base System Architecture) Generic Watchdog driver +* +* Copyright (c) 2015, Linaro Ltd. +* Author: Fu Wei <[email protected]> +* Suravee Suthikulpanit <[email protected]> +* +* 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
Quoted 8 lines
drivers/watchdog/sbsa_gwdt.c line 19
Quoted 5 lines
drivers/watchdog/sbsa_gwdt.c new file +5
-0+* GNU General Public License for more details. +* +* Note: This SBSA Generic watchdog driver is compatible with +* the pretimeout concept of Linux kernel. +* But timeout and pretimeout are set by the different REGs. Why "But" ?
deleted it :-)
Quoted 9 lines
Quoted 6 lines
drivers/watchdog/sbsa_gwdt.c new file +4
-0+* The first watch period is set by writing WCV directly, +* that can support more than 10s timeout at the maximum +* system counter frequency. +* And the second watch period is set by WOR(32bit) which will be loaded
s/And the/The/
Thanks, I have fixed them,
Quoted 55 lines
Quoted 55 lines
+ * automatically by hardware, when WS0 is triggered. + * This gives a maximum watch period of around 10s at the maximum + * system counter frequency. + * The System Counter shall run at maximum of 400MHz. + * More details: DEN0029B - Server Base System Architecture (SBSA)+ *
+ * Kernel/API: P---------| pretimeout
+ * |-------------------------------T timeout
+ * SBSA GWDT: P--WOR---WS1 pretimeout
+ * |-------WCV----------WS0~~~~~~~~T timeout
+ */drivers/watchdog/sbsa_gwdt.c new file +36
-0+ +#include <asm/arch_timer.h> + +#include <linux/acpi.h> +#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/spinlock.h> +#include <linux/uaccess.h> +#include <linux/watchdog.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_LO 0x010 +#define SBSA_GWDT_WCV_HI 0x014 + +/* 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) + +/* Watchdog Interface Identification Register */ +#define SBSA_GWDT_W_IIDR_PID (x) ((x >> 20) &
0xfff)drivers/watchdog/sbsa_gwdt.c new file +5
-0+#define SBSA_GWDT_W_IIDR_ARCH_VER (x) ((x >> 16) & 0xf) +#define SBSA_GWDT_W_IIDR_REV (x) ((x >> 12) & 0xf) +#define SBSA_GWDT_W_IIDR_IMPLEMENTER (x) (x & 0xfff) +#define SBSA_GWDT_W_IIDR_VID_BANK (x) ((x >> 8) & 0xf) +#define SBSA_GWDT_W_IIDR_VID (x) (x & 0x7f)
Quoted 8 lines
drivers/watchdog/sbsa_gwdt.c line 80
Quoted 5 lines
drivers/watchdog/sbsa_gwdt.c new file +5
-0+ +/* Watchdog Identification Register */ +#define SBSA_GWDT_IDR_W_PIDR2 0xfe8 +#define SBSA_GWDT_IDR_W_PIDR2_ARCH_VER (x) ((x >> 4) & 0xf) +(x) for all the above macros, please.
Great thanks , my bad , I have fixed them
Quoted 10 lines
Quoted 7 lines
+/**
+ * structsbsa_gwdt- Internal representation of the SBSA GWDT+ * @wdd: kernel watchdog_device structure + * @clk: store the System Counter clock frequency, in Hz. + * @refresh_base: VA of the watchdog refresh frame + * @control_base: VA of the watchdog control framePlease spell out "Virtual address".
done :-)
Quoted 16 lines
drivers/watchdog/sbsa_gwdt.c line 98
Quoted 13 lines
+ * @lock: struct
sbsa_gwdtspinlock
+ * @pm_status_store: store the PM info of WDT
+ */drivers/watchdog/sbsa_gwdt.c new file +9
-0+struct sbsa_gwdt { +struct watchdog_device wdd; +u32 clk; +void __iomem *refresh_base; +void __iomem *control_base; +#ifdef CONFIG_PM_SLEEP +spinlock_t lock; +u8 pm_status_store; +#endif Please avoid the #ifdef
I have deleted them , thanks
Quoted 90 lines
Quoted 90 lines
drivers/watchdog/sbsa_gwdt.c new file +12
-0+}; + +#define to_sbsa_gwdt (e) container_of(e, struct sbsa_gwdt, wdd) + +#define DEFAULT_TIMEOUT_WS0 10/* seconds, the 1st watch period*/ +#define DEFAULT_PRETIMEOUT 5/* seconds, the 2nd watch period*/ + +static unsigned int timeout; +module_param (timeout, uint,0 ); +MODULE_PARM_DESC (timeout, +"Watchdog timeout in seconds. (>=0, default=" + __MODULE_STRING(DEFAULT_TIMEOUT_WS0 + DEFAULT_PRETIMEOUT)")");
drivers/watchdog/sbsa_gwdt.c new file +45
-0+ +static unsigned int max_timeout =UINT_MAX ; +module_param (max_timeout, uint,0 ); +MODULE_PARM_DESC (max_timeout, + "Watchdog max timeout in seconds. (>=0, default=" + __MODULE_STRING(UINT_MAX) ")"); + +static unsigned int max_pretimeout =U32_MAX ; +module_param (max_pretimeout, uint,0 ); +MODULE_PARM_DESC (max_pretimeout, + "Watchdog max pretimeout in seconds. (>=0, default=" + __MODULE_STRING(U32_MAX) ")"); + +static unsigned int pretimeout; +module_param (pretimeout, uint,0 ); +MODULE_PARM_DESC (pretimeout, + "Watchdog pretimeout in seconds. (>=0, default=" + __MODULE_STRING(DEFAULT_PRETIMEOUT) ")"); + +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) ")"); + +/* +* Architected system timer support. +*/ +static void sbsa_gwdt_cf_write (unsigned int reg,u32 val, +struct watchdog_device *wdd) +{ +struct sbsa_gwdt *gwdt =to_sbsa_gwdt (wdd); + +writel_relaxed (val, gwdt->control_base + reg); +} + +static void sbsa_gwdt_rf_write (unsigned int reg,u32 val, +struct watchdog_device *wdd) +{ +struct sbsa_gwdt *gwdt =to_sbsa_gwdt (wdd); + +writel_relaxed (val, gwdt->refresh_base + reg); +} + +static u32 sbsa_gwdt_cf_read(unsigned int reg, struct watchdog_device*wdd)
drivers/watchdog/sbsa_gwdt.c new file +29
-0+{ +struct sbsa_gwdt *gwdt =to_sbsa_gwdt (wdd); + +return readl_relaxed (gwdt->control_base + reg); +} + +/* +* help founctions for accessing 64bit WCV register +* mutex_lock must be called prior to calling this function. +*/ +static u64 sbsa_gwdt_get_wcv (struct watchdog_device *wdd) +{ +u32 wcv_lo, wcv_hi; + +do { + wcv_hi =sbsa_gwdt_cf_read (SBSA_GWDT_WCV_HI , wdd); + wcv_lo =sbsa_gwdt_cf_read (SBSA_GWDT_WCV_LO , wdd); + }while (wcv_hi !=sbsa_gwdt_cf_read (SBSA_GWDT_WCV_HI , wdd)); + +return (((u64 )wcv_hi <<32 ) | wcv_lo); +} + +static void sbsa_gwdt_set_wcv (struct watchdog_device *wdd,u64 value) +{ +u32 wcv_lo, wcv_hi; + + wcv_lo = value &U32_MAX ; + wcv_hi = (value >>32 ) &U32_MAX ; +
Quoted 8 lines
drivers/watchdog/sbsa_gwdt.c line 189
Quoted 5 lines
drivers/watchdog/sbsa_gwdt.c new file +5
-0+sbsa_gwdt_cf_write (SBSA_GWDT_WCV_HI , wcv_hi, wdd); +sbsa_gwdt_cf_write (SBSA_GWDT_WCV_LO , wcv_lo, wdd); + +pr_debug ("sbsa_gwdt: set WCV to %llu, result: %llu\n" , + value,sbsa_gwdt_get_wcv (wdd));Is this
pr_debugstill necessary ?
will remove it , Thanks
Quoted 26 lines
Quoted 26 lines
drivers/watchdog/sbsa_gwdt.c new file +24
-0+} + +static void reload_timeout_to_wcv (struct watchdog_device *wdd) +{ +struct sbsa_gwdt *gwdt =to_sbsa_gwdt (wdd); +u64 wcv; + + wcv =arch_counter_get_cntvct () + + (u64)(wdd->timeout - wdd->pretimeout) * gwdt->clk; + +sbsa_gwdt_set_wcv (wdd, wcv); +} + +/* +* Use the following function to set the limit of timeout +* after updating pretimeout +*/ +static void sbsa_gwdt_set_timeout_limits (struct sbsa_gwdt *gwdt) +{ +unsigned int first_period_max = (U64_MAX / gwdt->clk); +struct watchdog_device *wdd = &gwdt->wdd; + + wdd->min_timeout = wdd->pretimeout +1 ; + wdd->max_timeout = min(wdd->pretimeout + first_period_max,
Quoted 8 lines
drivers/watchdog/sbsa_gwdt.c line 217
Quoted 5 lines
max_timeout);drivers/watchdog/sbsa_gwdt.c new file +4
-0+ +pr_debug ("sbsa_gwdt: timeout (%u-%u), pretimeout (%u-%u)\n" , + wdd->min_timeout, wdd->max_timeout, + wdd->min_pretimeout, wdd->max_pretimeout);Is this still necessary ?
will remove it , Thanks
Quoted 13 lines
drivers/watchdog/sbsa_gwdt.c line 226
Quoted 10 lines
drivers/watchdog/sbsa_gwdt.c new file +9
-0+} + +static int sbsa_gwdt_set_timeout (struct watchdog_device *wdd, +unsigned int timeout) +{ + wdd->timeout = timeout; + +return 0 ; +/* watchdog framework will trigger a ping, after this call */ Unnecessary comment.
will remove it , Thanks
Quoted 19 lines
Quoted 19 lines
drivers/watchdog/sbsa_gwdt.c new file +18
-0+} + +static int sbsa_gwdt_set_pretimeout (struct watchdog_device *wdd, +unsigned int pretimeout) +{ +struct sbsa_gwdt *gwdt =to_sbsa_gwdt (wdd); +u32 wor; + + wdd->pretimeout = pretimeout; +sbsa_gwdt_set_timeout_limits (gwdt); + +if (!pretimeout) +/* gives sbsa_gwdt_start a chance to setup timeout */ + wor = gwdt->clk; +else + wor = pretimeout * gwdt->clk; + +/* refresh the WOR, that will cause an explicit watchdog refresh
Quoted 8 lines
drivers/watchdog/sbsa_gwdt.c line 248
Quoted 5 lines
*/
drivers/watchdog/sbsa_gwdt.c new file +4
-0+sbsa_gwdt_cf_write (SBSA_GWDT_WOR , wor, wdd); + +pr_debug ("sbsa_gwdt: set WOR to %x(%us), result: %x\n" , + wor, pretimeout,sbsa_gwdt_cf_read (SBSA_GWDT_WOR , wdd));Is this still necessary ?
will remove it , Thanks
Quoted 7 lines
drivers/watchdog/sbsa_gwdt.c line 226
Quoted 4 lines
drivers/watchdog/sbsa_gwdt.c new file +3
-0+ +return 0 ; +/* watchdog framework will trigger a ping, after this call */ Unnecessary comment.
will remove it , Thanks
Quoted 13 lines
drivers/watchdog/sbsa_gwdt.c line 259
Quoted 9 lines
drivers/watchdog/sbsa_gwdt.c new file +8
-0+} + +static unsigned int sbsa_gwdt_get_timeleft (struct watchdog_device *wdd) +{ +struct sbsa_gwdt *gwdt =to_sbsa_gwdt (wdd); +u64 timeleft =sbsa_gwdt_get_wcv (wdd) -arch_counter_get_cntvct (); + +return timeleft / gwdt->clk;Will this ever be built on a 32 bit target ? That may cause a link error due to the 64 bit divide operation.
yes, you are right, you found a bug, I have fixed it by do_div().
Great thanks !!
Quoted 12 lines
Quoted 12 lines
drivers/watchdog/sbsa_gwdt.c new file +11
-0+} + +static int sbsa_gwdt_start (struct watchdog_device *wdd) +{ +/* Force refresh */ +sbsa_gwdt_rf_write (SBSA_GWDT_WRR ,0xc0ffee , wdd); +/* writing WCS will cause an explicit watchdog refresh */ +sbsa_gwdt_cf_write (SBSA_GWDT_WCS ,SBSA_GWDT_WCS_EN , wdd); + +reload_timeout_to_wcv (wdd); +
Quoted 8 lines
drivers/watchdog/sbsa_gwdt.c
Quoted 2 lines
drivers/watchdog/sbsa_gwdt.c new file +2
-0+pr_debug ("sbsa_gwdt: WCS is %x(%s)\n" , +sbsa_gwdt_cf_read (SBSA_GWDT_WCS , wdd), __func__);Another one. If you think you need to keep those, can you at least use
dev_dbg?
I won't comment on the debug messages further, but I really think that even for debug messages this is a bit noisy.
will remove it , Thanks
Quoted 81 lines
Quoted 81 lines
drivers/watchdog/sbsa_gwdt.c new file +28
-0+ +return 0 ; +} + +static int sbsa_gwdt_stop (struct watchdog_device *wdd) +{ +/* Force refresh */ +sbsa_gwdt_rf_write (SBSA_GWDT_WRR ,0xc0ffee , wdd); +/* writing WCS will cause an explicit watchdog refresh */ +sbsa_gwdt_cf_write (SBSA_GWDT_WCS ,0 , wdd); + +pr_debug ("sbsa_gwdt: WCS is %x(%s)\n" , +sbsa_gwdt_cf_read (SBSA_GWDT_WCS , wdd), __func__); + +return 0 ; +} + +static int sbsa_gwdt_keepalive (struct watchdog_device *wdd) +{ +/* +* Writing WRR for an explicit watchdog refresh +* You can write anyting(like 0xc0ffee) +*/ +sbsa_gwdt_rf_write (SBSA_GWDT_WRR ,0xc0ffee , wdd); + +reload_timeout_to_wcv (wdd); + + pr_debug("sbsa_gwdt: ping, %us left.\n",
sbsa_gwdt_get_timeleft(wdd));drivers/watchdog/sbsa_gwdt.c new file +50
-0+ +return 0 ; +} + +static irqreturn_t sbsa_gwdt_interrupt (int irq,void *dev_id) +{ +struct sbsa_gwdt *gwdt = (struct sbsa_gwdt *)dev_id; +struct watchdog_device *wdd = &gwdt->wdd; +u32 status; + + status =sbsa_gwdt_cf_read (SBSA_GWDT_WCS , wdd); + +pr_debug ("sbsa_gwdt: interrupt routine, WCS@%x\n" , status); + +if (status &SBSA_GWDT_WCS_WS0 ) { +pr_debug ("sbsa_gwdt WS0: trigger WS1 in %ds!\n" , +sbsa_gwdt_get_timeleft (wdd)); +panic ("SBSA Watchdog pre-timeout" ); + } + +return IRQ_HANDLED ; +} + +static struct watchdog_info sbsa_gwdt_info = { + .identity ="SBSA Generic Watchdog" , + .options =WDIOF_SETTIMEOUT | +WDIOF_KEEPALIVEPING | +WDIOF_MAGICCLOSE | +WDIOF_PRETIMEOUT | +WDIOF_CARDRESET , +}; + +static struct watchdog_ops sbsa_gwdt_ops = { + .owner =THIS_MODULE , + .start = sbsa_gwdt_start, + .stop = sbsa_gwdt_stop, + .ping = sbsa_gwdt_keepalive, + .set_timeout = sbsa_gwdt_set_timeout, + .set_pretimeout = sbsa_gwdt_set_pretimeout, + .get_timeleft = sbsa_gwdt_get_timeleft, +}; + +static int sbsa_gwdt_probe (struct platform_device *pdev) +{ +struct device *dev = &pdev->dev; + +struct sbsa_gwdt *gwdt; +struct watchdog_device *wdd; + +struct resource *res;
Quoted 8 lines
drivers/watchdog/sbsa_gwdt.c line 355
Quoted 5 lines
drivers/watchdog/sbsa_gwdt.c new file +5
-0+void *rf_base, *cf_base; +int irq; +u32 clk, status, w_iidr; + +int ret =0 ;Please drop the empty lines above.
OK, np, done :-)
Quoted 19 lines
Quoted 19 lines
drivers/watchdog/sbsa_gwdt.c new file +15
-0+ +/* +* Try to determine the frequency from the cp15 interface +*/ + clk =arch_timer_get_cntfrq (); +if (!clk) { +dev_err (dev,"System Counter frequency not available\n" ); +return -EINVAL ; + } + + gwdt =devm_kzalloc (dev,sizeof (*gwdt),GFP_KERNEL ); +if (!gwdt) +return -ENOMEM ; + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM,"refresh");
drivers/watchdog/sbsa_gwdt.c new file +2
-0+ rf_base =devm_ioremap_resource (dev, res); +if (IS_ERR (rf_base))
Quoted 8 lines
drivers/watchdog/sbsa_gwdt.c line 377
Quoted 5 lines
drivers/watchdog/sbsa_gwdt.c new file +5
-0+return PTR_ERR (rf_base); + +pr_debug ("sbsa_gwdt: ioremap %s frame 0x%llx(size: %llu)-->%p.\n" , + res->name, (unsigned long long )res->start, + (unsigned long long )(res->end - res->start +1 ), rf_base);If you think you need to keep those messages, please at least use %pR.
thanks for your suggestion, but I will remove it
Quoted 40 lines
Quoted 40 lines
drivers/watchdog/sbsa_gwdt.c new file +2
-0+ + res = platform_get_resource_byname(pdev, IORESOURCE_MEM,"control");
drivers/watchdog/sbsa_gwdt.c new file +25
-0+ cf_base =devm_ioremap_resource (dev, res); +if (IS_ERR (rf_base)) +return PTR_ERR (rf_base); + +pr_debug ("sbsa_gwdt: ioremap %s frame 0x%llx(size: %llu)-->%p.\n" , + res->name, (unsigned long long )res->start, + (unsigned long long )(res->end - res->start +1 ), cf_base); + + irq =platform_get_irq_byname (pdev,"ws0" ); +if (irq <0 ) { +dev_err (dev,"unable to get ws0 interrupt.\n" ); +return irq; + } + +pr_debug ("sbsa_gwdt: ws0 irq %d.\n" , irq); + + gwdt->refresh_base = rf_base; + gwdt->control_base = cf_base; + gwdt->clk = clk; +#ifdef CONFIG_PM_SLEEP +spin_lock_init (&gwdt->lock); +#endif +platform_set_drvdata (pdev, gwdt); + + pr_debug("sbsa_gwdt: hw clk: %uHz--> WOR(32bit) max timeout is%us.\n",
drivers/watchdog/sbsa_gwdt.c new file +9
-0+ gwdt->clk, U32_MAX / clk); + + 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); +
Quoted 8 lines
Quoted 4 lines
drivers/watchdog/sbsa_gwdt.c new file +3
-0+ status =sbsa_gwdt_cf_read (SBSA_GWDT_WCS , wdd); +if (status &SBSA_GWDT_WCS_WS1 ) { + dev_warn(dev, "System was reseted by WDT(WCS: %x, WCV:%llx)\n",
"was reseted" is kind of odd. Can you use just "reset" or maybe "restarted" ?
yes, will do , thanks
Quoted 37 lines
Quoted 20 lines
drivers/watchdog/sbsa_gwdt.c new file +19
-0+ status, sbsa_gwdt_get_wcv(wdd)); + wdd->bootstatus |=WDIOF_CARDRESET ; + } +/* Check if watchdog is already enabled */ +if (status &SBSA_GWDT_WCS_EN ) { +dev_warn (dev,"already enabled!\n" ); +sbsa_gwdt_keepalive (wdd); + } + +pr_debug ("sbsa_gwdt: WCS: %x(%s)\n" , status, __func__); + + wdd->min_pretimeout =0 ; + wdd->max_pretimeout =min (U32_MAX / clk, max_timeout -1 ); +sbsa_gwdt_set_timeout_limits (gwdt); + +watchdog_init_pretimeout (wdd, pretimeout, dev); +if (!wdd->pretimeout) { + wdd->pretimeout =DEFAULT_PRETIMEOUT ; + dev_info(dev, "can't get pretimeout param, set defaultQuoted 2 lines
%us.\n",
+wdd->pretimeout);Unnecessary message. The pretimeout is printed again below.
Quoted 9 lines
drivers/watchdog/sbsa_gwdt.c new file +7
-0+ } +sbsa_gwdt_set_pretimeout (wdd, wdd->pretimeout); + +watchdog_init_timeout (wdd, timeout, dev); +if (!wdd->timeout) { + wdd->timeout = wdd->pretimeout +DEFAULT_TIMEOUT_WS0 ; + dev_info(dev, "can't get timeout param, set default:%us.\n",
+wdd->timeout);
Quoted 2 lines
Same here.
yes, I have removed them.
Quoted 17 lines
Quoted 17 lines
drivers/watchdog/sbsa_gwdt.c new file +17
-0+ } +sbsa_gwdt_set_timeout (wdd, wdd->timeout); + + ret =devm_request_irq (dev, irq, sbsa_gwdt_interrupt,IRQF_TIMER , + pdev->name, gwdt); +if (ret) { +dev_err (dev,"unable to request IRQ %d\n" , irq); +return ret; + } + + ret =watchdog_register_device (wdd); +if (ret) +return ret; + +/* get device information from control frame and display */ + w_iidr =sbsa_gwdt_cf_read (SBSA_GWDT_W_IIDR , &gwdt->wdd); + dev_info(dev, "PID:%u(JEP106 %u-%u), Arch v%u Rev %u.",
Quoted 8 lines
drivers/watchdog/sbsa_gwdt.c line 466
Quoted 5 lines
drivers/watchdog/sbsa_gwdt.c new file +5
-0+SBSA_GWDT_W_IIDR_PID (w_iidr), +SBSA_GWDT_W_IIDR_VID_BANK (w_iidr), +SBSA_GWDT_W_IIDR_VID (w_iidr), +SBSA_GWDT_W_IIDR_ARCH_VER (w_iidr), + SBSA_GWDT_W_IIDR_REV(w_iidr));Is this valuable information ?
not too much value, just tell you the hw info, should I remove it?
Quoted 27 lines
Quoted 27 lines
drivers/watchdog/sbsa_gwdt.c new file +2
-0+ + dev_info(dev, "Initialized with %ds timeout, %ds pretimeout @%uHz\n",
drivers/watchdog/sbsa_gwdt.c new file +22
-0+ wdd->timeout, wdd->pretimeout, gwdt->clk); + +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); +int ret =0 ; + +if (!nowayout) + ret =sbsa_gwdt_stop (&gwdt->wdd); + +watchdog_unregister_device (&gwdt->wdd); +
Quoted 8 lines
drivers/watchdog/sbsa_gwdt.c line 494
Quoted 4 lines
drivers/watchdog/sbsa_gwdt.c new file +4
-0+return ret; +} + +#ifdef CONFIG_PM_SLEEP You don't need the #ifdef if you use
__maybe_unusedwith the function declarations.
yes, doing this way now
Quoted 29 lines
drivers/watchdog/sbsa_gwdt.c line 506
Quoted 13 lines
drivers/watchdog/sbsa_gwdt.c new file +12
-0+/* Disable watchdog if it is active during suspend */ +static int sbsa_gwdt_suspend (struct device *dev) +{ +struct sbsa_gwdt *gwdt =dev_get_drvdata (dev); +struct watchdog_device *wdd = &gwdt->wdd; + +spin_lock (&gwdt->lock); + gwdt->pm_status_store =sbsa_gwdt_cf_read (SBSA_GWDT_WCS , wdd); + +if (gwdt->pm_status_store &SBSA_GWDT_WCS_EN ) +sbsa_gwdt_stop (wdd); +spin_unlock (&gwdt->lock);Wonder what this lock is protecting against. Can you explain ? I would assume that suspend and resume are mutually exclusive and don't require locking against each other.
Quoted 10 lines
drivers/watchdog/sbsa_gwdt.c new file +10
-0+ +return 0 ; +} + +/* Enable watchdog and configure it if necessary */ +static int sbsa_gwdt_resume (struct device *dev) +{ +struct sbsa_gwdt *gwdt =dev_get_drvdata (dev); +struct watchdog_device *wdd = &gwdt->wdd; +
Quoted 8 lines
drivers/watchdog/sbsa_gwdt.c line 521
Quoted 5 lines
drivers/watchdog/sbsa_gwdt.c new file +5
-0+spin_lock (&gwdt->lock); +if (gwdt->pm_status_store &SBSA_GWDT_WCS_EN ) +sbsa_gwdt_start (wdd); +else +sbsa_gwdt_stop (wdd);What is the stop here for ?
Thanks , I have improved this part. :-)
Quoted 36 lines
Quoted 35 lines
drivers/watchdog/sbsa_gwdt.c new file +32
-0+spin_unlock (&gwdt->lock); + + return 0; +} +#endif + +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 dev_pm_ops sbsa_gwdt_pm_ops = { +SET_SYSTEM_SLEEP_PM_OPS (sbsa_gwdt_suspend, sbsa_gwdt_resume) +}; + +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, +}; + +module_platform_driver (sbsa_gwdt_driver); + +MODULE_DESCRIPTION ("SBSA Generic Watchdog Driver" ); +MODULE_AUTHOR ("Fu Wei <[email protected]>" ); +MODULE_LICENSE ("GPL v2" );
Signature · 14 lines
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 -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 6/6 ACPI: import watchdog info of GTDT into platform device
In reply to [email protected]From: Fu Wei <[email protected]>
Parse SBSA Generic Watchdog Structure in GTDT table of ACPI, and create a platform device with that information
This platform device can be used by the ARM SBSA Generic Watchdog driver
--- arch/arm64/kernel/acpi.c | 136 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+)
arch/arm64/kernel/acpi.c +136 -0
@@ -23,6 +23,7 @@#include <linux/irqdomain.h> #include <linux/memblock.h> #include <linux/of_fdt.h> +#include <linux/platform_device.h> #include <linux/smp.h> #include <asm/cputype.h>
@@ -343,3 +344,138 @@ void __init acpi_gic_init(void)early_acpi_os_unmap_memory ((char *)table, tbl_size); } + +static int __init acpi_gtdt_import_sbsa_gwdt (struct acpi_gtdt_watchdog *wd, +int index) +{ +struct platform_device *pdev; +struct resource *res; +u32 gsi, flags; +int irq, trigger, polarity; +resource_size_t rf_base_phy, cf_base_phy; +int err = -ENOMEM ; + +/* +* Get SBSA Generic Watchdog info +* from a Watchdog GT type structure in GTDT +*/ + rf_base_phy = (resource_size_t )wd->refresh_frame_address; + cf_base_phy = (resource_size_t )wd->control_frame_address; + gsi = wd->timer_interrupt; + flags = wd->timer_flags; + +pr_info ("GTDT: a Watchdog GT structure(0x%llx/0x%llx gsi:%u flags:0x%x)\n" , + rf_base_phy, cf_base_phy, gsi, flags); + +if (!(rf_base_phy && cf_base_phy && gsi)) { +pr_err ("GTDT: failed geting the device info.\n" ); +return -EINVAL ; + } + + trigger = (flags &ACPI_GTDT_INTERRUPT_MODE ) ?ACPI_EDGE_SENSITIVE + :ACPI_LEVEL_SENSITIVE ; + polarity = (flags &ACPI_GTDT_INTERRUPT_POLARITY ) ?ACPI_ACTIVE_LOW + :ACPI_ACTIVE_HIGH ; + irq =acpi_register_gsi (NULL , gsi, trigger, polarity); +if (irq <0 ) { +pr_err ("GTDT: failed to register GSI of the Watchdog GT.\n" ); +return -EINVAL ; + } + + pdev =platform_device_alloc ("sbsa-gwdt" , index); +if (!pdev) + goto err_unregister_gsi; + + res =kcalloc (3 ,sizeof (*res),GFP_KERNEL ); +if (!res) + goto err_device_put; + + res[0 ].start = rf_base_phy; + res[0 ].end = rf_base_phy +SZ_4K -1 ; + res[0 ].name ="refresh" ; + res[0 ].flags =IORESOURCE_MEM ; + + res[1 ].start = cf_base_phy; + res[1 ].end = cf_base_phy +SZ_4K -1 ; + res[1 ].name ="control" ; + res[1 ].flags =IORESOURCE_MEM ; + + res[2 ].start = irq; + res[2 ].end = res[2 ].start; + res[2 ].name ="ws0" ; + res[2 ].flags =IORESOURCE_IRQ ; + + err =platform_device_add_resources (pdev, res,3 ); +if (err) + goto err_free_res; + + err =platform_device_add (pdev); +if (err) + goto err_free_res; + +return 0 ; + +err_free_res: +kfree (res); +err_device_put: +platform_device_put (pdev); +err_unregister_gsi: +acpi_unregister_gsi (gsi); + +return err; +} + +/* Initialize SBSA generic Watchdog platform device info from GTDT */ +static int __init acpi_gtdt_sbsa_gwdt_init (struct acpi_table_header *table) +{ +struct acpi_table_gtdt *gtdt; +struct acpi_gtdt_header *header; +void *gtdt_subtable; +int i, gwdt_index; +int ret =0 ; + +if (table->revision <2 ) { +pr_info ("GTDT: Revision:%d doesn't support Platform Timers.\n" , + table->revision); +return 0 ; + } + + gtdt = container_of(table, struct acpi_table_gtdt, header); +if (!gtdt->platform_timer_count) { +pr_info ("GTDT: No Platform Timer structures.\n" ); +return 0 ; + } + + gtdt_subtable = (void *)gtdt + gtdt->platform_timer_offset; + +for (i =0 , gwdt_index =0 ; i < gtdt->platform_timer_count; i++) { +if (gtdt_subtable > (void *)table + table->length) { +pr_err ("GTDT: subtable pointer overflows, bad table\n" ); +return -EINVAL ; + } + header = (struct acpi_gtdt_header *)gtdt_subtable; +if (header->type ==ACPI_GTDT_TYPE_WATCHDOG ) { + ret =acpi_gtdt_import_sbsa_gwdt (gtdt_subtable, + gwdt_index); +if (ret) +pr_err ("GTDT: failed to import subtable %d\n" , + i); +else + gwdt_index++; + } + gtdt_subtable += header->length; + } + +return ret; +} + +/* Initialize the SBSA Generic Watchdog presented in GTDT */ +static int __init acpi_gtdt_init (void ) +{ +if (acpi_disabled) +return 0 ; + +return acpi_table_parse (ACPI_SIG_GTDT , acpi_gtdt_sbsa_gwdt_init); +} + +arch_initcall (acpi_gtdt_init);
Signature · 1 line
1.9.1
Guenter Roeck
maintainerRe: [PATCH 4/6] Watchdog: introdouce "pretimeout" into framework
In reply to [email protected]Quoted 21 lines · On 05/15/2015 04:24 AM, [email protected] wrote:
From: Fu Wei <[email protected]>
Reasons:
(1)kernel already has two watchdog drivers are using "pretimeout":
drivers/char/ipmi/ipmi_watchdog.cdrivers/watchdog/kempld_wdt.c(but the definition is different)
(2)some other dirvers are going to use this: ARM SBSA Generic WatchdogSigned-off-by Fu Wei <[email protected]>--- drivers/watchdog/watchdog_core.c | 66 ++++++++++++++++++++++++++++++++++++++++ drivers/watchdog/watchdog_dev.c | 48 +++++++++++++++++++++++++++++ include/linux/watchdog.h | 19 ++++++++++++ 3 files changed, 133 insertions(+)drivers/watchdog/watchdog_core.c +0
-0@@ -54,6 +54,14 @@ static void watchdog_check_min_max_timeout(struct watchdog_device *wdd) wdd->min_timeout =0 ;
drivers/watchdog/watchdog_core.c static void watchdog_check_min_max_timeout(struct watchdog_device *wdd) · line 64
Quoted 10 lines
drivers/watchdog/watchdog_core.c +8
-0wdd->max_timeout =0 ; } +if (wdd->min_pretimeout && wdd->min_timeout < wdd->min_pretimeout) { +pr_info ("Invalid min timeout, resetting to min pretimeout!\n" ); + wdd->min_timeout = wdd->min_pretimeout; + } +if (wdd->max_pretimeout && wdd->max_timeout < wdd->max_pretimeout) { +pr_info ("Invalid max timeout, resetting to max pretimeout!\n" ); + wdd->max_timeout = wdd->max_pretimeout; + }
I am a bit concerned about the context dependency introduced here. If someone calls _init_pretimeout after calling init_timeout, this may result in still invalid timeout values.
Quoted 23 lines
drivers/watchdog/watchdog_core.c +16
-0}/** @@ -98,6 +106,63 @@ int watchdog_init_timeout(struct watchdog_device *wdd, }EXPORT_SYMBOL_GPL (watchdog_init_timeout); +static void watchdog_check_min_max_pretimeout (struct watchdog_device *wdd) +{ +/* +* Check that we have valid min and max pretimeout values, if +* not reset them both to 0 (=not used or unknown) +*/ +if (wdd->min_pretimeout > wdd->max_pretimeout) { +pr_info ("Invalid min and max pretimeout, resetting to 0!\n" ); + wdd->min_pretimeout =0 ; + wdd->max_pretimeout =0 ; + } +} + +/** +* watchdog_init_pretimeout() - initialize the pretimeout field +* @pretimeout_parm: pretimeout module parameter
drivers/watchdog/watchdog_core.c int watchdog_init_timeout(struct watchdog_device *wdd, · line 134
Quoted 10 lines
drivers/watchdog/watchdog_core.c +10
-0+* @dev: Device that stores the timeout-sec property +* +* Initialize the pretimeout field of the watchdog_device struct with either +* the pretimeout module parameter (if it is valid value) or the timeout-sec +* property (only if it is a valid value and the timeout_parm is out of bounds). +* If none of them are valid then we keep the old value (which should normally +* be the default pretimeout value. +* +* A zero is returned on success and -EINVAL for failure. +*/
The new API function also needs to be documented in Documentation/watchdog/watchdog-kernel-api.txt.
Quoted 13 lines
drivers/watchdog/watchdog_core.c +13
-0+int watchdog_init_pretimeout (struct watchdog_device *wdd, +unsigned int pretimeout_parm,struct device *dev) +{ +int ret =0 ; +u32 timeouts[2 ]; + +watchdog_check_min_max_pretimeout (wdd); + +/* try to get the timeout module parameter first */ +if (!watchdog_pretimeout_invalid (wdd, pretimeout_parm) && + pretimeout_parm) { + wdd->pretimeout = pretimeout_parm; +return ret;
drivers/watchdog/watchdog_core.c int watchdog_init_timeout(struct watchdog_device *wdd, · line 157
Quoted 10 lines
drivers/watchdog/watchdog_core.c +10
-0+ } +if (pretimeout_parm) + ret = -EINVAL ; + +/* try to get the timeout_sec property */ +if (!dev || !dev->of_node) +return ret; + ret =of_property_read_u32_array (dev->of_node, +"timeout-sec" , timeouts,2 ); +if (!watchdog_pretimeout_invalid (wdd, timeouts[1 ]) && timeouts[1 ])
Guess we are still waiting for feedback from the devicetree maintainers on this.
Both the above synchronization concern and this makes me wonder if we should introduce watchdog_init_timeouts() instead, which would take pretimeout as additional parameter. What do you think about that ?
Quoted 64 lines
drivers/watchdog/watchdog_core.c +9
-0+ wdd->pretimeout = timeouts[1 ]; + else + ret = -EINVAL ; + +return ret; +} +EXPORT_SYMBOL_GPL (watchdog_init_pretimeout); +/** * watchdog_register_device() - register a watchdog device * @wdd: watchdog device @@ -119,6 +184,7 @@ int watchdog_register_device(struct watchdog_device *wdd)if (wdd->ops->start ==NULL || wdd->ops->stop ==NULL )return -EINVAL ; +watchdog_check_min_max_pretimeout (wdd);watchdog_check_min_max_timeout (wdd);/* drivers/watchdog/watchdog_dev.c +32
-0@@ -218,6 +218,38 @@ out_timeout: }/* +* watchdog_set_pretimeout: set the watchdog timer pretimeout +* @wddev: the watchdog device to set the timeout for +* @pretimeout: pretimeout to set in seconds +*/ + +static int watchdog_set_pretimeout (struct watchdog_device *wddev, +unsigned int pretimeout) +{ +int err; + +if (!wddev->ops->set_pretimeout || + !(wddev->info->options &WDIOF_PRETIMEOUT )) +return -EOPNOTSUPP ; + +if (watchdog_pretimeout_invalid (wddev, pretimeout)) +return -EINVAL ; + +mutex_lock (&wddev->lock); + +if (test_bit (WDOG_UNREGISTERED , &wddev->status)) { + err = -ENODEV ; + goto out_pretimeout; + } + + err = wddev->ops->set_pretimeout (wddev, pretimeout); + +out_pretimeout: +mutex_unlock (&wddev->lock); +return err; +} + +/* * watchdog_get_timeleft: wrapper to get the time left before a reboot * @wddev: the watchdog device to get the remaining time from * @timeleft: the time that's left @@ -388,6 +420,22 @@ static long watchdog_ioctl(struct file *file, unsigned int cmd,if (wdd->timeout ==0 )
drivers/watchdog/watchdog_dev.c static long watchdog_ioctl(struct file *file, unsigned int cmd, · line 430
Quoted 10 lines
drivers/watchdog/watchdog_dev.c +8
-0return -EOPNOTSUPP ;return put_user (wdd->timeout, p); +case WDIOC_SETPRETIMEOUT : +if (get_user (val, p)) +return -EFAULT ; + err =watchdog_set_pretimeout (wdd, val); +if (err <0 ) +return err; +/* If the watchdog is active then we send a keepalive ping +* to make sure that the watchdog keep's running (and if
s/keep's/keeps/
drivers/watchdog/watchdog_dev.c static long watchdog_ioctl(struct file *file, unsigned int cmd, · line 431
Quoted 1 line
drivers/watchdog/watchdog_dev.c +1
-0+* possible that it takes the new timeout) */
Please use the common multi-line comment style (that it isn't used above is not an argument).
Quoted 66 lines
drivers/watchdog/watchdog_dev.c +7
-0+watchdog_ping (wdd); +/* Fall */ +case WDIOC_GETPRETIMEOUT : +/* timeout == 0 means that we don't use the pretimeout */ +if (wdd->pretimeout ==0 ) +return -EOPNOTSUPP ; +return put_user (wdd->pretimeout, p);case WDIOC_GETTIMELEFT : err =watchdog_get_timeleft (wdd, &val);if (err)include/linux/watchdog.h +16
-0@@ -25,6 +25,7 @@ struct watchdog_device;* @ping: The routine that sends a keepalive ping to the watchdog device. * @status: The routine that shows the status of the watchdog device. * @set_timeout:The routine for setting the watchdog devices timeout value. +* @set_pretimeout:The routine for setting the watchdog devices pretimeout value * @get_timeleft:The routine that get's the time that's left before a reset. * @ref: The ref operation for dyn. allocated watchdog_device structs * @unref: The unref operation for dyn. allocated watchdog_device structs @@ -44,6 +45,7 @@ struct watchdog_ops {int (*ping)(struct watchdog_device *);unsigned int (*status)(struct watchdog_device *);int (*set_timeout)(struct watchdog_device *,unsigned int ); +int (*set_pretimeout)(struct watchdog_device *,unsigned int );unsigned int (*get_timeleft)(struct watchdog_device *);void (*ref)(struct watchdog_device *);void (*unref)(struct watchdog_device *);@@ -62,6 +64,9 @@ struct watchdog_ops {* @timeout: The watchdog devices timeout value. * @min_timeout:The watchdog devices minimum timeout value. * @max_timeout:The watchdog devices maximum timeout value. +* @pretimeout: The watchdog devices pretimeout value. +* @min_pretimeout:The watchdog devices minimum pretimeout value. +* @max_pretimeout:The watchdog devices maximum pretimeout value. * @driver-data:Pointer to the drivers private data. * @lock: Lock for watchdog core internal use only. * @status: Field that contains the devices internal status bits. @@ -86,6 +91,9 @@ struct watchdog_device {unsigned int timeout;unsigned int min_timeout;unsigned int max_timeout; +unsigned int pretimeout; +unsigned int min_pretimeout; +unsigned int max_pretimeout;void *driver_data;struct mutex lock;unsigned long status;@@ -120,6 +128,14 @@ static inline bool watchdog_timeout_invalid(struct watchdog_device *wdd, unsigne (t < wdd->min_timeout || t > wdd->max_timeout)); } +/* Use the following function to check if a pretimeout value is invalid */ +static inline bool watchdog_pretimeout_invalid (struct watchdog_device *wdd, +unsigned int t) +{ +return ((wdd->max_pretimeout !=0 ) && + (t < wdd->min_pretimeout || t > wdd->max_pretimeout)); +} +/* Use the following functions to manipulate watchdog driver specific data */ static inline void watchdog_set_drvdata (struct watchdog_device *wdd,void *data) {
include/linux/watchdog.h static inline void *watchdog_get_drvdata(struct watchdog_device *wdd) · line 155
Quoted 6 lines
include/linux/watchdog.h +3
-0@@ -134,6 +150,9 @@ static inline void *watchdog_get_drvdata(struct watchdog_device *wdd)/* drivers/watchdog/watchdog_core.c */ extern int watchdog_init_timeout (struct watchdog_device *wdd,unsigned int timeout_parm,struct device *dev); +extern int watchdog_init_pretimeout (struct watchdog_device *wdd, +unsigned int pretimeout_parm, +struct device *dev);
Please drop the 'extern'. Guess it may be time to clean up the watchdog core code ;-).
Thanks,
Guenter
Re: [PATCH 4/6] Watchdog: introdouce "pretimeout" into framework
Hi Guenter,
Great thanks for your review,
feedback inline below :-)
Quoted 39 lines · Guenter Roeck
Quoted 38 lines · On 05/15/2015 04:24 AM, [email protected] wrote:
From: Fu Wei <[email protected]>
Reasons:
(1)kernel already has two watchdog drivers are using "pretimeout":
drivers/char/ipmi/ipmi_watchdog.cdrivers/watchdog/kempld_wdt.c(but the definition is different)
(2)some other dirvers are going to use this: ARM SBSA Generic WatchdogSigned-off-by Fu Wei <[email protected]>--- drivers/watchdog/watchdog_core.c | 66 ++++++++++++++++++++++++++++++++++++++++ drivers/watchdog/watchdog_dev.c | 48 +++++++++++++++++++++++++++++ include/linux/watchdog.h | 19 ++++++++++++ 3 files changed, 133 insertions(+)drivers/watchdog/watchdog_core.c +5
-0@@ -54,6 +54,14 @@ static void watchdog_check_min_max_timeout(struct watchdog_device *wdd) wdd->min_timeout = 0; wdd->max_timeout =0 ; } +if (wdd->min_pretimeout && wdd->min_timeout < wdd->min_pretimeout) { +pr_info ("Invalid min timeout, resetting to min pretimeout!\n"); + wdd->min_timeout = wdd->min_pretimeout; + } +if (wdd->max_pretimeout && wdd->max_timeout < wdd->max_pretimeout){
+ pr_info("Invalid max timeout, resetting to max
pretimeout!\n");
+wdd->max_timeout=wdd->max_pretimeout;
Quoted 8 lines
Quoted 1 line
+ }
I am a bit concerned about the context dependency introduced here. If someone calls
_init_pretimeoutafter callinginit_timeout, this may result in still invalid timeout
values.
yes, that logic is not very clean, so my thought is :
maybe we can integrate watchdog_init_timeout and watchdog_init_pretimeout, if maintainer agree to add pretimeout into framework.
Quoted 37 lines
Quoted 37 lines
}/**
drivers/watchdog/watchdog_core.c +19
-0@@ -98,6 +106,63 @@ int watchdog_init_timeout(struct watchdog_device *wdd, }EXPORT_SYMBOL_GPL (watchdog_init_timeout); +static void watchdog_check_min_max_pretimeout (struct watchdog_device *wdd) +{ +/* +* Check that we have valid min and max pretimeout values, if +* not reset them both to 0 (=not used or unknown) +*/ +if (wdd->min_pretimeout > wdd->max_pretimeout) { +pr_info ("Invalid min and max pretimeout, resetting to 0!\n"); + wdd->min_pretimeout =0 ; + wdd->max_pretimeout =0 ; + } +} + +/** +* watchdog_init_pretimeout() - initialize the pretimeout field +* @pretimeout_parm: pretimeout module parameter +* @dev: Device that stores the timeout-sec property +* +* Initialize the pretimeout field of the watchdog_device struct with either
+ * the pretimeout module parameter (if it is valid value) or the timeout-sec
+ * property (only if it is a valid value and thetimeout_parmis out of bounds).
+ * If none of them are valid then we keep the old value (which should normally
Quoted 8 lines
Quoted 4 lines
+ * be the default pretimeout value.
+ *
+ * A zero is returned on success and-EINVALfor failure.
+ */The new API function also needs to be documented in
Documentation/watchdog/watchdog-kernel-api.txt.
good point, thanks will do
Quoted 21 lines
Quoted 21 lines
drivers/watchdog/watchdog_core.c +2
-0+int watchdog_init_pretimeout (struct watchdog_device *wdd, + unsigned int pretimeout_parm, struct device*dev)
drivers/watchdog/watchdog_core.c +17
-0+{ +int ret =0 ; +u32 timeouts[2 ]; + +watchdog_check_min_max_pretimeout (wdd); + +/* try to get the timeout module parameter first */ +if (!watchdog_pretimeout_invalid (wdd, pretimeout_parm) && + pretimeout_parm) { + wdd->pretimeout = pretimeout_parm; +return ret; + } +if (pretimeout_parm) + ret = -EINVAL ; + +/* try to get the timeout_sec property */ +if (!dev || !dev->of_node)
Quoted 8 lines
drivers/watchdog/watchdog_core.c int watchdog_init_timeout(struct watchdog_device *wdd, · line 157
Quoted 4 lines
drivers/watchdog/watchdog_core.c +4
-0+return ret; + ret =of_property_read_u32_array (dev->of_node, +"timeout-sec" , timeouts,2 ); +if (!watchdog_pretimeout_invalid (wdd, timeouts[1 ]) && timeouts[1 ])Guess we are still waiting for feedback from the devicetree maintainers on this.
yes!
Quoted 6 lines
Both the above synchronization concern and this makes me wonder if we should introduce
watchdog_init_timeouts()instead, which would take pretimeout as additional parameter.
What do you think about that ?
yes, that is what I am thinking about
Quoted 75 lines
Quoted 75 lines
drivers/watchdog/watchdog_core.c +9
-0+ wdd->pretimeout = timeouts[1 ]; + else + ret = -EINVAL ; + +return ret; +} +EXPORT_SYMBOL_GPL (watchdog_init_pretimeout); +/** * watchdog_register_device() - register a watchdog device * @wdd: watchdog device @@ -119,6 +184,7 @@ int watchdog_register_device(struct watchdog_device *wdd)if (wdd->ops->start ==NULL || wdd->ops->stop ==NULL )return -EINVAL ; +watchdog_check_min_max_pretimeout (wdd);watchdog_check_min_max_timeout (wdd);/*drivers/watchdog/watchdog_dev.c +32
-0@@ -218,6 +218,38 @@ out_timeout: }/* +* watchdog_set_pretimeout: set the watchdog timer pretimeout +* @wddev: the watchdog device to set the timeout for +* @pretimeout: pretimeout to set in seconds +*/ + +static int watchdog_set_pretimeout (struct watchdog_device *wddev, +unsigned int pretimeout) +{ +int err; + +if (!wddev->ops->set_pretimeout || + !(wddev->info->options &WDIOF_PRETIMEOUT )) +return -EOPNOTSUPP ; + +if (watchdog_pretimeout_invalid (wddev, pretimeout)) +return -EINVAL ; + +mutex_lock (&wddev->lock); + +if (test_bit (WDOG_UNREGISTERED , &wddev->status)) { + err = -ENODEV ; + goto out_pretimeout; + } + + err = wddev->ops->set_pretimeout (wddev, pretimeout); + +out_pretimeout: +mutex_unlock (&wddev->lock); +return err; +} + +/* * watchdog_get_timeleft: wrapper to get the time left before a reboot
* @wddev: the watchdog device to get the remaining time from
* @timeleft: the time that's leftdrivers/watchdog/watchdog_dev.c +3
-0@@ -388,6 +420,22 @@ static long watchdog_ioctl(struct file *file, unsigned int cmd, if (wdd->timeout == 0) return -EOPNOTSUPP;return put_user (wdd->timeout, p); +case WDIOC_SETPRETIMEOUT : +if (get_user (val, p)) +return -EFAULT ;
Quoted 8 lines
drivers/watchdog/watchdog_dev.c static long watchdog_ioctl(struct file *file, unsigned int cmd, · line 430
Quoted 5 lines
drivers/watchdog/watchdog_dev.c +5
-0+ err =watchdog_set_pretimeout (wdd, val); +if (err <0 ) +return err; +/* If the watchdog is active then we send a keepalive ping +* to make sure that the watchdog keep's running (and if s/keep's/keeps/
Great thanks, typo
Quoted 7 lines
drivers/watchdog/watchdog_dev.c static long watchdog_ioctl(struct file *file, unsigned int cmd, · line 431
Quoted 2 lines
drivers/watchdog/watchdog_dev.c +1
-0+* possible that it takes the new timeout) */ Please use the common multi-line comment style (that it isn't used above is not
an argument).
yes, my bad, will fixed .
Quoted 83 lines
Quoted 83 lines
drivers/watchdog/watchdog_dev.c +7
-0+watchdog_ping (wdd); +/* Fall */ +case WDIOC_GETPRETIMEOUT : +/* timeout == 0 means that we don't use the pretimeout */ +if (wdd->pretimeout ==0 ) +return -EOPNOTSUPP ; +return put_user (wdd->pretimeout, p);case WDIOC_GETTIMELEFT : err =watchdog_get_timeleft (wdd, &val);if (err)
include/linux/watchdog.h +0
-0@@ -25,6 +25,7 @@ struct watchdog_device;* @ping: The routine that sends a keepalive ping to the watchdog device.
* @status: The routine that shows the status of the watchdog device.
* @set_timeout:The routine for setting the watchdog devices timeout
value.
+ * @set_pretimeout:The routine for setting the watchdog devices pretimeout value
* @get_timeleft:The routine that get's the time that's left before a
reset.
* @ref: The ref operation for dyn. allocatedwatchdog_device
structs
* @unref: The unref operation for dyn. allocatedwatchdog_device
structsinclude/linux/watchdog.h +7
-0@@ -44,6 +45,7 @@ struct watchdog_ops {int (*ping)(struct watchdog_device *);unsigned int (*status)(struct watchdog_device *);int (*set_timeout)(struct watchdog_device *,unsigned int ); +int (*set_pretimeout)(struct watchdog_device *,unsigned int );unsigned int (*get_timeleft)(struct watchdog_device *);void (*ref)(struct watchdog_device *);void (*unref)(struct watchdog_device *);@@ -62,6 +64,9 @@ struct watchdog_ops {* @timeout: The watchdog devices timeout value. * @min_timeout:The watchdog devices minimum timeout value. * @max_timeout:The watchdog devices maximum timeout value. +* @pretimeout: The watchdog devices pretimeout value. +* @min_pretimeout:The watchdog devices minimum pretimeout value. +* @max_pretimeout:The watchdog devices maximum pretimeout value. * @driver-data:Pointer to the drivers private data. * @lock: Lock for watchdog core internal use only. * @status: Field that contains the devices internal status bits. @@ -86,6 +91,9 @@ struct watchdog_device {unsigned int timeout;unsigned int min_timeout;unsigned int max_timeout; +unsigned int pretimeout; +unsigned int min_pretimeout; +unsigned int max_pretimeout;void *driver_data;struct mutex lock;unsigned long status;@@ -120,6 +128,14 @@ static inline bool watchdog_timeout_invalid(struct
watchdog_device*wdd, unsigne(t < wdd->min_timeout || t > wdd->max_timeout));}
+/* Use the following function to check if a pretimeout value is invalid */
+static inline bool watchdog_pretimeout_invalid(structwatchdog_device*wdd,include/linux/watchdog.h +6
-0+ unsigned int t) +{ +return ((wdd->max_pretimeout !=0 ) && + (t < wdd->min_pretimeout || t > wdd->max_pretimeout)); +} +/* Use the following functions to manipulate watchdog driver specific data */
static inline void watchdog_set_drvdata(structwatchdog_device*wdd,
void *data)
{include/linux/watchdog.h +0
-0@@ -134,6 +150,9 @@ static inline void *watchdog_get_drvdata(struct watchdog_device *wdd)/* drivers/watchdog/watchdog_core.c */ extern int watchdog_init_timeout (struct watchdog_device *wdd, unsigned int timeout_parm, struct device
Quoted 8 lines
include/linux/watchdog.h static inline void *watchdog_get_drvdata(struct watchdog_device *wdd) · line 155
Quoted 4 lines
include/linux/watchdog.h +3
-0*dev); +extern int watchdog_init_pretimeout (struct watchdog_device *wdd, +unsigned int pretimeout_parm, +struct device *dev);Please drop the 'extern'. Guess it may be time to clean up the watchdog core code ;-).
yes, you are right, but in different patchset ??
Quoted 4 lines
Thanks,
Guenter
Signature · 10 lines
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
Re: [PATCH 4/6] Watchdog: introdouce "pretimeout" into framework
Quoted 3 lines · Fu Wei
Quoted 2 lines
Quoted 2 lines
The new API function also needs to be documented in
Documentation/watchdog/watchdog-kernel-api.txt.good point, thanks will do
Yes, please, since my driver does not use or need any pre-timeout support, so I don't understand why this patch exists. What is pre-timeout anyway?
Signature · 7 lines
Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation. -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Guenter Roeck
maintainerRe: [PATCH 4/6] Watchdog: introdouce "pretimeout" into framework
Quoted 7 lines · Timur Tabi
Quoted 3 lines · Fu Wei
Quoted 2 lines
Quoted 2 lines
The new API function also needs to be documented in
Documentation/watchdog/watchdog-kernel-api.txt.good point, thanks will do
Yes, please, since my driver does not use or need any pre-timeout support, so I don't understand why this patch exists. What is pre-timeout anyway?
Documentation/watchdog/watchdog-api.txt; look for "Pretimeouts:".
Guenter
Guenter Roeck
maintainerRe: [PATCH 4/6] Watchdog: introdouce "pretimeout" into framework
In reply to Fu WeiQuoted 6 lines · Fu Wei
Hi Guenter,
Great thanks for your review,
feedback inline below :-)On 15 May 2015 at 21:33, Guenter Roeck <[email protected]> wrote:
[ ... ]
Quoted 14 lines
Quoted 8 lines
drivers/watchdog/watchdog_core.c static void watchdog_check_min_max_timeout(struct watchdog_device *wdd) · line 64
Quoted 6 lines
+ if (
wdd->max_pretimeout&&wdd->max_timeout<wdd->max_pretimeout)
{
+ pr_info("Invalid max timeout, resetting to max
pretimeout!\n");drivers/watchdog/watchdog_core.c +2
-0+ wdd->max_timeout = wdd->max_pretimeout; + }Quoted 5 lines
I am a bit concerned about the context dependency introduced here. If someone calls
_init_pretimeoutafter callinginit_timeout, this may result in still invalid timeout
values.
Quoted 4 lines
yes, that logic is not very clean, so my thought is :
maybe we can integratewatchdog_init_timeoutandwatchdog_init_pretimeout, if maintainer agree to add pretimeout into framework.
I think we should just assume that Wim will accept it, and try to find the best possible solution (or at least a good one).
Guenter
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 4/6] Watchdog: introdouce "pretimeout" into framework
Hi Guenter,
yes, I think it is OK for me,
Once this patchset is merged, I will try to make a new patchset just for this integration.
Quoted 32 lines · Guenter Roeck
Quoted 6 lines · Fu Wei
Hi Guenter,
Great thanks for your review,
feedback inline below :-)On 15 May 2015 at 21:33, Guenter Roeck <[email protected]> wrote:
[ ... ]
Quoted 14 lines
Quoted 8 lines
drivers/watchdog/watchdog_core.c static void watchdog_check_min_max_timeout(struct watchdog_device *wdd) · line 64
Quoted 6 lines
+ if (
wdd->max_pretimeout&&wdd->max_timeout<wdd->max_pretimeout)
{
+ pr_info("Invalid max timeout, resetting to max
pretimeout!\n");drivers/watchdog/watchdog_core.c +2
-0+ wdd->max_timeout = wdd->max_pretimeout; + }Quoted 5 lines
I am a bit concerned about the context dependency introduced here. If someone calls
_init_pretimeoutafter callinginit_timeout, this may result in still invalid timeout
values.Quoted 4 lines
yes, that logic is not very clean, so my thought is :
maybe we can integratewatchdog_init_timeoutandwatchdog_init_pretimeout, if maintainer agree to add pretimeout into framework.I think we should just assume that Wim will accept it, and try to find the best possible solution (or at least a good one).
Guenter
Signature · 14 lines
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 -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 4/6] Watchdog: introdouce "pretimeout" into framework
In reply to [email protected]drivers/watchdog/watchdog_core.c int watchdog_init_timeout(struct watchdog_device *wdd, · line 120
Quoted 12 lines · On Friday 15 May 2015 19:24:48 [email protected] wrote:
drivers/watchdog/watchdog_core.c +12
-0+static void watchdog_check_min_max_pretimeout (struct watchdog_device *wdd) +{ +/* +* Check that we have valid min and max pretimeout values, if +* not reset them both to 0 (=not used or unknown) +*/ +if (wdd->min_pretimeout > wdd->max_pretimeout) { +pr_info ("Invalid min and max pretimeout, resetting to 0!\n" ); + wdd->min_pretimeout =0 ; + wdd->max_pretimeout =0 ; + } +}
I would probably just fold this function into the existing watchdog_check_min_max_timeout() and check both normal and pre-timeout there.
Quoted 33 lines
drivers/watchdog/watchdog_core.c +33
-0+/** +* watchdog_init_pretimeout() - initialize the pretimeout field +* @pretimeout_parm: pretimeout module parameter +* @dev: Device that stores the timeout-sec property +* +* Initialize the pretimeout field of the watchdog_device struct with either +* the pretimeout module parameter (if it is valid value) or the timeout-sec +* property (only if it is a valid value and the timeout_parm is out of bounds). +* If none of them are valid then we keep the old value (which should normally +* be the default pretimeout value. +* +* A zero is returned on success and -EINVAL for failure. +*/ +int watchdog_init_pretimeout (struct watchdog_device *wdd, +unsigned int pretimeout_parm,struct device *dev) +{ +int ret =0 ; +u32 timeouts[2 ]; + +watchdog_check_min_max_pretimeout (wdd); + +/* try to get the timeout module parameter first */ +if (!watchdog_pretimeout_invalid (wdd, pretimeout_parm) && + pretimeout_parm) { + wdd->pretimeout = pretimeout_parm; +return ret; + } +if (pretimeout_parm) + ret = -EINVAL ; + +/* try to get the timeout_sec property */ +if (!dev || !dev->of_node) +return ret;
drivers/watchdog/watchdog_core.c int watchdog_init_timeout(struct watchdog_device *wdd, · line 164
Quoted 10 lines
drivers/watchdog/watchdog_core.c +10
-0+ ret =of_property_read_u32_array (dev->of_node, +"timeout-sec" , timeouts,2 ); +if (!watchdog_pretimeout_invalid (wdd, timeouts[1 ]) && timeouts[1 ]) + wdd->pretimeout = timeouts[1 ]; +else + ret = -EINVAL ; + +return ret; +} +EXPORT_SYMBOL_GPL (watchdog_init_pretimeout);
Same here: the function is very similar to the watchdog_init_timeout function, and it reads the same property, so just do both here.
The easiest way for that is probably to use of_find_property() and of_prop_next_u32() to read the two numbers.
Arnd
Re: [PATCH 4/6] Watchdog: introdouce "pretimeout" into framework
Hi Arnd,
Great thanks for your suggestion :-)
feedback inline below
Quoted 17 lines · Arnd Bergmann
drivers/watchdog/watchdog_core.c int watchdog_init_timeout(struct watchdog_device *wdd, · line 120
Quoted 12 lines · On Friday 15 May 2015 19:24:48 [email protected]…
drivers/watchdog/watchdog_core.c +12
-0+static void watchdog_check_min_max_pretimeout (struct watchdog_device *wdd) +{ +/* +* Check that we have valid min and max pretimeout values, if +* not reset them both to 0 (=not used or unknown) +*/ +if (wdd->min_pretimeout > wdd->max_pretimeout) { +pr_info ("Invalid min and max pretimeout, resetting to 0!\n" ); + wdd->min_pretimeout =0 ; + wdd->max_pretimeout =0 ; + } +}I would probably just fold this function into the existing
watchdog_check_min_max_timeout()and check both normal and pre-timeout there.
yes, I can do that , and that is good idea
Quoted 48 lines
Quoted 34 lines
drivers/watchdog/watchdog_core.c +33
-0+/** +* watchdog_init_pretimeout() - initialize the pretimeout field +* @pretimeout_parm: pretimeout module parameter +* @dev: Device that stores the timeout-sec property +* +* Initialize the pretimeout field of the watchdog_device struct with either +* the pretimeout module parameter (if it is valid value) or the timeout-sec +* property (only if it is a valid value and the timeout_parm is out of bounds). +* If none of them are valid then we keep the old value (which should normally +* be the default pretimeout value. +* +* A zero is returned on success and -EINVAL for failure. +*/ +int watchdog_init_pretimeout (struct watchdog_device *wdd, +unsigned int pretimeout_parm,struct device *dev) +{ +int ret =0 ; +u32 timeouts[2 ]; + +watchdog_check_min_max_pretimeout (wdd); + +/* try to get the timeout module parameter first */ +if (!watchdog_pretimeout_invalid (wdd, pretimeout_parm) && + pretimeout_parm) { + wdd->pretimeout = pretimeout_parm; +return ret; + } +if (pretimeout_parm) + ret = -EINVAL ; + +/* try to get the timeout_sec property */ +if (!dev || !dev->of_node) +return ret;drivers/watchdog/watchdog_core.c int watchdog_init_timeout(struct watchdog_device *wdd, · line 164
Quoted 10 lines
drivers/watchdog/watchdog_core.c +10
-0+ ret =of_property_read_u32_array (dev->of_node, +"timeout-sec" , timeouts,2 ); +if (!watchdog_pretimeout_invalid (wdd, timeouts[1 ]) && timeouts[1 ]) + wdd->pretimeout = timeouts[1 ]; +else + ret = -EINVAL ; + +return ret; +} +EXPORT_SYMBOL_GPL (watchdog_init_pretimeout);Same here: the function is very similar to the
watchdog_init_timeoutfunction, and it reads the same property, so just do both here.
Quoted 2 lines
The easiest way for that is probably to use
of_find_property()andof_prop_next_u32()to read the two numbers.
integrate watchdog_init_pretimeout and watchdog_init_timeout will be a little hard,
we may need to change this API to :
watchdog_init_timeouts(struct watchdog_device *wdd, unsigned int timeout_parm,
unsigned int pretimeout_parm, struct device *dev)
then we need to update all the watchdog drivers which use this API, maybe we can do this in a individual patchset, after this pretimeout patch is merged.
Is that OK ? :-) any thought?
Quoted 3 lines
Arnd
Signature · 14 lines
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 -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Guenter Roeck
maintainerRe: [PATCH 4/6] Watchdog: introdouce "pretimeout" into framework
Quoted 82 lines · Fu Wei
Hi Arnd,
Great thanks for your suggestion :-)
feedback inline below
Quoted 17 lines · Arnd Bergmann
drivers/watchdog/watchdog_core.c int watchdog_init_timeout(struct watchdog_device *wdd, · line 120
Quoted 12 lines · On Friday 15 May 2015 19:24:48 [email protected] wrote:
drivers/watchdog/watchdog_core.c +12
-0+static void watchdog_check_min_max_pretimeout (struct watchdog_device *wdd) +{ +/* +* Check that we have valid min and max pretimeout values, if +* not reset them both to 0 (=not used or unknown) +*/ +if (wdd->min_pretimeout > wdd->max_pretimeout) { +pr_info ("Invalid min and max pretimeout, resetting to 0!\n" ); + wdd->min_pretimeout =0 ; + wdd->max_pretimeout =0 ; + } +}I would probably just fold this function into the existing
watchdog_check_min_max_timeout()and check both normal and pre-timeout there.yes, I can do that , and that is good idea
Quoted 48 lines
Quoted 34 lines
drivers/watchdog/watchdog_core.c +33
-0+/** +* watchdog_init_pretimeout() - initialize the pretimeout field +* @pretimeout_parm: pretimeout module parameter +* @dev: Device that stores the timeout-sec property +* +* Initialize the pretimeout field of the watchdog_device struct with either +* the pretimeout module parameter (if it is valid value) or the timeout-sec +* property (only if it is a valid value and the timeout_parm is out of bounds). +* If none of them are valid then we keep the old value (which should normally +* be the default pretimeout value. +* +* A zero is returned on success and -EINVAL for failure. +*/ +int watchdog_init_pretimeout (struct watchdog_device *wdd, +unsigned int pretimeout_parm,struct device *dev) +{ +int ret =0 ; +u32 timeouts[2 ]; + +watchdog_check_min_max_pretimeout (wdd); + +/* try to get the timeout module parameter first */ +if (!watchdog_pretimeout_invalid (wdd, pretimeout_parm) && + pretimeout_parm) { + wdd->pretimeout = pretimeout_parm; +return ret; + } +if (pretimeout_parm) + ret = -EINVAL ; + +/* try to get the timeout_sec property */ +if (!dev || !dev->of_node) +return ret;drivers/watchdog/watchdog_core.c int watchdog_init_timeout(struct watchdog_device *wdd, · line 164
Quoted 10 lines
drivers/watchdog/watchdog_core.c +10
-0+ ret =of_property_read_u32_array (dev->of_node, +"timeout-sec" , timeouts,2 ); +if (!watchdog_pretimeout_invalid (wdd, timeouts[1 ]) && timeouts[1 ]) + wdd->pretimeout = timeouts[1 ]; +else + ret = -EINVAL ; + +return ret; +} +EXPORT_SYMBOL_GPL (watchdog_init_pretimeout);Same here: the function is very similar to the
watchdog_init_timeoutfunction, and it reads the same property, so just do both here.Quoted 2 lines
The easiest way for that is probably to use
of_find_property()andof_prop_next_u32()to read the two numbers.integrate
watchdog_init_pretimeoutandwatchdog_init_timeoutwill be a little hard,
we may need to change this API to :
Quoted 9 lines
watchdog_init_timeouts(struct
watchdog_device*wdd, unsigned inttimeout_parm,
unsigned intpretimeout_parm, struct device *dev)then we need to update all the watchdog drivers which use this API, maybe we can do this in a individual patchset, after this pretimeout patch is merged.
Is that OK ? :-) any thought?
That is what I would recommend.
Guenter
Re: [PATCH 4/6] Watchdog: introdouce "pretimeout" into framework
Hi Guenter,
np, will do so :-)
Quoted 95 lines · Guenter Roeck
Quoted 82 lines · Fu Wei
Hi Arnd,
Great thanks for your suggestion :-)
feedback inline below
Quoted 17 lines · Arnd Bergmann
drivers/watchdog/watchdog_core.c int watchdog_init_timeout(struct watchdog_device *wdd, · line 120
Quoted 12 lines · On Friday 15 May 2015 19:24:48 [email protected] wrote:
drivers/watchdog/watchdog_core.c +12
-0+static void watchdog_check_min_max_pretimeout (struct watchdog_device *wdd) +{ +/* +* Check that we have valid min and max pretimeout values, if +* not reset them both to 0 (=not used or unknown) +*/ +if (wdd->min_pretimeout > wdd->max_pretimeout) { +pr_info ("Invalid min and max pretimeout, resetting to 0!\n" ); + wdd->min_pretimeout =0 ; + wdd->max_pretimeout =0 ; + } +}I would probably just fold this function into the existing
watchdog_check_min_max_timeout()and check both normal and pre-timeout there.yes, I can do that , and that is good idea
Quoted 48 lines
Quoted 34 lines
drivers/watchdog/watchdog_core.c +33
-0+/** +* watchdog_init_pretimeout() - initialize the pretimeout field +* @pretimeout_parm: pretimeout module parameter +* @dev: Device that stores the timeout-sec property +* +* Initialize the pretimeout field of the watchdog_device struct with either +* the pretimeout module parameter (if it is valid value) or the timeout-sec +* property (only if it is a valid value and the timeout_parm is out of bounds). +* If none of them are valid then we keep the old value (which should normally +* be the default pretimeout value. +* +* A zero is returned on success and -EINVAL for failure. +*/ +int watchdog_init_pretimeout (struct watchdog_device *wdd, +unsigned int pretimeout_parm,struct device *dev) +{ +int ret =0 ; +u32 timeouts[2 ]; + +watchdog_check_min_max_pretimeout (wdd); + +/* try to get the timeout module parameter first */ +if (!watchdog_pretimeout_invalid (wdd, pretimeout_parm) && + pretimeout_parm) { + wdd->pretimeout = pretimeout_parm; +return ret; + } +if (pretimeout_parm) + ret = -EINVAL ; + +/* try to get the timeout_sec property */ +if (!dev || !dev->of_node) +return ret;drivers/watchdog/watchdog_core.c int watchdog_init_timeout(struct watchdog_device *wdd, · line 164
Quoted 10 lines
drivers/watchdog/watchdog_core.c +10
-0+ ret =of_property_read_u32_array (dev->of_node, +"timeout-sec" , timeouts,2 ); +if (!watchdog_pretimeout_invalid (wdd, timeouts[1 ]) && timeouts[1 ]) + wdd->pretimeout = timeouts[1 ]; +else + ret = -EINVAL ; + +return ret; +} +EXPORT_SYMBOL_GPL (watchdog_init_pretimeout);Same here: the function is very similar to the
watchdog_init_timeoutfunction, and it reads the same property, so just do both here.Quoted 2 lines
The easiest way for that is probably to use
of_find_property()andof_prop_next_u32()to read the two numbers.integrate
watchdog_init_pretimeoutandwatchdog_init_timeoutwill be a little hard,
we may need to change this API to :Quoted 9 lines
watchdog_init_timeouts(struct
watchdog_device*wdd, unsigned inttimeout_parm,
unsigned intpretimeout_parm, struct device *dev)then we need to update all the watchdog drivers which use this API, maybe we can do this in a individual patchset, after this pretimeout patch is merged.
Is that OK ? :-) any thought?
That is what I would recommend.
Guenter
Signature · 10 lines
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
Re: [PATCH 4/6] Watchdog: introdouce "pretimeout" into framework
In reply to Guenter RoeckQuoted 8 lines · On Monday 18 May 2015 10:23:30 Guenter Roeck wrote:
Quoted 8 lines
integrate
watchdog_init_pretimeoutandwatchdog_init_timeoutwill be a little hard,
we may need to change this API to :watchdog_init_timeouts(struct
watchdog_device*wdd, unsigned inttimeout_parm,
unsigned intpretimeout_parm, struct device *dev)
Quoted 8 lines
Quoted 6 lines
then we need to update all the watchdog drivers which use this API, maybe we can do this in a individual patchset, after this pretimeout patch is merged.
Is that OK ? any thought?
That is what I would recommend.
The API change is fine, but I don't think you need to change all drivers.
Just add a small wrapper function in the header file doing the conversion:
static inline int watchdog_init_timeout(struct watchdog_device *wdd,
unsigned int timeout_parm, struct device *dev)
{
return watchdog_init_timeouts(wdd, timeout_parm, ~0ul, dev);
}Then you can update the drivers that actually use the pretimeout to use the new function at some point, and leave all other drivers calling the wrapper function.
Arnd
Guenter Roeck
maintainerRe: [PATCH 4/6] Watchdog: introdouce "pretimeout" into framework
Quoted 24 lines · Arnd Bergmann
Quoted 8 lines · On Monday 18 May 2015 10:23:30 Guenter Roeck wrote:
Quoted 8 lines
integrate
watchdog_init_pretimeoutandwatchdog_init_timeoutwill be a little hard,
we may need to change this API to :watchdog_init_timeouts(struct
watchdog_device*wdd, unsigned inttimeout_parm,
unsigned intpretimeout_parm, struct device *dev)Quoted 8 lines
Quoted 6 lines
then we need to update all the watchdog drivers which use this API, maybe we can do this in a individual patchset, after this pretimeout patch is merged.
Is that OK ? any thought?
That is what I would recommend.
The API change is fine, but I don't think you need to change all drivers.
Just add a small wrapper function in the header file doing the conversion:
static inline int watchdog_init_timeout(struct
watchdog_device*wdd,
unsigned inttimeout_parm, struct device *dev)
Quoted 8 lines
{ return watchdog_init_timeouts(wdd, timeout_parm, ~0ul, dev); }Then you can update the drivers that actually use the pretimeout to use the new function at some point, and leave all other drivers calling the wrapper function.
Excellent idea.
Guenter
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 4/6] Watchdog: introdouce "pretimeout" into framework
Hi Arnd, Guenter,
yes, that is brilliant idea!!
I will try to do so , that solve the compatibility problem , so I guess we can try this time :-)
Quoted 36 lines · Guenter Roeck
Quoted 24 lines · Arnd Bergmann
Quoted 8 lines · On Monday 18 May 2015 10:23:30 Guenter Roeck wrote:
Quoted 8 lines
integrate
watchdog_init_pretimeoutandwatchdog_init_timeoutwill be a little hard,
we may need to change this API to :watchdog_init_timeouts(struct
watchdog_device*wdd, unsigned inttimeout_parm,
unsigned intpretimeout_parm, struct device *dev)Quoted 8 lines
Quoted 6 lines
then we need to update all the watchdog drivers which use this API, maybe we can do this in a individual patchset, after this pretimeout patch is merged.
Is that OK ? any thought?
That is what I would recommend.
The API change is fine, but I don't think you need to change all drivers.
Just add a small wrapper function in the header file doing the conversion:
static inline int watchdog_init_timeout(struct
watchdog_device*wdd,
unsigned inttimeout_parm, struct device *dev)Quoted 8 lines
{ return watchdog_init_timeouts(wdd, timeout_parm, ~0ul, dev); }Then you can update the drivers that actually use the pretimeout to use the new function at some point, and leave all other drivers calling the wrapper function.
Excellent idea.
Guenter
Signature · 14 lines
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 -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
v2 cover Watchdog: introduce ARM SBSA watchdog driver
In reply to a message not in the archiveFrom: Fu Wei <[email protected]>
This patchset:
(1)Export "arch_timer_get_rate" in arm_arch_timer.c for the other drivers, like SBSA watchdog driver
(2)Introduce Documentation/devicetree/bindings/watchdog/sbsa-gwdt.txt for FDT info of SBSA Generic Watchdog, and give two examples of adding SBSA Generic Watchdog device node into the dts files:
foundation-v8.dts and amd-seattle-soc.dtsi.
(3)Introduce "pretimeout" into the watchdog framework, and update Documentation/watchdog/watchdog-kernel-api.txt to introduce:
(1)the new elements in the watchdog_device and watchdog_ops struct; (2)the new API "watchdog_init_timeouts".
(4)Introduce ARM SBSA watchdog driver:
a.Use linux kernel watchdog framework;
b.Work with FDT on ARM64;
c.Use "pretimeout" in watchdog framework;
d.In first timeout(WS0), do panic to save system context; e.Support geting timeout and pretimeout from parameter and FDT
at the driver init stage.
(5)Parse SBSA Generic Watchdog Structure in GTDT table of ACPI, and create a platform device with that information. This platform device can be used by This Watchdog driver.
This patchset has been tested with watchdog daemon (ACPI/FDT, module/build-in) on the following platforms:
(1)ARM Foundation v8 model
(2)AMD Seattle B0
Changelog:
v2: Improve watchdog-kernel-api.txt documentation for pretimeout support.
Export "arch_timer_get_rate" in arm_arch_timer.c.
Add watchdog_init_timeouts API for pretimeout support in framework. Improve suspend and resume foundation in driver
Improve timeout/pretimeout values init code in driver. Delete unnecessary items of the sbsa_gwdt struct and #define. Delete all unnecessary debug info in driver.
Fix 64bit division bug.
Use the arch_timer interface to get watchdog clock rate. Add MODULE_DEVICE_TABLE for platform device id.
Fix typoes.
v1: The first version upstream patchset to linux mailing list
Fu Wei (7):
clocksource: export "arch_timer_get_rate" for the other drivers
Documentation: add sbsa-gwdt.txt documentation
ARM64: add SBSA Generic Watchdog device node in foundation-v8.dts
ARM64: add SBSA Generic Watchdog device node in amd-seattle-soc.dtsi
Watchdog: introduce "pretimeout" into framework
Watchdog: introduce ARM SBSA watchdog driver
ACPI: import watchdog info of GTDT into platform device
.../devicetree/bindings/watchdog/sbsa-gwdt.txt | 36 ++ Documentation/watchdog/watchdog-kernel-api.txt | 62 ++- arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi | 11 + arch/arm64/boot/dts/arm/foundation-v8.dts | 10 + arch/arm64/kernel/acpi.c | 136 ++++++ drivers/clocksource/arm_arch_timer.c | 1 + drivers/watchdog/Kconfig | 12 + drivers/watchdog/Makefile | 1 + drivers/watchdog/sbsa_gwdt.c | 476 +++++++++++++++++++++ drivers/watchdog/watchdog_core.c | 103 +++-- drivers/watchdog/watchdog_dev.c | 48 +++ include/linux/watchdog.h | 30 +- 12 files changed, 891 insertions(+), 35 deletions(-) create mode 100644 Documentation/devicetree/bindings/watchdog/sbsa-gwdt.txt create mode 100644 drivers/watchdog/sbsa_gwdt.c
Signature · 6 lines
1.9.1 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH v2 1/7 clocksource: export "arch_timer_get_rate" for the other drivers
From: Fu Wei <[email protected]>
Some devices get clock from system counter, like SBSA watchdog driver. They may need to get system counter rate.
--- drivers/clocksource/arm_arch_timer.c | 1 + 1 file changed, 1 insertion(+)
drivers/clocksource/arm_arch_timer.c +1 -0
@@ -410,6 +410,7 @@ u32 arch_timer_get_rate(void) {return arch_timer_rate; } +EXPORT_SYMBOL_GPL (arch_timer_get_rate);static u64 arch_counter_get_cntvct_mem (void ) {
Signature · 6 lines
1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 1/7] clocksource: export "arch_timer_get_rate" for the other drivers
Quoted 4 lines · On 2015年05月21日 16:32, [email protected] wrote:
From: Fu Wei <[email protected]>
Some devices get clock from system counter, like SBSA watchdog driver. They may need to get system counter rate.
and please add a comment that SBSA watchdog is a kernel module, then it would explicit that why EXPORT_SYMBOL_GPL is needed.
Quoted 2 lines
Signed-off-by Fu Wei <[email protected]>
Other than that,
Quoted 17 lines
--- drivers/clocksource/arm_arch_timer.c | 1 + 1 file changed, 1 insertion(+)drivers/clocksource/arm_arch_timer.c +1
-0@@ -410,6 +410,7 @@ u32 arch_timer_get_rate(void) {return arch_timer_rate; } +EXPORT_SYMBOL_GPL (arch_timer_get_rate);static u64 arch_counter_get_cntvct_mem (void ) {
Re: [PATCH v2 1/7] clocksource: export "arch_timer_get_rate" for the other drivers
In reply to [email protected]Quoted 2 lines · [email protected] wrote:
Some devices get clock from system counter, like SBSA watchdog driver. They may need to get system counter rate.
We don't need this patch. The watchdog driver can use arch_timer_get_cntfrq() instead of arch_timer_get_rate(). There's nothing wrong with arch_timer_get_cntfrq() since the SBSA driver is intended only for ARM64 server systems, and arch_timer_get_cntfrq() is always defined for such systems.
Signature · 3 lines
Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation.
Guenter Roeck
maintainerRe: [PATCH v2 1/7] clocksource: export "arch_timer_get_rate" for the other drivers
Quoted 10 lines · Timur Tabi
Quoted 2 lines · [email protected] wrote:
Some devices get clock from system counter, like SBSA watchdog driver. They may need to get system counter rate.
We don't need this patch. The watchdog driver can use
arch_timer_get_cntfrq()instead ofarch_timer_get_rate(). There's nothing wrong witharch_timer_get_cntfrq()since the SBSA driver is intended only for ARM64 server systems, andarch_timer_get_cntfrq()is always defined for such systems.
I agree, since the SBSA driver also uses arch_counter_get_cntvct() which is declared in the same include file as arch_timer_get_cntfrq(). The additional dependency does not provide any value, unless architecture implementation dependencies can be removed entirely, which does not seem to be the case.
Doo bad that SBSA is not hardware independent enough to provide all the information needed to implement such a driver :-(.
Guenter
Re: [PATCH v2 1/7] clocksource: export "arch_timer_get_rate" for the other drivers
Quoted 2 lines · Guenter Roeck
Doo bad that SBSA is not hardware independent enough to provide all the information needed to implement such a driver:-(.
The SBSA is designed and intended only for ARM Servers. It has no value on non-ARM SOCs and and non-server SOCs. The SBSA is just a way for 64-bit ARM Server SOC vendors to re-use some drivers.
Signature · 3 lines
Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.
PATCH v2 2/7 Documentation: add sbsa-gwdt.txt documentation
In reply to [email protected]From: Fu Wei <[email protected]>
The sbsa-gwdt.txt documentation in devicetree/bindings/watchdog is for introducing SBSA(Server Base System Architecture) Generic Watchdog device node info into FDT.
--- .../devicetree/bindings/watchdog/sbsa-gwdt.txt | 36 ++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 Documentation/devicetree/bindings/watchdog/sbsa-gwdt.txt
Documentation/devicetree/bindings/watchdog/sbsa-gwdt.txt new file +36 -0
@@ -0,0 +1,36 @@ +* SBSA(Server Base System Architecture) Generic Watchdog + +The SBSA Generic Watchdog Timer is used for resetting the system after +two stages of timeout. +More details: ARM-DEN-0029 - Server Base System Architecture (SBSA) + +Required properties: +- compatible : Should at least contain "arm,sbsa-gwdt". + +- reg : base physical address of the frames and length of memory mapped region. + +- reg-names : Should contain the resource reg names to show the order of + the values in "reg". + Must include the following entries : "refresh", "control". + +- interrupts : Should at least contain WS0 interrupt, + the WS1 Signal is optional. + +- interrupt-names : Should contain the resource interrupt names. + Must include the following entries : "ws0". "ws1" is optional. + +Optional properties +- timeout-sec : Watchdog pre-timeout and timeout values (in seconds). + The first is timeout values, then pre-timeout. + +Example for FVP Foundation Model v8: + +watchdog@2a450000 { + compatible = "arm,sbsa-gwdt"; + reg = <0x0 0x2a450000 0 0x10000>, + <0x0 0x2a440000 0 0x10000>; + reg-names = "refresh", "control"; + interrupts = <0 27 4>; + interrupt-names = "ws0"; + timeout-sec = <10 5>; +};
Signature · 1 line
1.9.1
PATCH v2 3/7 ARM64: add SBSA Generic Watchdog device node in foundation-v8.dts
In reply to [email protected]From: Fu Wei <[email protected]>
This can be a example of adding SBSA Generic Watchdog device node into some dts files for the Soc which contains SBSA Generic Watchdog.
--- arch/arm64/boot/dts/arm/foundation-v8.dts | 10 ++++++++++ 1 file changed, 10 insertions(+)
arch/arm64/boot/dts/arm/foundation-v8.dts +10 -0
@@ -237,4 +237,14 @@ }; }; }; + watchdog0: watchdog@2a450000 { + compatible = "arm,sbsa-gwdt"; + reg = <0x0 0x2a450000 0 0x10000>, + <0x0 0x2a440000 0 0x10000>; + reg-names = "refresh", + "control"; + interrupts = <0 27 4>; + interrupt-names = "ws0"; + timeout-sec = <10 5>; + }; };
Signature · 1 line
1.9.1
Re: [PATCH v2 3/7] ARM64: add SBSA Generic Watchdog device node in foundation-v8.dts
arch/arm64/boot/dts/arm/foundation-v8.dts line 250
Quoted 12 lines · On Thursday 21 May 2015 16:32:32 [email protected] wrote:
arch/arm64/boot/dts/arm/foundation-v8.dts +10
-0+ watchdog0: watchdog@2a450000 { + compatible = "arm,sbsa-gwdt"; + reg = <0x0 0x2a450000 0 0x10000>, + <0x0 0x2a440000 0 0x10000>; + reg-names = "refresh", + "control"; + interrupts = <0 27 4>; + interrupt-names = "ws0"; + timeout-sec = <10 5>; + }; };
just one tiny comment: you can drop the 'watchdog0:' label here, there is normally no reason to assign a label to a watchdog device, especially if it's in a .dts file rather than a .dtsi.
The same is true for the example in the binding documentation.
Arnd
Re: [PATCH v2 3/7] ARM64: add SBSA Generic Watchdog device node in foundation-v8.dts
Hi Arnd,
yes, you are right , will delete it :-)
Quoted 21 lines · Arnd Bergmann
arch/arm64/boot/dts/arm/foundation-v8.dts line 250
Quoted 12 lines · On Thursday 21 May 2015 16:32:32 [email protected]…
arch/arm64/boot/dts/arm/foundation-v8.dts +10
-0+ watchdog0: watchdog@2a450000 { + compatible = "arm,sbsa-gwdt"; + reg = <0x0 0x2a450000 0 0x10000>, + <0x0 0x2a440000 0 0x10000>; + reg-names = "refresh", + "control"; + interrupts = <0 27 4>; + interrupt-names = "ws0"; + timeout-sec = <10 5>; + }; };just one tiny comment: you can drop the 'watchdog0:' label here, there is normally no reason to assign a label to a watchdog device, especially if it's in a .dts file rather than a .dtsi.
The same is true for the example in the binding documentation.
Arnd
Signature · 14 lines
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 -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH v2 4/7 ARM64: add SBSA Generic Watchdog device node in amd-seattle-soc.dtsi
In reply to [email protected]From: Fu Wei <[email protected]>
This can be a example of adding SBSA Generic Watchdog device node into some dts files for the Soc which contains SBSA Generic Watchdog.
--- arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi | 11 +++++++++++ 1 file changed, 11 insertions(+)
arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi +11 -0
@@ -84,6 +84,17 @@ clock-names = "uartclk", "apb_pclk"; }; + watchdog0: watchdog@e0bb0000 { + compatible = "arm,sbsa-gwdt"; + reg = <0x0 0xe0bb0000 0 0x10000>, + <0x0 0xe0bc0000 0 0x10000>; + reg-names = "refresh", + "control"; + interrupts = <0 337 4>; + interrupt-names = "ws0"; + timeout-sec = <10 5>; + }; + spi0: ssp@e1020000 { status = "disabled"; compatible = "arm,pl022", "arm,primecell";
Signature · 1 line
1.9.1
Re: [PATCH v2 4/7] ARM64: add SBSA Generic Watchdog device node in amd-seattle-soc.dtsi
Quoted 23 lines · On 5/21/15 03:32, [email protected] wrote:
From: Fu Wei <[email protected]>
This can be a example of adding SBSA Generic Watchdog device node into some dts files for the Soc which contains SBSA Generic Watchdog.
Signed-off-by Fu Wei <[email protected]>--- arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi | 11 +++++++++++ 1 file changed, 11 insertions(+)arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi +4
-0@@ -84,6 +84,17 @@ clock-names = "uartclk", "apb_pclk"; }; + watchdog0: watchdog@e0bb0000 { + compatible = "arm,sbsa-gwdt"; + reg = <0x0 0xe0bb0000 0 0x10000>, + <0x0 0xe0bc0000 0 0x10000>;
arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi line 100
Quoted 10 lines
arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi +7
-0+ reg-names = "refresh", + "control"; + interrupts = <0 337 4>; + interrupt-names = "ws0"; + timeout-sec = <10 5>; + }; + spi0: ssp@e1020000 { status = "disabled"; compatible = "arm,pl022", "arm,primecell";
PATCH v2 5/7 Watchdog: introduce "pretimeout" into framework
In reply to [email protected]From: Fu Wei <[email protected]>
Also update Documentation/watchdog/watchdog-kernel-api.txt to introduce:
(1)the new elements in the watchdog_device and watchdog_ops struct; (2)the new API "watchdog_init_timeouts".
Reasons:
(1)kernel already has two watchdog drivers are using "pretimeout":
drivers/char/ipmi/ipmi_watchdog.c drivers/watchdog/kempld_wdt.c(but the definition is different)
(2)some other dirvers are going to use this: ARM SBSA Generic Watchdog
--- Documentation/watchdog/watchdog-kernel-api.txt | 62 ++++++++++++--- drivers/watchdog/watchdog_core.c | 103 +++++++++++++++++++------ drivers/watchdog/watchdog_dev.c | 48 ++++++++++++ include/linux/watchdog.h | 30 ++++++- 4 files changed, 208 insertions(+), 35 deletions(-)
Documentation/watchdog/watchdog-kernel-api.txt +53 -9
@@ -49,6 +49,9 @@ struct watchdog_device { unsigned int timeout; unsigned int min_timeout; unsigned int max_timeout; + unsigned int pretimeout; + unsigned int min_pretimeout; + unsigned int max_pretimeout; void *driver_data; struct mutex lock; unsigned long status;
@@ -70,6 +73,9 @@ It contains following fields: * timeout: the watchdog timer's timeout value (in seconds). * min_timeout: the watchdog timer's minimum timeout value (in seconds). * max_timeout: the watchdog timer's maximum timeout value (in seconds). +* pretimeout: the watchdog timer's pretimeout value (in seconds). +* min_pretimeout: the watchdog timer's minimum pretimeout value (in seconds). +* max_pretimeout: the watchdog timer's maximum pretimeout value (in seconds). * bootstatus: status of the device after booting (reported with watchdog WDIOF_* status bits). * driver_data: a pointer to the drivers private data of a watchdog device.
@@ -92,6 +98,7 @@ struct watchdog_ops { int (*ping)(struct watchdog_device *); unsigned int (*status)(struct watchdog_device *); int (*set_timeout)(struct watchdog_device *, unsigned int); + int (*set_pretimeout)(struct watchdog_device *, unsigned int); unsigned int (*get_timeleft)(struct watchdog_device *); void (*ref)(struct watchdog_device *); void (*unref)(struct watchdog_device *);
@@ -153,9 +160,19 @@ they are supported. These optional routines/operations are: and -EIO for "could not write value to the watchdog". On success this routine should set the timeout value of the watchdog_device to the achieved timeout value (which may be different from the requested one - because the watchdog does not necessarily has a 1 second resolution). + because the watchdog does not necessarily has a 1 second resolution; + If the driver supports pretimeout, then the timeout value must be greater + than that). (Note: the WDIOF_SETTIMEOUT needs to be set in the options field of the watchdog's info structure). +* set_pretimeout: this routine checks and changes the pretimeout of the + watchdog timer device. It returns 0 on success, -EINVAL for "parameter out of + range" and -EIO for "could not write value to the watchdog". On success this + routine should set the pretimeout value of the watchdog_device to the + achieved pretimeout value (which may be different from the requested one + because the watchdog does not necessarily has a 1 second resolution). + (Note: the WDIOF_PRETIMEOUT needs to be set in the options field of the + watchdog's info structure). * get_timeleft: this routines returns the time that's left before a reset. * ref: the operation that calls kref_get on the kref of a dynamically allocated watchdog_device struct.
@@ -213,14 +230,41 @@ The watchdog_get_drvdata function allows you to retrieve driver specific data. The argument of this function is the watchdog device where you want to retrieve data from. The function returns the pointer to the driver specific data. -To initialize the timeout field, the following function can be used: +To initialize the timeout and pretimeout fields, the following function can be +used: -extern int watchdog_init_timeout(struct watchdog_device *wdd, - unsigned int timeout_parm, struct device *dev); +extern int watchdog_init_timeouts(struct watchdog_device *wdd, + unsigned int pretimeout_parm, + unsigned int timeout_parm, + void (*update_limits)(struct watchdog_device *), + struct device *dev); -The watchdog_init_timeout function allows you to initialize the timeout field -using the module timeout parameter or by retrieving the timeout-sec property from -the device tree (if the module timeout parameter is invalid). Best practice is -to set the default timeout value as timeout value in the watchdog_device and -then use this function to set the user "preferred" timeout value. +The watchdog_init_timeouts function allows you to initialize the pretimeout and +timeout fields using the module pretimeout and timeout parameter or by +retrieving the elements in the timeout-sec property(the first element is for +timeout, the second one is for pretimeout) from the device tree(if the module +pretimeout and timeout parameter are invalid). +Normally, the pretimeout value will affect the limitation of timeout, and it +is also hardware related. So you can write a function in your driver to update +the limitation of timeout, according to the pretimeout value. Then pass the +function pointer by the update_limits parameter. If you driver doesn't +need this adjustment, just pass NULL to the update_limits parameter. +Most of watchdog timers have not pretimeout as the warning signal. They just +reset the system, once the timeout watch period expires. In this case, we can +pass 0 to the pretimeout_parm, and pass NULL to the update_limits. Or use the +old API: watchdog_init_timeout(see below) +Best practice is to set the default pretimeout and timeout value as pretimeout +and timeout value in the watchdog_device and then use this function to set the +user "preferred" pretimeout value. This routine returns zero on success and a negative errno code for failure. + +For backward compatibility, we also support the timeout initialization API: + +static inline int watchdog_init_timeout(struct watchdog_device *wdd, + unsigned int timeout_parm, + struct device *dev); + +Because of the introduction of pretimeout and watchdog_init_timeouts, this +function has become a small wrapper function of watchdog_init_timeouts. + +
drivers/watchdog/watchdog_core.c +79 -24
146 lines not on this page · raw message
drivers/watchdog/watchdog_dev.c +48 -0
60 lines not on this page · raw message
include/linux/watchdog.h +28 -2
@@ -25,6 +25,7 @@ struct watchdog_device;* @ping: The routine that sends a keepalive ping to the watchdog device. * @status: The routine that shows the status of the watchdog device. * @set_timeout:The routine for setting the watchdog devices timeout value. +* @set_pretimeout:The routine for setting the watchdog devices pretimeout value * @get_timeleft:The routine that get's the time that's left before a reset. * @ref: The ref operation for dyn. allocated watchdog_device structs * @unref: The unref operation for dyn. allocated watchdog_device structs
@@ -44,6 +45,7 @@ struct watchdog_ops {int (*ping)(struct watchdog_device *);unsigned int (*status)(struct watchdog_device *);int (*set_timeout)(struct watchdog_device *,unsigned int ); +int (*set_pretimeout)(struct watchdog_device *,unsigned int );unsigned int (*get_timeleft)(struct watchdog_device *);void (*ref)(struct watchdog_device *);void (*unref)(struct watchdog_device *);
@@ -62,6 +64,9 @@ struct watchdog_ops {* @timeout: The watchdog devices timeout value. * @min_timeout:The watchdog devices minimum timeout value. * @max_timeout:The watchdog devices maximum timeout value. +* @pretimeout: The watchdog devices pretimeout value. +* @min_pretimeout:The watchdog devices minimum pretimeout value. +* @max_pretimeout:The watchdog devices maximum pretimeout value. * @driver-data:Pointer to the drivers private data. * @lock: Lock for watchdog core internal use only. * @status: Field that contains the devices internal status bits.
@@ -86,6 +91,9 @@ struct watchdog_device {unsigned int timeout;unsigned int min_timeout;unsigned int max_timeout; +unsigned int pretimeout; +unsigned int min_pretimeout; +unsigned int max_pretimeout;void *driver_data;struct mutex lock;unsigned long status;
@@ -120,6 +128,14 @@ static inline bool watchdog_timeout_invalid(struct watchdog_device *wdd, unsigne (t < wdd->min_timeout || t > wdd->max_timeout)); } +/* Use the following function to check if a pretimeout value is invalid */ +static inline bool watchdog_pretimeout_invalid (struct watchdog_device *wdd, +unsigned int t) +{ +return ((wdd->max_pretimeout !=0 ) && + (t < wdd->min_pretimeout || t > wdd->max_pretimeout)); +} +/* Use the following functions to manipulate watchdog driver specific data */ static inline void watchdog_set_drvdata (struct watchdog_device *wdd,void *data) {
@@ -132,11 +148,21 @@ static inline void *watchdog_get_drvdata(struct watchdog_device *wdd) }/* drivers/watchdog/watchdog_core.c */ -extern int watchdog_init_timeout (struct watchdog_device *wdd, -unsigned int timeout_parm,struct device *dev); +extern int watchdog_init_timeouts (struct watchdog_device *wdd, +unsigned int pretimeout_parm, +unsigned int timeout_parm, +void (*update_limits)(struct watchdog_device *), +struct device *dev);extern int watchdog_register_device (struct watchdog_device *);extern void watchdog_unregister_device (struct watchdog_device *); +static inline int watchdog_init_timeout (struct watchdog_device *wdd, +unsigned int timeout_parm, +struct device *dev) +{ +return watchdog_init_timeouts (wdd,0 , timeout_parm,NULL , dev); +} +#ifdef CONFIG_HARDLOCKUP_DETECTOR void watchdog_nmi_disable_all (void );void watchdog_nmi_enable_all (void );
Signature · 1 line
1.9.1
Guenter Roeck
maintainerRe: [PATCH v2 5/7] Watchdog: introduce "pretimeout" into framework
Quoted 15 lines · On 05/21/2015 01:32 AM, [email protected] wrote:
From: Fu Wei <[email protected]>
Also update
Documentation/watchdog/watchdog-kernel-api.txtto introduce:
(1)the new elements in thewatchdog_deviceandwatchdog_opsstruct; (2)the new API "watchdog_init_timeouts".Reasons:
(1)kernel already has two watchdog drivers are using "pretimeout":
drivers/char/ipmi/ipmi_watchdog.cdrivers/watchdog/kempld_wdt.c(but the definition is different)
(2)some other dirvers are going to use this: ARM SBSA Generic WatchdogSigned-off-by Fu Wei <[email protected]>---
[ ... ]
Quoted 11 lines
Documentation/watchdog/watchdog-kernel-api.txt +5
-5+extern int watchdog_init_timeouts(struct watchdog_device *wdd, + unsigned int pretimeout_parm, + unsigned int timeout_parm, + void (*update_limits)(struct watchdog_device *), + struct device *dev); -The watchdog_init_timeout function allows you to initialize the timeout field -using the module timeout parameter or by retrieving the timeout-sec property from -the device tree (if the module timeout parameter is invalid). Best practice is -to set the default timeout value as timeout value in the watchdog_device and -then use this function to set the user "preferred" timeout value.
Documentation/watchdog/watchdog-kernel-api.txt The watchdog_get_drvdata function allows you to retrieve driver specific data. · line 251
Quoted 10 lines
Documentation/watchdog/watchdog-kernel-api.txt +10
-0+The watchdog_init_timeouts function allows you to initialize the pretimeout and +timeout fields using the module pretimeout and timeout parameter or by +retrieving the elements in the timeout-sec property(the first element is for +timeout, the second one is for pretimeout) from the device tree(if the module +pretimeout and timeout parameter are invalid). +Normally, the pretimeout value will affect the limitation of timeout, and it +is also hardware related. So you can write a function in your driver to update +the limitation of timeout, according to the pretimeout value. Then pass the +function pointer by the update_limits parameter. If you driver doesn't +need this adjustment, just pass NULL to the update_limits parameter.
You've lost me a bit with the update_limits function. watchdog_init_timeouts() is called from the driver. Why should the function have to call back into the driver to update the parameters which are passed from the driver ? Seems to me the driver can do that calculation first, then call watchdog_init_timeouts() with the result. Am I missing something ?
Thanks,
Guenter
Re: [PATCH v2 5/7] Watchdog: introduce "pretimeout" into framework
Hi Guenter,
Thanks for review. :-)
feedback inline below
Quoted 50 lines · Guenter Roeck
Quoted 16 lines · On 05/21/2015 01:32 AM, [email protected] wrote:
From: Fu Wei <[email protected]>
Also update
Documentation/watchdog/watchdog-kernel-api.txtto introduce:
(1)the new elements in thewatchdog_deviceandwatchdog_opsstruct; (2)the new API "watchdog_init_timeouts".Reasons:
(1)kernel already has two watchdog drivers are using "pretimeout":
drivers/char/ipmi/ipmi_watchdog.cdrivers/watchdog/kempld_wdt.c(but the definition is different)
(2)some other dirvers are going to use this: ARM SBSA Generic WatchdogSigned-off-by Fu Wei <[email protected]>---
[ ... ]
Quoted 29 lines
Documentation/watchdog/watchdog-kernel-api.txt +4
-0+extern int watchdog_init_timeouts(struct watchdog_device *wdd, + unsigned int pretimeout_parm, + unsigned int timeout_parm, + void (*update_limits)(struct
watchdog_device*),Documentation/watchdog/watchdog-kernel-api.txt +1
-1+ struct device *dev); -The watchdog_init_timeout function allows you to initialize the timeoutfield
-using the module timeout parameter or by retrieving the timeout-sec property from
-the device tree (if the module timeout parameter is invalid). Best practice is
-to set the default timeout value as timeout value in thewatchdog_deviceand(quoted diff) +1
-1-then use this function to set the user "preferred" timeout value. +The watchdog_init_timeouts function allows you to initialize thepretimeout and
(quoted diff) +2
-0+timeout fields using the module pretimeout and timeout parameter or by +retrieving the elements in the timeout-sec property(the first element isfor
+timeout, the second one is for pretimeout) from the device tree(if the module(quoted diff) +2
-0+pretimeout and timeout parameter are invalid). +Normally, the pretimeout value will affect the limitation of timeout, andit
+is also hardware related. So you can write a function in your driver to update
+the limitation of timeout, according to the pretimeout value. Then pass
Quoted 8 lines
Documentation/watchdog/watchdog-kernel-api.txt The watchdog_get_drvdata function allows you to retrieve driver specific data. · line 251
Quoted 3 lines
the
Documentation/watchdog/watchdog-kernel-api.txt +2
-0+function pointer by the update_limits parameter. If you driver doesn't +need this adjustment, just pass NULL to the update_limits parameter.You've lost me a bit with the
update_limitsfunction.watchdog_init_timeouts()
is called from the driver.
yes, that is the help function which will be called from watchdog driver, like SBSA watchdog driver
Quoted 3 lines
Why should the function have to call back into
the
driver to update the parameters which are passed from the driver ?
Let me explain this, please correct me if I misunderstand something. According to the concept of "pretimeout" in kernel, the timeout contains the pretimeout, like
* Kernel/API: P---------| pretimeout
* |-------------------------------T timeout
If you set up the value of pretimeout, that means pretimeout <min_timeout < timeout < max_timeout < (pretimeout + max_timeout_for_1th_stage)
For min_timeout > pretimeout. if some one setup a timeout like :
pretimeout > timeout > min_timeout, I think that could be a problem For max_timeout < (pretimeout + max_timeout_for_1th_stage), if some one setup a timeout like (pretimeout + max_timeout_for_1th_stage) < timeout > max_timeout .
I have explained a little in doc, but the adjustment may have something to do with hardware, like max_timeout_for_1th_stage(in SBSA watchdog , limited by WCV)
maybe this problem wouldn't happen ,if you set up max_timeout to a small number. so you can pass NULL to the pointer.
but I think maybe for other device , that may happen.
Quoted 2 lines
Seems to me the driver can do that calculation first, then call
watchdog_init_timeouts()with the result. Am I missing something ?
maybe I am overthinking it :-)
please correct me
Quoted 4 lines
Thanks,
Guenter
Signature · 14 lines
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 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Guenter Roeck
maintainerRe: [PATCH v2 5/7] Watchdog: introduce "pretimeout" into framework
Quoted 96 lines · Fu Wei
Hi Guenter,
Thanks for review. :-)
feedback inline belowQuoted 50 lines · Guenter Roeck
Quoted 16 lines · On 05/21/2015 01:32 AM, [email protected] wrote:
From: Fu Wei <[email protected]>
Also update
Documentation/watchdog/watchdog-kernel-api.txtto introduce:
(1)the new elements in thewatchdog_deviceandwatchdog_opsstruct; (2)the new API "watchdog_init_timeouts".Reasons:
(1)kernel already has two watchdog drivers are using "pretimeout":
drivers/char/ipmi/ipmi_watchdog.cdrivers/watchdog/kempld_wdt.c(but the definition is different)
(2)some other dirvers are going to use this: ARM SBSA Generic WatchdogSigned-off-by Fu Wei <[email protected]>---
[ ... ]
Quoted 29 lines
Documentation/watchdog/watchdog-kernel-api.txt +4
-0+extern int watchdog_init_timeouts(struct watchdog_device *wdd, + unsigned int pretimeout_parm, + unsigned int timeout_parm, + void (*update_limits)(struct
watchdog_device*),Documentation/watchdog/watchdog-kernel-api.txt +1
-1+ struct device *dev); -The watchdog_init_timeout function allows you to initialize the timeoutfield
-using the module timeout parameter or by retrieving the timeout-sec property from
-the device tree (if the module timeout parameter is invalid). Best practice is
-to set the default timeout value as timeout value in thewatchdog_deviceand(quoted diff) +1
-1-then use this function to set the user "preferred" timeout value. +The watchdog_init_timeouts function allows you to initialize thepretimeout and
(quoted diff) +2
-0+timeout fields using the module pretimeout and timeout parameter or by +retrieving the elements in the timeout-sec property(the first element isfor
+timeout, the second one is for pretimeout) from the device tree(if the module(quoted diff) +2
-0+pretimeout and timeout parameter are invalid). +Normally, the pretimeout value will affect the limitation of timeout, andit
+is also hardware related. So you can write a function in your driver to update
+the limitation of timeout, according to the pretimeout value. Then passQuoted 8 lines
Documentation/watchdog/watchdog-kernel-api.txt The watchdog_get_drvdata function allows you to retrieve driver specific data. · line 251
Quoted 3 lines
the
Documentation/watchdog/watchdog-kernel-api.txt +2
-0+function pointer by the update_limits parameter. If you driver doesn't +need this adjustment, just pass NULL to the update_limits parameter.You've lost me a bit with the
update_limitsfunction.watchdog_init_timeouts()
is called from the driver.yes, that is the help function which will be called from watchdog driver, like SBSA watchdog driver
Quoted 3 lines
Why should the function have to call back into
the
driver to update the parameters which are passed from the driver ?Let me explain this, please correct me if I misunderstand something. According to the concept of "pretimeout" in kernel, the timeout contains the pretimeout, like
* Kernel/API: P---------| pretimeout
* |-------------------------------T timeoutIf you set up the value of pretimeout, that means pretimeout <
min_timeout< timeout <max_timeout< (pretimeout +max_timeout_for_1th_stage)
Formin_timeout> pretimeout. if some one setup a timeout like :
pretimeout > timeout >min_timeout, I think that could be a problem Formax_timeout< (pretimeout +max_timeout_for_1th_stage), if some one setup a timeout like (pretimeout +max_timeout_for_1th_stage) < timeout >max_timeout.I have explained a little in doc, but the adjustment may have something to do with hardware, like
max_timeout_for_1th_stage(in SBSA watchdog , limited by WCV)maybe this problem wouldn't happen ,if you set up
max_timeoutto a small number. so you can pass NULL to the pointer.
but I think maybe for other device , that may happen.
Quoted 6 lines
Quoted 2 lines
Seems to me the driver can do that calculation first, then call
watchdog_init_timeouts()with the result. Am I missing something ?maybe I am overthinking it :-)
please correct me
I just sent a more complete review. In general I think this problem (where the driver needs to update timeout limits based on the value of pretimeout) is very driver specific, and should be kept in the driver. I would prefer to keep it out of the API if possible.
Unless I am missing something, it should be possible to call the update_limits function in the driver after calling init_timeouts.
Thanks,
Guenter
Re: [PATCH v2 5/7] Watchdog: introduce "pretimeout" into framework
Hi Guenter,
Great thanks, I have got your review feedback, I will fix the problems :-) For update_limits, I also don't want to have that in the watchdog driver, and you can't find it in my last version.
And this version, I integrate the watchdog_init_timeout and watchdog_init_pretimeout. so I can not add a driver specific "update_limits" between them.
I think maybe we can not make this "update_limits" after calling init_timeouts, because we need to test and verify the timeout setting right after init_pretimeout by max_timeout and min_timeout. that is why I call update_limits right after init_pretimeout and before init_timeout.
any suggestion ? Great thanks ! :-)
Quoted 126 lines · Guenter Roeck
Quoted 106 lines · Fu Wei
Hi Guenter,
Thanks for review. :-)
feedback inline belowQuoted 57 lines · Guenter Roeck
Quoted 17 lines · On 05/21/2015 01:32 AM, [email protected] wrote:
From: Fu Wei <[email protected]>
Also update
Documentation/watchdog/watchdog-kernel-api.txtto introduce:
(1)the new elements in thewatchdog_deviceandwatchdog_opsstruct; (2)the new API "watchdog_init_timeouts".Reasons:
(1)kernel already has two watchdog drivers are using "pretimeout":
drivers/char/ipmi/ipmi_watchdog.cdrivers/watchdog/kempld_wdt.c(but the definition is different)
(2)some other dirvers are going to use this: ARM SBSA Generic WatchdogSigned-off-by Fu Wei <[email protected]>---
[ ... ]
Quoted 33 lines
Documentation/watchdog/watchdog-kernel-api.txt +4
-0+extern int watchdog_init_timeouts(struct watchdog_device *wdd, + unsigned int pretimeout_parm, + unsigned int timeout_parm, + void (*update_limits)(struct
watchdog_device*),Documentation/watchdog/watchdog-kernel-api.txt +1
-1+ struct device *dev); -The watchdog_init_timeout function allows you to initialize the timeoutfield
-using the module timeout parameter or by retrieving the timeout-sec property from
-the device tree (if the module timeout parameter is invalid). Best practice is
-to set the default timeout value as timeout value in thewatchdog_device
and(quoted diff) +1
-1-then use this function to set the user "preferred" timeout value. +The watchdog_init_timeouts function allows you to initialize thepretimeout and
(quoted diff) +2
-0+timeout fields using the module pretimeout and timeout parameter or by +retrieving the elements in the timeout-sec property(the first elementis
for
+timeout, the second one is for pretimeout) from the device tree(if the module(quoted diff) +2
-0+pretimeout and timeout parameter are invalid). +Normally, the pretimeout value will affect the limitation of timeout,and
it
+is also hardware related. So you can write a function in your driver to update
+the limitation of timeout, according to the pretimeout value. Then pass theQuoted 8 lines
Documentation/watchdog/watchdog-kernel-api.txt The watchdog_get_drvdata function allows you to retrieve driver specific data. · line 251
Quoted 2 lines
Documentation/watchdog/watchdog-kernel-api.txt +2
-0+function pointer by the update_limits parameter. If you driver doesn't +need this adjustment, just pass NULL to the update_limits parameter.You've lost me a bit with the
update_limitsfunction.watchdog_init_timeouts()
is called from the driver.yes, that is the help function which will be called from watchdog driver, like SBSA watchdog driver
Quoted 3 lines
Why should the function have to call back into
the
driver to update the parameters which are passed from the driver ?Let me explain this, please correct me if I misunderstand something. According to the concept of "pretimeout" in kernel, the timeout contains the pretimeout, like
* Kernel/API: P---------| pretimeout
* |-------------------------------T timeoutIf you set up the value of pretimeout, that means pretimeout <
min_timeout< timeout <max_timeout< (pretimeout +max_timeout_for_1th_stage)
Formin_timeout> pretimeout. if some one setup a timeout like :
pretimeout > timeout >min_timeout, I think that could be a problem Formax_timeout< (pretimeout +max_timeout_for_1th_stage), if some one setup a timeout like (pretimeout +max_timeout_for_1th_stage) < timeout >max_timeout.I have explained a little in doc, but the adjustment may have something to do with hardware, like
max_timeout_for_1th_stage(in SBSA watchdog , limited by WCV)maybe this problem wouldn't happen ,if you set up
max_timeoutto a small number. so you can pass NULL to the pointer.
but I think maybe for other device , that may happen.Quoted 7 lines
Quoted 2 lines
Seems to me the driver can do that calculation first, then call
watchdog_init_timeouts()with the result. Am I missing something ?maybe I am overthinking it :-)
please correct meI just sent a more complete review. In general I think this problem (where the driver needs to update timeout limits based on the value of pretimeout) is very driver specific, and should be kept in the driver. I would prefer to keep it out of the API if possible.
Unless I am missing something, it should be possible to call the
update_limitsfunction in the driver after callinginit_timeouts.Thanks,
Guenter
Signature · 14 lines
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 -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Guenter Roeck
maintainerRe: [PATCH v2 5/7] Watchdog: introduce "pretimeout" into framework
Quoted 11 lines · Fu Wei
Hi Guenter,
Great thanks, I have got your review feedback, I will fix the problems :-) For
update_limits, I also don't want to have that in the watchdog driver, and you can't find it in my last version.
And this version, I integrate thewatchdog_init_timeoutandwatchdog_init_pretimeout. so I can not add a driver specific "update_limits" between them.
I think maybe we can not make this "update_limits" after callinginit_timeouts, because we need to test and verify the timeout setting right afterinit_pretimeoutbymax_timeoutandmin_timeout. that is
Don't you have to do that in set_pretimeout as well, and even adjust timeout if necessary ?
Quoted 5 lines
why I call
update_limitsright afterinit_pretimeoutand beforeinit_timeout.any suggestion ? Great thanks ! :-)
Any sequence of
set_timeout()
set_pretimeout()
can result in an invalid timeout, since the practical timeout limits changed. Therefore, you'll have to validate (and possibly update) the timeout after or during each call to set_pretimeout(). Changing min_timeout and max_timeout won't help there, that validation still has to happen.
Given this, some other driver developer may choose to not change the timeout limits at all, validate (and if necessary silently adjust) the timeout value in the set_timeout function, and call the set_timeout function from set_pretimeout to ensure that the timeout is still valid after the call to set_pretimeout. At least I would most likely implement it that way.
This means your choice of continuously updating the timeout limits is really a driver developer choice, not something that is needed in the driver core. It might even be problematic, since driver developers might forget to re-validate the current timeout after changing the pretimeout in a similar situation.
Having said that, and looking through the SBSA driver code, it seems to me that it does not re-validate the current timeout after setting a new pretimeout. Unless I am missing something,
set_timeout(10); set_pretimeout(20); might therefore result in an invalid / unexpected timeout value. Setting set_timeout(10); set_pretimeout(10);
might have even more interesting results. Can you try what happens with your driver if you set those values ?
Thanks,
Guenter
Guenter Roeck
maintainerRe: [PATCH v2 5/7] Watchdog: introduce "pretimeout" into framework
In reply to [email protected]Quoted 7 lines · On 05/21/2015 01:32 AM, [email protected] wrote:
From: Fu Wei <[email protected]>
Also update
Documentation/watchdog/watchdog-kernel-api.txtto introduce:
(1)the new elements in thewatchdog_deviceandwatchdog_opsstruct; (2)the new API "watchdog_init_timeouts".
Quoted 6 lines
Reasons:
(1)kernel already has two watchdog drivers are using "pretimeout":
drivers/char/ipmi/ipmi_watchdog.cdrivers/watchdog/kempld_wdt.c(but the definition is different)
(2)some other dirvers are going to use this: ARM SBSA Generic Watchdog
drivers
Quoted 62 lines
Signed-off-by Fu Wei <[email protected]>--- Documentation/watchdog/watchdog-kernel-api.txt | 62 ++++++++++++--- drivers/watchdog/watchdog_core.c | 103 +++++++++++++++++++------ drivers/watchdog/watchdog_dev.c | 48 ++++++++++++ include/linux/watchdog.h | 30 ++++++- 4 files changed, 208 insertions(+), 35 deletions(-)Documentation/watchdog/watchdog-kernel-api.txt +18
-1@@ -49,6 +49,9 @@ struct watchdog_device { unsigned int timeout; unsigned int min_timeout; unsigned int max_timeout; + unsigned int pretimeout; + unsigned int min_pretimeout; + unsigned int max_pretimeout; void *driver_data; struct mutex lock; unsigned long status;@@ -70,6 +73,9 @@ It contains following fields: * timeout: the watchdog timer's timeout value (in seconds). * min_timeout: the watchdog timer's minimum timeout value (in seconds). * max_timeout: the watchdog timer's maximum timeout value (in seconds). +* pretimeout: the watchdog timer's pretimeout value (in seconds). +* min_pretimeout: the watchdog timer's minimum pretimeout value (in seconds). +* max_pretimeout: the watchdog timer's maximum pretimeout value (in seconds). * bootstatus: status of the device after booting (reported with watchdog WDIOF_* status bits). * driver_data: a pointer to the drivers private data of a watchdog device.@@ -92,6 +98,7 @@ struct watchdog_ops { int (*ping)(struct watchdog_device *); unsigned int (*status)(struct watchdog_device *); int (*set_timeout)(struct watchdog_device *, unsigned int); + int (*set_pretimeout)(struct watchdog_device *, unsigned int); unsigned int (*get_timeleft)(struct watchdog_device *); void (*ref)(struct watchdog_device *); void (*unref)(struct watchdog_device *);@@ -153,9 +160,19 @@ they are supported. These optional routines/operations are: and -EIO for "could not write value to the watchdog". On success this routine should set the timeout value of the watchdog_device to the achieved timeout value (which may be different from the requested one - because the watchdog does not necessarily has a 1 second resolution). + because the watchdog does not necessarily has a 1 second resolution; + If the driver supports pretimeout, then the timeout value must be greater + than that). (Note: the WDIOF_SETTIMEOUT needs to be set in the options field of the watchdog's info structure). +* set_pretimeout: this routine checks and changes the pretimeout of the + watchdog timer device. It returns 0 on success, -EINVAL for "parameter out of + range" and -EIO for "could not write value to the watchdog". On success this + routine should set the pretimeout value of the watchdog_device to the + achieved pretimeout value (which may be different from the requested one + because the watchdog does not necessarily has a 1 second resolution). + (Note: the WDIOF_PRETIMEOUT needs to be set in the options field of the + watchdog's info structure). * get_timeleft: this routines returns the time that's left before a reset. * ref: the operation that calls kref_get on the kref of a dynamically allocated watchdog_device struct.
Documentation/watchdog/watchdog-kernel-api.txt The watchdog_get_drvdata function allows you to retrieve driver specific data. · line 219
Quoted 9 lines
Documentation/watchdog/watchdog-kernel-api.txt +2
-3@@ -213,14 +230,41 @@ The watchdog_get_drvdata function allows you to retrieve driver specific data. The argument of this function is the watchdog device where you want to retrieve data from. The function returns the pointer to the driver specific data. -To initialize the timeout field, the following function can be used: +To initialize the timeout and pretimeout fields, the following function can be +used: -extern int watchdog_init_timeout(struct watchdog_device *wdd, - unsigned int timeout_parm, struct device *dev);
I think this API should still be listed here. Drivers not supporting pretimeout can and should still use it.
Quoted 11 lines
Documentation/watchdog/watchdog-kernel-api.txt +5
-5+extern int watchdog_init_timeouts(struct watchdog_device *wdd, + unsigned int pretimeout_parm, + unsigned int timeout_parm, + void (*update_limits)(struct watchdog_device *), + struct device *dev); -The watchdog_init_timeout function allows you to initialize the timeout field -using the module timeout parameter or by retrieving the timeout-sec property from -the device tree (if the module timeout parameter is invalid). Best practice is -to set the default timeout value as timeout value in the watchdog_device and -then use this function to set the user "preferred" timeout value.
Documentation/watchdog/watchdog-kernel-api.txt The watchdog_get_drvdata function allows you to retrieve driver specific data. · line 251
Quoted 10 lines
Documentation/watchdog/watchdog-kernel-api.txt +10
-0+The watchdog_init_timeouts function allows you to initialize the pretimeout and +timeout fields using the module pretimeout and timeout parameter or by +retrieving the elements in the timeout-sec property(the first element is for +timeout, the second one is for pretimeout) from the device tree(if the module +pretimeout and timeout parameter are invalid). +Normally, the pretimeout value will affect the limitation of timeout, and it +is also hardware related. So you can write a function in your driver to update +the limitation of timeout, according to the pretimeout value. Then pass the +function pointer by the update_limits parameter. If you driver doesn't +need this adjustment, just pass NULL to the update_limits parameter.
Is there a reason to believe that the update_limits function is necessary and can not be handled by the set_pretimeout and set_timeout driver functions, or possibly by the driver itself after calling watchdog_init_timeouts() ?
Documentation/watchdog/watchdog-kernel-api.txt The watchdog_get_drvdata function allows you to retrieve driver specific data. · line 262
Quoted 11 lines
Documentation/watchdog/watchdog-kernel-api.txt +10
-0+Most of watchdog timers have not pretimeout as the warning signal. They just +reset the system, once the timeout watch period expires. In this case, we can +pass 0 to the pretimeout_parm, and pass NULL to the update_limits. Or use the +old API: watchdog_init_timeout(see below) +Best practice is to set the default pretimeout and timeout value as pretimeout +and timeout value in the watchdog_device and then use this function to set the +user "preferred" pretimeout value. This routine returns zero on success and a negative errno code for failure. + +For backward compatibility, we also support the timeout initialization API: +
Why only for backward compatibility ? Why (try to) force new drivers which don't support pretimeout to use the new API function ?
Documentation/watchdog/watchdog-kernel-api.txt The watchdog_get_drvdata function allows you to retrieve driver specific data. · line 268
Quoted 6 lines
Documentation/watchdog/watchdog-kernel-api.txt +6
-0+static inline int watchdog_init_timeout(struct watchdog_device *wdd, + unsigned int timeout_parm, + struct device *dev); + +Because of the introduction of pretimeout and watchdog_init_timeouts, this +function has become a small wrapper function of watchdog_init_timeouts.
The last sentence is irrelevant; how watchdog_init_timeout() is implemented is an implementation detail, not part of the API.
Documentation/watchdog/watchdog-kernel-api.txt The watchdog_get_drvdata function allows you to retrieve driver specific data. · line 270
Quoted 2 lines
Documentation/watchdog/watchdog-kernel-api.txt +2
-0+ +
Empty lines at end of file will cause whitespace errors on merge. Doesn't checkpatch complain about this ?
Quoted 9 lines
drivers/watchdog/watchdog_core.c +0
-1@@ -43,60 +43,115 @@static DEFINE_IDA (watchdog_ida);static struct class *watchdog_class; -static void watchdog_check_min_max_timeout (struct watchdog_device *wdd)
drivers/watchdog/watchdog_core.c line 53
Quoted 10 lines
drivers/watchdog/watchdog_core.c +5
-2+static void watchdog_check_min_max_timeouts (struct watchdog_device *wdd) {/* -* Check that we have valid min and max timeout values, if -* not reset them both to 0 (=not used or unknown) +* Check that we have valid min and max pretimeout and timeout values, +* if not reset them both to 0 (=not used or unknown) */ +if (wdd->min_pretimeout > wdd->max_pretimeout) { +pr_info ("Invalid min and max pretimeout, resetting to 0!\n" );
Please drop the "!" at the end. While used in the old code, it is unnecessary and often frowned upon nowadays.
Quoted 30 lines
drivers/watchdog/watchdog_core.c +17
-2+ wdd->min_pretimeout =0 ; + wdd->max_pretimeout =0 ; + }if (wdd->min_timeout > wdd->max_timeout) {pr_info ("Invalid min and max timeout values, resetting to 0!\n" ); wdd->min_timeout =0 ; wdd->max_timeout =0 ; } +/* +* Check that we have valid min and max timeout values, +* if not reset them both to pretimeout limits +*/ +if (wdd->min_pretimeout && wdd->min_timeout < wdd->min_pretimeout) { +pr_info ("Invalid min timeout, resetting to min pretimeout!\n" ); + wdd->min_timeout = wdd->min_pretimeout; + } +if (wdd->max_pretimeout && wdd->max_timeout < wdd->max_pretimeout) { +pr_info ("Invalid max timeout, resetting to max pretimeout!\n" ); + wdd->max_timeout = wdd->max_pretimeout; + } }/** -* watchdog_init_timeout() - initialize the timeout field +* watchdog_init_timeouts() - initialize the pretimeout and timeout field +* @pretimeout_parm: pretimeout module parameter * @timeout_parm: timeout module parameter * @dev: Device that stores the timeout-sec property * -* Initialize the timeout field of the watchdog_device struct with either the
drivers/watchdog/watchdog_core.c line 87
Quoted 10 lines
drivers/watchdog/watchdog_core.c +6
-4-* timeout module parameter (if it is valid value) or the timeout-sec property -* (only if it is a valid value and the timeout_parm is out of bounds). -* If none of them are valid then we keep the old value (which should normally -* be the default timeout value. +* Initialize the pretimeout and timeout field of the watchdog_device struct +* with either the pretimeout and timeout module parameter (if it is valid +* value) or the timeout-sec property (only if it is a valid value and the +* pretimeout_parm and timeout_parm is out of bounds). If none of them are +* valid then we keep the old value (which should normally be the default +* timeout value.
valid, then we keep ... default timeout value).
Quoted 23 lines
drivers/watchdog/watchdog_core.c +10
-6* * A zero is returned on success and -EINVAL for failure. */ -int watchdog_init_timeout (struct watchdog_device *wdd, -unsigned int timeout_parm,struct device *dev) +int watchdog_init_timeouts (struct watchdog_device *wdd, +unsigned int pretimeout_parm, +unsigned int timeout_parm, +void (*update_limits)(struct watchdog_device *), +struct device *dev) { -unsigned int t =0 ; +unsigned int timeout =0 , pretimeout =0 ; +const __be32 *ppretimeout;int ret =0 ; +struct property *timeout_sec; +int length; -watchdog_check_min_max_timeout (wdd); +watchdog_check_min_max_timeouts (wdd); -/* try to get the timeout module parameter first */ -if (!watchdog_timeout_invalid (wdd, timeout_parm) && timeout_parm) {
drivers/watchdog/watchdog_core.c line 112
Quoted 10 lines
drivers/watchdog/watchdog_core.c +8
-2- wdd->timeout = timeout_parm; -return ret; +/* try to get the timeout and pretimeout module parameter first */ +if (pretimeout_parm) { +if (!watchdog_pretimeout_invalid (wdd, pretimeout_parm)) { + wdd->pretimeout = pretimeout_parm; +if (update_limits) +update_limits (wdd); + }else { +pr_warn ("Invalid pretimeout parameter!\n" );
We didn't have all this noise earlier. Can we keep it that way ?
Quoted 15 lines
drivers/watchdog/watchdog_core.c +10
-1+ ret = -EINVAL ; + } } -if (timeout_parm) + +if (timeout_parm) { +if (!watchdog_timeout_invalid (wdd, timeout_parm)) { + wdd->timeout = timeout_parm; +return ret; + } +pr_warn ("Invalid timeout parameter!\n" ); ret = -EINVAL ; + }/* try to get the timeout_sec property */
drivers/watchdog/watchdog_core.c line 132
Quoted 10 lines
drivers/watchdog/watchdog_core.c +4
-4if (dev ==NULL || dev->of_node ==NULL )return ret; -of_property_read_u32 (dev->of_node,"timeout-sec" , &t); -if (!watchdog_timeout_invalid (wdd, t) && t) - wdd->timeout = t; -else + + timeout_sec =of_find_property (dev->of_node,"timeout-sec" , &length); +if (timeout_sec) { + ppretimeout =of_prop_next_u32 (timeout_sec,NULL , &timeout);
Could you just use of_property_read_u32_array() and pass length as parameter ?
Quoted 81 lines
drivers/watchdog/watchdog_core.c +19
-2+if (length ==2 ) { +of_prop_next_u32 (timeout_sec, ppretimeout, &pretimeout); +if (!watchdog_pretimeout_invalid (wdd, pretimeout) && + pretimeout) { + wdd->pretimeout = pretimeout; +if (update_limits) +update_limits (wdd); + }else { + ret = -EINVAL ; + } + } +if (!watchdog_timeout_invalid (wdd, timeout) && timeout) + wdd->timeout = timeout; +else + ret = -EINVAL ; + }else { ret = -EINVAL ; + }return ret; } -EXPORT_SYMBOL_GPL (watchdog_init_timeout); +EXPORT_SYMBOL_GPL (watchdog_init_timeouts);/** * watchdog_register_device() - register a watchdog device @@ -119,7 +174,7 @@ int watchdog_register_device(struct watchdog_device *wdd)if (wdd->ops->start ==NULL || wdd->ops->stop ==NULL )return -EINVAL ; -watchdog_check_min_max_timeout (wdd); +watchdog_check_min_max_timeouts (wdd);/* * Note: now that all watchdog_device data has been verified, we drivers/watchdog/watchdog_dev.c +32
-0@@ -218,6 +218,38 @@ out_timeout: }/* +* watchdog_set_pretimeout: set the watchdog timer pretimeout +* @wddev: the watchdog device to set the timeout for +* @pretimeout: pretimeout to set in seconds +*/ + +static int watchdog_set_pretimeout (struct watchdog_device *wddev, +unsigned int pretimeout) +{ +int err; + +if (!wddev->ops->set_pretimeout || + !(wddev->info->options &WDIOF_PRETIMEOUT )) +return -EOPNOTSUPP ; + +if (watchdog_pretimeout_invalid (wddev, pretimeout)) +return -EINVAL ; + +mutex_lock (&wddev->lock); + +if (test_bit (WDOG_UNREGISTERED , &wddev->status)) { + err = -ENODEV ; + goto out_pretimeout; + } + + err = wddev->ops->set_pretimeout (wddev, pretimeout); + +out_pretimeout: +mutex_unlock (&wddev->lock); +return err; +} + +/* * watchdog_get_timeleft: wrapper to get the time left before a reboot * @wddev: the watchdog device to get the remaining time from * @timeleft: the time that's left @@ -388,6 +420,22 @@ static long watchdog_ioctl(struct file *file, unsigned int cmd,if (wdd->timeout ==0 )return -EOPNOTSUPP ;
drivers/watchdog/watchdog_dev.c static long watchdog_ioctl(struct file *file, unsigned int cmd, · line 431
Quoted 10 lines
drivers/watchdog/watchdog_dev.c +9
-0return put_user (wdd->timeout, p); +case WDIOC_SETPRETIMEOUT : +if (get_user (val, p)) +return -EFAULT ; + err =watchdog_set_pretimeout (wdd, val); +if (err <0 ) +return err; +/* If the watchdog is active then we send a keepalive ping +* to make sure that the watchdog keep's running (and if +* possible that it takes the new timeout) */
Please use the standard multi-line comment format.
drivers/watchdog/watchdog_dev.c static long watchdog_ioctl(struct file *file, unsigned int cmd, · line 435
Quoted 4 lines
drivers/watchdog/watchdog_dev.c +4
-0+watchdog_ping (wdd); +/* Fall */ +case WDIOC_GETPRETIMEOUT : +/* timeout == 0 means that we don't use the pretimeout */
pretimeout == 0 means ...
"use" or "know" ?
Quoted 47 lines
drivers/watchdog/watchdog_dev.c +3
-0+if (wdd->pretimeout ==0 ) +return -EOPNOTSUPP ; +return put_user (wdd->pretimeout, p);case WDIOC_GETTIMELEFT : err =watchdog_get_timeleft (wdd, &val);if (err)include/linux/watchdog.h +8
-0@@ -25,6 +25,7 @@ struct watchdog_device;* @ping: The routine that sends a keepalive ping to the watchdog device. * @status: The routine that shows the status of the watchdog device. * @set_timeout:The routine for setting the watchdog devices timeout value. +* @set_pretimeout:The routine for setting the watchdog devices pretimeout value * @get_timeleft:The routine that get's the time that's left before a reset. * @ref: The ref operation for dyn. allocated watchdog_device structs * @unref: The unref operation for dyn. allocated watchdog_device structs @@ -44,6 +45,7 @@ struct watchdog_ops {int (*ping)(struct watchdog_device *);unsigned int (*status)(struct watchdog_device *);int (*set_timeout)(struct watchdog_device *,unsigned int ); +int (*set_pretimeout)(struct watchdog_device *,unsigned int );unsigned int (*get_timeleft)(struct watchdog_device *);void (*ref)(struct watchdog_device *);void (*unref)(struct watchdog_device *);@@ -62,6 +64,9 @@ struct watchdog_ops {* @timeout: The watchdog devices timeout value. * @min_timeout:The watchdog devices minimum timeout value. * @max_timeout:The watchdog devices maximum timeout value. +* @pretimeout: The watchdog devices pretimeout value. +* @min_pretimeout:The watchdog devices minimum pretimeout value. +* @max_pretimeout:The watchdog devices maximum pretimeout value. * @driver-data:Pointer to the drivers private data. * @lock: Lock for watchdog core internal use only. * @status: Field that contains the devices internal status bits. @@ -86,6 +91,9 @@ struct watchdog_device {unsigned int timeout;unsigned int min_timeout;unsigned int max_timeout; +unsigned int pretimeout; +unsigned int min_pretimeout; +unsigned int max_pretimeout;void *driver_data;struct mutex lock;unsigned long status;
include/linux/watchdog.h static inline bool watchdog_timeout_invalid(struct watchdog_device *wdd, unsigne · line 135
Quoted 8 lines
include/linux/watchdog.h +5
-0@@ -120,6 +128,14 @@ static inline bool watchdog_timeout_invalid(struct watchdog_device *wdd, unsigne (t < wdd->min_timeout || t > wdd->max_timeout)); } +/* Use the following function to check if a pretimeout value is invalid */ +static inline bool watchdog_pretimeout_invalid (struct watchdog_device *wdd, +unsigned int t) +{ + return ((wdd->max_pretimeout != 0) &&
Please drop the unnecessary ( ).
Quoted 31 lines
include/linux/watchdog.h +15
-2+ (t < wdd->min_pretimeout || t > wdd->max_pretimeout)); +} +/* Use the following functions to manipulate watchdog driver specific data */ static inline void watchdog_set_drvdata (struct watchdog_device *wdd,void *data) {@@ -132,11 +148,21 @@ static inline void *watchdog_get_drvdata(struct watchdog_device *wdd) }/* drivers/watchdog/watchdog_core.c */ -extern int watchdog_init_timeout (struct watchdog_device *wdd, -unsigned int timeout_parm,struct device *dev); +extern int watchdog_init_timeouts (struct watchdog_device *wdd, +unsigned int pretimeout_parm, +unsigned int timeout_parm, +void (*update_limits)(struct watchdog_device *), +struct device *dev);extern int watchdog_register_device (struct watchdog_device *);extern void watchdog_unregister_device (struct watchdog_device *); +static inline int watchdog_init_timeout (struct watchdog_device *wdd, +unsigned int timeout_parm, +struct device *dev) +{ +return watchdog_init_timeouts (wdd,0 , timeout_parm,NULL , dev); +} +#ifdef CONFIG_HARDLOCKUP_DETECTOR void watchdog_nmi_disable_all (void );void watchdog_nmi_enable_all (void );
Guenter Roeck
maintainerRe: [PATCH v2 5/7] Watchdog: introduce "pretimeout" into framework
In reply to [email protected]Quoted 15 lines · On Thu, May 21, 2015 at 04:32:34PM +0800…
From: Fu Wei <[email protected]>
Also update
Documentation/watchdog/watchdog-kernel-api.txtto introduce:
(1)the new elements in thewatchdog_deviceandwatchdog_opsstruct; (2)the new API "watchdog_init_timeouts".Reasons:
(1)kernel already has two watchdog drivers are using "pretimeout":
drivers/char/ipmi/ipmi_watchdog.cdrivers/watchdog/kempld_wdt.c(but the definition is different)
(2)some other dirvers are going to use this: ARM SBSA Generic WatchdogSigned-off-by Fu Wei <[email protected]>---
[ ... ]
include/linux/watchdog.h static inline bool watchdog_timeout_invalid(struct watchdog_device *wdd, unsigne · line 137
Quoted 8 lines
include/linux/watchdog.h +7
-0+/* Use the following function to check if a pretimeout value is invalid */ +static inline bool watchdog_pretimeout_invalid (struct watchdog_device *wdd, +unsigned int t) +{ +return ((wdd->max_pretimeout !=0 ) && + (t < wdd->min_pretimeout || t > wdd->max_pretimeout)); +}
Should this function also enforce "t < wdd->timeout", and should watchdog_timeout_invalid() enforce "t > wdd->pretimeout" ?
Thanks,
Guenter
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 5/7] Watchdog: introduce "pretimeout" into framework
Hi Guenter,
Quoted 20 lines · Guenter Roeck
Quoted 15 lines · On Thu, May 21, 2015 at 04:32:34PM +0800, [email protected] wrote:
From: Fu Wei <[email protected]>
Also update
Documentation/watchdog/watchdog-kernel-api.txtto introduce:
(1)the new elements in thewatchdog_deviceandwatchdog_opsstruct; (2)the new API "watchdog_init_timeouts".Reasons:
(1)kernel already has two watchdog drivers are using "pretimeout":
drivers/char/ipmi/ipmi_watchdog.cdrivers/watchdog/kempld_wdt.c(but the definition is different)
(2)some other dirvers are going to use this: ARM SBSA Generic WatchdogSigned-off-by Fu Wei <[email protected]>---
[ ... ]
Quoted 1 line
Quoted 10 lines
include/linux/watchdog.h static inline bool watchdog_timeout_invalid(struct watchdog_device *wdd, unsigne · line 137
Quoted 7 lines
include/linux/watchdog.h +7
-0+/* Use the following function to check if a pretimeout value is invalid */ +static inline bool watchdog_pretimeout_invalid (struct watchdog_device *wdd, +unsigned int t) +{ +return ((wdd->max_pretimeout !=0 ) && + (t < wdd->min_pretimeout || t > wdd->max_pretimeout)); +}Should this function also enforce "t <
wdd->timeout", and shouldwatchdog_timeout_invalid()enforce "t >wdd->pretimeout" ?
yes, you are right , thanks for the correction !! :-)
Quoted 3 lines
Thanks,
Guenter
Signature · 10 lines
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
Re: [PATCH v2 5/7] Watchdog: introduce "pretimeout" into framework
In reply to Guenter RoeckHi Guenter,
Great thanks for your suggestion,
I have put this kind of validation into watchdog_pretimeout_invalid and watchdog_timeout_invalid.
So :
(1)
set_timeout(10); ------> if this setting is successful
set_pretimeout(20); -----> return fail (-EINVAL)
(2)set_timeout(10); ------> if this setting is successful set_pretimeout(10); -----> return fail (-EINVAL)
this kind of situation will not result in an invalid / unexpected timeout value.
you will see this change in my next patchset
Quoted 33 lines · Guenter Roeck
Quoted 15 lines · On Thu, May 21, 2015 at 04:32:34PM +0800…
From: Fu Wei <[email protected]>
Also update
Documentation/watchdog/watchdog-kernel-api.txtto introduce:
(1)the new elements in thewatchdog_deviceandwatchdog_opsstruct; (2)the new API "watchdog_init_timeouts".Reasons:
(1)kernel already has two watchdog drivers are using "pretimeout":
drivers/char/ipmi/ipmi_watchdog.cdrivers/watchdog/kempld_wdt.c(but the definition is different)
(2)some other dirvers are going to use this: ARM SBSA Generic WatchdogSigned-off-by Fu Wei <[email protected]>---
[ ... ]
include/linux/watchdog.h static inline bool watchdog_timeout_invalid(struct watchdog_device *wdd, unsigne · line 137
Quoted 8 lines
include/linux/watchdog.h +7
-0+/* Use the following function to check if a pretimeout value is invalid */ +static inline bool watchdog_pretimeout_invalid (struct watchdog_device *wdd, +unsigned int t) +{ +return ((wdd->max_pretimeout !=0 ) && + (t < wdd->min_pretimeout || t > wdd->max_pretimeout)); +}Should this function also enforce "t <
wdd->timeout", and shouldwatchdog_timeout_invalid()enforce "t >wdd->pretimeout" ?Thanks,
Guenter
Signature · 14 lines
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 -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 5/7] Watchdog: introduce "pretimeout" into framework
In reply to [email protected]Quoted 7 lines · On 21.05.2015 11:32, [email protected] wrote:
From: Fu Wei <[email protected]>
Also update
Documentation/watchdog/watchdog-kernel-api.txtto introduce:
(1)the new elements in thewatchdog_deviceandwatchdog_opsstruct; (2)the new API "watchdog_init_timeouts".
Quoted 6 lines
Reasons:
(1)kernel already has two watchdog drivers are using "pretimeout":
drivers/char/ipmi/ipmi_watchdog.cdrivers/watchdog/kempld_wdt.c(but the definition is different)
(2)some other dirvers are going to use this: ARM SBSA Generic Watchdog
Hi,
As I was proposing some other API changes with my early-timeout-sec work, I can see my work is going to collide with your API change proposal a bit. So maybe I should ask your opinion as well..
Could this pretimeout feature be something that other drivers could benefit too? I can see that it does not do anything else except call panic() before letting the watchdog expire. This is something that could be emulated easily by the watchdog core for drivers that don't know anything about pretimeouts at all.
The way I was planning the API change there would need to be a small change with each watchdog driver in order to let the watchdog core take over generic behaviour on behalf of the driver. My goal was to make the change so that each driver that gets converted to the new API extensions gets a support for early-timeout-sec for free, without needing to enable support for it any way. If the API was designed properly, also pretimeouts could be handled easily and maybe even so that other drivers could have that feature even though their hardware does not explicitly give any support for it.
Any thoughts?
Thanks,
-Timo
Re: [PATCH v2 5/7] Watchdog: introduce "pretimeout" into framework
Hi Timo,
Quoted 16 lines · Timo Kokkonen
Quoted 8 lines · On 21.05.2015 11:32, [email protected] wrote:
From: Fu Wei <[email protected]>
Also update
Documentation/watchdog/watchdog-kernel-api.txtto introduce:
(1)the new elements in thewatchdog_deviceandwatchdog_opsstruct; (2)the new API "watchdog_init_timeouts".Quoted 6 lines
Reasons:
(1)kernel already has two watchdog drivers are using "pretimeout":
drivers/char/ipmi/ipmi_watchdog.cdrivers/watchdog/kempld_wdt.c(but the definition is different)
(2)some other dirvers are going to use this: ARM SBSA Generic Watchdog
Quoted 5 lines
Hi,
As I was proposing some other API changes with my early-timeout-sec work, I can see my work is going to collide with your API change proposal a bit. So maybe I should ask your opinion as well..
Thank you for reminding me of that, I saw "early-timeout-sec", but because I don't get it in kernel API or watchdog_core.c, so I did not pay attention to it.
Sorry.
Quoted 3 lines
Could this pretimeout feature be something that other drivers could benefit too?
yes , as you may know, I am making a patch for pretimeout support in watchdog framework
Quoted 4 lines
I can see that it does not do anything else except call
panic()before letting the watchdog expire. This is something that could be emulated easily by the watchdog core for drivers that don't know anything about pretimeouts at all.
For SBSA watchdog, there are two stage timeout, and according to kernel doc:
----------------------
Pretimeouts:
Some watchdog timers can be set to have a trigger go off before the actual time they will reset the system. This can be done with an NMI, interrupt, or other mechanism. This allows Linux to record useful information (like panic information and kernel coredumps) before it resets.
----------------------
I think panic() is the right way to do now. but people may also need to config :PANIC_TIMEOUT [!=0]
KEXEC
KDUMP
for debug reason
Quoted 9 lines
The way I was planning the API change there would need to be a small change with each watchdog driver in order to let the watchdog core take over generic behaviour on behalf of the driver. My goal was to make the change so that each driver that gets converted to the new API extensions gets a support for early-timeout-sec for free, without needing to enable support for it any way. If the API was designed properly, also pretimeouts could be handled easily and maybe even so that other drivers could have that feature even though their hardware does not explicitly give any support for it.
could you please point out your patch , then I can learn your idea :-) For now , I am working on a common "Pretimeouts" following the concept in kernel doc.
Quoted 2 lines
Any thoughts?
my thoughts is in my pretimeout patch , would you provide some suggestion ?
Great thanks !
Quoted 3 lines
Thanks,
-Timo
Signature · 10 lines
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
Re: [PATCH v2 5/7] Watchdog: introduce "pretimeout" into framework
Quoted 54 lines · Fu Wei
Hi Timo,
Quoted 16 lines · Timo Kokkonen
Quoted 8 lines · On 21.05.2015 11:32, [email protected] wrote:
From: Fu Wei <[email protected]>
Also update
Documentation/watchdog/watchdog-kernel-api.txtto introduce:
(1)the new elements in thewatchdog_deviceandwatchdog_opsstruct; (2)the new API "watchdog_init_timeouts".Quoted 6 lines
Reasons:
(1)kernel already has two watchdog drivers are using "pretimeout":
drivers/char/ipmi/ipmi_watchdog.cdrivers/watchdog/kempld_wdt.c(but the definition is different)
(2)some other dirvers are going to use this: ARM SBSA Generic WatchdogQuoted 5 lines
Hi,
As I was proposing some other API changes with my early-timeout-sec work, I can see my work is going to collide with your API change proposal a bit. So maybe I should ask your opinion as well..
Thank you for reminding me of that, I saw "early-timeout-sec", but because I don't get it in kernel API or
watchdog_core.c, so I did not pay attention to it.
Sorry.Quoted 3 lines
Could this pretimeout feature be something that other drivers could benefit too?
yes , as you may know, I am making a patch for pretimeout support in watchdog framework
Quoted 4 lines
I can see that it does not do anything else except call
panic()before letting the watchdog expire. This is something that could be emulated easily by the watchdog core for drivers that don't know anything about pretimeouts at all.For SBSA watchdog, there are two stage timeout, and according to kernel doc:
----------------------
Pretimeouts:Some watchdog timers can be set to have a trigger go off before the actual time they will reset the system. This can be done with an NMI, interrupt, or other mechanism. This allows Linux to record useful information (like panic information and kernel coredumps) before it resets.
----------------------
Quoted 7 lines
I think
panic()is the right way to do now. but people may also need to config :PANIC_TIMEOUT[!=0]
KEXEC
KDUMP
for debug reason
Yes, so basically if we hit pretimeout, we probably have already crashed. The only difference is that we now have some seconds time to dump out useful data and then either reboot or let the actual watchdog reset take care of resetting the device. panic() sounds like a good thing to do. Maybe you could also dump registers on other CPUs too or try to get out some other useful information about the kernel in case it has crashed or something. But I'm just guessing.
Quoted 10 lines
Quoted 9 lines
The way I was planning the API change there would need to be a small change with each watchdog driver in order to let the watchdog core take over generic behaviour on behalf of the driver. My goal was to make the change so that each driver that gets converted to the new API extensions gets a support for early-timeout-sec for free, without needing to enable support for it any way. If the API was designed properly, also pretimeouts could be handled easily and maybe even so that other drivers could have that feature even though their hardware does not explicitly give any support for it.
Quoted 9 lines
could you please point out your patch , then I can learn your idea :-) For now , I am working on a common "Pretimeouts" following the concept in kernel doc.
Quoted 2 lines
Any thoughts?
my thoughts is in my pretimeout patch , would you provide some suggestion ?
Here is an archive link to my patch set:
http://www.spinics.net/lists/linux-watchdog/msg06473.html
Your patch set is adding a new call to the core for adjusting the pretimoeut, which is probably a good thing in case the driver needs special handling for it anyway. But if the core had capability to emulate pretimeout for drivers that can't support it in hardware, it would be good if there was a way for the core to support it even though the driver had zero code for it. The core also has watchdog_init_timeout() right now but even that is not called from that many drivers. I would like to fix that too so that drivers would not need to bother so much about it but let core take care of it more. This is why I proposed the watchdog_init_params() call that could dig all the generic parameters from device tree on behalf of the driver. This is where I though timeout and early-timeout-sec parameters would be parsed from device tree, but it could also parse pretimeout parameter as well. Apparently Guenter did not like my approach so we might need some other way to do it.
I don't get to say how this should be done, I'm just throwing ideas here. But I think the watchdog core would be a lot better place for implementing the generic features than drivers. That way a lot of drivers could enable support the new features for free.
Thanks,
-Timo
Re: [PATCH v2 5/7] Watchdog: introduce "pretimeout" into framework
Hi Timo,
Quoted 75 lines · Timo Kokkonen
Quoted 66 lines · Fu Wei
Hi Timo,
Quoted 18 lines · Timo Kokkonen
Quoted 9 lines · On 21.05.2015 11:32, [email protected] wrote:
From: Fu Wei <[email protected]>
Also update
Documentation/watchdog/watchdog-kernel-api.txtto introduce:
(1)the new elements in thewatchdog_deviceandwatchdog_opsstruct; (2)the new API "watchdog_init_timeouts".Quoted 6 lines
Reasons:
(1)kernel already has two watchdog drivers are using "pretimeout":
drivers/char/ipmi/ipmi_watchdog.cdrivers/watchdog/kempld_wdt.c(but the definition is different)
(2)some other dirvers are going to use this: ARM SBSA Generic WatchdogQuoted 7 lines
Hi,
As I was proposing some other API changes with my early-timeout-sec work, I
can see my work is going to collide with your API change proposal a bit. So
maybe I should ask your opinion as well..Thank you for reminding me of that, I saw "early-timeout-sec", but because I don't get it in kernel API or
watchdog_core.c, so I did not pay attention to it.
Sorry.Quoted 4 lines
Could this pretimeout feature be something that other drivers could benefit
too?yes , as you may know, I am making a patch for pretimeout support in watchdog framework
Quoted 6 lines
I can see that it does not do anything else except call
panic()before letting the watchdog expire. This is something that could be emulated easily
by the watchdog core for drivers that don't know anything about pretimeouts
at all.For SBSA watchdog, there are two stage timeout, and according to kernel doc:
----------------------
Pretimeouts:Some watchdog timers can be set to have a trigger go off before the actual time they will reset the system. This can be done with an NMI, interrupt, or other mechanism. This allows Linux to record useful information (like panic information and kernel coredumps) before it resets.
----------------------Quoted 7 lines
I think
panic()is the right way to do now. but people may also need to config :PANIC_TIMEOUT[!=0]
KEXEC
KDUMP
for debug reason
Quoted 1 line
Yes, so basically if we hit pretimeout, we probably have already crashed.
yes, for now , I only use panic(), but at the beginning, I offer user some options:
https://lists.linaro.org/pipermail/linaro-acpi/2015-April/004350.html
Quoted 6 lines
The only difference is that we now have some seconds time to dump out useful data and then either reboot or let the actual watchdog reset take care of resetting the device.
panic()sounds like a good thing to do. Maybe you could also dump registers on other CPUs too or try to get out some other useful information about the kernel in case it has crashed or something. But I'm just guessing.
yes, that is my thought.
because there is the kdump support in panic(), so that can give use a chance to figure out why the watchdog wasn't fed.
Quoted 24 lines
Quoted 24 lines
Quoted 14 lines
The way I was planning the API change there would need to be a small change
with each watchdog driver in order to let the watchdog core take over generic behaviour on behalf of the driver. My goal was to make the change so
that each driver that gets converted to the new API extensions gets a support for early-timeout-sec for free, without needing to enable support for it any way. If the API was designed properly, also pretimeouts could be
handled easily and maybe even so that other drivers could have that feature
even though their hardware does not explicitly give any support for it.could you please point out your patch , then I can learn your idea :-) For now , I am working on a common "Pretimeouts" following the concept in kernel doc.
Quoted 2 lines
Any thoughts?
Quoted 7 lines
Quoted 3 lines
my thoughts is in my pretimeout patch , would you provide some suggestion ?
Here is an archive link to my patch set:
Ah , cool, I can see some common in your patch. Thanks :-) See if I can learn something from your patches
Quoted 15 lines
Your patch set is adding a new call to the core for adjusting the pretimoeut, which is probably a good thing in case the driver needs special handling for it anyway. But if the core had capability to emulate pretimeout for drivers that can't support it in hardware, it would be good if there was a way for the core to support it even though the driver had zero code for it. The core also has
watchdog_init_timeout()right now but even that is not called from that many drivers. I would like to fix that too so that drivers would not need to bother so much about it but let core take care of it more. This is why I proposed thewatchdog_init_params()call that could dig all the generic parameters from device tree on behalf of the driver. This is where I though timeout and early-timeout-sec parameters would be parsed from device tree, but it could also parse pretimeout parameter as well. Apparently Guenter did not like my approach so we might need some other way to do it.
I am using pretimeout, because SBSA watchdog hardware support two stages timeout,
I am reusing the existing kernel concept, but your early_timeout_sec is a new concept.
If you check my previous patchset , you will see : at the beginning, pretimeout support is not a generic features in my patchset. Then Arnd suggest that I can try to make pretimeout into watchdog framework, and Guenter said :"Makes sense."
So I am still trying to improve pretimeout support :-)
If I can make pretimeout merged, may be you can try pretimeout to implement early_timeout_sec function?
It is up to the maintainers, I will try my best.
Thanks :-)
Quoted 8 lines
I don't get to say how this should be done, I'm just throwing ideas here. But I think the watchdog core would be a lot better place for implementing the generic features than drivers. That way a lot of drivers could enable support the new features for free.
Thanks,
-Timo
Signature · 14 lines
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 -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 5/7] Watchdog: introduce "pretimeout" into framework
Quoted 92 lines · Fu Wei
Hi Timo,
Quoted 75 lines · Timo Kokkonen
Quoted 66 lines · Fu Wei
Hi Timo,
Quoted 18 lines · Timo Kokkonen
Quoted 9 lines · On 21.05.2015 11:32, [email protected] wrote:
From: Fu Wei <[email protected]>
Also update
Documentation/watchdog/watchdog-kernel-api.txtto introduce:
(1)the new elements in thewatchdog_deviceandwatchdog_opsstruct; (2)the new API "watchdog_init_timeouts".Quoted 6 lines
Reasons:
(1)kernel already has two watchdog drivers are using "pretimeout":
drivers/char/ipmi/ipmi_watchdog.cdrivers/watchdog/kempld_wdt.c(but the definition is different)
(2)some other dirvers are going to use this: ARM SBSA Generic WatchdogQuoted 7 lines
Hi,
As I was proposing some other API changes with my early-timeout-sec work, I
can see my work is going to collide with your API change proposal a bit. So
maybe I should ask your opinion as well..Thank you for reminding me of that, I saw "early-timeout-sec", but because I don't get it in kernel API or
watchdog_core.c, so I did not pay attention to it.
Sorry.Quoted 4 lines
Could this pretimeout feature be something that other drivers could benefit
too?yes , as you may know, I am making a patch for pretimeout support in watchdog framework
Quoted 6 lines
I can see that it does not do anything else except call
panic()before letting the watchdog expire. This is something that could be emulated easily
by the watchdog core for drivers that don't know anything about pretimeouts
at all.For SBSA watchdog, there are two stage timeout, and according to kernel doc:
----------------------
Pretimeouts:Some watchdog timers can be set to have a trigger go off before the actual time they will reset the system. This can be done with an NMI, interrupt, or other mechanism. This allows Linux to record useful information (like panic information and kernel coredumps) before it resets.
----------------------Quoted 7 lines
I think
panic()is the right way to do now. but people may also need to config :PANIC_TIMEOUT[!=0]
KEXEC
KDUMP
for debug reasonQuoted 1 line
Yes, so basically if we hit pretimeout, we probably have already crashed.
yes, for now , I only use
panic(), but at the beginning, I offer user some options:https://lists.linaro.org/pipermail/linaro-acpi/2015-April/004350.html
Quoted 6 lines
The only difference is that we now have some seconds time to dump out useful data and then either reboot or let the actual watchdog reset take care of resetting the device.
panic()sounds like a good thing to do. Maybe you could also dump registers on other CPUs too or try to get out some other useful information about the kernel in case it has crashed or something. But I'm just guessing.
Quoted 4 lines
yes, that is my thought.
because there is the kdump support inpanic(), so that can give use a chance to figure out why the watchdog wasn't fed.
Yes indeed, sounds good!
Quoted 51 lines
Quoted 24 lines
Quoted 24 lines
Quoted 14 lines
The way I was planning the API change there would need to be a small change
with each watchdog driver in order to let the watchdog core take over generic behaviour on behalf of the driver. My goal was to make the change so
that each driver that gets converted to the new API extensions gets a support for early-timeout-sec for free, without needing to enable support for it any way. If the API was designed properly, also pretimeouts could be
handled easily and maybe even so that other drivers could have that feature
even though their hardware does not explicitly give any support for it.could you please point out your patch , then I can learn your idea :-) For now , I am working on a common "Pretimeouts" following the concept in kernel doc.
Quoted 2 lines
Any thoughts?
Quoted 7 lines
Quoted 3 lines
my thoughts is in my pretimeout patch , would you provide some suggestion ?
Here is an archive link to my patch set:
Ah , cool, I can see some common in your patch. Thanks :-) See if I can learn something from your patches
Quoted 15 lines
Your patch set is adding a new call to the core for adjusting the pretimoeut, which is probably a good thing in case the driver needs special handling for it anyway. But if the core had capability to emulate pretimeout for drivers that can't support it in hardware, it would be good if there was a way for the core to support it even though the driver had zero code for it. The core also has
watchdog_init_timeout()right now but even that is not called from that many drivers. I would like to fix that too so that drivers would not need to bother so much about it but let core take care of it more. This is why I proposed thewatchdog_init_params()call that could dig all the generic parameters from device tree on behalf of the driver. This is where I though timeout and early-timeout-sec parameters would be parsed from device tree, but it could also parse pretimeout parameter as well. Apparently Guenter did not like my approach so we might need some other way to do it.
Quoted 4 lines
I am using pretimeout, because SBSA watchdog hardware support two stages timeout,
I am reusing the existing kernel concept, but yourearly_timeout_secis a new concept.
Yes, the early-timeout-sec concept itself is new in mainline but there are a lot of production devices out there that start up with watchdog running and the watchdog must not be stopped ever. Those devices typically hack the watchdog policy somehow into the drivers so that they don't just freeze even if kernel or early userspace happens to crash for some reason. So I thought it would be about time to get support for this in mainline. I don't want to hack this feature any more into drivers :)
Quoted 4 lines
If you check my previous patchset , you will see : at the beginning, pretimeout support is not a generic features in my patchset. Then Arnd suggest that I can try to make pretimeout into watchdog framework, and Guenter said :"Makes sense."
Yeah, the same story as mine. Early-timeout-sec was first atmel driver specific but I was told to think something more generic. At first I objected as I felt I would need to implement a lot of stuff into the core before I could make it generic. Then I was given chance to spend some time with this and I actually wrote a generic implementation in the core in a way that allows all drivers to use it with minimal modifications. It also lets core deal with unstoppable watchdogs and watchdogs with very short maximum timeout so that driver don't need special handling for it.
Quoted 4 lines
So I am still trying to improve pretimeout support :-) If I can make pretimeout merged, may be you can try pretimeout to implement
early_timeout_secfunction?
It is up to the maintainers, I will try my best.
Yes, which brings us to the actual implementation details. Right now we only have watchdog_init_timeout() that some drivers are using. Your proposal is going into direction where we would also have init_watchdog_pretimeout() or init_watchdog_timeouts() call. Drivers providing pretimeout support would call these functions to set up pretimeout values.
My patch set is taking the timeout concept into completely different direction where we have hardware timeout properties and then we have userspace timeout requests. Watchdog core is in the middle and checks whether userspace timeout requested by user is something small enough that the hardware can actually support. If not, a worker pings the watchdog core on behalf of userspace so that user daemon can have longer timeout. The same works with unstoppable watchdogs and the new early-timeout-sec property. Right now drivers with restricted hardware are just implementing this on their own.
Also the parameter parsing is different on my patch set. I was trying to make it so that all generic parameters were parsed by the core and driver would not need to bother about then, unless user had specified eg. module parameter that it fills in the watchdog_device structure and the core would not then override it. This way new parameters could be introduced in a way that the driver does not explicitly need to implement support for it if core knows how to handle it. There was someone making windowed watchdogs, maybe we could implement support for that in core and let the watchdog core emulate windowed watchdog support for all drivers even if the actual hardware implementation was not there.
This is the direction we could go eventually. Of course not all features are in interest for everyone and it may not make sense to try implement everything in the core. But we have a lot of drivers that implement all sorts of timers in them and my patch set could eliminate a lot of code from them. We also have couple of drivers that have pretimeout support and there seems to be a desire make that generic as well. Obviously I think it makes sense to combine this effort in order to avoid conflicts.
So I am too hoping more guidelines on what is the acceptable direction where to aim at. For example we could make this parameter handling more generic and future proof if we allow an API change that require small change to all drivers. I don't know exactly where the line is drawn.
Thanks,
-Timo
Guenter Roeck
maintainerRe: [PATCH v2 5/7] Watchdog: introduce "pretimeout" into framework
On 05/22/2015 05:14 AM, Timo Kokkonen wrote:
[ ... ]
Quoted 2 lines
This is the direction we could go eventually. Of course not all features are in interest for everyone and it may not make sense to try implement everything in the core. But we have a lot of drivers that implement all sorts of timers in them and my patch set could eliminate a lot of code from them. We also have couple of drivers that have pretimeout support and there seems to be a desire make that generic as well. Obviously I think it makes sense to combine this effort in order to avoid conflicts.
I would suggest to avoid trying to combine efforts. If anything, I would suggest to _separate_ patch sets.
Quoted 2 lines
So I am too hoping more guidelines on what is the acceptable direction where to aim at. For example we could make this parameter handling more generic and future proof if we allow an API change that require small change to all drivers. I don't know exactly where the line is drawn.
As I just mentioned separately, the more changes you make, the less likely it will be to get your changes accepted. A patch set requiring changes to all drivers would have to provide substantial benefits to get accepted. Talking about parameters (and assuming you mean module parameters), I don't even see how you could make that work without changing the userspace ABI, which would be a no-go.
Personally I think it would be easier if you tried to accomplish less than more. Concentrate on early-timeout (only), get it merged. Provide a clear separation between is_active (as in "watchdog running") from is_open (userspace has the driver open) and get it merged. Add the ability to "ping" a running watchdog while the driver is closed into the watchdog core and get it merged. Add the ability to soft-ping a watchdog while the driver is open into the core and get it merged. Those are all logically separate functions, and could be introduced separately.
Just my personal opinion, of course.
Thanks,
Guenter
Guenter Roeck
maintainerRe: [PATCH v2 5/7] Watchdog: introduce "pretimeout" into framework
In reply to Fu WeiQuoted 2 lines · Fu Wei
Hi Timo,
[ ... ]
Quoted 1 line
So I am still trying to improve pretimeout support :-)
Is there anything still missing from it ?
Quoted 2 lines
If I can make pretimeout merged, may be you can try pretimeout to implement
early_timeout_secfunction?
Not sure how one would or even could do that.
Do you mean "implement early_pretimeout_sec", by any chance ?
Quoted 2 lines
It is up to the maintainers, I will try my best.
Please don't make the pretimeout concept more complicated than necessary.
The smaller the patch, the more likely it is to get accepted. The more you change, the more difficult it is for the maintainer to, for example, back-port later bug fixes into earlier kernel releases when needed. This is why it is, for example, better to keep the existing watchdog_init_timeout() function instead of just replacing it with watchdog_init_timeouts().
Try to put yourself into the maintainer's perspective: If you were the maintainer, would you rather accept a patch or patch set which maintains the existing API and doesn't require any changes to existing drivers, or would you accept one that changes, say, some function or variable names and will require manual back-ports later on if there is a bug fix ? Would you rather accept a patch that adds 50 lines of code, or one that changes another 100+ lines and rearranges everything along the line ?
Thanks,
Guenter
Re: [PATCH v2 5/7] Watchdog: introduce "pretimeout" into framework
Hi Guenter.
Sorry for my poor English .
let me explain this :
Quoted 11 lines · Guenter Roeck
Quoted 3 lines · Fu Wei
Hi Timo,
[ ... ]
Quoted 1 line
So I am still trying to improve pretimeout support :-)
Is there anything still missing from it ?
Quoted 7 lines
Quoted 2 lines
If I can make pretimeout merged, may be you can try pretimeout to implement
early_timeout_secfunction?Not sure how one would or even could do that.
Do you mean "implement
early_pretimeout_sec", by any chance ?
I mean: using pretimeout to implement the function you want, instead of early_pretimeout_sec
Hope I say the right word this time :-)
Quoted 25 lines
Quoted 3 lines
It is up to the maintainers, I will try my best.
Please don't make the pretimeout concept more complicated than necessary.
The smaller the patch, the more likely it is to get accepted. The more you change, the more difficult it is for the maintainer to, for example, back-port later bug fixes into earlier kernel releases when needed. This is why it is, for example, better to keep the existing
watchdog_init_timeout()function instead of just replacing it withwatchdog_init_timeouts().Try to put yourself into the maintainer's perspective: If you were the maintainer, would you rather accept a patch or patch set which maintains the existing API and doesn't require any changes to existing drivers, or would you accept one that changes, say, some function or variable names and will require manual back-ports later on if there is a bug fix ? Would you rather accept a patch that adds 50 lines of code, or one that changes another 100+ lines and rearranges everything along the line ?
Thanks,
Guenter
Signature · 14 lines
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 -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Guenter Roeck
maintainerRe: [PATCH v2 5/7] Watchdog: introduce "pretimeout" into framework
Quoted 21 lines · Fu Wei
Hi Guenter.
Sorry for my poor English .
let me explain this :Quoted 15 lines · Guenter Roeck
Quoted 3 lines · Fu Wei
Hi Timo,
[ ... ]
Quoted 1 line
So I am still trying to improve pretimeout support :-)
Is there anything still missing from it ?
Quoted 2 lines
If I can make pretimeout merged, may be you can try pretimeout to implement
early_timeout_secfunction?
Quoted 7 lines
Quoted 3 lines
Not sure how one would or even could do that.
Do you mean "implement
early_pretimeout_sec", by any chance ?I mean: using pretimeout to implement the function you want, instead of
early_pretimeout_sec
How would this work if the watchdog hardware doesn't support pretimeout ?
Pretimeout and early timeout are two logically different functions, with different goals, so I don't entirely (if at all) understand why it would make sense to tie them together.
Can you elaborate why you think this would be a good idea ?
Thanks,
Guenter
Re: [PATCH v2 5/7] Watchdog: introduce "pretimeout" into framework
Hi Guenter,
Quoted 29 lines · Guenter Roeck
Quoted 21 lines · Fu Wei
Hi Guenter.
Sorry for my poor English .
let me explain this :Quoted 15 lines · Guenter Roeck
Quoted 3 lines · Fu Wei
Hi Timo,
[ ... ]
Quoted 1 line
So I am still trying to improve pretimeout support :-)
Is there anything still missing from it ?
Quoted 2 lines
If I can make pretimeout merged, may be you can try pretimeout to implement
early_timeout_secfunction?Quoted 7 lines
Quoted 3 lines
Not sure how one would or even could do that.
Do you mean "implement
early_pretimeout_sec", by any chance ?I mean: using pretimeout to implement the function you want, instead of
early_pretimeout_sec
Quoted 7 lines
How would this work if the watchdog hardware doesn't support pretimeout ?
Pretimeout and early timeout are two logically different functions, with different goals, so I don't entirely (if at all) understand why it would make sense to tie them together.
Can you elaborate why you think this would be a good idea ?
sorry, my apology. forget about this, :-)
I think we should focus on SBSA watchdog patch here, but not a early_timeout_sec.
Quoted 7 lines
Thanks,
Guenter
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Signature · 10 lines
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
PATCH v2 6/7 Watchdog: introduce ARM SBSA watchdog driver
In reply to [email protected]From: Fu Wei <[email protected]>
This driver bases on linux kernel watchdog framework, and use "pretimeout" in the framework. It supports getting timeout and pretimeout from parameter and FDT at the driver init stage. In first timeout(WS0), the interrupt routine run panic to save system context.
--- drivers/watchdog/Kconfig | 12 ++ drivers/watchdog/Makefile | 1 + drivers/watchdog/sbsa_gwdt.c | 476 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 489 insertions(+) create mode 100644 drivers/watchdog/sbsa_gwdt.c
drivers/watchdog/Kconfig +12 -0
@@ -152,6 +152,18 @@ 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 ARM || ARM64 || COMPILE_TEST + depends on ARM_ARCH_TIMER + select WATCHDOG_CORE + help + ARM SBSA Generic Watchdog timer. This has two Watchdog Signals + (WS0/WS1), will trigger a warning interrupt(do panic) at the first + timeout(WS0); will reboot your system when the second timeout(WS1) + is reached. + More details: DEN0029B - Server Base System Architecture (SBSA) + config AT91RM9200_WATCHDOG tristate "AT91RM9200 watchdog" depends on SOC_AT91RM9200 && MFD_SYSCON
drivers/watchdog/Makefile +1 -0
@@ -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_AT91RM9200_WATCHDOG) += at91rm9200_wdt.o obj-$(CONFIG_AT91SAM9X_WATCHDOG) += at91sam9_wdt.o obj-$(CONFIG_CADENCE_WATCHDOG) += cadence_wdt.o
drivers/watchdog/sbsa_gwdt.c new file +476 -0
476 lines not on this page · raw message
Signature · 6 lines
1.9.1 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Guenter Roeck
maintainerRe: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
Quoted 24 lines · On 05/21/2015 01:32 AM, [email protected] wrote:
From: Fu Wei <[email protected]>
This driver bases on linux kernel watchdog framework, and use "pretimeout" in the framework. It supports getting timeout and pretimeout from parameter and FDT at the driver init stage. In first timeout(WS0), the interrupt routine run panic to save system context.
Signed-off-by Fu Wei <[email protected]>--- drivers/watchdog/Kconfig | 12 ++ drivers/watchdog/Makefile | 1 + drivers/watchdog/sbsa_gwdt.c | 476 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 489 insertions(+)create mode 100644
drivers/watchdog/sbsa_gwdt.cdrivers/watchdog/Kconfig +0
-0@@ -152,6 +152,18 @@ config ARM_SP805_WATCHDOG ARM Primecell SP805 Watchdog timer. This will reboot your system when the timeout is reached.
drivers/watchdog/Kconfig config ARM_SP805_WATCHDOG · line 164
Quoted 10 lines
drivers/watchdog/Kconfig +10
-0+config ARM_SBSA_WATCHDOG + tristate "ARM SBSA Generic Watchdog" + depends on ARM || ARM64 || COMPILE_TEST + depends on ARM_ARCH_TIMER + select WATCHDOG_CORE + help + ARM SBSA Generic Watchdog timer. This has two Watchdog Signals + (WS0/WS1), will trigger a warning interrupt(do panic) at the first + timeout(WS0); will reboot your system when the second timeout(WS1) + is reached.
I think it would be better to keep the WS0/WS1 out of the help text. It is an implementation detail, and no user will be able to make sense of it.
Quoted 131 lines
drivers/watchdog/Kconfig +2
-0+ More details: DEN0029B - Server Base System Architecture (SBSA) + config AT91RM9200_WATCHDOG tristate "AT91RM9200 watchdog" depends on SOC_AT91RM9200 && MFD_SYSCONdrivers/watchdog/Makefile +1
-0@@ -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_AT91RM9200_WATCHDOG) += at91rm9200_wdt.o obj-$(CONFIG_AT91SAM9X_WATCHDOG) += at91sam9_wdt.o obj-$(CONFIG_CADENCE_WATCHDOG) += cadence_wdt.odrivers/watchdog/sbsa_gwdt.c new file +108
-0@@ -0,0 +1,476 @@ +/* +* SBSA(Server Base System Architecture) Generic Watchdog driver +* +* Copyright (c) 2015, Linaro Ltd. +* Author: Fu Wei <[email protected]> +* Suravee Suthikulpanit <[email protected]> +* +* 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. +* +* Note: This SBSA Generic watchdog driver is compatible with +* the pretimeout concept of Linux kernel. +* The timeout and pretimeout are set by the different REGs. +* The first watch period is set by writing WCV directly, +* that can support more than 10s timeout at the maximum +* system counter frequency. +* The second watch period is set by WOR(32bit) which will be loaded +* automatically by hardware, when WS0 is triggered. +* This gives a maximum watch period of around 10s at the maximum +* system counter frequency. +* The System Counter shall run at maximum of 400MHz. +* More details: DEN0029B - Server Base System Architecture (SBSA) +* +* Kernel/API: P---------| pretimeout +* |-------------------------------T timeout +* SBSA GWDT: P--WOR---WS1 pretimeout +* |-------WCV----------WS0~~~~~~~~T timeout +*/ + +#include <asm/arch_timer.h> + +#include <linux/acpi.h> +#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> + +/* 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_LO 0x010 +#define SBSA_GWDT_WCV_HI 0x014 + +/* 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 10/* seconds, the 1st + 2nd watch periods*/ +#define DEFAULT_PRETIMEOUT 5/* seconds, the 2nd watch period*/ + +static unsigned int timeout; +module_param (timeout, uint,0 ); +MODULE_PARM_DESC (timeout, + "Watchdog timeout in seconds. (>=0, default=" + __MODULE_STRING(DEFAULT_TIMEOUT) ")"); + +static unsigned int max_timeout =UINT_MAX ; +module_param (max_timeout, uint,0 ); +MODULE_PARM_DESC (max_timeout, + "Watchdog max timeout in seconds. (>=0, default=" + __MODULE_STRING(UINT_MAX) ")"); + +static unsigned int pretimeout; +module_param (pretimeout, uint,0 ); +MODULE_PARM_DESC (pretimeout, + "Watchdog pretimeout in seconds. (>=0, default=" + __MODULE_STRING(DEFAULT_PRETIMEOUT) ")"); + +static unsigned int max_pretimeout =U32_MAX ; +module_param (max_pretimeout, uint,0 ); +MODULE_PARM_DESC (max_pretimeout, + "Watchdog max pretimeout in seconds. (>=0, default="
drivers/watchdog/sbsa_gwdt.c line 118
Quoted 10 lines
drivers/watchdog/sbsa_gwdt.c new file +10
-0+ __MODULE_STRING(U32_MAX) ")"); + +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) ")"); + +/* +* Architected system timer support.
Architected ? Sounds a bit odd. Not sure if this comment serves a real purpose.
Quoted 16 lines
drivers/watchdog/sbsa_gwdt.c new file +16
-0+*/ +static void sbsa_gwdt_cf_write (unsigned int reg,u32 val, +struct watchdog_device *wdd) +{ +struct sbsa_gwdt *gwdt =to_sbsa_gwdt (wdd); + +writel_relaxed (val, gwdt->control_base + reg); +} + +static void sbsa_gwdt_rf_write (unsigned int reg,u32 val, +struct watchdog_device *wdd) +{ +struct sbsa_gwdt *gwdt =to_sbsa_gwdt (wdd); + +writel_relaxed (val, gwdt->refresh_base + reg); +}
drivers/watchdog/sbsa_gwdt.c line 144
Quoted 10 lines
drivers/watchdog/sbsa_gwdt.c new file +10
-0+ +static u32 sbsa_gwdt_cf_read (unsigned int reg,struct watchdog_device *wdd) +{ +struct sbsa_gwdt *gwdt =to_sbsa_gwdt (wdd); + +return readl_relaxed (gwdt->control_base + reg); +} + +/* +* help founctions for accessing 64bit WCV register
functions
Quoted 27 lines
drivers/watchdog/sbsa_gwdt.c new file +27
-0+*/ +static u64 sbsa_gwdt_get_wcv (struct watchdog_device *wdd) +{ +u32 wcv_lo, wcv_hi; + +do { + wcv_hi =sbsa_gwdt_cf_read (SBSA_GWDT_WCV_HI , wdd); + wcv_lo =sbsa_gwdt_cf_read (SBSA_GWDT_WCV_LO , wdd); + }while (wcv_hi !=sbsa_gwdt_cf_read (SBSA_GWDT_WCV_HI , wdd)); + +return (((u64 )wcv_hi <<32 ) | wcv_lo); +} + +static void sbsa_gwdt_set_wcv (struct watchdog_device *wdd,u64 value) +{ +u32 wcv_lo, wcv_hi; + + wcv_lo = value &U32_MAX ; + wcv_hi = (value >>32 ) &U32_MAX ; + +sbsa_gwdt_cf_write (SBSA_GWDT_WCV_HI , wcv_hi, wdd); +sbsa_gwdt_cf_write (SBSA_GWDT_WCV_LO , wcv_lo, wdd); +} + +static void reload_timeout_to_wcv (struct watchdog_device *wdd) +{ +struct sbsa_gwdt *gwdt =to_sbsa_gwdt (wdd);
drivers/watchdog/sbsa_gwdt.c line 181
Quoted 10 lines
drivers/watchdog/sbsa_gwdt.c new file +10
-0+u64 wcv; + + wcv =arch_counter_get_cntvct () + + (u64)(wdd->timeout - wdd->pretimeout) * gwdt->clk; + +sbsa_gwdt_set_wcv (wdd, wcv); +} + +/* +* Use the following function to set the limit of timeout
s/limit of timeout/timeout limits/
Quoted 38 lines
drivers/watchdog/sbsa_gwdt.c new file +38
-0+* after updating pretimeout +*/ +static void sbsa_gwdt_update_limits (struct watchdog_device *wdd) +{ +struct sbsa_gwdt *gwdt =to_sbsa_gwdt (wdd); +u64 first_period_max =U64_MAX ; + +do_div (first_period_max, gwdt->clk); + + wdd->min_timeout = wdd->pretimeout +1 ; + wdd->max_timeout =min ((uint)(wdd->pretimeout + first_period_max), + wdd->max_timeout); +} + +static int sbsa_gwdt_set_timeout (struct watchdog_device *wdd, +unsigned int timeout) +{ + wdd->timeout = timeout; + +return 0 ; +} + +static int sbsa_gwdt_set_pretimeout (struct watchdog_device *wdd, +unsigned int pretimeout) +{ +struct sbsa_gwdt *gwdt =to_sbsa_gwdt (wdd); +u32 wor; + + wdd->pretimeout = pretimeout; +sbsa_gwdt_update_limits (wdd); + +if (!pretimeout) +/* gives sbsa_gwdt_start a chance to setup timeout */ + wor = gwdt->clk; +else + wor = pretimeout * gwdt->clk; + +/* refresh the WOR, that will cause an explicit watchdog refresh */
drivers/watchdog/sbsa_gwdt.c line 229
Quoted 10 lines
drivers/watchdog/sbsa_gwdt.c new file +10
-0+sbsa_gwdt_cf_write (SBSA_GWDT_WOR , wor, wdd); + +return 0 ; +} + +static unsigned int sbsa_gwdt_get_timeleft (struct watchdog_device *wdd) +{ +struct sbsa_gwdt *gwdt =to_sbsa_gwdt (wdd); +u64 timeleft =sbsa_gwdt_get_wcv (wdd) -arch_counter_get_cntvct (); +
Still not happy about the use of arch_counter_get_cntvct instead of using the clock subsystem. I am quite sure this could be done, possibly through arch_sys_counter, though at this point I am getting wary of bringing it up, so I guess I'll just let it go.
Quoted 79 lines
drivers/watchdog/sbsa_gwdt.c new file +79
-0+do_div (timeleft, gwdt->clk); + +return timeleft; +} + +static int sbsa_gwdt_start (struct watchdog_device *wdd) +{ +/* Force refresh */ +sbsa_gwdt_rf_write (SBSA_GWDT_WRR ,0xc0ffee , wdd); +/* writing WCS will cause an explicit watchdog refresh */ +sbsa_gwdt_cf_write (SBSA_GWDT_WCS ,SBSA_GWDT_WCS_EN , wdd); + +reload_timeout_to_wcv (wdd); + +return 0 ; +} + +static int sbsa_gwdt_stop (struct watchdog_device *wdd) +{ +/* Force refresh */ +sbsa_gwdt_rf_write (SBSA_GWDT_WRR ,0xc0ffee , wdd); +/* writing WCS will cause an explicit watchdog refresh */ +sbsa_gwdt_cf_write (SBSA_GWDT_WCS ,0 , wdd); + +return 0 ; +} + +static int sbsa_gwdt_keepalive (struct watchdog_device *wdd) +{ +/* +* Writing WRR for an explicit watchdog refresh +* You can write anyting(like 0xc0ffee) +*/ +sbsa_gwdt_rf_write (SBSA_GWDT_WRR ,0xc0ffee , wdd); + +reload_timeout_to_wcv (wdd); + +return 0 ; +} + +static irqreturn_t sbsa_gwdt_interrupt (int irq,void *dev_id) +{ +struct sbsa_gwdt *gwdt = (struct sbsa_gwdt *)dev_id; +struct watchdog_device *wdd = &gwdt->wdd; +u32 status; + + status =sbsa_gwdt_cf_read (SBSA_GWDT_WCS , wdd); + +if (status &SBSA_GWDT_WCS_WS0 ) +panic ("SBSA Watchdog pre-timeout" ); + +return IRQ_HANDLED ; +} + +static struct watchdog_info sbsa_gwdt_info = { + .identity ="SBSA Generic Watchdog" , + .options =WDIOF_SETTIMEOUT | +WDIOF_KEEPALIVEPING | +WDIOF_MAGICCLOSE | +WDIOF_PRETIMEOUT | +WDIOF_CARDRESET , +}; + +static struct watchdog_ops sbsa_gwdt_ops = { + .owner =THIS_MODULE , + .start = sbsa_gwdt_start, + .stop = sbsa_gwdt_stop, + .ping = sbsa_gwdt_keepalive, + .set_timeout = sbsa_gwdt_set_timeout, + .set_pretimeout = sbsa_gwdt_set_pretimeout, + .get_timeleft = sbsa_gwdt_get_timeleft, +}; + +static int sbsa_gwdt_probe (struct platform_device *pdev) +{ +struct device *dev = &pdev->dev; +struct sbsa_gwdt *gwdt; +struct watchdog_device *wdd; +struct resource *res;
drivers/watchdog/sbsa_gwdt.c line 318
Quoted 10 lines
drivers/watchdog/sbsa_gwdt.c new file +10
-0+void *rf_base, *cf_base; +int irq; +u32 clk, status; +int ret =0 ; +u64 first_period_max =U64_MAX ; + +/* +* Try to determine the frequency from the arch_timer interface +*/ + clk =arch_timer_get_rate ();
arch_timer_get_rate() does not seem to be exported. Did you try to build the driver as module ?
Quoted 149 lines
drivers/watchdog/sbsa_gwdt.c new file +148
-0+if (!clk) { +dev_err (dev,"System Counter frequency not available\n" ); +return -EINVAL ; + } + + gwdt =devm_kzalloc (dev,sizeof (*gwdt),GFP_KERNEL ); +if (!gwdt) +return -ENOMEM ; + + res =platform_get_resource_byname (pdev,IORESOURCE_MEM ,"refresh" ); + rf_base =devm_ioremap_resource (dev, res); +if (IS_ERR (rf_base)) +return PTR_ERR (rf_base); + + res =platform_get_resource_byname (pdev,IORESOURCE_MEM ,"control" ); + cf_base =devm_ioremap_resource (dev, res); +if (IS_ERR (rf_base)) +return PTR_ERR (rf_base); + + irq =platform_get_irq_byname (pdev,"ws0" ); +if (irq <0 ) { +dev_err (dev,"unable to get ws0 interrupt.\n" ); +return irq; + } + + gwdt->refresh_base = rf_base; + gwdt->control_base = cf_base; + gwdt->clk = clk; + +platform_set_drvdata (pdev, gwdt); + + 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); + + status =sbsa_gwdt_cf_read (SBSA_GWDT_WCS , wdd); +if (status &SBSA_GWDT_WCS_WS1 ) { +dev_warn (dev,"System reset by WDT(WCS: %x, WCV: %llx)\n" , + status,sbsa_gwdt_get_wcv (wdd)); + wdd->bootstatus |=WDIOF_CARDRESET ; + } +/* Check if watchdog is already enabled */ +if (status &SBSA_GWDT_WCS_EN ) { +dev_warn (dev,"already enabled! WCS:0x%x\n" , status); +sbsa_gwdt_keepalive (wdd); + } + + wdd->min_pretimeout =0 ; + wdd->max_pretimeout =min (U32_MAX / clk, max_pretimeout); + wdd->min_timeout =1 ; +do_div (first_period_max, clk); + wdd->max_timeout =min ((uint)(wdd->pretimeout + first_period_max), + max_timeout); + + wdd->pretimeout =DEFAULT_PRETIMEOUT ; + wdd->timeout =DEFAULT_TIMEOUT ; +watchdog_init_timeouts (wdd, pretimeout, timeout, + sbsa_gwdt_update_limits, dev); +/* update pretimeout to WOR */ +sbsa_gwdt_cf_write (SBSA_GWDT_WOR , wdd->pretimeout * clk, wdd); + + ret =devm_request_irq (dev, irq, sbsa_gwdt_interrupt,IRQF_TIMER , + pdev->name, gwdt); +if (ret) { +dev_err (dev,"unable to request IRQ %d\n" , irq); +return ret; + } + + ret =watchdog_register_device (wdd); +if (ret) +return ret; + +dev_info (dev,"Initialized with %ds timeout, %ds pretimeout @ %uHz\n" , + wdd->timeout, wdd->pretimeout, gwdt->clk); + +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); +int ret =0 ; + +if (!nowayout) + ret =sbsa_gwdt_stop (&gwdt->wdd); + +watchdog_unregister_device (&gwdt->wdd); + +return ret; +} + +/* 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,
drivers/watchdog/sbsa_gwdt.c line 476
Quoted 10 lines
drivers/watchdog/sbsa_gwdt.c new file +10
-0+ .id_table = sbsa_gwdt_pdev_match, +}; + +module_platform_driver (sbsa_gwdt_driver); + +MODULE_DESCRIPTION ("SBSA Generic Watchdog Driver" ); +MODULE_VERSION ("v1.0" ); +MODULE_AUTHOR ("Fu Wei <[email protected]>" ); +MODULE_AUTHOR ("Suravee Suthikulpanit <[email protected]>" ); +MODULE_LICENSE ("GPL v2" );
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
Hi Guenter,
Thanks for review :-)
Quoted 37 lines · Guenter Roeck
Quoted 36 lines · On 05/21/2015 01:32 AM, [email protected] wrote:
From: Fu Wei <[email protected]>
This driver bases on linux kernel watchdog framework, and use "pretimeout" in the framework. It supports getting timeout and pretimeout from parameter and FDT at the driver init stage. In first timeout(WS0), the interrupt routine run panic to save system context.
Signed-off-by Fu Wei <[email protected]>--- drivers/watchdog/Kconfig | 12 ++ drivers/watchdog/Makefile | 1 + drivers/watchdog/sbsa_gwdt.c | 476 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 489 insertions(+)create mode 100644
drivers/watchdog/sbsa_gwdt.cdrivers/watchdog/Kconfig +0
-0@@ -152,6 +152,18 @@ config ARM_SP805_WATCHDOG ARM Primecell SP805 Watchdog timer. This will reboot your systemwhen
the timeout is reached.drivers/watchdog/Kconfig +8
-0+config ARM_SBSA_WATCHDOG + tristate "ARM SBSA Generic Watchdog" + depends on ARM || ARM64 || COMPILE_TEST + depends on ARM_ARCH_TIMER + select WATCHDOG_CORE + help + ARM SBSA Generic Watchdog timer. This has two Watchdog Signals + (WS0/WS1), will trigger a warning interrupt(do panic) at thefirst
Quoted 8 lines
Quoted 3 lines
+ timeout(WS0); will reboot your system when the second
timeout(WS1)
+ is reached.I think it would be better to keep the WS0/WS1 out of the help text. It is an implementation detail, and no user will be able to make sense of it.
I don't mind to delete it , but those are in SBSA spec, is that an implementation detail ?
Sorry , just try to re-confirm it :-)
Quoted 141 lines
Quoted 141 lines
drivers/watchdog/Kconfig +2
-0+ More details: DEN0029B - Server Base System Architecture (SBSA) + config AT91RM9200_WATCHDOG tristate "AT91RM9200 watchdog" depends on SOC_AT91RM9200 && MFD_SYSCONdrivers/watchdog/Makefile +1
-0@@ -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_AT91RM9200_WATCHDOG) += at91rm9200_wdt.o obj-$(CONFIG_AT91SAM9X_WATCHDOG) += at91sam9_wdt.o obj-$(CONFIG_CADENCE_WATCHDOG) += cadence_wdt.odrivers/watchdog/sbsa_gwdt.c new file +23
-0@@ -0,0 +1,476 @@ +/* +* SBSA(Server Base System Architecture) Generic Watchdog driver +* +* Copyright (c) 2015, Linaro Ltd. +* Author: Fu Wei <[email protected]> +* Suravee Suthikulpanit <[email protected]> +* +* 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. +* +* Note: This SBSA Generic watchdog driver is compatible with +* the pretimeout concept of Linux kernel. +* The timeout and pretimeout are set by the different REGs. +* The first watch period is set by writing WCV directly, +* that can support more than 10s timeout at the maximum +* system counter frequency. +* The second watch period is set by WOR(32bit) which will be loaded
+ * automatically by hardware, when WS0 is triggered. + * This gives a maximum watch period of around 10s at the maximum + * system counter frequency. + * The System Counter shall run at maximum of 400MHz. + * More details: DEN0029B - Server Base System Architecture (SBSA)+ *
+ * Kernel/API: P---------| pretimeout
+ * |-------------------------------T timeout
+ * SBSA GWDT: P--WOR---WS1 pretimeout
+ * |-------WCV----------WS0~~~~~~~~T timeout
+ */drivers/watchdog/sbsa_gwdt.c new file +50
-0+ +#include <asm/arch_timer.h> + +#include <linux/acpi.h> +#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> + +/* 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_LO 0x010 +#define SBSA_GWDT_WCV_HI 0x014 + +/* 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 10/* seconds, the 1st + 2nd watch periods*/
drivers/watchdog/sbsa_gwdt.c new file +30
-0+#define DEFAULT_PRETIMEOUT 5/* seconds, the 2nd watch period*/ + +static unsigned int timeout; +module_param (timeout, uint,0 ); +MODULE_PARM_DESC (timeout, + "Watchdog timeout in seconds. (>=0, default=" + __MODULE_STRING(DEFAULT_TIMEOUT) ")"); + +static unsigned int max_timeout =UINT_MAX ; +module_param (max_timeout, uint,0 ); +MODULE_PARM_DESC (max_timeout, + "Watchdog max timeout in seconds. (>=0, default=" + __MODULE_STRING(UINT_MAX) ")"); + +static unsigned int pretimeout; +module_param (pretimeout, uint,0 ); +MODULE_PARM_DESC (pretimeout, + "Watchdog pretimeout in seconds. (>=0, default=" + __MODULE_STRING(DEFAULT_PRETIMEOUT) ")"); + +static unsigned int max_pretimeout =U32_MAX ; +module_param (max_pretimeout, uint,0 ); +MODULE_PARM_DESC (max_pretimeout, + "Watchdog max pretimeout in seconds. (>=0, default=" + __MODULE_STRING(U32_MAX) ")"); + +static bool nowayout =WATCHDOG_NOWAYOUT ; +module_param (nowayout, bool,S_IRUGO ); +MODULE_PARM_DESC (nowayout, + "Watchdog cannot be stopped once started (default="
Quoted 8 lines
drivers/watchdog/sbsa_gwdt.c line 118
Quoted 4 lines
drivers/watchdog/sbsa_gwdt.c new file +4
-0+ __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + +/* +* Architected system timer support. Architected ? Sounds a bit odd. Not sure if this comment serves a real purpose.
Ah, sorry , this is comment is a legacy , will update it . :-)
Quoted 24 lines
Quoted 24 lines
+ */
drivers/watchdog/sbsa_gwdt.c new file +17
-0+static void sbsa_gwdt_cf_write (unsigned int reg,u32 val, +struct watchdog_device *wdd) +{ +struct sbsa_gwdt *gwdt =to_sbsa_gwdt (wdd); + +writel_relaxed (val, gwdt->control_base + reg); +} + +static void sbsa_gwdt_rf_write (unsigned int reg,u32 val, +struct watchdog_device *wdd) +{ +struct sbsa_gwdt *gwdt =to_sbsa_gwdt (wdd); + +writel_relaxed (val, gwdt->refresh_base + reg); +} + +static u32 sbsa_gwdt_cf_read(unsigned int reg, struct watchdog_device*wdd)
drivers/watchdog/sbsa_gwdt.c new file +3
-0+{ +struct sbsa_gwdt *gwdt =to_sbsa_gwdt (wdd); +
Quoted 8 lines
drivers/watchdog/sbsa_gwdt.c line 144
Quoted 5 lines
drivers/watchdog/sbsa_gwdt.c new file +5
-0+return readl_relaxed (gwdt->control_base + reg); +} + +/* +* help founctions for accessing 64bit WCV register functions
Ah , typo , sorry
Quoted 34 lines
Quoted 34 lines
+ */
drivers/watchdog/sbsa_gwdt.c new file +31
-0+static u64 sbsa_gwdt_get_wcv (struct watchdog_device *wdd) +{ +u32 wcv_lo, wcv_hi; + +do { + wcv_hi =sbsa_gwdt_cf_read (SBSA_GWDT_WCV_HI , wdd); + wcv_lo =sbsa_gwdt_cf_read (SBSA_GWDT_WCV_LO , wdd); + }while (wcv_hi !=sbsa_gwdt_cf_read (SBSA_GWDT_WCV_HI , wdd)); + +return (((u64 )wcv_hi <<32 ) | wcv_lo); +} + +static void sbsa_gwdt_set_wcv (struct watchdog_device *wdd,u64 value) +{ +u32 wcv_lo, wcv_hi; + + wcv_lo = value &U32_MAX ; + wcv_hi = (value >>32 ) &U32_MAX ; + +sbsa_gwdt_cf_write (SBSA_GWDT_WCV_HI , wcv_hi, wdd); +sbsa_gwdt_cf_write (SBSA_GWDT_WCV_LO , wcv_lo, wdd); +} + +static void reload_timeout_to_wcv (struct watchdog_device *wdd) +{ +struct sbsa_gwdt *gwdt =to_sbsa_gwdt (wdd); +u64 wcv; + + wcv =arch_counter_get_cntvct () + + (u64)(wdd->timeout - wdd->pretimeout) * gwdt->clk; +
Quoted 8 lines
drivers/watchdog/sbsa_gwdt.c line 181
Quoted 5 lines
drivers/watchdog/sbsa_gwdt.c new file +5
-0+sbsa_gwdt_set_wcv (wdd, wcv); +} + +/* +* Use the following function to set the limit of timeout s/limit of timeout/timeout limits/
Thanks , will fix it
Quoted 49 lines
Quoted 49 lines
+ * after updating pretimeout
+ */drivers/watchdog/sbsa_gwdt.c new file +36
-0+static void sbsa_gwdt_update_limits (struct watchdog_device *wdd) +{ +struct sbsa_gwdt *gwdt =to_sbsa_gwdt (wdd); +u64 first_period_max =U64_MAX ; + +do_div (first_period_max, gwdt->clk); + + wdd->min_timeout = wdd->pretimeout +1 ; + wdd->max_timeout =min ((uint)(wdd->pretimeout + first_period_max), + wdd->max_timeout); +} + +static int sbsa_gwdt_set_timeout (struct watchdog_device *wdd, +unsigned int timeout) +{ + wdd->timeout = timeout; + +return 0 ; +} + +static int sbsa_gwdt_set_pretimeout (struct watchdog_device *wdd, +unsigned int pretimeout) +{ +struct sbsa_gwdt *gwdt =to_sbsa_gwdt (wdd); +u32 wor; + + wdd->pretimeout = pretimeout; +sbsa_gwdt_update_limits (wdd); + +if (!pretimeout) +/* gives sbsa_gwdt_start a chance to setup timeout */ + wor = gwdt->clk; +else + wor = pretimeout * gwdt->clk; + +/* refresh the WOR, that will cause an explicit watchdog refresh */
drivers/watchdog/sbsa_gwdt.c new file +8
-0+sbsa_gwdt_cf_write (SBSA_GWDT_WOR , wor, wdd); + +return 0 ; +} + +static unsigned int sbsa_gwdt_get_timeleft (struct watchdog_device *wdd) +{ +struct sbsa_gwdt *gwdt =to_sbsa_gwdt (wdd);
Quoted 8 lines
drivers/watchdog/sbsa_gwdt.c line 229
Quoted 2 lines
drivers/watchdog/sbsa_gwdt.c new file +2
-0+u64 timeleft =sbsa_gwdt_get_wcv (wdd) -arch_counter_get_cntvct (); +Still not happy about the use of
arch_counter_get_cntvctinstead of using the clock subsystem. I am quite sure this could be done, possibly througharch_sys_counter, though at this point I am getting wary of bringing it up, so I guess I'll just let it go.
yes, It is the code I should check again, will sent more feedback once I get better idea
Quoted 87 lines
Quoted 87 lines
drivers/watchdog/sbsa_gwdt.c new file +85
-0+do_div (timeleft, gwdt->clk); + +return timeleft; +} + +static int sbsa_gwdt_start (struct watchdog_device *wdd) +{ +/* Force refresh */ +sbsa_gwdt_rf_write (SBSA_GWDT_WRR ,0xc0ffee , wdd); +/* writing WCS will cause an explicit watchdog refresh */ +sbsa_gwdt_cf_write (SBSA_GWDT_WCS ,SBSA_GWDT_WCS_EN , wdd); + +reload_timeout_to_wcv (wdd); + +return 0 ; +} + +static int sbsa_gwdt_stop (struct watchdog_device *wdd) +{ +/* Force refresh */ +sbsa_gwdt_rf_write (SBSA_GWDT_WRR ,0xc0ffee , wdd); +/* writing WCS will cause an explicit watchdog refresh */ +sbsa_gwdt_cf_write (SBSA_GWDT_WCS ,0 , wdd); + +return 0 ; +} + +static int sbsa_gwdt_keepalive (struct watchdog_device *wdd) +{ +/* +* Writing WRR for an explicit watchdog refresh +* You can write anyting(like 0xc0ffee) +*/ +sbsa_gwdt_rf_write (SBSA_GWDT_WRR ,0xc0ffee , wdd); + +reload_timeout_to_wcv (wdd); + +return 0 ; +} + +static irqreturn_t sbsa_gwdt_interrupt (int irq,void *dev_id) +{ +struct sbsa_gwdt *gwdt = (struct sbsa_gwdt *)dev_id; +struct watchdog_device *wdd = &gwdt->wdd; +u32 status; + + status =sbsa_gwdt_cf_read (SBSA_GWDT_WCS , wdd); + +if (status &SBSA_GWDT_WCS_WS0 ) +panic ("SBSA Watchdog pre-timeout" ); + +return IRQ_HANDLED ; +} + +static struct watchdog_info sbsa_gwdt_info = { + .identity ="SBSA Generic Watchdog" , + .options =WDIOF_SETTIMEOUT | +WDIOF_KEEPALIVEPING | +WDIOF_MAGICCLOSE | +WDIOF_PRETIMEOUT | +WDIOF_CARDRESET , +}; + +static struct watchdog_ops sbsa_gwdt_ops = { + .owner =THIS_MODULE , + .start = sbsa_gwdt_start, + .stop = sbsa_gwdt_stop, + .ping = sbsa_gwdt_keepalive, + .set_timeout = sbsa_gwdt_set_timeout, + .set_pretimeout = sbsa_gwdt_set_pretimeout, + .get_timeleft = sbsa_gwdt_get_timeleft, +}; + +static int sbsa_gwdt_probe (struct platform_device *pdev) +{ +struct device *dev = &pdev->dev; +struct sbsa_gwdt *gwdt; +struct watchdog_device *wdd; +struct resource *res; +void *rf_base, *cf_base; +int irq; +u32 clk, status; +int ret =0 ; +u64 first_period_max =U64_MAX ; +
Quoted 8 lines
drivers/watchdog/sbsa_gwdt.c line 318
Quoted 4 lines
drivers/watchdog/sbsa_gwdt.c new file +4
-0+/* +* Try to determine the frequency from the arch_timer interface +*/ + clk =arch_timer_get_rate ();
arch_timer_get_rate()does not seem to be exported. Did you try to build the driver as module ?
yes, I have built it as a ko module, that is why I made a patch to export this interface in the first patch of this patchset
but I will confirm it again :-)
Quoted 165 lines
Quoted 164 lines
drivers/watchdog/sbsa_gwdt.c new file +10
-0+if (!clk) { +dev_err (dev,"System Counter frequency not available\n" ); +return -EINVAL ; + } + + gwdt =devm_kzalloc (dev,sizeof (*gwdt),GFP_KERNEL ); +if (!gwdt) +return -ENOMEM ; + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM,"refresh");
drivers/watchdog/sbsa_gwdt.c new file +5
-0+ rf_base =devm_ioremap_resource (dev, res); +if (IS_ERR (rf_base)) +return PTR_ERR (rf_base); + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM,"control");
drivers/watchdog/sbsa_gwdt.c new file +61
-0+ cf_base =devm_ioremap_resource (dev, res); +if (IS_ERR (rf_base)) +return PTR_ERR (rf_base); + + irq =platform_get_irq_byname (pdev,"ws0" ); +if (irq <0 ) { +dev_err (dev,"unable to get ws0 interrupt.\n" ); +return irq; + } + + gwdt->refresh_base = rf_base; + gwdt->control_base = cf_base; + gwdt->clk = clk; + +platform_set_drvdata (pdev, gwdt); + + 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); + + status =sbsa_gwdt_cf_read (SBSA_GWDT_WCS , wdd); +if (status &SBSA_GWDT_WCS_WS1 ) { +dev_warn (dev,"System reset by WDT(WCS: %x, WCV: %llx)\n" , + status,sbsa_gwdt_get_wcv (wdd)); + wdd->bootstatus |=WDIOF_CARDRESET ; + } +/* Check if watchdog is already enabled */ +if (status &SBSA_GWDT_WCS_EN ) { +dev_warn (dev,"already enabled! WCS:0x%x\n" , status); +sbsa_gwdt_keepalive (wdd); + } + + wdd->min_pretimeout =0 ; + wdd->max_pretimeout =min (U32_MAX / clk, max_pretimeout); + wdd->min_timeout =1 ; +do_div (first_period_max, clk); + wdd->max_timeout =min ((uint)(wdd->pretimeout + first_period_max), + max_timeout); + + wdd->pretimeout =DEFAULT_PRETIMEOUT ; + wdd->timeout =DEFAULT_TIMEOUT ; +watchdog_init_timeouts (wdd, pretimeout, timeout, + sbsa_gwdt_update_limits, dev); +/* update pretimeout to WOR */ +sbsa_gwdt_cf_write (SBSA_GWDT_WOR , wdd->pretimeout * clk, wdd); + + ret =devm_request_irq (dev, irq, sbsa_gwdt_interrupt,IRQF_TIMER , + pdev->name, gwdt); +if (ret) { +dev_err (dev,"unable to request IRQ %d\n" , irq); +return ret; + } + + ret =watchdog_register_device (wdd); +if (ret) +return ret; + + dev_info(dev, "Initialized with %ds timeout, %ds pretimeout @%uHz\n",
drivers/watchdog/sbsa_gwdt.c new file +82
-0+ wdd->timeout, wdd->pretimeout, gwdt->clk); + +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); +int ret =0 ; + +if (!nowayout) + ret =sbsa_gwdt_stop (&gwdt->wdd); + +watchdog_unregister_device (&gwdt->wdd); + +return ret; +} + +/* 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_VERSION ("v1.0" ); +MODULE_AUTHOR ("Fu Wei <[email protected]>" ); +MODULE_AUTHOR ("Suravee Suthikulpanit <[email protected]>" ); +MODULE_LICENSE ("GPL v2" );
Signature · 10 lines
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
Guenter Roeck
maintainerRe: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
Quoted 51 lines · Fu Wei
Hi Guenter,
Thanks for review :-)
Quoted 37 lines · Guenter Roeck
Quoted 36 lines · On 05/21/2015 01:32 AM, [email protected] wrote:
From: Fu Wei <[email protected]>
This driver bases on linux kernel watchdog framework, and use "pretimeout" in the framework. It supports getting timeout and pretimeout from parameter and FDT at the driver init stage. In first timeout(WS0), the interrupt routine run panic to save system context.
Signed-off-by Fu Wei <[email protected]>--- drivers/watchdog/Kconfig | 12 ++ drivers/watchdog/Makefile | 1 + drivers/watchdog/sbsa_gwdt.c | 476 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 489 insertions(+)create mode 100644
drivers/watchdog/sbsa_gwdt.cdrivers/watchdog/Kconfig +0
-0@@ -152,6 +152,18 @@ config ARM_SP805_WATCHDOG ARM Primecell SP805 Watchdog timer. This will reboot your systemwhen
the timeout is reached.drivers/watchdog/Kconfig +8
-0+config ARM_SBSA_WATCHDOG + tristate "ARM SBSA Generic Watchdog" + depends on ARM || ARM64 || COMPILE_TEST + depends on ARM_ARCH_TIMER + select WATCHDOG_CORE + help + ARM SBSA Generic Watchdog timer. This has two Watchdog Signals + (WS0/WS1), will trigger a warning interrupt(do panic) at thefirst
Quoted 8 lines
Quoted 3 lines
+ timeout(WS0); will reboot your system when the second
timeout(WS1)
+ is reached.I think it would be better to keep the WS0/WS1 out of the help text. It is an implementation detail, and no user will be able to make sense of it.
Quoted 3 lines
I don't mind to delete it , but those are in SBSA spec, is that an implementation detail ?
I think so.
Ask yourself - assuming you are not involved in the development of this driver, and you read this help text. Is the help text going to help you to know about WS0 and WS1 ? Why not just something like the following, if you want to be verbose ?
ARM SBSA Generic Watchdog. This watchdog has two Watchdog timeouts. The first timeout will trigger a panic; the second timeout will trigger a system reset.
Anyway, not worth arguing about.
Quoted 7 lines
Quoted 7 lines
Quoted 5 lines
drivers/watchdog/Kconfig +5
-0+ + /* + * Try to determine the frequency from the arch_timer interface + */ + clk = arch_timer_get_rate();
Quoted 8 lines
Quoted 2 lines
arch_timer_get_rate()does not seem to be exported. Did you try to build the driver as module ?yes, I have built it as a ko module, that is why I made a patch to export this interface in the first patch of this patchset
but I will confirm it again :-)
Guess I'll give it a try myself. I don't really understand how this can work unless arch_timer_get_rate() is exported in your tree.
Guenter
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
Hi Guenter,
Great thanks :-)
Quoted 57 lines · Guenter Roeck
Quoted 51 lines · Fu Wei
Hi Guenter,
Thanks for review :-)
Quoted 37 lines · Guenter Roeck
Quoted 36 lines · On 05/21/2015 01:32 AM, [email protected] wrote:
From: Fu Wei <[email protected]>
This driver bases on linux kernel watchdog framework, and use "pretimeout" in the framework. It supports getting timeout and pretimeout from parameter and FDT at the driver init stage. In first timeout(WS0), the interrupt routine run panic to save system context.
Signed-off-by Fu Wei <[email protected]>--- drivers/watchdog/Kconfig | 12 ++ drivers/watchdog/Makefile | 1 + drivers/watchdog/sbsa_gwdt.c | 476 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 489 insertions(+)create mode 100644
drivers/watchdog/sbsa_gwdt.cdrivers/watchdog/Kconfig +0
-0@@ -152,6 +152,18 @@ config ARM_SP805_WATCHDOG ARM Primecell SP805 Watchdog timer. This will reboot your systemwhen
the timeout is reached.drivers/watchdog/Kconfig +8
-0+config ARM_SBSA_WATCHDOG + tristate "ARM SBSA Generic Watchdog" + depends on ARM || ARM64 || COMPILE_TEST + depends on ARM_ARCH_TIMER + select WATCHDOG_CORE + help + ARM SBSA Generic Watchdog timer. This has two Watchdog Signals + (WS0/WS1), will trigger a warning interrupt(do panic) at thefirst
Quoted 8 lines
Quoted 3 lines
+ timeout(WS0); will reboot your system when the second
timeout(WS1)
+ is reached.I think it would be better to keep the WS0/WS1 out of the help text. It is an implementation detail, and no user will be able to make sense of it.
Quoted 3 lines
I don't mind to delete it , but those are in SBSA spec, is that an implementation detail ?
I think so.
Quoted 8 lines
Ask yourself - assuming you are not involved in the development of this driver, and you read this help text. Is the help text going to help you to know about WS0 and WS1 ? Why not just something like the following, if you want to be verbose ?
ARM SBSA Generic Watchdog. This watchdog has two Watchdog timeouts. The first timeout will trigger a panic; the second timeout will trigger a system reset.
Great thanks, that is better, yes, If I never read SBSA spec, I don't know WS is watchdog signal :-)
Quoted 2 lines
Anyway, not worth arguing about.
yes, agree , Thanks for the example "help" :-)
Quoted 11 lines
Quoted 11 lines
Quoted 10 lines
drivers/watchdog/Kconfig
Quoted 6 lines
drivers/watchdog/Kconfig +5
-0+ + /* + * Try to determine the frequency from the arch_timer interface + */ + clk = arch_timer_get_rate();
arch_timer_get_rate()does not seem to be exported. Did you try to build the driver as module ?
Quoted 7 lines
Quoted 5 lines
yes, I have built it as a ko module, that is why I made a patch to export this interface in the first patch of this patchset
but I will confirm it again :-)
Guess I'll give it a try myself. I don't really understand how this can work unless
arch_timer_get_rate()is exported in your tree.
yes, I have exported it , I think it make sense to export it. Because other driver maybe need to get system counter info
Do you agree ? :-)
Quoted 2 lines
Guenter
Signature · 10 lines
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
Guenter Roeck
maintainerRe: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
Quoted 2 lines · Fu Wei
Hi Guenter,
[ ... ]
Quoted 15 lines
Quoted 15 lines
Quoted 15 lines
Quoted 9 lines
drivers/watchdog/sbsa_gwdt.c line 318
Quoted 5 lines
drivers/watchdog/sbsa_gwdt.c new file +5
-0+ +/* +* Try to determine the frequency from the arch_timer interface +*/ + clk =arch_timer_get_rate ();
arch_timer_get_rate()does not seem to be exported. Did you try to build the driver as module ?yes, I have built it as a ko module, that is why I made a patch to export this interface in the first patch of this patchset
but I will confirm it again :-)
Quoted 8 lines
Quoted 2 lines
Guess I'll give it a try myself. I don't really understand how this can work unless
arch_timer_get_rate()is exported in your tree.yes, I have exported it , I think it make sense to export it. Because other driver maybe need to get system counter info
Do you agree ? :-)
I don't think it is for me to agree or not. The arm maintainers will need to be involved. You can not just export such a function without maintainer Ack.
Having said that, my personal preference would be for the counter and rate to be exported through the clock subsystem (ie with clk_get_rate). But that would still not provide the current counter value, so maybe that isn't even possible.
Thanks,
Guenter
Re: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
Hi Guenter,
Quoted 23 lines · Guenter Roeck
Quoted 2 lines · Fu Wei
Hi Guenter,
[ ... ]
Quoted 18 lines
Quoted 17 lines
Quoted 7 lines
Quoted 7 lines
Quoted 5 lines
drivers/watchdog/sbsa_gwdt.c new file +5
-0+ +/* +* Try to determine the frequency from the arch_timer interface +*/ + clk =arch_timer_get_rate ();Quoted 8 lines
Quoted 2 lines
arch_timer_get_rate()does not seem to be exported. Did you try to build the driver as module ?yes, I have built it as a ko module, that is why I made a patch to export this interface in the first patch of this patchset
but I will confirm it again :-)
Guess I'll give it a try myself. I don't really understand how this can work unless
arch_timer_get_rate()is exported in your tree.
Quoted 8 lines
Quoted 5 lines
yes, I have exported it , I think it make sense to export it. Because other driver maybe need to get system counter info
Do you agree ? :-)
I don't think it is for me to agree or not. The arm maintainers will need to be involved. You can not just export such a function without maintainer Ack.
yes, I have added Mark Rutland in the CC list when I sent this patchset . He added the "arch_timer_get_rate();" in the arch timer driver.
See if he can provide some suggestion. :-)
maybe I should add some more arm arch timer maintainers to get more help on this :-)
Quoted 5 lines
Having said that, my personal preference would be for the counter and rate to be exported through the clock subsystem (ie with
clk_get_rate). But that would still not provide the current counter value, so maybe that isn't even possible.
I will try to make a patch for this, If the arm maintainers don't like exporting "arch_timer_get_rate();"
But your thought is good, the clk_get_rate is the best way to do for now
Quoted 3 lines
Thanks,
Guenter
Signature · 14 lines
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 -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
Quoted 9 lines · Fu Wei
Quoted 5 lines
Quoted 5 lines
Having said that, my personal preference would be for the counter and rate to be exported through the clock subsystem (ie with
clk_get_rate). But that would still not provide the current counter value, so maybe that isn't even possible.I will try to make a patch for this, If the arm maintainers don't like exporting "
arch_timer_get_rate();"But your thought is good, the
clk_get_rateis the best way to do for now
The rate isn't the problem. It's the current timestamp counter. The only way to get that is with either arch_counter_get_cntvct() or arch_timer_read_counter(). I'm not sure which of the two functions is better. However, arch_timer_read_counter() is really just a function pointer that points to arch_counter_get_cntvct().
Also, clk_get_rate() only works if you have a real clk object. I've said this before many times, but on my ACPI platform, there are no clk objects. Clocks are handled by UEFI.
Signature · 7 lines
Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project. -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
Hi Timur.
Quoted 20 lines · Timur Tabi
Quoted 11 lines · Fu Wei
Quoted 6 lines
Quoted 6 lines
Having said that, my personal preference would be for the counter and rate to be exported through the clock subsystem (ie with
clk_get_rate). But that would still not provide the current counter value, so maybe that isn't even possible.I will try to make a patch for this, If the arm maintainers don't like exporting "
arch_timer_get_rate();"But your thought is good, the
clk_get_rateis the best way to do for nowThe rate isn't the problem. It's the current timestamp counter. The only way to get that is with either
arch_counter_get_cntvct()orarch_timer_read_counter(). I'm not sure which of the two functions is better. However,arch_timer_read_counter()is really just a function pointer that points toarch_counter_get_cntvct().
Quoted 3 lines
Also,
clk_get_rate()only works if you have a real clk object. I've said this before many times, but on my ACPI platform, there are no clk objects. Clocks are handled by UEFI.
Thanks for your info,
I think : right now , do what we can do, export the interface of arch_timer, If the arm maintainers don't like this way, we can find another way later or find a option as plan B.
Quoted 5 lines
--
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.
Signature · 14 lines
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 -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
In reply to Guenter RoeckQuoted 11 lines · Guenter Roeck
drivers/watchdog/sbsa_gwdt.c line 229
Quoted 6 lines
drivers/watchdog/sbsa_gwdt.c new file +5
-0+static unsigned int sbsa_gwdt_get_timeleft (struct watchdog_device *wdd) +{ +struct sbsa_gwdt *gwdt =to_sbsa_gwdt (wdd); +u64 timeleft =sbsa_gwdt_get_wcv (wdd) -arch_counter_get_cntvct (); +Still not happy about the use of
arch_counter_get_cntvctinstead of using the clock subsystem. I am quite sure this could be done, possibly througharch_sys_counter, though at this point I am getting wary of bringing it up, so I guess I'll just let it go.
You made the same comment with my driver, and I keep asking for clarification. The clk_get_sys() API does not work on my system, because there are not clocks defined. That must be an ACPI limitation that I can't fix.
The alternative to arch_counter_get_cntvct() is arch_timer_read_counter(), which is not exported. So we have two choices,
1) Continue to use arch_counter_get_cntvct(), which works on all ARM64 platforms that this driver supports anyway
2) Export arch_timer_read_counter()
I prefer option #1.
Signature · 3 lines
Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation.
Guenter Roeck
maintainerRe: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
Quoted 13 lines · Timur Tabi
Quoted 11 lines · Guenter Roeck
drivers/watchdog/sbsa_gwdt.c line 229
Quoted 6 lines
drivers/watchdog/sbsa_gwdt.c new file +5
-0+static unsigned int sbsa_gwdt_get_timeleft (struct watchdog_device *wdd) +{ +struct sbsa_gwdt *gwdt =to_sbsa_gwdt (wdd); +u64 timeleft =sbsa_gwdt_get_wcv (wdd) -arch_counter_get_cntvct (); +Still not happy about the use of
arch_counter_get_cntvctinstead of using the clock subsystem. I am quite sure this could be done, possibly througharch_sys_counter, though at this point I am getting wary of bringing it up, so I guess I'll just let it go.
Quoted 5 lines
You made the same comment with my driver, and I keep asking for clarification. The
clk_get_sys()API does not work on my system, because there are not clocks defined. That must be an ACPI limitation that I can't fix.
Would it be possible to define such clocks ?
Quoted 10 lines
The alternative to
arch_counter_get_cntvct()isarch_timer_read_counter(), which is not exported. So we have two choices,1) Continue to use
arch_counter_get_cntvct(), which works on all ARM64 platforms that this driver supports anyway2) Export
arch_timer_read_counter()I prefer option #1.
Do we have any feedback from the arm maintainers ?
My problem is that I don't want to be the first one to permit using those functions outside architecture and clock code. If we do this, we should get an Ack from an arm maintainer specifically for the use of arch_counter_get_cntvct() and arch_timer_get_rate().
Thanks,
Guenter
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
Hi Guenter,
Quoted 29 lines · Guenter Roeck
Quoted 13 lines · Timur Tabi
Quoted 11 lines · Guenter Roeck
drivers/watchdog/sbsa_gwdt.c line 229
Quoted 6 lines
drivers/watchdog/sbsa_gwdt.c new file +5
-0+static unsigned int sbsa_gwdt_get_timeleft (struct watchdog_device *wdd) +{ +struct sbsa_gwdt *gwdt =to_sbsa_gwdt (wdd); +u64 timeleft =sbsa_gwdt_get_wcv (wdd) -arch_counter_get_cntvct (); +Still not happy about the use of
arch_counter_get_cntvctinstead of using the clock subsystem. I am quite sure this could be done, possibly througharch_sys_counter, though at this point I am getting wary of bringing it up, so I guess I'll just let it go.Quoted 5 lines
You made the same comment with my driver, and I keep asking for clarification. The
clk_get_sys()API does not work on my system, because there are not clocks defined. That must be an ACPI limitation that I can't fix.Would it be possible to define such clocks ?
Quoted 8 lines
The alternative to
arch_counter_get_cntvct()isarch_timer_read_counter(), which is not exported. So we have two choices,1) Continue to use
arch_counter_get_cntvct(), which works on all ARM64 platforms that this driver supports anyway2) Export
arch_timer_read_counter()
Quoted 8 lines
Quoted 2 lines
I prefer option #1.
Do we have any feedback from the arm maintainers ?
My problem is that I don't want to be the first one to permit using those functions outside architecture and clock code. If we do this, we should get an Ack from an arm maintainer specifically for the use of
arch_counter_get_cntvct()andarch_timer_get_rate().
IMO, we may need to use arch_timer_read_counter.
Reason: Once the Linux kernel has KVM support and is in hyp mode. we may need to use arch_counter_get_cntpct.
So arch_timer driver have helped us to make arch_timer_read_counter point to the right function.
and arch_timer_read_counter is in the include/clocksource/arm_arch_timer.h, just like arch_timer_get_rate as a interface
Quoted 7 lines
Thanks,
Guenter
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Signature · 14 lines
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 -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
Quoted 2 lines · Fu Wei
Once the Linux kernel has KVM support and is in hyp mode. we may need to use
arch_counter_get_cntpct.
arch_counter_get_cntpct() does not appear to be valid for ARM64:
http://lxr.free-electrons.com/source/arch/arm64/include/asm/arch_timer.h#L108
Signature · 7 lines
Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation. -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
Hi Timur.
Quoted 9 lines · Timur Tabi
Quoted 3 lines · Fu Wei
Once the Linux kernel has KVM support and is in hyp mode. we may need to use
arch_counter_get_cntpct.
arch_counter_get_cntpct()does not appear to be valid for ARM64:http://lxr.free-electrons.com/source/arch/arm64/include/asm/arch_timer.h#L108
Great thank for correction, that make sense.
Quoted 6 lines
--
Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation.
Signature · 14 lines
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 -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
In reply to [email protected]Quoted 10 lines · On 05/21/2015 03:32 AM, [email protected] wrote:
drivers/watchdog/sbsa_gwdt.c new file +10
-0+static void reload_timeout_to_wcv (struct watchdog_device *wdd) +{ +struct sbsa_gwdt *gwdt =to_sbsa_gwdt (wdd); +u64 wcv; + + wcv =arch_counter_get_cntvct () + + (u64)(wdd->timeout - wdd->pretimeout) * gwdt->clk; + +sbsa_gwdt_set_wcv (wdd, wcv); +}
...
Quoted 7 lines
drivers/watchdog/sbsa_gwdt.c new file +7
-0+static int sbsa_gwdt_set_timeout (struct watchdog_device *wdd, +unsigned int timeout) +{ + wdd->timeout = timeout; + +return 0 ; +}
...
drivers/watchdog/sbsa_gwdt.c line 282
Quoted 13 lines
drivers/watchdog/sbsa_gwdt.c new file +13
-0+static irqreturn_t sbsa_gwdt_interrupt (int irq,void *dev_id) +{ +struct sbsa_gwdt *gwdt = (struct sbsa_gwdt *)dev_id; +struct watchdog_device *wdd = &gwdt->wdd; +u32 status; + + status =sbsa_gwdt_cf_read (SBSA_GWDT_WCS , wdd); + +if (status &SBSA_GWDT_WCS_WS0 ) +panic ("SBSA Watchdog pre-timeout" ); + +return IRQ_HANDLED ; +}
There's one thing I don't understand about your driver. The 'timeout' value from the kernel is supposed to to be the number of seconds until the system reboots. You are programming the WCV with that value, which means that the WS0 interrupt will fire when the timeout expires the first time. However, you don't reboot the system during this interrupt.
The "panic" will cause the system to halt, but not reboot. Instead,
it will just sit there. You're waiting for the WS1 timeout for the system to reboot, but this is not a clean reboot, and it occurs at 2*timeout seconds.
That's why I like my driver better. It doesn't have any of this pretimeout stuff, and when the timeout expires during the WS0 interrupt, it calls emergency_restart() which reboots the system properly. The WS1 hard reset is used as a "backup" reset in case emergency_restart() fails.
Signature · 7 lines
Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project. -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
Hi Timur,
Quoted 42 lines · Timur Tabi
Quoted 10 lines · On 05/21/2015 03:32 AM, [email protected] wrote:
drivers/watchdog/sbsa_gwdt.c new file +10
-0+static void reload_timeout_to_wcv (struct watchdog_device *wdd) +{ +struct sbsa_gwdt *gwdt =to_sbsa_gwdt (wdd); +u64 wcv; + + wcv =arch_counter_get_cntvct () + + (u64)(wdd->timeout - wdd->pretimeout) * gwdt->clk; + +sbsa_gwdt_set_wcv (wdd, wcv); +}...
Quoted 7 lines
drivers/watchdog/sbsa_gwdt.c new file +7
-0+static int sbsa_gwdt_set_timeout (struct watchdog_device *wdd, +unsigned int timeout) +{ + wdd->timeout = timeout; + +return 0 ; +}...
drivers/watchdog/sbsa_gwdt.c line 282
Quoted 13 lines
drivers/watchdog/sbsa_gwdt.c new file +13
-0+static irqreturn_t sbsa_gwdt_interrupt (int irq,void *dev_id) +{ +struct sbsa_gwdt *gwdt = (struct sbsa_gwdt *)dev_id; +struct watchdog_device *wdd = &gwdt->wdd; +u32 status; + + status =sbsa_gwdt_cf_read (SBSA_GWDT_WCS , wdd); + +if (status &SBSA_GWDT_WCS_WS0 ) +panic ("SBSA Watchdog pre-timeout" ); + +return IRQ_HANDLED ; +}
Quoted 6 lines
There's one thing I don't understand about your driver. The 'timeout' value from the kernel is supposed to to be the number of seconds until the system reboots. You are programming the WCV with that value, which means that the WS0 interrupt will fire when the timeout expires the first time. However, you don't reboot the system during this interrupt. The "panic" will cause the system to halt, but not reboot. Instead, it will just sit there.
the "panic" is not just halt the system, please check the code :
(1)It can trigger Kdump (not just print the panic message), if you enable this in the config. that can help server administrator to figure out why the system goes wrong.
(2)panic also can trigger a reboot, if you set up "panic timeout".
Obviously, it won't just sit there, it can help user figure out the problem.
At the beginning, I would like to make the first signal more useful, but for simplifying the first version of driver , I decide to use panic(). but if there is better "alerts" for a ARM server , I will go on maintaining this driver to make WS0 more useful.
Quoted 7 lines
You're waiting for the WS1 timeout for the system to reboot, but this is not a clean reboot, and it occurs at 2*timeout seconds.
That's why I like my driver better. It doesn't have any of this pretimeout stuff, and when the timeout expires during the WS0 interrupt, it calls
emergency_restart()which reboots the system properly. The WS1 hard reset is used as a "backup" reset in caseemergency_restart()fails.
OK, If you think so, I hope you can read the SBSA spec more carefully For the watchdog signal (WS0/WS1), SBSA say:
"The initial signal is typically wired to an interrupt and alerts the system. The system can attempt to take corrective
action that includes refreshing the watchdog within the second watch period. If the refresh is successful the
system returns to the previous normal operation. If it fails then the second watch period expires and a second
signal is generated. The signal is fed to a higher agent as an interrupt or reset for it to take executive action."
So WS0 is a warning, but not a reset. the WS1 maybe a reset, or a interrupt to higher agent.
That is different from a normal watchdog use before. the two stage of WS are not just for reset , at least the first one is definitely not a reset. and the second one is not a backup.
If you make SBSA watchdog work like a normal watchdog,:
(1)why we need a new driver and new device? you can just use SP805 in the system.
(2) why we need a two stages? ( if the second hardware reset signal can work more reliably , why use emergency_restart() which is a software reset, does it clean the system and do some useful backup or sync? )
the only useful thing done by emergency_restart() iskmsg_dump(KMSG_DUMP_EMERG);)
(3)why the first WS is connect to a interrupt, but not a reset signal(I believe the direct reset signal is far more reliable than a interrupt to trigger a software reset )
And because of WS0 is a warning, so I decide to use a existing watchdog concept "pretimeout":
-----------------
Pretimeouts:
Some watchdog timers can be set to have a trigger go off before the actual time they will reset the system. This can be done with an NMI, interrupt, or other mechanism. This allows Linux to record useful information (like panic information and kernel coredumps) before it resets.
-----------------
Quoted 5 lines
--
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.
Signature · 10 lines
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
Re: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
Hi Timur,
Quoted 83 lines · Fu Wei
Hi Timur,
Quoted 42 lines · Timur Tabi
Quoted 10 lines · On 05/21/2015 03:32 AM, [email protected] wrote:
drivers/watchdog/sbsa_gwdt.c new file +10
-0+static void reload_timeout_to_wcv (struct watchdog_device *wdd) +{ +struct sbsa_gwdt *gwdt =to_sbsa_gwdt (wdd); +u64 wcv; + + wcv =arch_counter_get_cntvct () + + (u64)(wdd->timeout - wdd->pretimeout) * gwdt->clk; + +sbsa_gwdt_set_wcv (wdd, wcv); +}...
Quoted 7 lines
drivers/watchdog/sbsa_gwdt.c new file +7
-0+static int sbsa_gwdt_set_timeout (struct watchdog_device *wdd, +unsigned int timeout) +{ + wdd->timeout = timeout; + +return 0 ; +}...
drivers/watchdog/sbsa_gwdt.c line 282
Quoted 13 lines
drivers/watchdog/sbsa_gwdt.c new file +13
-0+static irqreturn_t sbsa_gwdt_interrupt (int irq,void *dev_id) +{ +struct sbsa_gwdt *gwdt = (struct sbsa_gwdt *)dev_id; +struct watchdog_device *wdd = &gwdt->wdd; +u32 status; + + status =sbsa_gwdt_cf_read (SBSA_GWDT_WCS , wdd); + +if (status &SBSA_GWDT_WCS_WS0 ) +panic ("SBSA Watchdog pre-timeout" ); + +return IRQ_HANDLED ; +}Quoted 6 lines
There's one thing I don't understand about your driver. The 'timeout' value from the kernel is supposed to to be the number of seconds until the system reboots. You are programming the WCV with that value, which means that the WS0 interrupt will fire when the timeout expires the first time. However, you don't reboot the system during this interrupt. The "panic" will cause the system to halt, but not reboot. Instead, it will just sit there.
the "panic" is not just halt the system, please check the code :
(1)It can trigger Kdump (not just print the panic message), if you enable this in the config. that can help server administrator to figure out why the system goes wrong.
(2)panic also can trigger a reboot, if you set up "panic timeout".Obviously, it won't just sit there, it can help user figure out the problem.
At the beginning, I would like to make the first signal more useful, but for simplifying the first version of driver , I decide to use
panic(). but if there is better "alerts" for a ARM server , I will go on maintaining this driver to make WS0 more useful.Quoted 7 lines
You're waiting for the WS1 timeout for the system to reboot, but this is not a clean reboot, and it occurs at 2*timeout seconds.
That's why I like my driver better. It doesn't have any of this pretimeout stuff, and when the timeout expires during the WS0 interrupt, it calls
emergency_restart()which reboots the system properly. The WS1 hard reset is used as a "backup" reset in caseemergency_restart()fails.OK, If you think so, I hope you can read the SBSA spec more carefully For the watchdog signal (WS0/WS1), SBSA say:
"The initial signal is typically wired to an interrupt and alerts the system. The system can attempt to take corrective
action that includes refreshing the watchdog within the second watch period. If the refresh is successful the
system returns to the previous normal operation.
Quoted 1 line
From here, you can see, even a panic is not good enough. we even can
refreshing the watchdog.
But for simplifying the driver, I think, at least, panic() can help user to backup system context, it is very helpful for a server administrator.
Because server should be very stable and important , if its software goes wrong, we must figure out the problem, we can not let it happen again.
but in WS0 interrupt routine , just simply restart , it is not a server watchdog should do.
Quoted 56 lines
If it fails then the
second watch period expires and a second
signal is generated. The signal is fed to a higher agent as an interrupt or reset for it to take executive action."So WS0 is a warning, but not a reset. the WS1 maybe a reset, or a interrupt to higher agent.
That is different from a normal watchdog use before. the two stage of WS are not just for reset , at least the first one is definitely not a reset. and the second one is not a backup.
If you make SBSA watchdog work like a normal watchdog,:
(1)why we need a new driver and new device? you can just use SP805 in the system.
(2) why we need a two stages? ( if the second hardware reset signal can work more reliably , why useemergency_restart()which is a software reset, does it clean the system and do some useful backup or sync? )
the only useful thing done byemergency_restart()iskmsg_dump(KMSG_DUMP_EMERG);)
(3)why the first WS is connect to a interrupt, but not a reset signal(I believe the direct reset signal is far more reliable than a interrupt to trigger a software reset )And because of WS0 is a warning, so I decide to use a existing watchdog concept "pretimeout":
-----------------
Pretimeouts:Some watchdog timers can be set to have a trigger go off before the actual time they will reset the system. This can be done with an NMI, interrupt, or other mechanism. This allows Linux to record useful information (like panic information and kernel coredumps) before it resets.
-----------------Quoted 5 lines
--
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.--
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
Signature · 10 lines
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
Re: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
In reply to Fu WeiQuoted 60 lines · Fu Wei
Hi Timur,
Quoted 42 lines · Timur Tabi
Quoted 10 lines · On 05/21/2015 03:32 AM, [email protected] wrote:
drivers/watchdog/sbsa_gwdt.c new file +10
-0+static void reload_timeout_to_wcv (struct watchdog_device *wdd) +{ +struct sbsa_gwdt *gwdt =to_sbsa_gwdt (wdd); +u64 wcv; + + wcv =arch_counter_get_cntvct () + + (u64)(wdd->timeout - wdd->pretimeout) * gwdt->clk; + +sbsa_gwdt_set_wcv (wdd, wcv); +}...
Quoted 7 lines
drivers/watchdog/sbsa_gwdt.c new file +7
-0+static int sbsa_gwdt_set_timeout (struct watchdog_device *wdd, +unsigned int timeout) +{ + wdd->timeout = timeout; + +return 0 ; +}...
drivers/watchdog/sbsa_gwdt.c line 282
Quoted 13 lines
drivers/watchdog/sbsa_gwdt.c new file +13
-0+static irqreturn_t sbsa_gwdt_interrupt (int irq,void *dev_id) +{ +struct sbsa_gwdt *gwdt = (struct sbsa_gwdt *)dev_id; +struct watchdog_device *wdd = &gwdt->wdd; +u32 status; + + status =sbsa_gwdt_cf_read (SBSA_GWDT_WCS , wdd); + +if (status &SBSA_GWDT_WCS_WS0 ) +panic ("SBSA Watchdog pre-timeout" ); + +return IRQ_HANDLED ; +}Quoted 6 lines
There's one thing I don't understand about your driver. The 'timeout' value from the kernel is supposed to to be the number of seconds until the system reboots. You are programming the WCV with that value, which means that the WS0 interrupt will fire when the timeout expires the first time. However, you don't reboot the system during this interrupt. The "panic" will cause the system to halt, but not reboot. Instead, it will just sit there.
the "panic" is not just halt the system, please check the code :
(1)It can trigger Kdump (not just print the panic message), if you enable this in the config. that can help server administrator to figure out why the system goes wrong.
(2)panic also can trigger a reboot, if you set up "panic timeout".
Quoted 6 lines
Obviously, it won't just sit there, it can help user figure out the problem.
At the beginning, I would like to make the first signal more useful, but for simplifying the first version of driver , I decide to use
panic(). but if there is better "alerts" for a ARM server , I will go on maintaining this driver to make WS0 more useful.
I use emergency_restart(), because the watchdog-api.txt documentation says this:
"If userspace fails (RAM error, kernel bug, whatever), the notifications cease to occur, and the hardware watchdog will reset the system (causing a reboot) after the timeout occurs."
Maybe I'm reading this too literally, but to me this means that when the timeout expires, the system has to reset immediately.
However, maybe panic() is better, since it can do the same thing and more.
Quoted 2 lines
So WS0 is a warning, but not a reset. the WS1 maybe a reset, or a interrupt to higher agent.
The watchdog documentation says that the system should reset when the timeout occurs. Therefore, WCV needs to be programming for one-half the timeout value, so that WS1 can occur when the watchdog expires. If the application says, "set timeout to 10 second", then the system has to reboot after 10 second (if the watchdog is pinged).
If the user does not specify a pre-timeout, and if he sets the watchdog to 10 seconds, then WC1 will occur in 20 seconds. You will still call panic() in 10 seconds (during WS0 interrupt), however, so I don't understand how pre-timeout is supposed to work.
That's why I'm confused. I can't tell if you're programming WCV correctly.
Signature · 7 lines
Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation. -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Guenter Roeck
maintainerRe: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
On 05/23/2015 12:40 PM, Timur Tabi wrote:
[ ... ]
Quoted 11 lines
I use
emergency_restart(), because the watchdog-api.txt documentation says this:"If userspace fails (RAM error, kernel bug, whatever), the notifications cease to occur, and the hardware watchdog will reset the system (causing a reboot) after the timeout occurs."
Maybe I'm reading this too literally, but to me this means that when the timeout expires, the system has to reset immediately.
However, maybe
panic()is better, since it can do the same thing and more.
I have a specific requirement at work to have watchdog expiration (not this watchdog, this is different HW) result in a panic, specifically to enable crashdump support and thus post-mortem analysis.
I had not thought about this use case myself, and I had always wondered why watchdog driver implementers would choose to call panic() after an interrupt or NMI. But we live and learn, so now I finally understand.
In the pretimeout/timeout world, the pretimeout would (typically) result in a panic, and the timeout would result in a reset. So one would set the timer register to 10s for 10s pretimeout and 20s timeout.
However, the pretimeout concept assumes that there are two timers which can be set independently. As you had pointed out earlier, and as the specification seems to confirm, that is not the case here. As such, I don't really understand why and how the pretimeout / timeout concept would add any value here and not just make things more complicated than necessary. Maybe I am just missing something.
Thanks,
Guenter
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
Quoted 7 lines · Guenter Roeck
However, the pretimeout concept assumes that there are two timers which can be set independently. As you had pointed out earlier, and as the specification seems to confirm, that is not the case here. As such, I don't really understand why and how the pretimeout / timeout concept would add any value here and not just make things more complicated than necessary. Maybe I am just missing something.
It might be possible to load a new value into the WOR register after the WS0 interrupt occurs. That is, in the interrupt handler, we can do something like this:
if (status & SBSA_GWDT_WCS_WS0) // write new WOR value, // then ping watchdog so that it's loaded
I'm not convinced that it's worth it, however. It would require interrupts to still be working when WS0 times out, which somewhat defeats the purpose of a watchdog.
Signature · 7 lines
Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation. -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Guenter Roeck
maintainerRe: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
Quoted 9 lines · Timur Tabi
Quoted 7 lines · Guenter Roeck
However, the pretimeout concept assumes that there are two timers which can be set independently. As you had pointed out earlier, and as the specification seems to confirm, that is not the case here. As such, I don't really understand why and how the pretimeout / timeout concept would add any value here and not just make things more complicated than necessary. Maybe I am just missing something.
Quoted 8 lines
It might be possible to load a new value into the WOR register after the WS0 interrupt occurs. That is, in the interrupt handler, we can do something like this:
if (status & SBSA_GWDT_WCS_WS0) // write new WOR value, // then ping watchdog so that it's loadedI'm not convinced that it's worth it, however. It would require interrupts to still be working when WS0 times out, which somewhat defeats the purpose of a watchdog.
If I understand the specification correctly, reloading the register would result in another WS0, not in WS1. That isn't really what we would want to happen.
Reloading the register would normally be done in the crashdump kernel, if it is loaded, to give it time to actually take the crashdump. But that is post-restart, not pre-restart.
Thanks,
Guenter
Re: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
Hi Guenter,
Quoted 21 lines · Guenter Roeck
Quoted 20 lines · Timur Tabi
Quoted 8 lines · Guenter Roeck
However, the pretimeout concept assumes that there are two timers which can be set independently. As you had pointed out earlier, and as the specification seems to confirm, that is not the case here. As such, I don't really understand why and how the pretimeout / timeout concept would add any value here and not just make things more complicated than necessary. Maybe I am just missing something.
It might be possible to load a new value into the WOR register after the WS0 interrupt occurs. That is, in the interrupt handler, we can do something like this:
if (status & SBSA_GWDT_WCS_WS0) // write new WOR value, // then ping watchdog so that it's loaded
Quoted 8 lines
Quoted 4 lines
I'm not convinced that it's worth it, however. It would require interrupts to still be working when WS0 times out, which somewhat defeats the purpose of a watchdog.
If I understand the specification correctly, reloading the register would result in another WS0, not in WS1. That isn't really what we would want to happen.
Yes, you are 100% correct.
In SBSA:
---------------
An explicit watchdog refresh occurs when one of a number of different events occur:
(1) The Watchdog Refresh Register is written.
(2) The Watchdog Offset Register is written.
(3) The Watchdog Control and Status register is written. In the case of an explicit refresh the Watchdog Signals are cleared.
---------------
So, for the second timeout, we can only use WOR.(but maybe we can write WCV in the WS0 routine to make the second timeout longer, if we really need a long time for panic)
If we write WOR , that will clean WCS, then the system go back to first timeout stage.
But for the first timeout, we can use WOR (that means the two timeout stages will be the same, in another world, WS0==WS1*2 ) or we can write WCV directly.
And writing WCV will not trigger an explicit watchdog refresh, that is what I am doing to set up pretimeout.
Quoted 8 lines
Reloading the register would normally be done in the crashdump kernel, if it is loaded, to give it time to actually take the crashdump. But that is post-restart, not pre-restart.
Thanks,
Guenter
Signature · 10 lines
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
Re: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
In reply to Guenter RoeckHi Guenter,
Quoted 25 lines · Guenter Roeck
On 05/23/2015 12:40 PM, Timur Tabi wrote:
[ ... ]Quoted 5 lines
I use
emergency_restart(), because the watchdog-api.txt documentation says this:Quoted 9 lines
"If userspace fails (RAM error, kernel bug, whatever), the notifications cease to occur, and the hardware watchdog will reset the system (causing a reboot) after the timeout occurs."
Maybe I'm reading this too literally, but to me this means that when the timeout expires, the system has to reset immediately.
However, maybe
panic()is better, since it can do the same thing and more.I have a specific requirement at work to have watchdog expiration (not this watchdog, this is different HW) result in a panic, specifically to enable crashdump support and thus post-mortem analysis.
I had not thought about this use case myself, and I had always wondered why watchdog driver implementers would choose to call
panic()after an interrupt or NMI. But we live and learn, so now I finally understand.
Quoted 7 lines
In the pretimeout/timeout world, the pretimeout would (typically) result in a panic, and the timeout would result in a reset. So one would set the timer register to 10s for 10s pretimeout and 20s timeout.
However, the pretimeout concept assumes that there are two timers which can be set independently. As you had pointed out earlier, and as the specification seems to confirm, that is not the case here.
Sorry, in Documentation/watchdog/watchdog-api.txt, I can not get the info about " the pretimeout concept assumes that there are two timers which can be set independently."
Could you kindly point out where is the assumption.
I thinks in kernel documentation, that meams "one watchdog has two timeout stages", maybe I miss something. Could you help me out?
Quoted 3 lines
As such, I don't really understand why and how the pretimeout / timeout concept would add any value here and not just make things more complicated than necessary. Maybe I am just missing something.
If pretimeout concept assumes that there are two timers, I misunderstand the "pretimeout", then I will delete the pretimeout immediately.
Quoted 4 lines
Thanks,
Guenter
Signature · 10 lines
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
Guenter Roeck
maintainerRe: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
Quoted 36 lines · Fu Wei
Hi Guenter,
Quoted 25 lines · Guenter Roeck
On 05/23/2015 12:40 PM, Timur Tabi wrote:
[ ... ]Quoted 5 lines
I use
emergency_restart(), because the watchdog-api.txt documentation says this:Quoted 9 lines
"If userspace fails (RAM error, kernel bug, whatever), the notifications cease to occur, and the hardware watchdog will reset the system (causing a reboot) after the timeout occurs."
Maybe I'm reading this too literally, but to me this means that when the timeout expires, the system has to reset immediately.
However, maybe
panic()is better, since it can do the same thing and more.I have a specific requirement at work to have watchdog expiration (not this watchdog, this is different HW) result in a panic, specifically to enable crashdump support and thus post-mortem analysis.
I had not thought about this use case myself, and I had always wondered why watchdog driver implementers would choose to call
panic()after an interrupt or NMI. But we live and learn, so now I finally understand.Quoted 7 lines
In the pretimeout/timeout world, the pretimeout would (typically) result in a panic, and the timeout would result in a reset. So one would set the timer register to 10s for 10s pretimeout and 20s timeout.
However, the pretimeout concept assumes that there are two timers which can be set independently. As you had pointed out earlier, and as the specification seems to confirm, that is not the case here.
Quoted 8 lines
Sorry, in
Documentation/watchdog/watchdog-api.txt, I can not get the info about " the pretimeout concept assumes that there are two timers which can be set independently."
Could you kindly point out where is the assumption.I thinks in kernel documentation, that meams "one watchdog has two timeout stages", maybe I miss something. Could you help me out?
My apologies. Terminology problem; see below.
Note that the pretimeout, as documented, is a difference to the real timeout, not an absolute time (which I had not realized before).
"Note that the pretimeout is the number of seconds before the time
when the timeout will go off. It is not the number of seconds until the pretimeout. So, for instance, if you set the timeout to 60 seconds and the pretimeout to 10 seconds, the pretimeout will go off in 50 seconds. Setting a pretimeout to zero disables it."
Quoted 8 lines
Quoted 3 lines
As such, I don't really understand why and how the pretimeout / timeout concept would add any value here and not just make things more complicated than necessary. Maybe I am just missing something.
If pretimeout concept assumes that there are two timers, I misunderstand the "pretimeout", then I will delete the pretimeout immediately.
I think I used the wrong term. I should have said something like "two distinct timeout values".
Guenter
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
Hi Guenter,
Thanks for your feedback
Quoted 53 lines · Guenter Roeck
Quoted 42 lines · Fu Wei
Hi Guenter,
Quoted 29 lines · Guenter Roeck
On 05/23/2015 12:40 PM, Timur Tabi wrote:
[ ... ]Quoted 11 lines
I use
emergency_restart(), because the watchdog-api.txt documentation says
this:"If userspace fails (RAM error, kernel bug, whatever), the notifications cease to occur, and the hardware watchdog will reset the system (causing a reboot) after the timeout occurs."
Quoted 6 lines
Maybe I'm reading this too literally, but to me this means that when the timeout expires, the system has to reset immediately.
However, maybe
panic()is better, since it can do the same thing and more.I have a specific requirement at work to have watchdog expiration (not this watchdog, this is different HW) result in a panic, specifically to enable crashdump support and thus post-mortem analysis.
I had not thought about this use case myself, and I had always wondered why watchdog driver implementers would choose to call
panic()after an interrupt or NMI. But we live and learn, so now I finally understand.Quoted 7 lines
In the pretimeout/timeout world, the pretimeout would (typically) result in a panic, and the timeout would result in a reset. So one would set the timer register to 10s for 10s pretimeout and 20s timeout.
However, the pretimeout concept assumes that there are two timers which can be set independently. As you had pointed out earlier, and as the specification seems to confirm, that is not the case here.
Quoted 8 lines
Sorry, in
Documentation/watchdog/watchdog-api.txt, I can not get the info about " the pretimeout concept assumes that there are two timers which can be set independently."
Could you kindly point out where is the assumption.I thinks in kernel documentation, that meams "one watchdog has two timeout stages", maybe I miss something. Could you help me out?
My apologies. Terminology problem; see below.
Quoted 8 lines
Note that the pretimeout, as documented, is a difference to the real timeout, not an absolute time (which I had not realized before).
"Note that the pretimeout is the number of seconds before the time
when the timeout will go off. It is not the number of seconds until the pretimeout. So, for instance, if you set the timeout to 60 seconds and the pretimeout to 10 seconds, the pretimeout will go off in 50 seconds. Setting a pretimeout to zero disables it."
yes , this patchset is designed for this pretimeout concept
Quoted 6 lines
Quoted 6 lines
Quoted 4 lines
As such, I don't really understand why and how the pretimeout / timeout concept would add any value here and not just make things more complicated than necessary. Maybe I am just missing something.
Quoted 6 lines
Quoted 4 lines
If pretimeout concept assumes that there are two timers, I misunderstand the "pretimeout", then I will delete the pretimeout immediately.
I think I used the wrong term. I should have said something like "two distinct timeout values".
Actually, I have added my thought at the head of sbsa_gwdt.c as a comment :
*
* Note: This SBSA Generic watchdog driver is compatible with
* the pretimeout concept of Linux kernel. * The timeout and pretimeout are set by the different REGs. * The first watch period is set by writing WCV directly, * that can support more than 10s timeout at the maximum * system counter frequency. * The second watch period is set by WOR(32bit) which will be loaded * automatically by hardware, when WS0 is triggered. * This gives a maximum watch period of around 10s at the maximum * system counter frequency. * The System Counter shall run at maximum of 400MHz. * More details: DEN0029B - Server Base System Architecture (SBSA)
*
* Kernel/API: P---------| pretimeout
* |-------------------------------T timeout
* SBSA GWDT: P--WOR---WS1 pretimeout
* |-------WCV----------WS0~~~~~~~~T timeout
*/
Quoted 3 lines
Guenter
Signature · 14 lines
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 -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Guenter Roeck
maintainerRe: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
On 05/24/2015 08:50 AM, Fu Wei wrote:
[ ...]
Quoted 15 lines
Actually, I have added my thought at the head of
sbsa_gwdt.cas a comment :* * Note: This SBSA Generic watchdog driver is compatible with * the pretimeout concept of Linux kernel. * The timeout and pretimeout are set by the different REGs. * The first watch period is set by writing WCV directly, * that can support more than 10s timeout at the maximum * system counter frequency. * The second watch period is set by WOR(32bit) which will be loaded * automatically by hardware, when WS0 is triggered. * This gives a maximum watch period of around 10s at the maximum * system counter frequency. * The System Counter shall run at maximum of 400MHz. * More details: DEN0029B - Server Base System Architecture (SBSA)
Quoted 7 lines
*
* Kernel/API: P---------| pretimeout
* |-------------------------------T timeout
* SBSA GWDT: P--WOR---WS1 pretimeout
* |-------WCV----------WS0~~~~~~~~T timeout
*/
Yes, but do we actually _know_ that it works that way, ie that WCV drives WS0 and that WOR drives WS1 ? Unless I am missing something, the specification doesn't say that, and it would have been a really easy statement to make if that was the intent.
My concern here is that the above behavior is not spelled out in the document, meaning it is up to interpretation by the hardware engineer implementing it, to the point where it appears that not even two software engineers can agree how it is supposed to work. Which is a really bad starting point :-(.
Thanks,
Guenter
Re: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
Hi Guenter,
Quoted 28 lines · Guenter Roeck
On 05/24/2015 08:50 AM, Fu Wei wrote:
[ ...]Quoted 17 lines
Actually, I have added my thought at the head of
sbsa_gwdt.cas a comment :* * Note: This SBSA Generic watchdog driver is compatible with * the pretimeout concept of Linux kernel. * The timeout and pretimeout are set by the different REGs. * The first watch period is set by writing WCV directly, * that can support more than 10s timeout at the maximum * system counter frequency. * The second watch period is set by WOR(32bit) which will be loaded * automatically by hardware, when WS0 is triggered. * This gives a maximum watch period of around 10s at the maximum * system counter frequency. * The System Counter shall run at maximum of 400MHz. * More details: DEN0029B - Server Base System Architecture (SBSA)Quoted 7 lines
*
* Kernel/API: P---------| pretimeout
* |-------------------------------T timeout
* SBSA GWDT: P--WOR---WS1 pretimeout
* |-------WCV----------WS0~~~~~~~~T timeout
*/
Quoted 4 lines
Yes, but do we actually _know_ that it works that way, ie that WCV drives WS0 and that WOR drives WS1 ? Unless I am missing something, the specification doesn't say that, and it would have been a really easy statement to make if that was the intent.
yes, Suravee has tested it on Seattle B0 Soc, that works.
But hope Suravee can provide more info about test, I will ping him later.
According to SBSA, that WCV and WOR can both drive WS1 and WS0
the timeout and pretimeout in my patchset have been tested on Seattle B0 and Foundation model.
Quoted 6 lines
My concern here is that the above behavior is not spelled out in the document, meaning it is up to interpretation by the hardware engineer implementing it, to the point where it appears that not even two software engineers can agree how it is supposed to work. Which is a really bad starting point :-(.
Is that a real hardware teat can prove it works?
or actually, SBSA say that it should work:
-----------------
Note: the watchdog offset register is 32 bits wide. This gives a maximum watch period of around 10s at a system
counter frequency of 400MHz. If a larger watch period is required then the compare value can be programmed
directly into the compare value register.
-----------------
offset register == WOR
compare value register == WCV
Quoted 9 lines
Thanks,
Guenter--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Signature · 10 lines
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
Guenter Roeck
maintainerRe: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
Quoted 53 lines · Fu Wei
Hi Guenter,
Quoted 28 lines · Guenter Roeck
On 05/24/2015 08:50 AM, Fu Wei wrote:
[ ...]Quoted 17 lines
Actually, I have added my thought at the head of
sbsa_gwdt.cas a comment :* * Note: This SBSA Generic watchdog driver is compatible with * the pretimeout concept of Linux kernel. * The timeout and pretimeout are set by the different REGs. * The first watch period is set by writing WCV directly, * that can support more than 10s timeout at the maximum * system counter frequency. * The second watch period is set by WOR(32bit) which will be loaded * automatically by hardware, when WS0 is triggered. * This gives a maximum watch period of around 10s at the maximum * system counter frequency. * The System Counter shall run at maximum of 400MHz. * More details: DEN0029B - Server Base System Architecture (SBSA)Quoted 7 lines
*
* Kernel/API: P---------| pretimeout
* |-------------------------------T timeout
* SBSA GWDT: P--WOR---WS1 pretimeout
* |-------WCV----------WS0~~~~~~~~T timeout
*/Quoted 4 lines
Yes, but do we actually _know_ that it works that way, ie that WCV drives WS0 and that WOR drives WS1 ? Unless I am missing something, the specification doesn't say that, and it would have been a really easy statement to make if that was the intent.
yes, Suravee has tested it on Seattle B0 Soc, that works.
But hope Suravee can provide more info about test, I will ping him later.According to SBSA, that WCV and WOR can both drive WS1 and WS0
the timeout and pretimeout in my patchset have been tested on Seattle B0 and Foundation model.
Quoted 6 lines
My concern here is that the above behavior is not spelled out in the document, meaning it is up to interpretation by the hardware engineer implementing it, to the point where it appears that not even two software engineers can agree how it is supposed to work. Which is a really bad starting point :-(.
Is that a real hardware teat can prove it works?
Quoted 11 lines
or actually, SBSA say that it should work:
-----------------
Note: the watchdog offset register is 32 bits wide. This gives a maximum watch period of around 10s at a system
counter frequency of 400MHz. If a larger watch period is required then the compare value can be programmed
directly into the compare value register.
-----------------
offset register == WOR
compare value register == WCV
Where does it say that WCV shall be associated with WS0 and that WOR shall be associated with WS1 ? Guess I am missing that part.
Thanks,
Guenter
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
Hi Guenter,
Quoted 73 lines · Guenter Roeck
Quoted 60 lines · Fu Wei
Hi Guenter,
Quoted 32 lines · Guenter Roeck
On 05/24/2015 08:50 AM, Fu Wei wrote:
[ ...]Quoted 19 lines
Actually, I have added my thought at the head of
sbsa_gwdt.cas a comment
:* * Note: This SBSA Generic watchdog driver is compatible with * the pretimeout concept of Linux kernel. * The timeout and pretimeout are set by the different REGs. * The first watch period is set by writing WCV directly, * that can support more than 10s timeout at the maximum * system counter frequency. * The second watch period is set by WOR(32bit) which will beloaded
* automatically by hardware, when WS0 is triggered.
* This gives a maximum watch period of around 10s at the
maximum* system counter frequency. * The System Counter shall run at maximum of 400MHz. * More details: DEN0029B - Server Base System ArchitectureQuoted 8 lines
(SBSA)
*
* Kernel/API: P---------| pretimeout
* |-------------------------------T timeout
* SBSA GWDT: P--WOR---WS1 pretimeout
* |-------WCV----------WS0~~~~~~~~T timeout
*/Quoted 4 lines
Yes, but do we actually _know_ that it works that way, ie that WCV drives WS0 and that WOR drives WS1 ? Unless I am missing something, the specification doesn't say that, and it would have been a really easy statement to make if that was the intent.
yes, Suravee has tested it on Seattle B0 Soc, that works.
But hope Suravee can provide more info about test, I will ping him later.According to SBSA, that WCV and WOR can both drive WS1 and WS0
the timeout and pretimeout in my patchset have been tested on Seattle B0 and Foundation model.
Quoted 6 lines
My concern here is that the above behavior is not spelled out in the document, meaning it is up to interpretation by the hardware engineer implementing it, to the point where it appears that not even two software engineers can agree how it is supposed to work. Which is a really bad starting point :-(.
Is that a real hardware teat can prove it works?
Quoted 11 lines
or actually, SBSA say that it should work:
-----------------
Note: the watchdog offset register is 32 bits wide. This gives a maximum watch period of around 10s at a system
counter frequency of 400MHz. If a larger watch period is required then the compare value can be programmed
directly into the compare value register.
-----------------
offset register == WOR
compare value register == WCV
Quoted 2 lines
Where does it say that WCV shall be associated with WS0 and that WOR shall be associated with WS1 ? Guess I am missing that part.
no, it doesn't say WCV shall be associated with WS0, that is my driver doing.
but WCV can control both WS1/WS0. WOR is just a auto-reload value.
I think maybe you can read SBSA 2.3 Page 23, The pseudocode can explain everything. :-)
Great thanks for your time
Quoted 9 lines
Thanks,
Guenter--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Signature · 14 lines
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 -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
In reply to Fu WeiQuoted 3 lines · Fu Wei
If pretimeout concept assumes that there are two timers, I misunderstand the "pretimeout", then I will delete the pretimeout immediately.
In my opinion, calling panic() on a pre-timeout is not useful, because that's really just a normal timeout. If there were a way to "warn" user space that a timeout is about to occur, without a panic or reset, then that might be useful. But as far as I can see, all you're doing is redefining the word "timeout".
Signature · 3 lines
Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation.
Re: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
Hi Timur,
I have said this before:
in the first timeout, just panic() maybe not enough, in [RFC] version of my patchset, I offer some option as "preaction" to use, but for simplifying the first version of driver, I have deleted them. but at least, panic() is far more useful than a simple reset. at least, it can provide the context of the crashed system to admin.
If you want to warn user space, that will make driver more complicated, I don't think that is a good choose for a first version. but we can find a way to improve this later
Quoted 18 lines · Timur Tabi
Quoted 4 lines · Fu Wei
If pretimeout concept assumes that there are two timers, I misunderstand the "pretimeout", then I will delete the pretimeout immediately.
In my opinion, calling
panic()on a pre-timeout is not useful, because that's really just a normal timeout. If there were a way to "warn" user space that a timeout is about to occur, without a panic or reset, then that might be useful. But as far as I can see, all you're doing is redefining the word "timeout".--
Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation.
Signature · 14 lines
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 -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
Quoted 5 lines · Fu Wei
in the first timeout, just
panic()maybe not enough, in [RFC] version of my patchset, I offer some option as "preaction" to use, but for simplifying the first version of driver, I have deleted them. but at least,panic()is far more useful than a simple reset. at least, it can provide the context of the crashed system to admin.
My point is that there is very little difference between
1) calling panic() on pre-timeout
2) calling panic() on timeout
In both cases, the system will panic. The watchdog API says that the system should reset when a timeout occurs, so you cannot call panic() before the timeout expires.
Quoted 3 lines
If you want to warn user space, that will make driver more complicated, I don't think that is a good choose for a first version. but we can find a way to improve this later
In my opinion, this "first version" is not useful. I would like to see a pre-timeout feature that does not panic or reset when a pre-timeout occurs.
Signature · 7 lines
Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation. -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Guenter Roeck
maintainerRe: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
Quoted 7 lines · Timur Tabi
Quoted 5 lines · Fu Wei
in the first timeout, just
panic()maybe not enough, in [RFC] version of my patchset, I offer some option as "preaction" to use, but for simplifying the first version of driver, I have deleted them. but at least,panic()is far more useful than a simple reset. at least, it can provide the context of the crashed system to admin.
Quoted 5 lines
My point is that there is very little difference between
1) calling
panic()on pre-timeout
2) callingpanic()on timeout
The assumption would be that the second timeout doesn't cause a panic but a system reset.
Quoted 8 lines
In both cases, the system will panic. The watchdog API says that the system should reset when a timeout occurs, so you cannot call
panic()before the timeout expires.Quoted 3 lines
If you want to warn user space, that will make driver more complicated, I don't think that is a good choose for a first version. but we can find a way to improve this later
In my opinion, this "first version" is not useful. I would like to see a pre-timeout feature that does not panic or reset when a pre-timeout occurs.
The current watchdog API suggests that the pretimeout "allows Linux to record useful information (like panic information and kernel coredumps) before it resets". The call to panic() would be the means to make this happen.
Are you suggesting to change this definition ? What should it do instead in your opinion ?
Thanks,
Guenter
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
Hi Guenter
Quoted 28 lines · Guenter Roeck
Quoted 10 lines · Timur Tabi
Quoted 6 lines · Fu Wei
in the first timeout, just
panic()maybe not enough, in [RFC] version of my patchset, I offer some option as "preaction" to use, but for simplifying the first version of driver, I have deleted them. but at least,panic()is far more useful than a simple reset. at least, it can provide the context of the crashed system to admin.Quoted 5 lines
My point is that there is very little difference between
1) calling
panic()on pre-timeout
2) callingpanic()on timeoutThe assumption would be that the second timeout doesn't cause a panic but a system reset.
Quoted 8 lines
In both cases, the system will panic. The watchdog API says that the system should reset when a timeout occurs, so you cannot call
panic()before the timeout expires.Quoted 3 lines
If you want to warn user space, that will make driver more complicated, I don't think that is a good choose for a first version. but we can find a way to improve this later
Quoted 8 lines
Quoted 3 lines
In my opinion, this "first version" is not useful. I would like to see a pre-timeout feature that does not panic or reset when a pre-timeout occurs.
The current watchdog API suggests that the pretimeout "allows Linux to record useful information (like panic information and kernel coredumps) before it resets". The call to
panic()would be the means to make this happen.
Yes, that is what I mean. Great thanks for your explanation. :-)
Quoted 7 lines
Are you suggesting to change this definition ? What should it do instead in your opinion ?
Thanks,
Guenter
Signature · 10 lines
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
Re: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
In reply to Guenter RoeckQuoted 4 lines · Guenter Roeck
The current watchdog API suggests that the pretimeout "allows Linux to record useful information (like panic information and kernel coredumps) before it resets". The call to
panic()would be the means to make this happen.
Now that I think about it, that does make sense.
However, if a pre-timeout is not set, then the driver should never call panic(). That means that the interrupt handler should only be registered if sbsa_gwdt_set_pretimeout() is called.
Signature · 3 lines
Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation.
Guenter Roeck
maintainerRe: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
Quoted 11 lines · Timur Tabi
Quoted 4 lines · Guenter Roeck
The current watchdog API suggests that the pretimeout "allows Linux to record useful information (like panic information and kernel coredumps) before it resets". The call to
panic()would be the means to make this happen.Now that I think about it, that does make sense.
However, if a pre-timeout is not set, then the driver should never call
panic(). That means that the interrupt handler should only be registered ifsbsa_gwdt_set_pretimeout()is called.
This is a matter of opinion. Some watchdogs have two (or even more) levels of timeouts without explicit pretimeout. The iTCO watchdog in Intel systems is an example, but there are several others.
For such systems, there may be an initial interrupt followed by a hard reset a little later. In such cases it does make sense to wire up the interrupt and have it call panic(). If the system gets stuck, the second timeout will reset it.
Guenter
Re: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
In reply to Timur TabiHi Timur
Quoted 8 lines · Timur Tabi
Quoted 4 lines · Guenter Roeck
The current watchdog API suggests that the pretimeout "allows Linux to record useful information (like panic information and kernel coredumps) before it resets". The call to
panic()would be the means to make this happen.
Quoted 5 lines
Now that I think about it, that does make sense.
However, if a pre-timeout is not set, then the driver should never call
panic(). That means that the interrupt handler should only be registered ifsbsa_gwdt_set_pretimeout()is called.
I don't know why you want to do this tricky way. you can always register the interrupt handler,
if pre-timeout is 0, system will just trigger WS1 right after WS0
Quoted 6 lines
--
Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation.
Signature · 10 lines
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
Re: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
Quoted 3 lines · Fu Wei
I don't know why you want to do this tricky way. you can always register the interrupt handler,
if pre-timeout is 0, system will just trigger WS1 right after WS0
But that only works if the pre-timeout and timeout can be programmed to separate values. And as Guenter says, the SBSA may not guarantee that.
Signature · 7 lines
Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation. -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
Hi Timur,
Quoted 9 lines · Timur Tabi
Quoted 4 lines · Fu Wei
I don't know why you want to do this tricky way. you can always register the interrupt handler,
if pre-timeout is 0, system will just trigger WS1 right after WS0But that only works if the pre-timeout and timeout can be programmed to separate values. And as Guenter says, the SBSA may not guarantee that.
In my driver patch, the first stage, I am using WCV, for the second stage I am using WOR,
that have been tested on real hardware.
would you please read the pseudocode in Page 23 of SBSA 2.3
Quoted 6 lines
--
Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation.
Signature · 10 lines
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
Guenter Roeck
maintainerRe: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
In reply to Timur TabiQuoted 7 lines · Timur Tabi
Quoted 3 lines · Fu Wei
I don't know why you want to do this tricky way. you can always register the interrupt handler,
if pre-timeout is 0, system will just trigger WS1 right after WS0But that only works if the pre-timeout and timeout can be programmed to separate values. And as Guenter says, the SBSA may not guarantee that.
The pseudo-code in the specification suggests that if WCV is configured,
WS0 = WCV
WS1 = WCV + WOR
Assuming that the implementation follows the pseudo-code in the specification, we would have separately programmable values. Since the pretimeout (per ABI) is the difference in seconds to the timeout, and not an absolute value, we would have to program the registers as follows.
WCV = timeout - pretimeout; WOR = pretimeout;
Does this make sense ?
Thanks,
Guenter
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
Quoted 12 lines · Guenter Roeck
The pseudo-code in the specification suggests that if WCV is configured,
WS0 = WCV
WS1 = WCV + WORAssuming that the implementation follows the pseudo-code in the specification,
we would have separately programmable values. Since the pretimeout (per ABI)
is the difference in seconds to the timeout, and not an absolute value, we would have to program the registers as follows.
Quoted 4 lines
WCV = timeout - pretimeout; WOR = pretimeout;Does this make sense ?
Yes, thank you. I will test this on my hardware.
Signature · 3 lines
Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation.
Re: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
Hi Guenter,
Quoted 14 lines · Timur Tabi
Quoted 13 lines · Guenter Roeck
The pseudo-code in the specification suggests that if WCV is configured,
WS0 = WCV
WS1 = WCV + WORAssuming that the implementation follows the pseudo-code in the specification,
we would have separately programmable values. Since the pretimeout (per ABI)
is the difference in seconds to the timeout, and not an absolute value, we would have to program the registers as follows.
Quoted 4 lines
Quoted 4 lines
WCV = timeout - pretimeout; WOR = pretimeout;Does this make sense ?
And actually all the patchset I sent to upstream are all follow this design, and have been test on Foundation model and Seattle B0
Quoted 9 lines
Yes, thank you. I will test this on my hardware.
--
Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation.
Signature · 10 lines
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
Re: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
In reply to Guenter RoeckHi, Guenter,
Quoted 17 lines · Guenter Roeck
Quoted 11 lines · Timur Tabi
Quoted 4 lines · Fu Wei
I don't know why you want to do this tricky way. you can always register the interrupt handler,
if pre-timeout is 0, system will just trigger WS1 right after WS0But that only works if the pre-timeout and timeout can be programmed to separate values. And as Guenter says, the SBSA may not guarantee that.
The pseudo-code in the specification suggests that if WCV is configured,
WS0 = WCV
WS1 = WCV + WOR
Quoted 8 lines
Assuming that the implementation follows the pseudo-code in the specification,
we would have separately programmable values. Since the pretimeout (per ABI) is the difference in seconds to the timeout, and not an absolute value, we would have to program the registers as follows.WCV = timeout - pretimeout; WOR = pretimeout;
yes, this patchset is doing this way.
Quoted 6 lines
Does this make sense ?
Thanks,
Guenter
Signature · 10 lines
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
Re: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
In reply to Timur TabiHi Timur,
Sorry, how do you trigger a panic if WS1 ties to reset ?? don't know what is your question
could you make it simple:
1) calling panic() on pre-timeout (WS0????)
2) calling panic() on timeout (WS1????)
in "first version" , I just print the timeleft for WS1 or panic when WS0 occurs.
Quoted 30 lines · Timur Tabi
Quoted 6 lines · Fu Wei
in the first timeout, just
panic()maybe not enough, in [RFC] version of my patchset, I offer some option as "preaction" to use, but for simplifying the first version of driver, I have deleted them. but at least,panic()is far more useful than a simple reset. at least, it can provide the context of the crashed system to admin.My point is that there is very little difference between
1) calling
panic()on pre-timeout
2) callingpanic()on timeoutIn both cases, the system will panic. The watchdog API says that the system should reset when a timeout occurs, so you cannot call
panic()before the timeout expires.Quoted 3 lines
If you want to warn user space, that will make driver more complicated, I don't think that is a good choose for a first version. but we can find a way to improve this later
In my opinion, this "first version" is not useful. I would like to see a pre-timeout feature that does not panic or reset when a pre-timeout occurs.
--
Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation.
Signature · 10 lines
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
Re: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
In reply to [email protected]Quoted 21 lines · On 2015年05月21日 16:32, [email protected] wrote:
From: Fu Wei <[email protected]>
This driver bases on linux kernel watchdog framework, and use "pretimeout" in the framework. It supports getting timeout and pretimeout from parameter and FDT at the driver init stage. In first timeout(WS0), the interrupt routine run panic to save system context.
Signed-off-by Fu Wei <[email protected]>--- drivers/watchdog/Kconfig | 12 ++ drivers/watchdog/Makefile | 1 + drivers/watchdog/sbsa_gwdt.c | 476 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 489 insertions(+)create mode 100644
drivers/watchdog/sbsa_gwdt.cdrivers/watchdog/Kconfig +0
-0
drivers/watchdog/Kconfig config ARM_SP805_WATCHDOG · line 157
Quoted 6 lines
drivers/watchdog/Kconfig +3
-0@@ -152,6 +152,18 @@ 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 ARM || ARM64 || COMPILE_TEST
SBSA is for ARMv8-A based (64-bit) servers, no need to depends on ARM, and why we depends on COMPILE_TEST?
Quoted 56 lines
drivers/watchdog/Kconfig +9
-0+ depends on ARM_ARCH_TIMER + select WATCHDOG_CORE + help + ARM SBSA Generic Watchdog timer. This has two Watchdog Signals + (WS0/WS1), will trigger a warning interrupt(do panic) at the first + timeout(WS0); will reboot your system when the second timeout(WS1) + is reached. + More details: DEN0029B - Server Base System Architecture (SBSA) + config AT91RM9200_WATCHDOG tristate "AT91RM9200 watchdog" depends on SOC_AT91RM9200 && MFD_SYSCONdrivers/watchdog/Makefile +1
-0@@ -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_AT91RM9200_WATCHDOG) += at91rm9200_wdt.o obj-$(CONFIG_AT91SAM9X_WATCHDOG) += at91sam9_wdt.o obj-$(CONFIG_CADENCE_WATCHDOG) += cadence_wdt.odrivers/watchdog/sbsa_gwdt.c new file +26
-0@@ -0,0 +1,476 @@ +/* +* SBSA(Server Base System Architecture) Generic Watchdog driver +* +* Copyright (c) 2015, Linaro Ltd. +* Author: Fu Wei <[email protected]> +* Suravee Suthikulpanit <[email protected]> +* +* 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. +* +* Note: This SBSA Generic watchdog driver is compatible with +* the pretimeout concept of Linux kernel. +* The timeout and pretimeout are set by the different REGs. +* The first watch period is set by writing WCV directly, +* that can support more than 10s timeout at the maximum +* system counter frequency. +* The second watch period is set by WOR(32bit) which will be loaded +* automatically by hardware, when WS0 is triggered. +* This gives a maximum watch period of around 10s at the maximum +* system counter frequency.
drivers/watchdog/sbsa_gwdt.c line 36
Quoted 10 lines
drivers/watchdog/sbsa_gwdt.c new file +10
-0+* The System Counter shall run at maximum of 400MHz. +* More details: DEN0029B - Server Base System Architecture (SBSA) +* +* Kernel/API: P---------| pretimeout +* |-------------------------------T timeout +* SBSA GWDT: P--WOR---WS1 pretimeout +* |-------WCV----------WS0~~~~~~~~T timeout +*/ + +#include <asm/arch_timer.h>
please put it under #include <linux/*.h>, this is
the convention of order head files.
drivers/watchdog/sbsa_gwdt.c line 38
Quoted 2 lines
drivers/watchdog/sbsa_gwdt.c new file +2
-0+ +#include <linux/acpi.h>
Will we add any acpi realted code in this patch? if not, please remove this head file.
Quoted 405 lines
drivers/watchdog/sbsa_gwdt.c new file +405
-0+#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> + +/* 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_LO 0x010 +#define SBSA_GWDT_WCV_HI 0x014 + +/* 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 10/* seconds, the 1st + 2nd watch periods*/ +#define DEFAULT_PRETIMEOUT 5/* seconds, the 2nd watch period*/ + +static unsigned int timeout; +module_param (timeout, uint,0 ); +MODULE_PARM_DESC (timeout, + "Watchdog timeout in seconds. (>=0, default=" + __MODULE_STRING(DEFAULT_TIMEOUT) ")"); + +static unsigned int max_timeout =UINT_MAX ; +module_param (max_timeout, uint,0 ); +MODULE_PARM_DESC (max_timeout, + "Watchdog max timeout in seconds. (>=0, default=" + __MODULE_STRING(UINT_MAX) ")"); + +static unsigned int pretimeout; +module_param (pretimeout, uint,0 ); +MODULE_PARM_DESC (pretimeout, + "Watchdog pretimeout in seconds. (>=0, default=" + __MODULE_STRING(DEFAULT_PRETIMEOUT) ")"); + +static unsigned int max_pretimeout =U32_MAX ; +module_param (max_pretimeout, uint,0 ); +MODULE_PARM_DESC (max_pretimeout, + "Watchdog max pretimeout in seconds. (>=0, default=" + __MODULE_STRING(U32_MAX) ")"); + +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) ")"); + +/* +* Architected system timer support. +*/ +static void sbsa_gwdt_cf_write (unsigned int reg,u32 val, +struct watchdog_device *wdd) +{ +struct sbsa_gwdt *gwdt =to_sbsa_gwdt (wdd); + +writel_relaxed (val, gwdt->control_base + reg); +} + +static void sbsa_gwdt_rf_write (unsigned int reg,u32 val, +struct watchdog_device *wdd) +{ +struct sbsa_gwdt *gwdt =to_sbsa_gwdt (wdd); + +writel_relaxed (val, gwdt->refresh_base + reg); +} + +static u32 sbsa_gwdt_cf_read (unsigned int reg,struct watchdog_device *wdd) +{ +struct sbsa_gwdt *gwdt =to_sbsa_gwdt (wdd); + +return readl_relaxed (gwdt->control_base + reg); +} + +/* +* help founctions for accessing 64bit WCV register +*/ +static u64 sbsa_gwdt_get_wcv (struct watchdog_device *wdd) +{ +u32 wcv_lo, wcv_hi; + +do { + wcv_hi =sbsa_gwdt_cf_read (SBSA_GWDT_WCV_HI , wdd); + wcv_lo =sbsa_gwdt_cf_read (SBSA_GWDT_WCV_LO , wdd); + }while (wcv_hi !=sbsa_gwdt_cf_read (SBSA_GWDT_WCV_HI , wdd)); + +return (((u64 )wcv_hi <<32 ) | wcv_lo); +} + +static void sbsa_gwdt_set_wcv (struct watchdog_device *wdd,u64 value) +{ +u32 wcv_lo, wcv_hi; + + wcv_lo = value &U32_MAX ; + wcv_hi = (value >>32 ) &U32_MAX ; + +sbsa_gwdt_cf_write (SBSA_GWDT_WCV_HI , wcv_hi, wdd); +sbsa_gwdt_cf_write (SBSA_GWDT_WCV_LO , wcv_lo, wdd); +} + +static void reload_timeout_to_wcv (struct watchdog_device *wdd) +{ +struct sbsa_gwdt *gwdt =to_sbsa_gwdt (wdd); +u64 wcv; + + wcv =arch_counter_get_cntvct () + + (u64)(wdd->timeout - wdd->pretimeout) * gwdt->clk; + +sbsa_gwdt_set_wcv (wdd, wcv); +} + +/* +* Use the following function to set the limit of timeout +* after updating pretimeout +*/ +static void sbsa_gwdt_update_limits (struct watchdog_device *wdd) +{ +struct sbsa_gwdt *gwdt =to_sbsa_gwdt (wdd); +u64 first_period_max =U64_MAX ; + +do_div (first_period_max, gwdt->clk); + + wdd->min_timeout = wdd->pretimeout +1 ; + wdd->max_timeout =min ((uint)(wdd->pretimeout + first_period_max), + wdd->max_timeout); +} + +static int sbsa_gwdt_set_timeout (struct watchdog_device *wdd, +unsigned int timeout) +{ + wdd->timeout = timeout; + +return 0 ; +} + +static int sbsa_gwdt_set_pretimeout (struct watchdog_device *wdd, +unsigned int pretimeout) +{ +struct sbsa_gwdt *gwdt =to_sbsa_gwdt (wdd); +u32 wor; + + wdd->pretimeout = pretimeout; +sbsa_gwdt_update_limits (wdd); + +if (!pretimeout) +/* gives sbsa_gwdt_start a chance to setup timeout */ + wor = gwdt->clk; +else + wor = pretimeout * gwdt->clk; + +/* refresh the WOR, that will cause an explicit watchdog refresh */ +sbsa_gwdt_cf_write (SBSA_GWDT_WOR , wor, wdd); + +return 0 ; +} + +static unsigned int sbsa_gwdt_get_timeleft (struct watchdog_device *wdd) +{ +struct sbsa_gwdt *gwdt =to_sbsa_gwdt (wdd); +u64 timeleft =sbsa_gwdt_get_wcv (wdd) -arch_counter_get_cntvct (); + +do_div (timeleft, gwdt->clk); + +return timeleft; +} + +static int sbsa_gwdt_start (struct watchdog_device *wdd) +{ +/* Force refresh */ +sbsa_gwdt_rf_write (SBSA_GWDT_WRR ,0xc0ffee , wdd); +/* writing WCS will cause an explicit watchdog refresh */ +sbsa_gwdt_cf_write (SBSA_GWDT_WCS ,SBSA_GWDT_WCS_EN , wdd); + +reload_timeout_to_wcv (wdd); + +return 0 ; +} + +static int sbsa_gwdt_stop (struct watchdog_device *wdd) +{ +/* Force refresh */ +sbsa_gwdt_rf_write (SBSA_GWDT_WRR ,0xc0ffee , wdd); +/* writing WCS will cause an explicit watchdog refresh */ +sbsa_gwdt_cf_write (SBSA_GWDT_WCS ,0 , wdd); + +return 0 ; +} + +static int sbsa_gwdt_keepalive (struct watchdog_device *wdd) +{ +/* +* Writing WRR for an explicit watchdog refresh +* You can write anyting(like 0xc0ffee) +*/ +sbsa_gwdt_rf_write (SBSA_GWDT_WRR ,0xc0ffee , wdd); + +reload_timeout_to_wcv (wdd); + +return 0 ; +} + +static irqreturn_t sbsa_gwdt_interrupt (int irq,void *dev_id) +{ +struct sbsa_gwdt *gwdt = (struct sbsa_gwdt *)dev_id; +struct watchdog_device *wdd = &gwdt->wdd; +u32 status; + + status =sbsa_gwdt_cf_read (SBSA_GWDT_WCS , wdd); + +if (status &SBSA_GWDT_WCS_WS0 ) +panic ("SBSA Watchdog pre-timeout" ); + +return IRQ_HANDLED ; +} + +static struct watchdog_info sbsa_gwdt_info = { + .identity ="SBSA Generic Watchdog" , + .options =WDIOF_SETTIMEOUT | +WDIOF_KEEPALIVEPING | +WDIOF_MAGICCLOSE | +WDIOF_PRETIMEOUT | +WDIOF_CARDRESET , +}; + +static struct watchdog_ops sbsa_gwdt_ops = { + .owner =THIS_MODULE , + .start = sbsa_gwdt_start, + .stop = sbsa_gwdt_stop, + .ping = sbsa_gwdt_keepalive, + .set_timeout = sbsa_gwdt_set_timeout, + .set_pretimeout = sbsa_gwdt_set_pretimeout, + .get_timeleft = sbsa_gwdt_get_timeleft, +}; + +static int sbsa_gwdt_probe (struct platform_device *pdev) +{ +struct device *dev = &pdev->dev; +struct sbsa_gwdt *gwdt; +struct watchdog_device *wdd; +struct resource *res; +void *rf_base, *cf_base; +int irq; +u32 clk, status; +int ret =0 ; +u64 first_period_max =U64_MAX ; + +/* +* Try to determine the frequency from the arch_timer interface +*/ + clk =arch_timer_get_rate (); +if (!clk) { +dev_err (dev,"System Counter frequency not available\n" ); +return -EINVAL ; + } + + gwdt =devm_kzalloc (dev,sizeof (*gwdt),GFP_KERNEL ); +if (!gwdt) +return -ENOMEM ; + + res =platform_get_resource_byname (pdev,IORESOURCE_MEM ,"refresh" ); + rf_base =devm_ioremap_resource (dev, res); +if (IS_ERR (rf_base)) +return PTR_ERR (rf_base); + + res =platform_get_resource_byname (pdev,IORESOURCE_MEM ,"control" ); + cf_base =devm_ioremap_resource (dev, res); +if (IS_ERR (rf_base)) +return PTR_ERR (rf_base); + + irq =platform_get_irq_byname (pdev,"ws0" ); +if (irq <0 ) { +dev_err (dev,"unable to get ws0 interrupt.\n" ); +return irq; + } + + gwdt->refresh_base = rf_base; + gwdt->control_base = cf_base; + gwdt->clk = clk; + +platform_set_drvdata (pdev, gwdt); + + 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); + + status =sbsa_gwdt_cf_read (SBSA_GWDT_WCS , wdd); +if (status &SBSA_GWDT_WCS_WS1 ) { +dev_warn (dev,"System reset by WDT(WCS: %x, WCV: %llx)\n" , + status,sbsa_gwdt_get_wcv (wdd)); + wdd->bootstatus |=WDIOF_CARDRESET ; + } +/* Check if watchdog is already enabled */ +if (status &SBSA_GWDT_WCS_EN ) { +dev_warn (dev,"already enabled! WCS:0x%x\n" , status); +sbsa_gwdt_keepalive (wdd); + } + + wdd->min_pretimeout =0 ; + wdd->max_pretimeout =min (U32_MAX / clk, max_pretimeout); + wdd->min_timeout =1 ; +do_div (first_period_max, clk); + wdd->max_timeout =min ((uint)(wdd->pretimeout + first_period_max), + max_timeout); + + wdd->pretimeout =DEFAULT_PRETIMEOUT ; + wdd->timeout =DEFAULT_TIMEOUT ; +watchdog_init_timeouts (wdd, pretimeout, timeout, + sbsa_gwdt_update_limits, dev); +/* update pretimeout to WOR */ +sbsa_gwdt_cf_write (SBSA_GWDT_WOR , wdd->pretimeout * clk, wdd); + + ret =devm_request_irq (dev, irq, sbsa_gwdt_interrupt,IRQF_TIMER , + pdev->name, gwdt); +if (ret) { +dev_err (dev,"unable to request IRQ %d\n" , irq); +return ret; + } + + ret =watchdog_register_device (wdd); +if (ret) +return ret; + +dev_info (dev,"Initialized with %ds timeout, %ds pretimeout @ %uHz\n" , + wdd->timeout, wdd->pretimeout, gwdt->clk); + +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); +int ret =0 ; + +if (!nowayout) + ret =sbsa_gwdt_stop (&gwdt->wdd); + +watchdog_unregister_device (&gwdt->wdd); + +return ret; +} + +/* 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)
drivers/watchdog/sbsa_gwdt.c line 453
Quoted 10 lines
drivers/watchdog/sbsa_gwdt.c new file +10
-0+}; + +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" , },
So this is because we need to auto load the module if those resources are parsed from ACPI table, because there is no acpi_device_id for ACPI tables, right?
If so, please add related code in the ACPI patch, and comment on it please :)
Thanks
Hanjun
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
Quoted 8 lines · On Friday 22 May 2015 22:50:30 Hanjun Guo wrote:
Quoted 8 lines
drivers/watchdog/Kconfig +0
-0@@ -152,6 +152,18 @@ config ARM_SP805_WATCHDOG ARM Primecell SP805 Watchdog timer. This will reboot your system when the timeout is reached.
Quoted 7 lines
drivers/watchdog/Kconfig config ARM_SP805_WATCHDOG · line 157
Quoted 3 lines
drivers/watchdog/Kconfig +3
-0+config ARM_SBSA_WATCHDOG + tristate "ARM SBSA Generic Watchdog" + depends on ARM || ARM64 || COMPILE_TESTSBSA is for ARMv8-A based (64-bit) servers, no need to depends on ARM, and why we depends on
COMPILE_TEST?
I think it's a reasonable assumption that someone will sooner or later put that hardware into an ARM32 machine, or run a 32-bit kernel on a chip that has it.
While SBSA requires this watchdog device, nothing prevents SoC manufacturers from using the same design in something that is not a server.
Arnd
Guenter Roeck
maintainerRe: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
Quoted 17 lines · Arnd Bergmann
Quoted 8 lines · On Friday 22 May 2015 22:50:30 Hanjun Guo wrote:
Quoted 8 lines
drivers/watchdog/Kconfig +0
-0@@ -152,6 +152,18 @@ config ARM_SP805_WATCHDOG ARM Primecell SP805 Watchdog timer. This will reboot your system when the timeout is reached.Quoted 7 lines
drivers/watchdog/Kconfig config ARM_SP805_WATCHDOG · line 157
Quoted 3 lines
drivers/watchdog/Kconfig +3
-0+config ARM_SBSA_WATCHDOG + tristate "ARM SBSA Generic Watchdog" + depends on ARM || ARM64 || COMPILE_TESTSBSA is for ARMv8-A based (64-bit) servers, no need to depends on ARM, and why we depends on
COMPILE_TEST?
Quoted 8 lines
I think it's a reasonable assumption that someone will sooner or later put that hardware into an ARM32 machine, or run a 32-bit kernel on a chip that has it.
While SBSA requires this watchdog device, nothing prevents SoC manufacturers from using the same design in something that is not a server.
Tricky, though. Since teh driver uses arm specific clock functions, I don't think this can compile on a non-arm machine.
Guenter
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
Quoted 18 lines · Guenter Roeck
Quoted 17 lines · Arnd Bergmann
Quoted 15 lines · On Friday 22 May 2015 22:50:30 Hanjun Guo wrote:
drivers/watchdog/Kconfig config ARM_SP805_WATCHDOG · line 157
Quoted 11 lines
drivers/watchdog/Kconfig +3
-0@@ -152,6 +152,18 @@ 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 ARM || ARM64 || COMPILE_TESTSBSA is for ARMv8-A based (64-bit) servers, no need to depends on ARM, and why we depends on
COMPILE_TEST?
Quoted 7 lines
Quoted 7 lines
I think it's a reasonable assumption that someone will sooner or later put that hardware into an ARM32 machine, or run a 32-bit kernel on a chip that has it.
While SBSA requires this watchdog device, nothing prevents SoC manufacturers from using the same design in something that is not a server.
From this point of view, I agree that SBSA watchdog design may used in other ARM SoCs in the future, but how about add it back when this kind of hardware showing up?
Quoted 3 lines
Quoted 1 line
Tricky, though. Since teh driver uses arm specific clock functions, I don't think this can compile on a non-arm machine.
Since it depends on ARM64/ARM, we can temporary release from that now :)
Thanks
Hanjun
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [Linaro-acpi] [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
Quoted 23 lines · On Friday 22 May 2015 23:18:21 Hanjun Guo wrote:
Quoted 22 lines · Guenter Roeck
Quoted 21 lines · Arnd Bergmann
Quoted 8 lines · On Friday 22 May 2015 22:50:30 Hanjun Guo wrote:
Quoted 8 lines
drivers/watchdog/Kconfig +0
-0@@ -152,6 +152,18 @@ config ARM_SP805_WATCHDOG ARM Primecell SP805 Watchdog timer. This will reboot your system when the timeout is reached.Quoted 7 lines
drivers/watchdog/Kconfig config ARM_SP805_WATCHDOG · line 157
Quoted 3 lines
drivers/watchdog/Kconfig +3
-0+config ARM_SBSA_WATCHDOG + tristate "ARM SBSA Generic Watchdog" + depends on ARM || ARM64 || COMPILE_TESTSBSA is for ARMv8-A based (64-bit) servers, no need to depends on ARM, and why we depends on
COMPILE_TEST?I think it's a reasonable assumption that someone will sooner or later put that hardware into an ARM32 machine, or run a 32-bit kernel on a chip that has it.
Quoted 7 lines
Quoted 3 lines
Quoted 3 lines
While SBSA requires this watchdog device, nothing prevents SoC manufacturers from using the same design in something that is not a server.
From this point of view, I agree that SBSA watchdog design may used
in other ARM SoCs in the future, but how about add it back when this kind of hardware showing up?
If it builds on ARM32, I'd rather leave the option in, it doesn't hurt.
Quoted 4 lines
Quoted 2 lines
Tricky, though. Since teh driver uses arm specific clock functions, I don't think this can compile on a non-arm machine.
Since it depends on ARM64/ARM, we can temporary release from that now
We have to drop the '|| COMPILE_TEST' though as a result, or fix the driver to look up the clock in DT and call 'clk_get_rate'.
That will break the ACPI case, but ACPI could use platform_data to pass the clock rate into the driver, to make it independent of low-level APIs.
Arnd
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [Linaro-acpi] [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
Quoted 3 lines · Arnd Bergmann
That will break the ACPI case, but ACPI could use
platform_datato pass the clock rate into the driver, to make it independent of low-level APIs.
The clock rate isn't the only problem. You still need to current clock timestamp, and that's ARM-specific.
Signature · 3 lines
Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.
Re: [Linaro-acpi] [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
Quoted 7 lines · On Friday 22 May 2015 11:19:52 Timur Tabi wrote:
Quoted 3 lines · Arnd Bergmann
That will break the ACPI case, but ACPI could use
platform_datato pass the clock rate into the driver, to make it independent of low-level APIs.The clock rate isn't the only problem. You still need to current clock timestamp, and that's ARM-specific.
Ah, I didn't realize that. I also just noticed that the two arch_timer functions we call here are inline functions that just access control registers.
If we want to enable COMPILE_TEST then, it would have to be something like
#ifdef CONFIG_ARM || CONFIG_ARM64
#include <asm/arch_timer.h>
#else
... /* stub functions */
#endif
That might still be helpful to get coverage from things like the public coverity builds that always build x86 allmodconfig, but it's also a bit ugly.
Arnd
Re: [Linaro-acpi] [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
Quoted 4 lines · Arnd Bergmann
That might still be helpful to get coverage from things like the public coverity builds that always build x86 allmodconfig, but it's also a bit ugly.
Adding #ifdefs to allow COMPILE_TEST to work seems ironic to me.
Signature · 3 lines
Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.
Re: [Linaro-acpi] [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
In reply to Arnd BergmannHi Arnd
Thanks :-)
Quoted 28 lines · Arnd Bergmann
Quoted 27 lines · On Friday 22 May 2015 23:18:21 Hanjun Guo wrote:
Quoted 25 lines · Guenter Roeck
Quoted 24 lines · Arnd Bergmann
Quoted 8 lines · On Friday 22 May 2015 22:50:30 Hanjun Guo wrote:
Quoted 8 lines
drivers/watchdog/Kconfig +0
-0@@ -152,6 +152,18 @@ config ARM_SP805_WATCHDOG ARM Primecell SP805 Watchdog timer. This will reboot your system when the timeout is reached.Quoted 7 lines
drivers/watchdog/Kconfig config ARM_SP805_WATCHDOG · line 157
Quoted 3 lines
drivers/watchdog/Kconfig +3
-0+config ARM_SBSA_WATCHDOG + tristate "ARM SBSA Generic Watchdog" + depends on ARM || ARM64 || COMPILE_TESTSBSA is for ARMv8-A based (64-bit) servers, no need to depends on ARM, and why we depends on
COMPILE_TEST?I think it's a reasonable assumption that someone will sooner or later put that hardware into an ARM32 machine, or run a 32-bit kernel on a chip that has it.
While SBSA requires this watchdog device, nothing prevents SoC manufacturers from using the same design in something that is not a server.
Quoted 5 lines
Quoted 3 lines
From this point of view, I agree that SBSA watchdog design may used
in other ARM SoCs in the future, but how about add it back when this kind of hardware showing up?If it builds on ARM32, I'd rather leave the option in, it doesn't hurt.
yes, I am agree with you.
Reason:
(1)Although the SBSA spec is all about ARMv8, but in "5 APPENDIX A:
GENERIC WATCHDOG", nothing says SBSA watchdog is only for ARM64. (2)SBSA watchdog should work with arch_timer which has be used on ARMv7 and ARMv8.
(3)there are ARM32 servers in the market(although there is not SBSA watchdog in them)
(4) all the regs of SBSA watchdog are 32Bit, this IP core can be use in ARM32(I don't know the implementation detail of this IP core, but from the spec , I don't see "It can't be used on ARM32") (5)we don't need to change any code, any line.(yes, it doesn't hurt)
So maybe we can keep this
The only problem we face is : there is not a ARM32 hardware or a simulator of ARM32 has SBSA watchdog on it. and we don't know if ARM will put this IP core in any Soc in the future :-(
Maybe because this IP core is new.
Quoted 4 lines
Quoted 4 lines
Quoted 3 lines
Tricky, though. Since teh driver uses arm specific clock functions, I don't think this can compile on a non-arm machine.
Quoted 8 lines
Quoted 1 line
Since it depends on ARM64/ARM, we can temporary release from that now
We have to drop the '||
COMPILE_TEST' though as a result, or fix the driver to look up the clock in DT and call 'clk_get_rate'.That will break the ACPI case, but ACPI could use
platform_datato pass the clock rate into the driver, to make it independent of low-level APIs.
for this problem , we not only need to get "rate" but also need to get timestamp.
So for now , we need to use some ARM specific code in arm_arch_timer.c, unless those interface is integrated into clk framework(or we have make a patch for if)
any suggestion or thought?
Great thanks for your review :-)
Quoted 6 lines
Arnd
_______________________________________________
Linaro-acpi mailing list [email protected]
https://lists.linaro.org/mailman/listinfo/linaro-acpi
Signature · 14 lines
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 -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
In reply to Guenter RoeckQuoted 3 lines · Guenter Roeck
Quoted 1 line
Quoted 1 line
Tricky, though. Since teh driver uses arm specific clock functions, I don't think this can compile on a non-arm machine.
Any it doesn't need to. This driver is for 64-bit ARM Server SOCs. There will never be any other kind of SOC that has an SBSA watchdog device in it.
Signature · 3 lines
Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.
Re: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
In reply to Guenter RoeckHi Guenter,
Quoted 22 lines · Guenter Roeck
Quoted 21 lines · Arnd Bergmann
Quoted 8 lines · On Friday 22 May 2015 22:50:30 Hanjun Guo wrote:
Quoted 8 lines
drivers/watchdog/Kconfig +0
-0@@ -152,6 +152,18 @@ config ARM_SP805_WATCHDOG ARM Primecell SP805 Watchdog timer. This will reboot your system when the timeout is reached.Quoted 7 lines
drivers/watchdog/Kconfig config ARM_SP805_WATCHDOG · line 157
Quoted 3 lines
drivers/watchdog/Kconfig +3
-0+config ARM_SBSA_WATCHDOG + tristate "ARM SBSA Generic Watchdog" + depends on ARM || ARM64 || COMPILE_TESTSBSA is for ARMv8-A based (64-bit) servers, no need to depends on ARM, and why we depends on
COMPILE_TEST?I think it's a reasonable assumption that someone will sooner or later put that hardware into an ARM32 machine, or run a 32-bit kernel on a chip that has it.
Quoted 6 lines
Quoted 4 lines
While SBSA requires this watchdog device, nothing prevents SoC manufacturers from using the same design in something that is not a server.
Tricky, though. Since teh driver uses arm specific clock functions, I don't think this can compile on a non-arm machine.
yes, According to SBSA spec, the clock source of SBSAwatchdog is system counter which is a part of arm arch timer.
So I think SBSA watchdog always goes with ARM.
ARM arch timer has been used on ARM32 and ARM64, so SBSA also can be used on ARM32.
Just there is not a ARM32 hardware has that IP core right now.
Quoted 2 lines
Guenter
Signature · 10 lines
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
Re: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
In reply to Arnd BergmannQuoted 3 lines · Arnd Bergmann
While SBSA requires this watchdog device, nothing prevents SoC manufacturers from using the same design in something that is not a server.
The first "S" in SBSA stands for "Server". I don't think it makes sense to put an SBSA watchdog device in a non-server SOC.
Frankly, I don't understand why people want to make this driver work on hardware that doesn't exist. The SBSA is intended for 64-bit ARM Servers that use ACPI. Yes, there are a couple of ARM64 servers that use device tree, but those are legacy platforms.
Signature · 3 lines
Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.
Re: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
In reply to Arnd BergmannQuoted 2 lines · Arnd Bergmann
I think it's a reasonable assumption that someone will sooner or later put that hardware into an ARM32 machine,
I'm going to have to disagree. If they haven't done it by now, I can't imagine any ARM SOC vendor creating a 32-bit ARM SOC with an SBSA watchdog in it. I can imagine a vendor trying to repurpose an existing 32-bit ARM SOC for the server market, but that SOC won't have an SBSA watchdog in it.
Quoted 2 lines
or run a 32-bit kernel on
a chip that has it.
That might happen, but I would be very surprised, and I would need to be convinced that it's useful.
Signature · 7 lines
Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation. -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
Hi Timur,
Quoted 10 lines · Timur Tabi
Quoted 3 lines · Arnd Bergmann
I think it's a reasonable assumption that someone will sooner or later put that hardware into an ARM32 machine,
I'm going to have to disagree. If they haven't done it by now, I can't imagine any ARM SOC vendor creating a 32-bit ARM SOC with an SBSA watchdog in it. I can imagine a vendor trying to repurpose an existing 32-bit ARM SOC for the server market, but that SOC won't have an SBSA watchdog in it.
I will agree with you on this, ONLY IF a people can represent ARM and all chip vendors say publicly:
" We never ever use SBSA watchdog IP core on ARM32!" or " SBSA watchdog IP core is imcompatible with ARM32"
Although the SBSA is all about ARMv8, but in "5 APPENDIX A: GENERIC WATCHDOG", it doesn't say "this is only for ARMv8".
and its clock source "system counter" and arm_arch_timer have been in ARM32 Soc for years,
and all the regs in SBSA watchdog is 32bit. I can't see why we can not do that, unless I miss something.
I wonder why you are so sure "that SOC won't have an SBSA watchdog in it." any documentation ?
Sorry, I am not a chip design engineer, I can't see why 32-bit ARM won't have an SBSA watchdog in it.
Quoted 13 lines
Quoted 4 lines
or run a 32-bit kernel on
a chip that has it.
That might happen, but I would be very surprised, and I would need to be convinced that it's useful.
--
Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation.
Signature · 10 lines
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
Guenter Roeck
maintainerRe: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
Quoted 28 lines · Fu Wei
Hi Timur,
Quoted 10 lines · Timur Tabi
Quoted 3 lines · Arnd Bergmann
I think it's a reasonable assumption that someone will sooner or later put that hardware into an ARM32 machine,
I'm going to have to disagree. If they haven't done it by now, I can't imagine any ARM SOC vendor creating a 32-bit ARM SOC with an SBSA watchdog in it. I can imagine a vendor trying to repurpose an existing 32-bit ARM SOC for the server market, but that SOC won't have an SBSA watchdog in it.
I will agree with you on this, ONLY IF a people can represent ARM and all chip vendors say publicly:
" We never ever use SBSA watchdog IP core on ARM32!" or " SBSA watchdog IP core is imcompatible with ARM32"Although the SBSA is all about ARMv8, but in "5 APPENDIX A: GENERIC WATCHDOG", it doesn't say "this is only for ARMv8".
and its clock source "system counter" andarm_arch_timerhave been in ARM32 Soc for years,
and all the regs in SBSA watchdog is 32bit. I can't see why we can not do that, unless I miss something.
Quoted 5 lines
I wonder why you are so sure "that SOC won't have an SBSA watchdog in it." any documentation ?
Sorry, I am not a chip design engineer, I can't see why 32-bit ARM won't have an SBSA watchdog in it.
I think it is quite unfortunate that the specification is not public. We have heard many statements about what is in the spec or not. We have two possible implementations of the SBSA watchdog, but not even the implementers of those two implementations seem to be able to agree what the specification actually mandates/supports, or what it doesn't mandate/support.
We have heard that the SBSA watchdog would require ACPI, and that it doesn't. We have heard that it would require ARM64, and that it doesn't. We have heard various assumptions about how WS0 and WS1 are supposed to be wired. We have heard that all its registers are 32 bit (which would suggest they have to be treated as such), but then we have a 64 bit register access in one of the drivers, and a more complex implementation to read the same value as two 32-bit reads in the other. We have heard that WS0 and WS1 are at least to some degree independent of each other (and thus that it makes sense to set them separately), and we have heard that WS1 is always equal to WS0 * 2. We have one implementation limiting support to architecture revision 0, and the other not imposing such a restriction.
Is the specification really that vague in such key areas ? How do you expect anyone who doesn't have access to the specification to be able to figure out what is actually correct and how to proceed ?
Thanks,
Guenter
Re: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
Quoted 2 lines · Guenter Roeck
I think it is quite unfortunate that the specification is not public. We have heard many statements about what is in the spec or not.
All you need to do is go to http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.den0029b/index.html, get a free ARM account, and download the spec.
Signature · 3 lines
Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation.
Re: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
Hi Timur
Quoted 10 lines · Timur Tabi
Quoted 3 lines · Guenter Roeck
I think it is quite unfortunate that the specification is not public. We have heard many statements about what is in the spec or not.
All you need to do is go to
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.den0029b/index.html,
get a free ARM account, and download the spec.
Great thanks for providing this info!
Quoted 5 lines
--
Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation.
Signature · 10 lines
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
Guenter Roeck
maintainerRe: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
In reply to Timur TabiQuoted 6 lines · Timur Tabi
Quoted 2 lines · Guenter Roeck
I think it is quite unfortunate that the specification is not public. We have heard many statements about what is in the spec or not.
All you need to do is go to http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.den0029b/index.html, get a free ARM account, and download the spec.
That helps - thanks a lot!
Folks, please correct me if my understanding of the specification is wrong.
1) Pretimeout
The document suggests that
WS1 = WS0 * 2
is in fact correct. In essence, there is just one counter, not two. This means that a separate pretimeout does not really make sense, since in practice the timeout would always be twice the pretimeout, and changing just one without affecting the other is not really possible.
2) 64 bit WCV register
The specification is not clear on how to read this register. It clearly states that it is comprised of two 32-bit registers, but it does not specify if a single 64-bit read would be atomic, or if it would be split into two separate 32-bit operations. This leaves room for interpretation by the implementer, and may result in bad values if the implementation changes the counter from, say, 0x000010000 to 0x0000ffff while the value is read.
My interpretation of this is that it would be safer to read two 32-bit values and ensure that the values are consistent instead of relying on the assumption that a single 64-bit read would be atomic.
3) ACPI vs. FDT
The specification does not say anything about ACPI or FDT support except that it assumes that there are "System description data structures such as ACPI or FDT". Given that, the driver should support both.
4) ARM vs. ARM64
SBSA clearly states that any CPU supporting it shall be ARM v8 compliant (4.1.1, CPU architecture). Personally I think the discussion around supporting the driver on ARM/ARM64 or ARM64 only is a bit pointless, especially since being able to build it on ARM doesn't really hurt, even though there is currently no HW supporting it.
Overall I must admit that I don't really understand why this is such a contentious issue.
5) Revision support
While it is difficult to predict the future, it is common practice in the industry to make future revisions of a standard (and chip) as much backward compatible as possible, and to only add functionality. As such, I don't see a reason to restrict support to revision 0 of the standard.
6) A note about driver messages
Implementation defined registers are just that, implementation defined registers. I don't think it makes sense to display any of those, not even for debugging purposes.
---
Again, please correct me if any of those statements is wrong. When doing so, please reference the specification, to make sure that we all know what we are talking about.
My hope is that we can use this as a starting point to converge on a single driver.
Thanks,
Guenter
Re: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
Hi Guenter,
Great thanks for your suggestion and review,
I have some questions below , would you please help me out?
Quoted 14 lines · Guenter Roeck
Quoted 11 lines · Timur Tabi
Quoted 3 lines · Guenter Roeck
I think it is quite unfortunate that the specification is not public. We have heard many statements about what is in the spec or not.
All you need to do is go to
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.den0029b/index.html,
get a free ARM account, and download the spec.That helps - thanks a lot!
Quoted 7 lines
Folks, please correct me if my understanding of the specification is wrong.
1) Pretimeout
The document suggests that
WS1 = WS0 * 2
Are you saying: the first timeout == the second timeout
|-------------WS0
|-------------WS1
Sorry, could you let me know where is that suggestion?? I have checked the SBSA again, but I can not find it. Maybe I really miss this part.
Quoted 4 lines
is in fact correct. In essence, there is just one counter, not two. This means that a separate pretimeout does not really make sense, since in practice the timeout would always be twice the pretimeout,
Yes, you are right, if we only use "WOR", then the first timeout == the second timeout
Quoted 2 lines
and changing just one without affecting
the other is not really possible.
although there is only one counter, and it is 32 bits wide. In SBSA, we can see this:
-------
Note: the watchdog offset register is 32 bits wide. This gives a maximum watch period of around 10s at a system counter frequency of 400MHz.
If a larger watch period is required then the compare value can be programmed directly into the compare value register.
-------
So for the first timeout, we can set the compare value register(WCV). Then the two timeouts are different. and the first timeout has not 10s(@400MHz) limit.
just the the second timeout must use "WOR".
Quoted 12 lines
2) 64 bit WCV register
The specification is not clear on how to read this register. It clearly states that it is comprised of two 32-bit registers, but it does not specify if a single 64-bit read would be atomic, or if it would be split into two separate 32-bit operations. This leaves room for interpretation by the implementer, and may result in bad values if the implementation changes the counter from, say,
0x000010000to0x0000ffffwhile the value is read.
Quoted 4 lines
My interpretation of this is that it would be safer to read two 32-bit values and ensure that the values are consistent instead of relying on the assumption that a single 64-bit read would be atomic.
yes, thanks for pointing it out.
I found this problem in my first upstream patchset. So in this patchset, there is not that problem now:
-------
do {
wcv_hi = sbsa_gwdt_cf_read(SBSA_GWDT_WCV_HI, wdd);
wcv_lo = sbsa_gwdt_cf_read(SBSA_GWDT_WCV_LO, wdd);
} while (wcv_hi != sbsa_gwdt_cf_read(SBSA_GWDT_WCV_HI, wdd));-------
Quoted 7 lines
3) ACPI vs. FDT
The specification does not say anything about ACPI or FDT support except that it assumes that there are "System description data structures such as ACPI or FDT". Given that, the driver should support both.
yes, this patchset has fully support ACPI and FDT, and has been successfully tested on
(1)Foundation model
(2)AMD Seattle B0 Soc
Quoted 10 lines
4) ARM vs. ARM64
SBSA clearly states that any CPU supporting it shall be ARM v8 compliant (4.1.1, CPU architecture). Personally I think the discussion around supporting the driver on ARM/ARM64 or ARM64 only is a bit pointless, especially since being able to build it on ARM doesn't really hurt, even though there is currently no HW supporting it.
Quoted 2 lines
Overall I must admit that I don't really understand why this is such a contentious issue.
I think that is not a contentious issue.
Just some one has that suggestion, then we discussed it. So I am going to delete ARM support.
If we have this hardware in the future, we can add it by then.
Quoted 8 lines
5) Revision support
While it is difficult to predict the future, it is common practice in the industry to make future revisions of a standard (and chip) as much backward compatible as possible, and to only add functionality. As such, I don't see a reason to restrict support to revision 0 of the standard.
Totally agree, there is not this problem in my patchset.
Quoted 6 lines
6) A note about driver messages
Implementation defined registers are just that, implementation defined registers. I don't think it makes sense to display any of those, not even for debugging purposes.
in this patchset, I have totally deleted all the debug message, only keep:
(1)3 error messages
(2)2 warning messages
reason:
1. if system reset by watchdog, we need to inform user (WCS: store
watchdog status, WCV: store the timestamp of the last reboot, maybe these can provide some basic info of reboot )
2. if watchdog has been enabled before register, there is something
wrong we need to inform user. (WCS: store watchdog status) (3)1 info message
reason: if watchdog has been successfully registered, we log it.
Please let me know if there is any redundant massage, I will fix it.
Quoted 6 lines
---
Again, please correct me if any of those statements is wrong. When doing so, please reference the specification, to make sure that we all know what we are talking about.
Great thanks for your help , those help me a lot.
So, for now , this only big problem in my patchset is "pretimeout", but I have some doubt above, would you help me out ? :-) Thanks
Quoted 7 lines
My hope is that we can use this as a starting point to converge on a single driver.
Thanks,
Guenter
Signature · 10 lines
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
Guenter Roeck
maintainerRe: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
Quoted 28 lines · Fu Wei
Hi Guenter,
Great thanks for your suggestion and review,
I have some questions below , would you please help me out?Quoted 14 lines · Guenter Roeck
Quoted 11 lines · Timur Tabi
Quoted 3 lines · Guenter Roeck
I think it is quite unfortunate that the specification is not public. We have heard many statements about what is in the spec or not.
All you need to do is go to
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.den0029b/index.html,
get a free ARM account, and download the spec.That helps - thanks a lot!
Quoted 7 lines
Folks, please correct me if my understanding of the specification is wrong.
1) Pretimeout
The document suggests that
WS1 = WS0 * 2
Quoted 9 lines
Are you saying: the first timeout == the second timeout
|-------------WS0
|-------------WS1Sorry, could you let me know where is that suggestion?? I have checked the SBSA again, but I can not find it. Maybe I really miss this part.
The document states:
"If both watchdog signals are deasserted and a timeout refresh occurs then WS0 is asserted.
If WS0 is asserted and a timeout refresh occurs then WS1 is asserted."
There is no mention that programming both WOR and WCV would or even could result in different timeouts for the two watchdog signals.
Quoted 11 lines
Quoted 4 lines
is in fact correct. In essence, there is just one counter, not two. This means that a separate pretimeout does not really make sense, since in practice the timeout would always be twice the pretimeout,
Yes, you are right, if we only use "WOR", then the first timeout == the second timeout
Quoted 2 lines
and changing just one without affecting
the other is not really possible.
Quoted 14 lines
although there is only one counter, and it is 32 bits wide. In SBSA, we can see this:
-------
Note: the watchdog offset register is 32 bits wide. This gives a maximum watch period of around 10s at a system counter frequency of 400MHz.
If a larger watch period is required then the compare value can be programmed directly into the compare value register.
-------
So for the first timeout, we can set the compare value register(WCV). Then the two timeouts are different. and the first timeout has not 10s(@400MHz) limit.
just the the second timeout must use "WOR".
That is not how I read the specification. It only talks about "timeout refresh". There is no indication that using both registers would have the impact you describe.
Since there is no mention of different WS0 and WS1 timeout periods in the specification, I am concerned that even _if_ a specific implementation supports such different timeouts, it would be implementation specific.
Maybe you and/or Timur can test this on the real systems you have access to. It should be quite straightforward to test - have the interrupt handler only print a message, program some values into the watchdog, and see when WS0 and WS1 occur.
Thanks,
Guenter
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
Quoted 5 lines · Guenter Roeck
Maybe you and/or Timur can test this on the real systems you have access to. It should be quite straightforward to test - have the interrupt handler only print a message, program some values into the watchdog, and see when WS0 and WS1 occur.
I'll try, but on my system, WS1 is currently not implemented fully. Let me investigate and get back to you.
Signature · 7 lines
Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation. -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
In reply to Guenter RoeckHi Guenter,
Great thanks for your time,
you provide your feedback in your weekend, I am so appreciate that.
my feedback inline below
Quoted 46 lines · Guenter Roeck
Quoted 35 lines · Fu Wei
Hi Guenter,
Great thanks for your suggestion and review,
I have some questions below , would you please help me out?Quoted 19 lines · Guenter Roeck
Quoted 10 lines · Timur Tabi
Quoted 4 lines · Guenter Roeck
I think it is quite unfortunate that the specification is not public. We have heard many statements about what is in the spec or not.
Quoted 5 lines
All you need to do is go to
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.den0029b/index.html,
get a free ARM account, and download the spec.That helps - thanks a lot!
Quoted 7 lines
Folks, please correct me if my understanding of the specification is wrong.
1) Pretimeout
The document suggests that
WS1 = WS0 * 2Quoted 9 lines
Are you saying: the first timeout == the second timeout
|-------------WS0
|-------------WS1Sorry, could you let me know where is that suggestion?? I have checked the SBSA again, but I can not find it. Maybe I really miss this part.
Quoted 5 lines
The document states:
"If both watchdog signals are deasserted and a timeout refresh occurs then WS0 is asserted.
If WS0 is asserted and a timeout refresh occurs then WS1 is asserted."
yes, this just describe how the WS0/WS1 are deasserted or asserted. but it doesn't suggest WS1 = WS0 * 2.
Of course, If we only config WOR in the driver, we get WS1 = WS0 * 2.
If we delete pretimeout concept from this driver
Then what is the timeout, |-------------WS0 or
|-------------WS0-------------WS1 ?
If we only config WOR , the timeout for two stage will be the same I think the first stage should be called timeout, the user get a panic in timeout(the first stage)
Then we can tell user, in this driver, if first timeout is triggered but fail, we can wait for the same time for reboot.
but the second timeout is still like a pretimeout, why not just use it ?
IMO, the key point of SBSA watchdog is two signal, and the first one is interrupt, the second one maybe a hardware reset OR a interrupt if we drop "pretimeout", the watchdog just acts like a common watchdog (just like SP805)
Now we assume that the second signal is a reset, but according to SBSA, that maybe a interrupt. If that happens on a Soc(that will happen), how to deal with that?
what is the timeout between WS0 and WS1?
If the two signals are all connect to interrupts, I think we still need a pretimeout. why not use pretimeout right now. that will be more easy to maintain the driver.
Quoted 3 lines
There is no mention that programming both WOR and WCV would or even could result in different timeouts for the two watchdog signals.
yes, they don't mention it.
using WCV to config the first stage and WOR for the second stage is my idea to solve the two stage timeouts.
Because by this way, we can make the first stage longer(has not that 10s(@400MHz) limit), and we can provide the full feature of SBSA watchdog.
as I have mentioned above, If the two signals are all connect to interrupts, we don't need to tell user : the two stage timeout must be the same and 10s(@400MHz) limit,
Quoted 29 lines
Quoted 14 lines
Quoted 5 lines
is in fact correct. In essence, there is just one counter, not two. This means that a separate pretimeout does not really make sense, since in practice the timeout would always be twice the pretimeout,
Yes, you are right, if we only use "WOR", then the first timeout == the second timeout
Quoted 2 lines
and changing just one without affecting
the other is not really possible.Quoted 14 lines
although there is only one counter, and it is 32 bits wide. In SBSA, we can see this:
-------
Note: the watchdog offset register is 32 bits wide. This gives a maximum watch period of around 10s at a system counter frequency of 400MHz.
If a larger watch period is required then the compare value can be programmed directly into the compare value register.
-------
So for the first timeout, we can set the compare value register(WCV). Then the two timeouts are different. and the first timeout has not 10s(@400MHz) limit.
just the the second timeout must use "WOR".
Quoted 8 lines
That is not how I read the specification. It only talks about "timeout refresh". There is no indication that using both registers would have the impact you describe.
Since there is no mention of different WS0 and WS1 timeout periods in the specification, I am concerned that even _if_ a specific implementation supports such different timeouts, it would be implementation specific.
yes, you are right, they don't mention, but they can be different, that is the way I use.
I just put limit on user , say: the two timeout must be the same. I hope my driver can provide the full feature of hardware. but they make driver a little more complicated than the one which simply config WOR.
I have to say , another one make SBSA watchdog become a watchdog.
Quoted 5 lines
Maybe you and/or Timur can test this on the real systems you have access to. It should be quite straightforward to test - have the interrupt handler only print a message, program some values into the watchdog, and see when WS0 and WS1 occur.
yes, the first version of my driver has printed the timeleft out, I can have different timeouts and pretimeout
Quoted 4 lines
Thanks,
Guenter
Signature · 14 lines
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 -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
In reply to Fu WeiQuoted 4 lines · Fu Wei
I wonder why you are so sure "that SOC won't have an SBSA watchdog in it." any documentation ?
Sorry, I am not a chip design engineer, I can't see why 32-bit ARM won't have an SBSA watchdog in it.
Because there's no market for it. I'm not talking about what's theoretically possible. I'm only talking about what makes sense and what will actually happen. And I'm quite certain that we will never see an actual 32-bit ARM SOC with an SBSA watchdog device in it.
Therefore, it makes no sense to complicated the code so that we can support an SOC that will never exist.
So can we PLEASE stop talking about 32-bit ARM support?
Signature · 3 lines
Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation.
Re: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
Hi Timur
Quoted 8 lines · Timur Tabi
Quoted 5 lines · Fu Wei
I wonder why you are so sure "that SOC won't have an SBSA watchdog in it." any documentation ?
Sorry, I am not a chip design engineer, I can't see why 32-bit ARM won't have an SBSA watchdog in it.
Quoted 4 lines
Because there's no market for it. I'm not talking about what's theoretically possible. I'm only talking about what makes sense and what will actually happen. And I'm quite certain that we will never see an actual 32-bit ARM SOC with an SBSA watchdog device in it.
Why are you quite certain? any info you can kindly share here?
Quoted 3 lines
Therefore, it makes no sense to complicated the code so that we can support an SOC that will never exist.
yes, that is a good reason!
Quoted 2 lines
So can we PLEASE stop talking about 32-bit ARM support?
why? we are just trying to figure out:
Do we need to add ARM in "depends on" for SBSA watchdog driver?
If some one suggests this, we need to figure out.
Quoted 6 lines
--
Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation.
Signature · 14 lines
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 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 6/7] Watchdog: introduce ARM SBSA watchdog driver
Quoted 6 lines · Fu Wei
Quoted 4 lines
Because there's no market for it. I'm not talking about what's theoretically possible. I'm only talking about what makes sense and what will actually happen. And I'm quite certain that we will never see an actual 32-bit ARM SOC with an SBSA watchdog device in it.
Why are you quite certain? any info you can kindly share here?
I used to work for a company called Calxeda that tried to sell a 32-bit ARM Server SOC. Calxeda went out of business because no one would buy it, and that was two years ago.
Quoted 6 lines
Quoted 1 line
So can we PLEASE stop talking about 32-bit ARM support?
why? we are just trying to figure out:
Do we need to add ARM in "depends on" for SBSA watchdog driver?If some one suggests this, we need to figure out.
We do not need to add "depends on ARM" in the Kconfig for the SBSA watchdog driver.
Signature · 3 lines
Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation.
PATCH v2 7/7 ACPI: import watchdog info of GTDT into platform device
In reply to [email protected]From: Fu Wei <[email protected]>
Parse SBSA Generic Watchdog Structure in GTDT table of ACPI, and create a platform device with that information. This platform device can be used by the ARM SBSA Generic Watchdog driver.
--- arch/arm64/kernel/acpi.c | 136 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+)
arch/arm64/kernel/acpi.c +136 -0
@@ -23,6 +23,7 @@#include <linux/irqdomain.h> #include <linux/memblock.h> #include <linux/of_fdt.h> +#include <linux/platform_device.h> #include <linux/smp.h> #include <asm/cputype.h>
@@ -343,3 +344,138 @@ void __init acpi_gic_init(void)early_acpi_os_unmap_memory ((char *)table, tbl_size); } + +static int __init acpi_gtdt_import_sbsa_gwdt (struct acpi_gtdt_watchdog *wd, +int index) +{ +struct platform_device *pdev; +struct resource *res; +u32 gsi, flags; +int irq, trigger, polarity; +resource_size_t rf_base_phy, cf_base_phy; +int err = -ENOMEM ; + +/* +* Get SBSA Generic Watchdog info +* from a Watchdog GT type structure in GTDT +*/ + rf_base_phy = (resource_size_t )wd->refresh_frame_address; + cf_base_phy = (resource_size_t )wd->control_frame_address; + gsi = wd->timer_interrupt; + flags = wd->timer_flags; + +pr_info ("GTDT: a Watchdog GT structure(0x%llx/0x%llx gsi:%u flags:0x%x)\n" , + rf_base_phy, cf_base_phy, gsi, flags); + +if (!(rf_base_phy && cf_base_phy && gsi)) { +pr_err ("GTDT: failed geting the device info.\n" ); +return -EINVAL ; + } + + trigger = (flags &ACPI_GTDT_INTERRUPT_MODE ) ?ACPI_EDGE_SENSITIVE + :ACPI_LEVEL_SENSITIVE ; + polarity = (flags &ACPI_GTDT_INTERRUPT_POLARITY ) ?ACPI_ACTIVE_LOW + :ACPI_ACTIVE_HIGH ; + irq =acpi_register_gsi (NULL , gsi, trigger, polarity); +if (irq <0 ) { +pr_err ("GTDT: failed to register GSI of the Watchdog GT.\n" ); +return -EINVAL ; + } + + pdev =platform_device_alloc ("sbsa-gwdt" , index); +if (!pdev) + goto err_unregister_gsi; + + res =kcalloc (3 ,sizeof (*res),GFP_KERNEL ); +if (!res) + goto err_device_put; + + res[0 ].start = rf_base_phy; + res[0 ].end = rf_base_phy +SZ_4K -1 ; + res[0 ].name ="refresh" ; + res[0 ].flags =IORESOURCE_MEM ; + + res[1 ].start = cf_base_phy; + res[1 ].end = cf_base_phy +SZ_4K -1 ; + res[1 ].name ="control" ; + res[1 ].flags =IORESOURCE_MEM ; + + res[2 ].start = irq; + res[2 ].end = res[2 ].start; + res[2 ].name ="ws0" ; + res[2 ].flags =IORESOURCE_IRQ ; + + err =platform_device_add_resources (pdev, res,3 ); +if (err) + goto err_free_res; + + err =platform_device_add (pdev); +if (err) + goto err_free_res; + +return 0 ; + +err_free_res: +kfree (res); +err_device_put: +platform_device_put (pdev); +err_unregister_gsi: +acpi_unregister_gsi (gsi); + +return err; +} + +/* Initialize SBSA generic Watchdog platform device info from GTDT */ +static int __init acpi_gtdt_sbsa_gwdt_init (struct acpi_table_header *table) +{ +struct acpi_table_gtdt *gtdt; +struct acpi_gtdt_header *header; +void *gtdt_subtable; +int i, gwdt_index; +int ret =0 ; + +if (table->revision <2 ) { +pr_info ("GTDT: Revision:%d doesn't support Platform Timers.\n" , + table->revision); +return 0 ; + } + + gtdt = container_of(table, struct acpi_table_gtdt, header); +if (!gtdt->platform_timer_count) { +pr_info ("GTDT: No Platform Timer structures.\n" ); +return 0 ; + } + + gtdt_subtable = (void *)gtdt + gtdt->platform_timer_offset; + +for (i =0 , gwdt_index =0 ; i < gtdt->platform_timer_count; i++) { +if (gtdt_subtable > (void *)table + table->length) { +pr_err ("GTDT: subtable pointer overflows, bad table\n" ); +return -EINVAL ; + } + header = (struct acpi_gtdt_header *)gtdt_subtable; +if (header->type ==ACPI_GTDT_TYPE_WATCHDOG ) { + ret =acpi_gtdt_import_sbsa_gwdt (gtdt_subtable, + gwdt_index); +if (ret) +pr_err ("GTDT: failed to import subtable %d\n" , + i); +else + gwdt_index++; + } + gtdt_subtable += header->length; + } + +return ret; +} + +/* Initialize the SBSA Generic Watchdog presented in GTDT */ +static int __init acpi_gtdt_init (void ) +{ +if (acpi_disabled) +return 0 ; + +return acpi_table_parse (ACPI_SIG_GTDT , acpi_gtdt_sbsa_gwdt_init); +} + +arch_initcall (acpi_gtdt_init);
Signature · 1 line
1.9.1
Re: [PATCH v2 7/7] ACPI: import watchdog info of GTDT into platform device
+CC Catalin and Will
Quoted 40 lines · On 2015年05月21日 16:32, [email protected] wrote:
From: Fu Wei <[email protected]>
Parse SBSA Generic Watchdog Structure in GTDT table of ACPI, and create a platform device with that information. This platform device can be used by the ARM SBSA Generic Watchdog driver.
Signed-off-by Fu Wei <[email protected]>--- arch/arm64/kernel/acpi.c | 136 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+)arch/arm64/kernel/acpi.c +13
-0@@ -23,6 +23,7 @@#include <linux/irqdomain.h> #include <linux/memblock.h> #include <linux/of_fdt.h> +#include <linux/platform_device.h> #include <linux/smp.h> #include <asm/cputype.h> @@ -343,3 +344,138 @@ void __init acpi_gic_init(void)early_acpi_os_unmap_memory ((char *)table, tbl_size); } + +static int __init acpi_gtdt_import_sbsa_gwdt (struct acpi_gtdt_watchdog *wd, +int index) +{ +struct platform_device *pdev; +struct resource *res; +u32 gsi, flags; +int irq, trigger, polarity; +resource_size_t rf_base_phy, cf_base_phy; +int err = -ENOMEM ; + +/*
arch/arm64/kernel/acpi.c void __init acpi_gic_init(void) · line 368
Quoted 10 lines
arch/arm64/kernel/acpi.c +10
-0+* Get SBSA Generic Watchdog info +* from a Watchdog GT type structure in GTDT +*/ + rf_base_phy = (resource_size_t )wd->refresh_frame_address; + cf_base_phy = (resource_size_t )wd->control_frame_address; + gsi = wd->timer_interrupt; + flags = wd->timer_flags; + +pr_info ("GTDT: a Watchdog GT structure(0x%llx/0x%llx gsi:%u flags:0x%x)\n" , + rf_base_phy, cf_base_phy, gsi, flags);
Can we use pr_debug here? I don't think those information worthy a pr_info.
arch/arm64/kernel/acpi.c void __init acpi_gic_init(void) · line 378
Quoted 10 lines
arch/arm64/kernel/acpi.c +10
-0+ +if (!(rf_base_phy && cf_base_phy && gsi)) { +pr_err ("GTDT: failed geting the device info.\n" ); +return -EINVAL ; + } + + trigger = (flags &ACPI_GTDT_INTERRUPT_MODE ) ?ACPI_EDGE_SENSITIVE + :ACPI_LEVEL_SENSITIVE ; + polarity = (flags &ACPI_GTDT_INTERRUPT_POLARITY ) ?ACPI_ACTIVE_LOW + :ACPI_ACTIVE_HIGH ;
I see places to duplicate this, I will look into this to see we can form a function to handle it.
arch/arm64/kernel/acpi.c void __init acpi_gic_init(void) · line 385
Quoted 7 lines
arch/arm64/kernel/acpi.c +7
-0+ irq =acpi_register_gsi (NULL , gsi, trigger, polarity); +if (irq <0 ) { +pr_err ("GTDT: failed to register GSI of the Watchdog GT.\n" ); +return -EINVAL ; + } + + pdev =platform_device_alloc ("sbsa-gwdt" , index);
Please put a comment before this function to explain why we need a "sbsa-gwdt" name here.
Quoted 4 lines
arch/arm64/kernel/acpi.c +4
-0+if (!pdev) + goto err_unregister_gsi; + + res =kcalloc (3 ,sizeof (*res),GFP_KERNEL );
arch/arm64/kernel/acpi.c void __init acpi_gic_init(void) · line 399
Quoted 10 lines
arch/arm64/kernel/acpi.c +10
-0+if (!res) + goto err_device_put; + + res[0 ].start = rf_base_phy; + res[0 ].end = rf_base_phy +SZ_4K -1 ; + res[0 ].name ="refresh" ; + res[0 ].flags =IORESOURCE_MEM ; + + res[1 ].start = cf_base_phy; + res[1 ].end = cf_base_phy +SZ_4K -1 ;
So why SZ_4K? is it defined in SBSA spec? if so, please comment on it too.
Quoted 30 lines
arch/arm64/kernel/acpi.c +30
-0+ res[1 ].name ="control" ; + res[1 ].flags =IORESOURCE_MEM ; + + res[2 ].start = irq; + res[2 ].end = res[2 ].start; + res[2 ].name ="ws0" ; + res[2 ].flags =IORESOURCE_IRQ ; + + err =platform_device_add_resources (pdev, res,3 ); +if (err) + goto err_free_res; + + err =platform_device_add (pdev); +if (err) + goto err_free_res; + +return 0 ; + +err_free_res: +kfree (res); +err_device_put: +platform_device_put (pdev); +err_unregister_gsi: +acpi_unregister_gsi (gsi); + +return err; +} + +/* Initialize SBSA generic Watchdog platform device info from GTDT */ +static int __init acpi_gtdt_sbsa_gwdt_init (struct acpi_table_header *table)
arch/arm64/kernel/acpi.c void __init acpi_gic_init(void) · line 439
Quoted 10 lines
arch/arm64/kernel/acpi.c +10
-0+{ +struct acpi_table_gtdt *gtdt; +struct acpi_gtdt_header *header; +void *gtdt_subtable; +int i, gwdt_index; +int ret =0 ; + +if (table->revision <2 ) { +pr_info ("GTDT: Revision:%d doesn't support Platform Timers.\n" , + table->revision);
pr_warn() would be good.
Thanks
Hanjun
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 7/7] ACPI: import watchdog info of GTDT into platform device
In reply to [email protected]Quoted 8 lines · [email protected] wrote:
From: Fu Wei<[email protected]>
Parse SBSA Generic Watchdog Structure in GTDT table of ACPI, and create a platform device with that information. This platform device can be used by the ARM SBSA Generic Watchdog driver.
Signed-off-by Fu Wei<[email protected]>
I have modified my watchdog driver to use this patch.
Signature · 7 lines
Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation. -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [Linaro-acpi] [PATCH v2 0/7] Watchdog: introduce ARM SBSA watchdog driver
In reply to [email protected]Quoted 16 lines · On Thursday 21 May 2015 16:32:29 [email protected]…
This patchset:
(1)Export "
arch_timer_get_rate" inarm_arch_timer.cfor the other drivers, like SBSA watchdog driver(2)Introduce
Documentation/devicetree/bindings/watchdog/sbsa-gwdt.txtfor FDT info of SBSA Generic Watchdog, and give two examples of adding SBSA Generic Watchdog device node into the dts files:
foundation-v8.dtsandamd-seattle-soc.dtsi.(3)Introduce "pretimeout" into the watchdog framework, and update
Documentation/watchdog/watchdog-kernel-api.txtto introduce:
(1)the new elements in thewatchdog_deviceandwatchdog_opsstruct; (2)the new API "watchdog_init_timeouts".
Quoted 7 lines
(4)Introduce ARM SBSA watchdog driver:
a.Use linux kernel watchdog framework;
b.Work with FDT on ARM64;
c.Use "pretimeout" in watchdog framework;
d.In first timeout(WS0), do panic to save system context; e.Support geting timeout and pretimeout from parameter and FDT
at the driver init stage.
Looks all good to me, please add
for patches 1-6.
Quoted 3 lines
(5)Parse SBSA Generic Watchdog Structure in GTDT table of ACPI, and create a platform device with that information. This platform device can be used by This Watchdog driver.
This needs to be reviewed by someone who understands ACPI.
Arnd
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [Linaro-acpi] [PATCH v2 0/7] Watchdog: introduce ARM SBSA watchdog driver
Hi Arnd,
Great thanks for your review! :-)
Quoted 25 lines · Arnd Bergmann
Quoted 16 lines · On Thursday 21 May 2015 16:32:29 [email protected]…
This patchset:
(1)Export "
arch_timer_get_rate" inarm_arch_timer.cfor the other drivers, like SBSA watchdog driver(2)Introduce
Documentation/devicetree/bindings/watchdog/sbsa-gwdt.txtfor FDT info of SBSA Generic Watchdog, and give two examples of adding SBSA Generic Watchdog device node into the dts files:
foundation-v8.dtsandamd-seattle-soc.dtsi.(3)Introduce "pretimeout" into the watchdog framework, and update
Documentation/watchdog/watchdog-kernel-api.txtto introduce:
(1)the new elements in thewatchdog_deviceandwatchdog_opsstruct; (2)the new API "watchdog_init_timeouts".Quoted 7 lines
(4)Introduce ARM SBSA watchdog driver:
a.Use linux kernel watchdog framework;
b.Work with FDT on ARM64;
c.Use "pretimeout" in watchdog framework;
d.In first timeout(WS0), do panic to save system context; e.Support geting timeout and pretimeout from parameter and FDT
at the driver init stage.
Quoted 5 lines
Looks all good to me, please add
Acked-by Arnd Bergmann <[email protected]>for patches 1-6.
Great! happy to do so :-)
Quoted 6 lines
Quoted 4 lines
(5)Parse SBSA Generic Watchdog Structure in GTDT table of ACPI, and create a platform device with that information. This platform device can be used by This Watchdog driver.
This needs to be reviewed by someone who understands ACPI.
yes, maybe Hanjun and Al can help :-)
Quoted 2 lines
Arnd
Signature · 14 lines
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 -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 0/7] Watchdog: introduce ARM SBSA watchdog driver
In reply to [email protected]For patch 1,4,5,6,and 7, I have tested this on AMD Seattle platform.
Thanks,
Suravee
Quoted 74 lines · On 5/21/15 03:32, [email protected] wrote:
From: Fu Wei <[email protected]>
This patchset:
(1)Export "
arch_timer_get_rate" inarm_arch_timer.cfor the other drivers, like SBSA watchdog driver(2)Introduce
Documentation/devicetree/bindings/watchdog/sbsa-gwdt.txtfor FDT info of SBSA Generic Watchdog, and give two examples of adding SBSA Generic Watchdog device node into the dts files:
foundation-v8.dtsandamd-seattle-soc.dtsi.(3)Introduce "pretimeout" into the watchdog framework, and update
Documentation/watchdog/watchdog-kernel-api.txtto introduce:
(1)the new elements in thewatchdog_deviceandwatchdog_opsstruct; (2)the new API "watchdog_init_timeouts".(4)Introduce ARM SBSA watchdog driver:
a.Use linux kernel watchdog framework;
b.Work with FDT on ARM64;
c.Use "pretimeout" in watchdog framework;
d.In first timeout(WS0), do panic to save system context; e.Support geting timeout and pretimeout from parameter and FDT
at the driver init stage.(5)Parse SBSA Generic Watchdog Structure in GTDT table of ACPI, and create a platform device with that information. This platform device can be used by This Watchdog driver.
This patchset has been tested with watchdog daemon (ACPI/FDT, module/build-in) on the following platforms:
(1)ARM Foundation v8 model
(2)AMD Seattle B0Changelog:
v2: Improve watchdog-kernel-api.txt documentation for pretimeout support.
Export "arch_timer_get_rate" inarm_arch_timer.c.
Addwatchdog_init_timeoutsAPI for pretimeout support in framework. Improve suspend and resume foundation in driver
Improve timeout/pretimeout values init code in driver. Delete unnecessary items of thesbsa_gwdtstruct and #define. Delete all unnecessary debug info in driver.
Fix 64bit division bug.
Use thearch_timerinterface to get watchdog clock rate. AddMODULE_DEVICE_TABLEfor platform device id.
Fix typoes.v1: The first version upstream patchset to linux mailing list
Fu Wei (7):
clocksource: export "arch_timer_get_rate" for the other drivers
Documentation: add sbsa-gwdt.txt documentation
ARM64: add SBSA Generic Watchdog device node infoundation-v8.dts
ARM64: add SBSA Generic Watchdog device node inamd-seattle-soc.dtsi
Watchdog: introduce "pretimeout" into framework
Watchdog: introduce ARM SBSA watchdog driver
ACPI: import watchdog info of GTDT into platform device.../devicetree/bindings/watchdog/sbsa-gwdt.txt | 36 ++ Documentation/watchdog/watchdog-kernel-api.txt | 62 ++- arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi | 11 + arch/arm64/boot/dts/arm/foundation-v8.dts | 10 + arch/arm64/kernel/acpi.c | 136 ++++++ drivers/clocksource/arm_arch_timer.c | 1 + drivers/watchdog/Kconfig | 12 + drivers/watchdog/Makefile | 1 + drivers/watchdog/sbsa_gwdt.c | 476 +++++++++++++++++++++ drivers/watchdog/watchdog_core.c | 103 +++-- drivers/watchdog/watchdog_dev.c | 48 +++ include/linux/watchdog.h | 30 +- 12 files changed, 891 insertions(+), 35 deletions(-)create mode 100644
Documentation/devicetree/bindings/watchdog/sbsa-gwdt.txtcreate mode 100644drivers/watchdog/sbsa_gwdt.c
Re: [PATCH v2 0/7] Watchdog: introduce ARM SBSA watchdog driver
Hi Suravee,
Great thanks for your test, will add your "Tested-by:" in these patches, if I don't modify them in the next version
Quoted 89 lines · Suravee Suthikulpanit
For patch 1,4,5,6,and 7, I have tested this on AMD Seattle platform.
Thanks,
Suravee
Quoted 78 lines · On 5/21/15 03:32, [email protected] wrote:
From: Fu Wei <[email protected]>
This patchset:
(1)Export "
arch_timer_get_rate" inarm_arch_timer.cfor the other drivers, like SBSA watchdog driver(2)Introduce
Documentation/devicetree/bindings/watchdog/sbsa-gwdt.txtfor FDT info of SBSA Generic Watchdog, and give two examples of adding SBSA Generic Watchdog device node into the dts files:
foundation-v8.dtsandamd-seattle-soc.dtsi.(3)Introduce "pretimeout" into the watchdog framework, and update
Documentation/watchdog/watchdog-kernel-api.txtto introduce:
(1)the new elements in thewatchdog_deviceandwatchdog_ops
struct;
(2)the new API "watchdog_init_timeouts".(4)Introduce ARM SBSA watchdog driver:
a.Use linux kernel watchdog framework;
b.Work with FDT on ARM64;
c.Use "pretimeout" in watchdog framework;
d.In first timeout(WS0), do panic to save system context; e.Support geting timeout and pretimeout from parameter and FDT
at the driver init stage.(5)Parse SBSA Generic Watchdog Structure in GTDT table of ACPI, and create a platform device with that information. This platform device can be used by This Watchdog driver.
This patchset has been tested with watchdog daemon (ACPI/FDT, module/build-in) on the following platforms:
(1)ARM Foundation v8 model
(2)AMD Seattle B0Changelog:
v2: Improve watchdog-kernel-api.txt documentation for pretimeout support.
Export "arch_timer_get_rate" inarm_arch_timer.c.
Addwatchdog_init_timeoutsAPI for pretimeout support in framework. Improve suspend and resume foundation in driver
Improve timeout/pretimeout values init code in driver. Delete unnecessary items of thesbsa_gwdtstruct and #define. Delete all unnecessary debug info in driver.
Fix 64bit division bug.
Use thearch_timerinterface to get watchdog clock rate. AddMODULE_DEVICE_TABLEfor platform device id.
Fix typoes.v1: The first version upstream patchset to linux mailing list
Fu Wei (7):
clocksource: export "arch_timer_get_rate" for the other drivers
Documentation: add sbsa-gwdt.txt documentation
ARM64: add SBSA Generic Watchdog device node infoundation-v8.dts
ARM64: add SBSA Generic Watchdog device node inamd-seattle-soc.dtsi
Watchdog: introduce "pretimeout" into framework
Watchdog: introduce ARM SBSA watchdog driver
ACPI: import watchdog info of GTDT into platform device.../devicetree/bindings/watchdog/sbsa-gwdt.txt | 36 ++ Documentation/watchdog/watchdog-kernel-api.txt | 62 ++- arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi | 11 + arch/arm64/boot/dts/arm/foundation-v8.dts | 10 + arch/arm64/kernel/acpi.c | 136 ++++++ drivers/clocksource/arm_arch_timer.c | 1 + drivers/watchdog/Kconfig | 12 + drivers/watchdog/Makefile | 1 + drivers/watchdog/sbsa_gwdt.c | 476 +++++++++++++++++++++ drivers/watchdog/watchdog_core.c | 103 +++-- drivers/watchdog/watchdog_dev.c | 48 +++ include/linux/watchdog.h | 30 +- 12 files changed, 891 insertions(+), 35 deletions(-)create mode 100644
Documentation/devicetree/bindings/watchdog/sbsa-gwdt.txt
create mode 100644drivers/watchdog/sbsa_gwdt.c
Signature · 10 lines
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
v3 cover Watchdog: introduce ARM SBSA watchdog driver
In reply to a message not in the archiveFrom: Fu Wei <[email protected]>
This patchset:
(1)Introduce Documentation/devicetree/bindings/watchdog/sbsa-gwdt.txt for FDT info of SBSA Generic Watchdog, and give two examples of adding SBSA Generic Watchdog device node into the dts files:
foundation-v8.dts and amd-seattle-soc.dtsi.
(2)Introduce "pretimeout" into the watchdog framework, and update Documentation/watchdog/watchdog-kernel-api.txt to introduce:
(1)the new elements in the watchdog_device and watchdog_ops struct; (2)the new API "watchdog_init_timeouts".
(3)Introduce ARM SBSA watchdog driver:
a.Use linux kernel watchdog framework;
b.Work with FDT on ARM64;
c.Use "pretimeout" in watchdog framework;
d.In first timeout, do panic to save system context; e.Support getting timeout and pretimeout from parameter and FDT
at the driver init stage.
(4)Parse SBSA Generic Watchdog Structure in GTDT table of ACPI, and create a platform device with that information. This platform device can be used by This Watchdog driver.
This patchset has been tested with watchdog daemon (ACPI/FDT, module/build-in) on the following platforms:
(1)ARM Foundation v8 model
(2)AMD Seattle B0
Changelog:
v3: Delete "export arch_timer_get_rate" patch.
Driver back to use arch_timer_get_cntfrq.
Improve watchdog_init_timeouts function and update relevant documentation. Improve watchdog_timeout_invalid and watchdog_pretimeout_invalid. Improve foundation-v8.dts: delete the unnecessary tag of device node. Remove "ARM64 || COMPILE_TEST" from Kconfig.
Add comments in arch/arm64/kernel/acpi.c
Fix typoes and incorrect comments.
v2: Improve watchdog-kernel-api.txt documentation for pretimeout support.
Export "arch_timer_get_rate" in arm_arch_timer.c.
Add watchdog_init_timeouts API for pretimeout support in framework. Improve suspend and resume foundation in driver
Improve timeout/pretimeout values init code in driver. Delete unnecessary items of the sbsa_gwdt struct and #define. Delete all unnecessary debug info in driver.
Fix 64bit division bug.
Use the arch_timer interface to get watchdog clock rate. Add MODULE_DEVICE_TABLE for platform device id.
Fix typoes.
v1: The first version upstream patchset to linux mailing list.
Fu Wei (6):
Documentation: add sbsa-gwdt.txt documentation
ARM64: add SBSA Generic Watchdog device node in foundation-v8.dts
ARM64: add SBSA Generic Watchdog device node in amd-seattle-soc.dtsi
Watchdog: introdouce "pretimeout" into framework
Watchdog: introduce ARM SBSA watchdog driver
ACPI: import watchdog info of GTDT into platform device
.../devicetree/bindings/watchdog/sbsa-gwdt.txt | 36 ++ Documentation/watchdog/watchdog-kernel-api.txt | 47 +- arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi | 11 + arch/arm64/boot/dts/arm/foundation-v8.dts | 10 + arch/arm64/kernel/acpi.c | 145 +++++++ drivers/watchdog/Kconfig | 11 + drivers/watchdog/Makefile | 1 + drivers/watchdog/sbsa_gwdt.c | 474 +++++++++++++++++++++ drivers/watchdog/watchdog_core.c | 95 +++-- drivers/watchdog/watchdog_dev.c | 50 +++ include/linux/watchdog.h | 33 +- 11 files changed, 880 insertions(+), 33 deletions(-) create mode 100644 Documentation/devicetree/bindings/watchdog/sbsa-gwdt.txt create mode 100644 drivers/watchdog/sbsa_gwdt.c
Signature · 6 lines
1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH v3 1/6 Documentation: add sbsa-gwdt.txt documentation
From: Fu Wei <[email protected]>
The sbsa-gwdt.txt documentation in devicetree/bindings/watchdog is for introducing SBSA(Server Base System Architecture) Generic Watchdog device node info into FDT.
--- .../devicetree/bindings/watchdog/sbsa-gwdt.txt | 36 ++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 Documentation/devicetree/bindings/watchdog/sbsa-gwdt.txt
Documentation/devicetree/bindings/watchdog/sbsa-gwdt.txt new file +36 -0
@@ -0,0 +1,36 @@ +* SBSA(Server Base System Architecture) Generic Watchdog + +The SBSA Generic Watchdog Timer is used for resetting the system after +two stages of timeout. +More details: ARM-DEN-0029 - Server Base System Architecture (SBSA) + +Required properties: +- compatible : Should at least contain "arm,sbsa-gwdt". + +- reg : base physical address of the frames and length of memory mapped region. + +- reg-names : Should contain the resource reg names to show the order of + the values in "reg". + Must include the following entries : "refresh", "control". + +- interrupts : Should at least contain WS0 interrupt, + the WS1 Signal is optional. + +- interrupt-names : Should contain the resource interrupt names. + Must include the following entries : "ws0". "ws1" is optional. + +Optional properties +- timeout-sec : Watchdog pre-timeout and timeout values (in seconds). + The first is timeout values, then pre-timeout. + +Example for FVP Foundation Model v8: + +watchdog@2a440000 { + compatible = "arm,sbsa-gwdt"; + reg = <0x0 0x2a440000 0 0x10000>, + <0x0 0x2a450000 0 0x10000>; + reg-names = "control", "refresh"; + interrupts = <0 27 4>; + interrupt-names = "ws0"; + timeout-sec = <10 5>; +};
Signature · 6 lines
1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH v3 2/6 ARM64: add SBSA Generic Watchdog device node in foundation-v8.dts
In reply to [email protected]From: Fu Wei <[email protected]>
This can be a example of adding SBSA Generic Watchdog device node into some dts files for the Soc which contains SBSA Generic Watchdog.
--- arch/arm64/boot/dts/arm/foundation-v8.dts | 10 ++++++++++ 1 file changed, 10 insertions(+)
arch/arm64/boot/dts/arm/foundation-v8.dts +10 -0
@@ -237,4 +237,14 @@ }; }; }; + watchdog@2a440000 { + compatible = "arm,sbsa-gwdt"; + reg = <0x0 0x2a440000 0 0x10000>, + <0x0 0x2a450000 0 0x10000>; + reg-names = "control", + "refresh"; + interrupts = <0 27 4>; + interrupt-names = "ws0"; + timeout-sec = <10 5>; + }; };
Signature · 1 line
1.9.1
PATCH v3 3/6 ARM64: add SBSA Generic Watchdog device node in amd-seattle-soc.dtsi
In reply to [email protected]From: Fu Wei <[email protected]>
This can be a example of adding SBSA Generic Watchdog device node into some dts files for the Soc which contains SBSA Generic Watchdog.
--- arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi | 11 +++++++++++ 1 file changed, 11 insertions(+)
arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi +11 -0
@@ -84,6 +84,17 @@ clock-names = "uartclk", "apb_pclk"; }; + watchdog0: watchdog@e0bb0000 { + compatible = "arm,sbsa-gwdt"; + reg = <0x0 0xe0bb0000 0 0x10000>, + <0x0 0xe0bc0000 0 0x10000>; + reg-names = "refresh", + "control"; + interrupts = <0 337 4>; + interrupt-names = "ws0"; + timeout-sec = <10 5>; + }; + spi0: ssp@e1020000 { status = "disabled"; compatible = "arm,pl022", "arm,primecell";
Signature · 1 line
1.9.1
PATCH v3 4/6 Watchdog: introdouce "pretimeout" into framework
In reply to [email protected]From: Fu Wei <[email protected]>
Also update Documentation/watchdog/watchdog-kernel-api.txt to introduce:
(1)the new elements in the watchdog_device and watchdog_ops struct; (2)the new API "watchdog_init_timeouts"
Reasons:
(1)kernel already has two watchdog drivers are using "pretimeout":
drivers/char/ipmi/ipmi_watchdog.c drivers/watchdog/kempld_wdt.c(but the definition is different)
(2)some other drivers are going to use this: ARM SBSA Generic Watchdog
--- Documentation/watchdog/watchdog-kernel-api.txt | 47 +++++++++++-- drivers/watchdog/watchdog_core.c | 95 +++++++++++++++++++------- drivers/watchdog/watchdog_dev.c | 50 ++++++++++++++ include/linux/watchdog.h | 33 ++++++++- 4 files changed, 192 insertions(+), 33 deletions(-)
Documentation/watchdog/watchdog-kernel-api.txt +42 -5
@@ -49,6 +49,9 @@ struct watchdog_device { unsigned int timeout; unsigned int min_timeout; unsigned int max_timeout; + unsigned int pretimeout; + unsigned int min_pretimeout; + unsigned int max_pretimeout; void *driver_data; struct mutex lock; unsigned long status;
@@ -70,6 +73,9 @@ It contains following fields: * timeout: the watchdog timer's timeout value (in seconds). * min_timeout: the watchdog timer's minimum timeout value (in seconds). * max_timeout: the watchdog timer's maximum timeout value (in seconds). +* pretimeout: the watchdog timer's pretimeout value (in seconds). +* min_pretimeout: the watchdog timer's minimum pretimeout value (in seconds). +* max_pretimeout: the watchdog timer's maximum pretimeout value (in seconds). * bootstatus: status of the device after booting (reported with watchdog WDIOF_* status bits). * driver_data: a pointer to the drivers private data of a watchdog device.
@@ -92,6 +98,7 @@ struct watchdog_ops { int (*ping)(struct watchdog_device *); unsigned int (*status)(struct watchdog_device *); int (*set_timeout)(struct watchdog_device *, unsigned int); + int (*set_pretimeout)(struct watchdog_device *, unsigned int); unsigned int (*get_timeleft)(struct watchdog_device *); void (*ref)(struct watchdog_device *); void (*unref)(struct watchdog_device *);
@@ -153,9 +160,19 @@ they are supported. These optional routines/operations are: and -EIO for "could not write value to the watchdog". On success this routine should set the timeout value of the watchdog_device to the achieved timeout value (which may be different from the requested one - because the watchdog does not necessarily has a 1 second resolution). + because the watchdog does not necessarily has a 1 second resolution; + If the driver supports pretimeout, then the timeout value must be greater + than that). (Note: the WDIOF_SETTIMEOUT needs to be set in the options field of the watchdog's info structure). +* set_pretimeout: this routine checks and changes the pretimeout of the + watchdog timer device. It returns 0 on success, -EINVAL for "parameter out of + range" and -EIO for "could not write value to the watchdog". On success this + routine should set the pretimeout value of the watchdog_device to the + achieved pretimeout value (which may be different from the requested one + because the watchdog does not necessarily has a 1 second resolution). + (Note: the WDIOF_PRETIMEOUT needs to be set in the options field of the + watchdog's info structure). * get_timeleft: this routines returns the time that's left before a reset. * ref: the operation that calls kref_get on the kref of a dynamically allocated watchdog_device struct.
@@ -219,8 +236,28 @@ extern int watchdog_init_timeout(struct watchdog_device *wdd, unsigned int timeout_parm, struct device *dev); The watchdog_init_timeout function allows you to initialize the timeout field -using the module timeout parameter or by retrieving the timeout-sec property from -the device tree (if the module timeout parameter is invalid). Best practice is -to set the default timeout value as timeout value in the watchdog_device and -then use this function to set the user "preferred" timeout value. +using the module timeout parameter or by retrieving the first element of +the timeout-sec property from the device tree (if the module timeout parameter +is invalid). Best practice is to set the default timeout value as timeout value +in the watchdog_device and then use this function to set the user "preferred" +timeout value. +This routine returns zero on success and a negative errno code for failure. + +Some watchdog timers have two stage of timeouts(timeout and pretimeout), +to initialize the timeout and pretimeout fields at the same time, the following +function can be used: + +extern int watchdog_init_timeouts(struct watchdog_device *wdd, + unsigned int pretimeout_parm, + unsigned int timeout_parm, + struct device *dev); + +The watchdog_init_timeouts function allows you to initialize the pretimeout and +timeout fields using the module pretimeout and timeout parameter or by +retrieving the elements in the timeout-sec property(the first element is for +timeout, the second one is for pretimeout) from the device tree(if the module +pretimeout and timeout parameter are invalid). +Best practice is to set the default pretimeout and timeout value as pretimeout +and timeout value in the watchdog_device and then use this function to set the +user "preferred" pretimeout value. This routine returns zero on success and a negative errno code for failure.
drivers/watchdog/watchdog_core.c +70 -25
137 lines not on this page · raw message
drivers/watchdog/watchdog_dev.c +50 -0
62 lines not on this page · raw message
include/linux/watchdog.h +30 -3
@@ -25,6 +25,7 @@ struct watchdog_device;* @ping: The routine that sends a keepalive ping to the watchdog device. * @status: The routine that shows the status of the watchdog device. * @set_timeout:The routine for setting the watchdog devices timeout value. +* @set_pretimeout:The routine for setting the watchdog devices pretimeout value * @get_timeleft:The routine that get's the time that's left before a reset. * @ref: The ref operation for dyn. allocated watchdog_device structs * @unref: The unref operation for dyn. allocated watchdog_device structs
@@ -44,6 +45,7 @@ struct watchdog_ops {int (*ping)(struct watchdog_device *);unsigned int (*status)(struct watchdog_device *);int (*set_timeout)(struct watchdog_device *,unsigned int ); +int (*set_pretimeout)(struct watchdog_device *,unsigned int );unsigned int (*get_timeleft)(struct watchdog_device *);void (*ref)(struct watchdog_device *);void (*unref)(struct watchdog_device *);
@@ -62,6 +64,9 @@ struct watchdog_ops {* @timeout: The watchdog devices timeout value. * @min_timeout:The watchdog devices minimum timeout value. * @max_timeout:The watchdog devices maximum timeout value. +* @pretimeout: The watchdog devices pretimeout value. +* @min_pretimeout:The watchdog devices minimum pretimeout value. +* @max_pretimeout:The watchdog devices maximum pretimeout value. * @driver-data:Pointer to the drivers private data. * @lock: Lock for watchdog core internal use only. * @status: Field that contains the devices internal status bits.
@@ -86,6 +91,9 @@ struct watchdog_device {unsigned int timeout;unsigned int min_timeout;unsigned int max_timeout; +unsigned int pretimeout; +unsigned int min_pretimeout; +unsigned int max_pretimeout;void *driver_data;struct mutex lock;unsigned long status;
@@ -117,7 +125,17 @@ static inline void watchdog_set_nowayout(struct watchdog_device *wdd, bool nowaystatic inline bool watchdog_timeout_invalid (struct watchdog_device *wdd,unsigned int t) {return ((wdd->max_timeout !=0 ) && - (t < wdd->min_timeout || t > wdd->max_timeout)); + (t < wdd->min_timeout || t > wdd->max_timeout || + t < wdd->pretimeout)); +} + +/* Use the following function to check if a pretimeout value is invalid */ +static inline bool watchdog_pretimeout_invalid (struct watchdog_device *wdd, +unsigned int t) +{ +return (wdd->max_pretimeout !=0 && + (t < wdd->min_pretimeout || t > wdd->max_pretimeout || + (wdd->timeout !=0 && t > wdd->timeout))); }/* Use the following functions to manipulate watchdog driver specific data */
@@ -132,11 +150,20 @@ static inline void *watchdog_get_drvdata(struct watchdog_device *wdd) }/* drivers/watchdog/watchdog_core.c */ -extern int watchdog_init_timeout (struct watchdog_device *wdd, -unsigned int timeout_parm,struct device *dev); +extern int watchdog_init_timeouts (struct watchdog_device *wdd, +unsigned int pretimeout_parm, +unsigned int timeout_parm, +struct device *dev);extern int watchdog_register_device (struct watchdog_device *);extern void watchdog_unregister_device (struct watchdog_device *); +static inline int watchdog_init_timeout (struct watchdog_device *wdd, +unsigned int timeout_parm, +struct device *dev) +{ +return watchdog_init_timeouts (wdd,0 , timeout_parm, dev); +} +#ifdef CONFIG_HARDLOCKUP_DETECTOR void watchdog_nmi_disable_all (void );void watchdog_nmi_enable_all (void );
Signature · 1 line
1.9.1
Guenter Roeck
maintainerRe: [PATCH v3 4/6] Watchdog: introdouce "pretimeout" into framework
Quoted 13 lines · On 05/25/2015 03:03 AM, [email protected] wrote:
From: Fu Wei <[email protected]>
Also update
Documentation/watchdog/watchdog-kernel-api.txtto introduce:
(1)the new elements in thewatchdog_deviceandwatchdog_opsstruct; (2)the new API "watchdog_init_timeouts"Reasons:
(1)kernel already has two watchdog drivers are using "pretimeout":
drivers/char/ipmi/ipmi_watchdog.cdrivers/watchdog/kempld_wdt.c(but the definition is different)
(2)some other drivers are going to use this: ARM SBSA Generic Watchdog
Quoted 4 lines
Acked-by Arnd Bergmann <[email protected]>Signed-off-by Fu Wei <[email protected]>---
Comments inline.
Thanks,
Guenter
Quoted 120 lines
Documentation/watchdog/watchdog-kernel-api.txt | 47 +++++++++++-- drivers/watchdog/watchdog_core.c | 95 +++++++++++++++++++------- drivers/watchdog/watchdog_dev.c | 50 ++++++++++++++ include/linux/watchdog.h | 33 ++++++++- 4 files changed, 192 insertions(+), 33 deletions(-)Documentation/watchdog/watchdog-kernel-api.txt +42
-5@@ -49,6 +49,9 @@ struct watchdog_device { unsigned int timeout; unsigned int min_timeout; unsigned int max_timeout; + unsigned int pretimeout; + unsigned int min_pretimeout; + unsigned int max_pretimeout; void *driver_data; struct mutex lock; unsigned long status;@@ -70,6 +73,9 @@ It contains following fields: * timeout: the watchdog timer's timeout value (in seconds). * min_timeout: the watchdog timer's minimum timeout value (in seconds). * max_timeout: the watchdog timer's maximum timeout value (in seconds). +* pretimeout: the watchdog timer's pretimeout value (in seconds). +* min_pretimeout: the watchdog timer's minimum pretimeout value (in seconds). +* max_pretimeout: the watchdog timer's maximum pretimeout value (in seconds). * bootstatus: status of the device after booting (reported with watchdog WDIOF_* status bits). * driver_data: a pointer to the drivers private data of a watchdog device.@@ -92,6 +98,7 @@ struct watchdog_ops { int (*ping)(struct watchdog_device *); unsigned int (*status)(struct watchdog_device *); int (*set_timeout)(struct watchdog_device *, unsigned int); + int (*set_pretimeout)(struct watchdog_device *, unsigned int); unsigned int (*get_timeleft)(struct watchdog_device *); void (*ref)(struct watchdog_device *); void (*unref)(struct watchdog_device *);@@ -153,9 +160,19 @@ they are supported. These optional routines/operations are: and -EIO for "could not write value to the watchdog". On success this routine should set the timeout value of the watchdog_device to the achieved timeout value (which may be different from the requested one - because the watchdog does not necessarily has a 1 second resolution). + because the watchdog does not necessarily has a 1 second resolution; + If the driver supports pretimeout, then the timeout value must be greater + than that). (Note: the WDIOF_SETTIMEOUT needs to be set in the options field of the watchdog's info structure). +* set_pretimeout: this routine checks and changes the pretimeout of the + watchdog timer device. It returns 0 on success, -EINVAL for "parameter out of + range" and -EIO for "could not write value to the watchdog". On success this + routine should set the pretimeout value of the watchdog_device to the + achieved pretimeout value (which may be different from the requested one + because the watchdog does not necessarily has a 1 second resolution). + (Note: the WDIOF_PRETIMEOUT needs to be set in the options field of the + watchdog's info structure). * get_timeleft: this routines returns the time that's left before a reset. * ref: the operation that calls kref_get on the kref of a dynamically allocated watchdog_device struct.@@ -219,8 +236,28 @@ extern int watchdog_init_timeout(struct watchdog_device *wdd, unsigned int timeout_parm, struct device *dev); The watchdog_init_timeout function allows you to initialize the timeout field -using the module timeout parameter or by retrieving the timeout-sec property from -the device tree (if the module timeout parameter is invalid). Best practice is -to set the default timeout value as timeout value in the watchdog_device and -then use this function to set the user "preferred" timeout value. +using the module timeout parameter or by retrieving the first element of +the timeout-sec property from the device tree (if the module timeout parameter +is invalid). Best practice is to set the default timeout value as timeout value +in the watchdog_device and then use this function to set the user "preferred" +timeout value. +This routine returns zero on success and a negative errno code for failure. + +Some watchdog timers have two stage of timeouts(timeout and pretimeout), +to initialize the timeout and pretimeout fields at the same time, the following +function can be used: + +extern int watchdog_init_timeouts(struct watchdog_device *wdd, + unsigned int pretimeout_parm, + unsigned int timeout_parm, + struct device *dev); + +The watchdog_init_timeouts function allows you to initialize the pretimeout and +timeout fields using the module pretimeout and timeout parameter or by +retrieving the elements in the timeout-sec property(the first element is for +timeout, the second one is for pretimeout) from the device tree(if the module +pretimeout and timeout parameter are invalid). +Best practice is to set the default pretimeout and timeout value as pretimeout +and timeout value in the watchdog_device and then use this function to set the +user "preferred" pretimeout value. This routine returns zero on success and a negative errno code for failure.drivers/watchdog/watchdog_core.c +9
-3@@ -43,60 +43,105 @@static DEFINE_IDA (watchdog_ida);static struct class *watchdog_class; -static void watchdog_check_min_max_timeout (struct watchdog_device *wdd) +static void watchdog_check_min_max_timeouts (struct watchdog_device *wdd) {/* -* Check that we have valid min and max timeout values, if -* not reset them both to 0 (=not used or unknown) +* Check that we have valid min and max pretimeout and timeout values, +* if not reset them both to 0 (=not used or unknown) */ +if (wdd->min_pretimeout > wdd->max_pretimeout) { +pr_info ("Invalid min and max pretimeout, resetting to 0\n" ); + wdd->min_pretimeout =0 ; + wdd->max_pretimeout =0 ; + }if (wdd->min_timeout > wdd->max_timeout) {pr_info ("Invalid min and max timeout values, resetting to 0!\n" ); wdd->min_timeout =0 ; wdd->max_timeout =0 ; } +/*
drivers/watchdog/watchdog_core.c line 72
Quoted 10 lines
drivers/watchdog/watchdog_core.c +10
-0+* Check that we have valid min and max timeout values, +* if not reset them both to pretimeout limits +*/ +if (wdd->min_pretimeout && wdd->min_timeout < wdd->min_pretimeout) { +pr_info ("Invalid min timeout, resetting to min pretimeout\n" ); + wdd->min_timeout = wdd->min_pretimeout; + } +if (wdd->max_pretimeout && wdd->max_timeout < wdd->max_pretimeout) { +pr_info ("Invalid max timeout, resetting to max pretimeout\n" ); + wdd->max_timeout = wdd->max_pretimeout;
I think you should rather update max_pretimeout in this case, to be < max_timeout.
Quoted 25 lines
drivers/watchdog/watchdog_core.c +9
-7+ } }/** -* watchdog_init_timeout() - initialize the timeout field +* watchdog_init_timeouts() - initialize the pretimeout and timeout field +* @pretimeout_parm: pretimeout module parameter * @timeout_parm: timeout module parameter * @dev: Device that stores the timeout-sec property * -* Initialize the timeout field of the watchdog_device struct with either the -* timeout module parameter (if it is valid value) or the timeout-sec property -* (only if it is a valid value and the timeout_parm is out of bounds). -* If none of them are valid then we keep the old value (which should normally -* be the default timeout value. +* Initialize the pretimeout and timeout field of the watchdog_device struct +* with either the pretimeout and timeout module parameter (if it is valid +* value) or the timeout-sec property (only if it is a valid value and the +* pretimeout_parm and timeout_parm is out of bounds). If none of them are +* valid, then we keep the old value (which should normally be the default +* timeout value). * * A zero is returned on success and -EINVAL for failure. */ -int watchdog_init_timeout(struct watchdog_device *wdd,
drivers/watchdog/watchdog_core.c line 97
Quoted 10 lines
drivers/watchdog/watchdog_core.c +6
-3- unsigned int timeout_parm, struct device *dev) +int watchdog_init_timeouts (struct watchdog_device *wdd, +unsigned int pretimeout_parm, +unsigned int timeout_parm, +struct device *dev) { - unsigned int t = 0; -int ret =0 ; +u32 timeouts[2 ]; +int ret =0 , length =0 ;
Please keep the longest variable chain first.
Quoted 11 lines
drivers/watchdog/watchdog_core.c +4
-5-watchdog_check_min_max_timeout (wdd); +watchdog_check_min_max_timeouts (wdd); -/* try to get the timeout module parameter first */ -if (!watchdog_timeout_invalid (wdd, timeout_parm) && timeout_parm) { - wdd->timeout = timeout_parm; -return ret; +/* try to get the timeout and pretimeout module parameter first */ +if (pretimeout_parm) { +if (!watchdog_pretimeout_invalid (wdd, pretimeout_parm))
drivers/watchdog/watchdog_core.c line 112
Quoted 10 lines
drivers/watchdog/watchdog_core.c +8
-1+ wdd->pretimeout = pretimeout_parm; + else + ret = -EINVAL ; } -if (timeout_parm) + +if (timeout_parm) { +if (!watchdog_timeout_invalid (wdd, timeout_parm)) { + wdd->timeout = timeout_parm; +return ret;
This would return -EINVAL if timeout is correct but pretimeout isn't. How about this ?
if (!ret) return 0;
Quoted 11 lines
drivers/watchdog/watchdog_core.c +2
-4+ } ret = -EINVAL ; + }/* try to get the timeout_sec property */ if (dev ==NULL || dev->of_node ==NULL )return ret; -of_property_read_u32 (dev->of_node,"timeout-sec" , &t); -if (!watchdog_timeout_invalid (wdd, t) && t) - wdd->timeout = t; -else
drivers/watchdog/watchdog_core.c line 129
Quoted 10 lines
drivers/watchdog/watchdog_core.c +10
-0+ +of_find_property (dev->of_node,"timeout-sec" , &length); +if (length >0 && length <=sizeof (u32) *2 ) { +of_property_read_u32_array (dev->of_node, +"timeout-sec" , timeouts, + length /sizeof (u32)); +if (length ==2 ) { +if (!watchdog_pretimeout_invalid (wdd, timeouts[1 ]) && + timeouts[1 ]) + wdd->pretimeout = timeouts[1 ];
A pretimeout of 0 is a valid timeout, so why not use it ?
drivers/watchdog/watchdog_core.c line 130
Quoted 2 lines
drivers/watchdog/watchdog_core.c +2
-0+else + ret = -EINVAL ;
and why is pretimeout == 0 considered invalid here ?
Quoted 72 lines
drivers/watchdog/watchdog_core.c +10
-2+ } + +if (!watchdog_timeout_invalid (wdd, timeouts[0 ]) && timeouts[0 ]) + wdd->timeout = timeouts[0 ]; +else + ret = -EINVAL ; + }else { ret = -EINVAL ; + }return ret; } -EXPORT_SYMBOL_GPL (watchdog_init_timeout); +EXPORT_SYMBOL_GPL (watchdog_init_timeouts);/** * watchdog_register_device() - register a watchdog device @@ -119,7 +164,7 @@ int watchdog_register_device(struct watchdog_device *wdd)if (wdd->ops->start ==NULL || wdd->ops->stop ==NULL )return -EINVAL ; -watchdog_check_min_max_timeout (wdd); +watchdog_check_min_max_timeouts (wdd);/* * Note: now that all watchdog_device data has been verified, we drivers/watchdog/watchdog_dev.c +32
-0@@ -218,6 +218,38 @@ out_timeout: }/* +* watchdog_set_pretimeout: set the watchdog timer pretimeout +* @wddev: the watchdog device to set the timeout for +* @pretimeout: pretimeout to set in seconds +*/ + +static int watchdog_set_pretimeout (struct watchdog_device *wddev, +unsigned int pretimeout) +{ +int err; + +if (!wddev->ops->set_pretimeout || + !(wddev->info->options &WDIOF_PRETIMEOUT )) +return -EOPNOTSUPP ; + +if (watchdog_pretimeout_invalid (wddev, pretimeout)) +return -EINVAL ; + +mutex_lock (&wddev->lock); + +if (test_bit (WDOG_UNREGISTERED , &wddev->status)) { + err = -ENODEV ; + goto out_pretimeout; + } + + err = wddev->ops->set_pretimeout (wddev, pretimeout); + +out_pretimeout: +mutex_unlock (&wddev->lock); +return err; +} + +/* * watchdog_get_timeleft: wrapper to get the time left before a reboot * @wddev: the watchdog device to get the remaining time from * @timeleft: the time that's left @@ -388,6 +420,24 @@ static long watchdog_ioctl(struct file *file, unsigned int cmd,if (wdd->timeout ==0 )return -EOPNOTSUPP ;
drivers/watchdog/watchdog_dev.c static long watchdog_ioctl(struct file *file, unsigned int cmd, · line 431
Quoted 10 lines
drivers/watchdog/watchdog_dev.c +9
-0return put_user (wdd->timeout, p); +case WDIOC_SETPRETIMEOUT : +if (get_user (val, p)) +return -EFAULT ; + err =watchdog_set_pretimeout (wdd, val); +if (err <0 ) +return err; +/* +* If the watchdog is active then we send a keepalive ping +* to make sure that the watchdog keep's running (and if
s/keep's/keeps/
drivers/watchdog/watchdog_dev.c static long watchdog_ioctl(struct file *file, unsigned int cmd, · line 432
Quoted 1 line
drivers/watchdog/watchdog_dev.c +1
-0+* possible that it takes the new timeout)
new pretimeout
drivers/watchdog/watchdog_dev.c static long watchdog_ioctl(struct file *file, unsigned int cmd, · line 439
Quoted 7 lines
drivers/watchdog/watchdog_dev.c +7
-0+*/ +watchdog_ping (wdd); +/* Fall */ +case WDIOC_GETPRETIMEOUT : +/* pretimeout == 0 means that we don't know the pretimeout */ +if (wdd->pretimeout ==0 ) +return -EOPNOTSUPP ;
pretimeout == 0 is a valid parameter, though, and means that it is disabled. So we can not return -EOPNOTSUPP here.
Either this code needs to explicitly check for pretimeout support, or just return 0 if it is disabled / not supported.
Quoted 45 lines
drivers/watchdog/watchdog_dev.c +1
-0+return put_user (wdd->pretimeout, p);case WDIOC_GETTIMELEFT : err =watchdog_get_timeleft (wdd, &val);if (err)include/linux/watchdog.h +8
-0@@ -25,6 +25,7 @@ struct watchdog_device;* @ping: The routine that sends a keepalive ping to the watchdog device. * @status: The routine that shows the status of the watchdog device. * @set_timeout:The routine for setting the watchdog devices timeout value. +* @set_pretimeout:The routine for setting the watchdog devices pretimeout value * @get_timeleft:The routine that get's the time that's left before a reset. * @ref: The ref operation for dyn. allocated watchdog_device structs * @unref: The unref operation for dyn. allocated watchdog_device structs @@ -44,6 +45,7 @@ struct watchdog_ops {int (*ping)(struct watchdog_device *);unsigned int (*status)(struct watchdog_device *);int (*set_timeout)(struct watchdog_device *,unsigned int ); +int (*set_pretimeout)(struct watchdog_device *,unsigned int );unsigned int (*get_timeleft)(struct watchdog_device *);void (*ref)(struct watchdog_device *);void (*unref)(struct watchdog_device *);@@ -62,6 +64,9 @@ struct watchdog_ops {* @timeout: The watchdog devices timeout value. * @min_timeout:The watchdog devices minimum timeout value. * @max_timeout:The watchdog devices maximum timeout value. +* @pretimeout: The watchdog devices pretimeout value. +* @min_pretimeout:The watchdog devices minimum pretimeout value. +* @max_pretimeout:The watchdog devices maximum pretimeout value. * @driver-data:Pointer to the drivers private data. * @lock: Lock for watchdog core internal use only. * @status: Field that contains the devices internal status bits. @@ -86,6 +91,9 @@ struct watchdog_device {unsigned int timeout;unsigned int min_timeout;unsigned int max_timeout; +unsigned int pretimeout; +unsigned int min_pretimeout; +unsigned int max_pretimeout;void *driver_data;struct mutex lock;unsigned long status;
include/linux/watchdog.h static inline void watchdog_set_nowayout(struct watchdog_device *wdd, bool noway · line 129
Quoted 6 lines
include/linux/watchdog.h +2
-1@@ -117,7 +125,17 @@ static inline void watchdog_set_nowayout(struct watchdog_device *wdd, bool nowaystatic inline bool watchdog_timeout_invalid (struct watchdog_device *wdd,unsigned int t) {return ((wdd->max_timeout !=0 ) && - (t < wdd->min_timeout || t > wdd->max_timeout)); + (t < wdd->min_timeout || t > wdd->max_timeout || + t < wdd->pretimeout));
< or <= ?
timeout == pretimeout implies that the pretimeout would expire immediately, which doesn't seem to make much sense.
include/linux/watchdog.h static inline void watchdog_set_nowayout(struct watchdog_device *wdd, bool noway · line 138
Quoted 9 lines
include/linux/watchdog.h +9
-0+} + +/* Use the following function to check if a pretimeout value is invalid */ +static inline bool watchdog_pretimeout_invalid (struct watchdog_device *wdd, +unsigned int t) +{ +return (wdd->max_pretimeout !=0 && + (t < wdd->min_pretimeout || t > wdd->max_pretimeout || + (wdd->timeout !=0 && t > wdd->timeout)));
> or >= ?
Quoted 17 lines
include/linux/watchdog.h +4
-2}/* Use the following functions to manipulate watchdog driver specific data */ @@ -132,11 +150,20 @@ static inline void *watchdog_get_drvdata(struct watchdog_device *wdd) }/* drivers/watchdog/watchdog_core.c */ -extern int watchdog_init_timeout (struct watchdog_device *wdd, -unsigned int timeout_parm,struct device *dev); +extern int watchdog_init_timeouts (struct watchdog_device *wdd, +unsigned int pretimeout_parm, +unsigned int timeout_parm, +struct device *dev);extern int watchdog_register_device (struct watchdog_device *);extern void watchdog_unregister_device (struct watchdog_device *);
include/linux/watchdog.h static inline void *watchdog_get_drvdata(struct watchdog_device *wdd) · line 169
Quoted 10 lines
include/linux/watchdog.h +7
-0+static inline int watchdog_init_timeout (struct watchdog_device *wdd, +unsigned int timeout_parm, +struct device *dev) +{ +return watchdog_init_timeouts (wdd,0 , timeout_parm, dev); +} +#ifdef CONFIG_HARDLOCKUP_DETECTOR void watchdog_nmi_disable_all (void );void watchdog_nmi_enable_all (void );
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH v3 5/6 Watchdog: introduce ARM SBSA watchdog driver
In reply to [email protected]From: Fu Wei <[email protected]>
This driver bases on linux kernel watchdog framework, and use "pretimeout" in the framework. It supports getting timeout and pretimeout from parameter and FDT at the driver init stage. In first timeout, the interrupt routine run panic to save system context.
--- drivers/watchdog/Kconfig | 11 + drivers/watchdog/Makefile | 1 + drivers/watchdog/sbsa_gwdt.c | 474 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 486 insertions(+) create mode 100644 drivers/watchdog/sbsa_gwdt.c
drivers/watchdog/Kconfig +11 -0
@@ -152,6 +152,17 @@ 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. This watchdog has two Watchdog timeouts. + The first timeout will trigger a panic; the second timeout will + trigger a system reset. + More details: ARM DEN0029B - Server Base System Architecture (SBSA) + config AT91RM9200_WATCHDOG tristate "AT91RM9200 watchdog" depends on SOC_AT91RM9200 && MFD_SYSCON
drivers/watchdog/Makefile +1 -0
@@ -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_AT91RM9200_WATCHDOG) += at91rm9200_wdt.o obj-$(CONFIG_AT91SAM9X_WATCHDOG) += at91sam9_wdt.o obj-$(CONFIG_CADENCE_WATCHDOG) += cadence_wdt.o
drivers/watchdog/sbsa_gwdt.c new file +474 -0
474 lines not on this page · raw message
Signature · 1 line
1.9.1