* [PATCH v5 0/5] STM32 Independent watchdog
@ 2017-04-06 12:19 Yannick Fertre
[not found] ` <1491481168-22213-1-git-send-email-yannick.fertre-qxv4g6HH51o@public.gmane.org>
` (5 more replies)
0 siblings, 6 replies; 9+ messages in thread
From: Yannick Fertre @ 2017-04-06 12:19 UTC (permalink / raw)
To: Wim Van Sebroeck, Guenter Roeck, Rob Herring, Alexandre TORGUE,
Benjamin Gaignard, Yannick Fertre, Maxime Coquelin
Cc: devicetree, linux-watchdog, Philippe Cornu, linux-kernel,
Gabriel FERNANDEZ, linux-arm-kernel
Version 5:
- Update bindings (add field timeout-sec)
- Update driver (rework start, rework settings & remove max_timeout)
Version 4:
- Update bindings (iwdg > watchdog)
- Update typo
- Update commit header
- remove gerrit tags
- Update driver (remove unnecessary tests) a add watchdog_init_timeout
Version 3:
- Update typo into bindings file
- Reorder node in devicetree (ordering by address)
- Remove unnecessary lines in commits
Version 2:
- Add commit messages
Version 1:
- Initial commit
The purpose of this set of patches is to add a new watchdog driver for
stm32f429.
This driver was developed and tested on evaluation board stm32429i.
Yannick Fertre (5):
dt-bindings: watchdog: Document STM32 IWDG bindings
drivers: watchdog: Add STM32 IWDG driver
ARM: dts: stm32: Add watchdog support for STM32F429 SoC
ARM: dts: stm32: Add watchdog support for STM32F429 eval board
ARM: configs: stm32: Add watchdog support in STM32 defconfig
.../devicetree/bindings/watchdog/st,stm32-iwdg.txt | 19 ++
arch/arm/boot/dts/stm32429i-eval.dts | 5 +
arch/arm/boot/dts/stm32f429.dtsi | 9 +-
arch/arm/configs/stm32_defconfig | 1 +
drivers/watchdog/Kconfig | 12 +
drivers/watchdog/Makefile | 1 +
drivers/watchdog/stm32_iwdg.c | 253 +++++++++++++++++++++
7 files changed, 299 insertions(+), 1 deletion(-)
create mode 100644 Documentation/devicetree/bindings/watchdog/st,stm32-iwdg.txt
create mode 100644 drivers/watchdog/stm32_iwdg.c
--
1.9.1
^ permalink raw reply [flat|nested] 9+ messages in thread[parent not found: <1491481168-22213-1-git-send-email-yannick.fertre-qxv4g6HH51o@public.gmane.org>]
* [PATCH v5 1/5] dt-bindings: watchdog: Document STM32 IWDG bindings [not found] ` <1491481168-22213-1-git-send-email-yannick.fertre-qxv4g6HH51o@public.gmane.org> @ 2017-04-06 12:19 ` Yannick Fertre [not found] ` <1491481168-22213-2-git-send-email-yannick.fertre-qxv4g6HH51o@public.gmane.org> 0 siblings, 1 reply; 9+ messages in thread From: Yannick Fertre @ 2017-04-06 12:19 UTC (permalink / raw) To: Wim Van Sebroeck, Guenter Roeck, Rob Herring, Alexandre TORGUE, Benjamin Gaignard, Yannick Fertre, Maxime Coquelin Cc: linux-watchdog-u79uwXL29TY76Z2rM5mHXA, linux-kernel-u79uwXL29TY76Z2rM5mHXA, Philippe Cornu, Gabriel FERNANDEZ, devicetree-u79uwXL29TY76Z2rM5mHXA, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r This adds documentation of device tree bindings for the STM32 IWDG (Independent WatchDoG). Signed-off-by: Yannick Fertre <yannick.fertre-qxv4g6HH51o@public.gmane.org> --- .../devicetree/bindings/watchdog/st,stm32-iwdg.txt | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 Documentation/devicetree/bindings/watchdog/st,stm32-iwdg.txt diff --git a/Documentation/devicetree/bindings/watchdog/st,stm32-iwdg.txt b/Documentation/devicetree/bindings/watchdog/st,stm32-iwdg.txt new file mode 100644 index 0000000..cc13b10a --- /dev/null +++ b/Documentation/devicetree/bindings/watchdog/st,stm32-iwdg.txt @@ -0,0 +1,19 @@ +STM32 Independent WatchDoG (IWDG) +--------------------------------- + +Required properties: +- compatible: "st,stm32-iwdg" +- reg: physical base address and length of the registers set for the device +- clocks: must contain a single entry describing the clock input + +Optional Properties: +- timeout-sec: Watchdog timeout value in seconds. + +Example: + +iwdg: watchdog@40003000 { + compatible = "st,stm32-iwdg"; + reg = <0x40003000 0x400>; + clocks = <&clk_lsi>; + timeout-sec = <32>; +}; -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply related [flat|nested] 9+ messages in thread
[parent not found: <1491481168-22213-2-git-send-email-yannick.fertre-qxv4g6HH51o@public.gmane.org>]
* Re: [PATCH v5 1/5] dt-bindings: watchdog: Document STM32 IWDG bindings [not found] ` <1491481168-22213-2-git-send-email-yannick.fertre-qxv4g6HH51o@public.gmane.org> @ 2017-04-10 18:25 ` Rob Herring 0 siblings, 0 replies; 9+ messages in thread From: Rob Herring @ 2017-04-10 18:25 UTC (permalink / raw) To: Yannick Fertre Cc: Wim Van Sebroeck, Guenter Roeck, Alexandre TORGUE, Benjamin Gaignard, Maxime Coquelin, linux-watchdog-u79uwXL29TY76Z2rM5mHXA, linux-kernel-u79uwXL29TY76Z2rM5mHXA, Philippe Cornu, Gabriel FERNANDEZ, devicetree-u79uwXL29TY76Z2rM5mHXA, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r On Thu, Apr 06, 2017 at 02:19:24PM +0200, Yannick Fertre wrote: > This adds documentation of device tree bindings for the STM32 IWDG > (Independent WatchDoG). > > Signed-off-by: Yannick Fertre <yannick.fertre-qxv4g6HH51o@public.gmane.org> > --- > .../devicetree/bindings/watchdog/st,stm32-iwdg.txt | 19 +++++++++++++++++++ > 1 file changed, 19 insertions(+) > create mode 100644 Documentation/devicetree/bindings/watchdog/st,stm32-iwdg.txt Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v5 2/5] drivers: watchdog: Add STM32 IWDG driver 2017-04-06 12:19 [PATCH v5 0/5] STM32 Independent watchdog Yannick Fertre [not found] ` <1491481168-22213-1-git-send-email-yannick.fertre-qxv4g6HH51o@public.gmane.org> @ 2017-04-06 12:19 ` Yannick Fertre [not found] ` <1491481168-22213-3-git-send-email-yannick.fertre-qxv4g6HH51o@public.gmane.org> 2017-04-06 12:19 ` [PATCH v5 3/5] ARM: dts: stm32: Add watchdog support for STM32F429 SoC Yannick Fertre ` (3 subsequent siblings) 5 siblings, 1 reply; 9+ messages in thread From: Yannick Fertre @ 2017-04-06 12:19 UTC (permalink / raw) To: Wim Van Sebroeck, Guenter Roeck, Rob Herring, Alexandre TORGUE, Benjamin Gaignard, Yannick Fertre, Maxime Coquelin Cc: devicetree, linux-watchdog, Philippe Cornu, linux-kernel, Gabriel FERNANDEZ, linux-arm-kernel This patch adds IWDG (Independent WatchDoG) support for STM32 platform. Signed-off-by: Yannick FERTRE <yannick.fertre@st.com> --- drivers/watchdog/Kconfig | 12 ++ drivers/watchdog/Makefile | 1 + drivers/watchdog/stm32_iwdg.c | 253 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 266 insertions(+) create mode 100644 drivers/watchdog/stm32_iwdg.c diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 52a70ee..d014deb 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -744,6 +744,18 @@ config ZX2967_WATCHDOG To compile this driver as a module, choose M here: the module will be called zx2967_wdt. +config STM32_WATCHDOG + tristate "STM32 Independent WatchDoG (IWDG) support" + depends on ARCH_STM32 + select WATCHDOG_CORE + default y + help + Say Y here to include support for the watchdog timer + in stm32 SoCs. + + To compile this driver as a module, choose M here: the + module will be called stm32_iwdg. + # AVR32 Architecture config AT32AP700X_WDT diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index a2126e2..a35e423 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -84,6 +84,7 @@ obj-$(CONFIG_ATLAS7_WATCHDOG) += atlas7_wdt.o obj-$(CONFIG_RENESAS_WDT) += renesas_wdt.o obj-$(CONFIG_ASPEED_WATCHDOG) += aspeed_wdt.o obj-$(CONFIG_ZX2967_WATCHDOG) += zx2967_wdt.o +obj-$(CONFIG_STM32_WATCHDOG) += stm32_iwdg.o # AVR32 Architecture obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o diff --git a/drivers/watchdog/stm32_iwdg.c b/drivers/watchdog/stm32_iwdg.c new file mode 100644 index 0000000..6c501b7 --- /dev/null +++ b/drivers/watchdog/stm32_iwdg.c @@ -0,0 +1,253 @@ +/* + * Driver for STM32 Independent Watchdog + * + * Copyright (C) Yannick Fertre 2017 + * Author: Yannick Fertre <yannick.fertre@st.com> + * + * This driver is based on tegra_wdt.c + * + * License terms: GNU General Public License (GPL), version 2 + */ + +#include <linux/clk.h> +#include <linux/delay.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/interrupt.h> +#include <linux/io.h> +#include <linux/iopoll.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/watchdog.h> + +/* IWDG registers */ +#define IWDG_KR 0x00 /* Key register */ +#define IWDG_PR 0x04 /* Prescaler Register */ +#define IWDG_RLR 0x08 /* ReLoad Register */ +#define IWDG_SR 0x0C /* Status Register */ +#define IWDG_WINR 0x10 /* Windows Register */ + +/* IWDG_KR register bit mask */ +#define KR_KEY_RELOAD 0xAAAA /* reload counter enable */ +#define KR_KEY_ENABLE 0xCCCC /* peripheral enable */ +#define KR_KEY_EWA 0x5555 /* write access enable */ +#define KR_KEY_DWA 0x0000 /* write access disable */ + +/* IWDG_PR register bit values */ +#define PR_4 0x00 /* prescaler set to 4 */ +#define PR_8 0x01 /* prescaler set to 8 */ +#define PR_16 0x02 /* prescaler set to 16 */ +#define PR_32 0x03 /* prescaler set to 32 */ +#define PR_64 0x04 /* prescaler set to 64 */ +#define PR_128 0x05 /* prescaler set to 128 */ +#define PR_256 0x06 /* prescaler set to 256 */ + +/* IWDG_RLR register values */ +#define RLR_MIN 0x07C /* min value supported by reload register */ +#define RLR_MAX 0xFFF /* max value supported by reload register */ + +/* IWDG_SR register bit mask */ +#define FLAG_PVU BIT(0) /* Watchdog prescaler value update */ +#define FLAG_RVU BIT(1) /* Watchdog counter reload value update */ + +/* set timeout to 100000 us */ +#define TIMEOUT_US 100000 +#define SLEEP_US 1000 + +struct stm32_iwdg { + struct watchdog_device wdd; + void __iomem *regs; + struct clk *clk; + unsigned int rate; +}; + +static inline u32 reg_read(void __iomem *base, u32 reg) +{ + return readl_relaxed(base + reg); +} + +static inline void reg_write(void __iomem *base, u32 reg, u32 val) +{ + writel_relaxed(val, base + reg); +} + +static int stm32_iwdg_start(struct watchdog_device *wdd) +{ + struct stm32_iwdg *wdt = watchdog_get_drvdata(wdd); + u32 val = FLAG_PVU | FLAG_RVU; + u32 reload; + int ret; + + dev_dbg(wdd->parent, "%s\n", __func__); + + /* prescaler fixed to 256 */ + reload = clamp_t(unsigned int, ((wdd->timeout * wdt->rate) / 256) - 1, + RLR_MIN, RLR_MAX); + + /* enable write access */ + reg_write(wdt->regs, IWDG_KR, KR_KEY_EWA); + + /* set prescaler & reload registers */ + reg_write(wdt->regs, IWDG_PR, PR_256); /* prescaler fix to 256 */ + reg_write(wdt->regs, IWDG_RLR, reload); + reg_write(wdt->regs, IWDG_KR, KR_KEY_ENABLE); + + /* wait for the registers to be updated (max 100ms) */ + ret = readl_relaxed_poll_timeout(wdt->regs + IWDG_SR, val, + !(val & (FLAG_PVU | FLAG_RVU)), + SLEEP_US, TIMEOUT_US); + if (ret) { + dev_err(wdd->parent, + "Fail to set prescaler or reload registers\n"); + return ret; + } + + /* reload watchdog */ + reg_write(wdt->regs, IWDG_KR, KR_KEY_RELOAD); + + return 0; +} + +static int stm32_iwdg_ping(struct watchdog_device *wdd) +{ + struct stm32_iwdg *wdt = watchdog_get_drvdata(wdd); + + dev_dbg(wdd->parent, "%s\n", __func__); + + /* reload watchdog */ + reg_write(wdt->regs, IWDG_KR, KR_KEY_RELOAD); + + return 0; +} + +static int stm32_iwdg_set_timeout(struct watchdog_device *wdd, + unsigned int timeout) +{ + dev_dbg(wdd->parent, "%s timeout: %d sec\n", __func__, timeout); + + wdd->timeout = timeout; + + if (watchdog_active(wdd)) + return stm32_iwdg_start(wdd); + + return 0; +} + +static const struct watchdog_info stm32_iwdg_info = { + .options = WDIOF_SETTIMEOUT | + WDIOF_MAGICCLOSE | + WDIOF_KEEPALIVEPING, + .identity = "STM32 Independent Watchdog", +}; + +static struct watchdog_ops stm32_iwdg_ops = { + .owner = THIS_MODULE, + .start = stm32_iwdg_start, + .ping = stm32_iwdg_ping, + .set_timeout = stm32_iwdg_set_timeout, +}; + +static int stm32_iwdg_probe(struct platform_device *pdev) +{ + struct watchdog_device *wdd; + struct stm32_iwdg *wdt; + struct resource *res; + void __iomem *regs; + struct clk *clk; + int ret; + + /* This is the timer base. */ + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + regs = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(regs)) { + dev_err(&pdev->dev, "Could not get resource\n"); + return PTR_ERR(regs); + } + + clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(clk)) { + dev_err(&pdev->dev, "Unable to get clock\n"); + return PTR_ERR(clk); + } + + ret = clk_prepare_enable(clk); + if (ret) { + dev_err(&pdev->dev, "Unable to prepare clock %p\n", clk); + return ret; + } + + /* + * Allocate our watchdog driver data, which has the + * struct watchdog_device nested within it. + */ + wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL); + if (!wdt) { + ret = -ENOMEM; + goto err; + } + + /* Initialize struct stm32_iwdg. */ + wdt->regs = regs; + wdt->clk = clk; + wdt->rate = clk_get_rate(clk); + + /* Initialize struct watchdog_device. */ + wdd = &wdt->wdd; + wdd->info = &stm32_iwdg_info; + wdd->ops = &stm32_iwdg_ops; + wdd->min_timeout = ((RLR_MIN + 1) * 256) / wdt->rate; + wdd->max_hw_heartbeat_ms = ((RLR_MAX + 1) * 256 * 1000) / wdt->rate; + wdd->parent = &pdev->dev; + + watchdog_set_drvdata(wdd, wdt); + watchdog_set_nowayout(wdd, WATCHDOG_NOWAYOUT); + + ret = watchdog_init_timeout(wdd, 0, &pdev->dev); + if (ret) + dev_warn(&pdev->dev, + "unable to set timeout value, using default\n"); + + ret = watchdog_register_device(wdd); + if (ret) { + dev_err(&pdev->dev, "failed to register watchdog device\n"); + goto err; + } + + platform_set_drvdata(pdev, wdt); + + return 0; +err: + clk_disable_unprepare(clk); + + return ret; +} + +static int stm32_iwdg_remove(struct platform_device *pdev) +{ + struct stm32_iwdg *wdt = platform_get_drvdata(pdev); + + watchdog_unregister_device(&wdt->wdd); + clk_disable_unprepare(wdt->clk); + + return 0; +} + +static const struct of_device_id stm32_iwdg_of_match[] = { + { .compatible = "st,stm32-iwdg" }, + { /* end node */ } +}; +MODULE_DEVICE_TABLE(of, stm32_iwdg_of_match); + +static struct platform_driver stm32_iwdg_driver = { + .probe = stm32_iwdg_probe, + .remove = stm32_iwdg_remove, + .driver = { + .name = "iwdg", + .of_match_table = stm32_iwdg_of_match, + }, +}; +module_platform_driver(stm32_iwdg_driver); + +MODULE_AUTHOR("Yannick Fertre <yannick.fertre@st.com>"); +MODULE_DESCRIPTION("STMicroelectronics STM32 Independent Watchdog Driver"); +MODULE_LICENSE("GPL v2"); -- 1.9.1 ^ permalink raw reply related [flat|nested] 9+ messages in thread
[parent not found: <1491481168-22213-3-git-send-email-yannick.fertre-qxv4g6HH51o@public.gmane.org>]
* Re: [PATCH v5 2/5] drivers: watchdog: Add STM32 IWDG driver [not found] ` <1491481168-22213-3-git-send-email-yannick.fertre-qxv4g6HH51o@public.gmane.org> @ 2017-04-17 1:11 ` Guenter Roeck 0 siblings, 0 replies; 9+ messages in thread From: Guenter Roeck @ 2017-04-17 1:11 UTC (permalink / raw) To: Yannick Fertre, Wim Van Sebroeck, Rob Herring, Alexandre TORGUE, Benjamin Gaignard, Maxime Coquelin Cc: linux-watchdog-u79uwXL29TY76Z2rM5mHXA, linux-kernel-u79uwXL29TY76Z2rM5mHXA, Philippe Cornu, Gabriel FERNANDEZ, devicetree-u79uwXL29TY76Z2rM5mHXA, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r On 04/06/2017 05:19 AM, Yannick Fertre wrote: > This patch adds IWDG (Independent WatchDoG) support for STM32 platform. > > Signed-off-by: Yannick FERTRE <yannick.fertre-qxv4g6HH51o@public.gmane.org> Reviewed-by: Guenter Roeck <linux-0h96xk9xTtrk1uMJSBkQmQ@public.gmane.org> > --- > drivers/watchdog/Kconfig | 12 ++ > drivers/watchdog/Makefile | 1 + > drivers/watchdog/stm32_iwdg.c | 253 ++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 266 insertions(+) > create mode 100644 drivers/watchdog/stm32_iwdg.c > > diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig > index 52a70ee..d014deb 100644 > --- a/drivers/watchdog/Kconfig > +++ b/drivers/watchdog/Kconfig > @@ -744,6 +744,18 @@ config ZX2967_WATCHDOG > To compile this driver as a module, choose M here: the > module will be called zx2967_wdt. > > +config STM32_WATCHDOG > + tristate "STM32 Independent WatchDoG (IWDG) support" > + depends on ARCH_STM32 > + select WATCHDOG_CORE > + default y > + help > + Say Y here to include support for the watchdog timer > + in stm32 SoCs. > + > + To compile this driver as a module, choose M here: the > + module will be called stm32_iwdg. > + > # AVR32 Architecture > > config AT32AP700X_WDT > diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile > index a2126e2..a35e423 100644 > --- a/drivers/watchdog/Makefile > +++ b/drivers/watchdog/Makefile > @@ -84,6 +84,7 @@ obj-$(CONFIG_ATLAS7_WATCHDOG) += atlas7_wdt.o > obj-$(CONFIG_RENESAS_WDT) += renesas_wdt.o > obj-$(CONFIG_ASPEED_WATCHDOG) += aspeed_wdt.o > obj-$(CONFIG_ZX2967_WATCHDOG) += zx2967_wdt.o > +obj-$(CONFIG_STM32_WATCHDOG) += stm32_iwdg.o > > # AVR32 Architecture > obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o > diff --git a/drivers/watchdog/stm32_iwdg.c b/drivers/watchdog/stm32_iwdg.c > new file mode 100644 > index 0000000..6c501b7 > --- /dev/null > +++ b/drivers/watchdog/stm32_iwdg.c > @@ -0,0 +1,253 @@ > +/* > + * Driver for STM32 Independent Watchdog > + * > + * Copyright (C) Yannick Fertre 2017 > + * Author: Yannick Fertre <yannick.fertre-qxv4g6HH51o@public.gmane.org> > + * > + * This driver is based on tegra_wdt.c > + * > + * License terms: GNU General Public License (GPL), version 2 > + */ > + > +#include <linux/clk.h> > +#include <linux/delay.h> > +#include <linux/kernel.h> > +#include <linux/module.h> > +#include <linux/interrupt.h> > +#include <linux/io.h> > +#include <linux/iopoll.h> > +#include <linux/of.h> > +#include <linux/platform_device.h> > +#include <linux/watchdog.h> > + > +/* IWDG registers */ > +#define IWDG_KR 0x00 /* Key register */ > +#define IWDG_PR 0x04 /* Prescaler Register */ > +#define IWDG_RLR 0x08 /* ReLoad Register */ > +#define IWDG_SR 0x0C /* Status Register */ > +#define IWDG_WINR 0x10 /* Windows Register */ > + > +/* IWDG_KR register bit mask */ > +#define KR_KEY_RELOAD 0xAAAA /* reload counter enable */ > +#define KR_KEY_ENABLE 0xCCCC /* peripheral enable */ > +#define KR_KEY_EWA 0x5555 /* write access enable */ > +#define KR_KEY_DWA 0x0000 /* write access disable */ > + > +/* IWDG_PR register bit values */ > +#define PR_4 0x00 /* prescaler set to 4 */ > +#define PR_8 0x01 /* prescaler set to 8 */ > +#define PR_16 0x02 /* prescaler set to 16 */ > +#define PR_32 0x03 /* prescaler set to 32 */ > +#define PR_64 0x04 /* prescaler set to 64 */ > +#define PR_128 0x05 /* prescaler set to 128 */ > +#define PR_256 0x06 /* prescaler set to 256 */ > + > +/* IWDG_RLR register values */ > +#define RLR_MIN 0x07C /* min value supported by reload register */ > +#define RLR_MAX 0xFFF /* max value supported by reload register */ > + > +/* IWDG_SR register bit mask */ > +#define FLAG_PVU BIT(0) /* Watchdog prescaler value update */ > +#define FLAG_RVU BIT(1) /* Watchdog counter reload value update */ > + > +/* set timeout to 100000 us */ > +#define TIMEOUT_US 100000 > +#define SLEEP_US 1000 > + > +struct stm32_iwdg { > + struct watchdog_device wdd; > + void __iomem *regs; > + struct clk *clk; > + unsigned int rate; > +}; > + > +static inline u32 reg_read(void __iomem *base, u32 reg) > +{ > + return readl_relaxed(base + reg); > +} > + > +static inline void reg_write(void __iomem *base, u32 reg, u32 val) > +{ > + writel_relaxed(val, base + reg); > +} > + > +static int stm32_iwdg_start(struct watchdog_device *wdd) > +{ > + struct stm32_iwdg *wdt = watchdog_get_drvdata(wdd); > + u32 val = FLAG_PVU | FLAG_RVU; > + u32 reload; > + int ret; > + > + dev_dbg(wdd->parent, "%s\n", __func__); > + > + /* prescaler fixed to 256 */ > + reload = clamp_t(unsigned int, ((wdd->timeout * wdt->rate) / 256) - 1, > + RLR_MIN, RLR_MAX); > + > + /* enable write access */ > + reg_write(wdt->regs, IWDG_KR, KR_KEY_EWA); > + > + /* set prescaler & reload registers */ > + reg_write(wdt->regs, IWDG_PR, PR_256); /* prescaler fix to 256 */ > + reg_write(wdt->regs, IWDG_RLR, reload); > + reg_write(wdt->regs, IWDG_KR, KR_KEY_ENABLE); > + > + /* wait for the registers to be updated (max 100ms) */ > + ret = readl_relaxed_poll_timeout(wdt->regs + IWDG_SR, val, > + !(val & (FLAG_PVU | FLAG_RVU)), > + SLEEP_US, TIMEOUT_US); > + if (ret) { > + dev_err(wdd->parent, > + "Fail to set prescaler or reload registers\n"); > + return ret; > + } > + > + /* reload watchdog */ > + reg_write(wdt->regs, IWDG_KR, KR_KEY_RELOAD); > + > + return 0; > +} > + > +static int stm32_iwdg_ping(struct watchdog_device *wdd) > +{ > + struct stm32_iwdg *wdt = watchdog_get_drvdata(wdd); > + > + dev_dbg(wdd->parent, "%s\n", __func__); > + > + /* reload watchdog */ > + reg_write(wdt->regs, IWDG_KR, KR_KEY_RELOAD); > + > + return 0; > +} > + > +static int stm32_iwdg_set_timeout(struct watchdog_device *wdd, > + unsigned int timeout) > +{ > + dev_dbg(wdd->parent, "%s timeout: %d sec\n", __func__, timeout); > + > + wdd->timeout = timeout; > + > + if (watchdog_active(wdd)) > + return stm32_iwdg_start(wdd); > + > + return 0; > +} > + > +static const struct watchdog_info stm32_iwdg_info = { > + .options = WDIOF_SETTIMEOUT | > + WDIOF_MAGICCLOSE | > + WDIOF_KEEPALIVEPING, > + .identity = "STM32 Independent Watchdog", > +}; > + > +static struct watchdog_ops stm32_iwdg_ops = { > + .owner = THIS_MODULE, > + .start = stm32_iwdg_start, > + .ping = stm32_iwdg_ping, > + .set_timeout = stm32_iwdg_set_timeout, > +}; > + > +static int stm32_iwdg_probe(struct platform_device *pdev) > +{ > + struct watchdog_device *wdd; > + struct stm32_iwdg *wdt; > + struct resource *res; > + void __iomem *regs; > + struct clk *clk; > + int ret; > + > + /* This is the timer base. */ > + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); > + regs = devm_ioremap_resource(&pdev->dev, res); > + if (IS_ERR(regs)) { > + dev_err(&pdev->dev, "Could not get resource\n"); > + return PTR_ERR(regs); > + } > + > + clk = devm_clk_get(&pdev->dev, NULL); > + if (IS_ERR(clk)) { > + dev_err(&pdev->dev, "Unable to get clock\n"); > + return PTR_ERR(clk); > + } > + > + ret = clk_prepare_enable(clk); > + if (ret) { > + dev_err(&pdev->dev, "Unable to prepare clock %p\n", clk); > + return ret; > + } > + > + /* > + * Allocate our watchdog driver data, which has the > + * struct watchdog_device nested within it. > + */ > + wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL); > + if (!wdt) { > + ret = -ENOMEM; > + goto err; > + } > + > + /* Initialize struct stm32_iwdg. */ > + wdt->regs = regs; > + wdt->clk = clk; > + wdt->rate = clk_get_rate(clk); > + > + /* Initialize struct watchdog_device. */ > + wdd = &wdt->wdd; > + wdd->info = &stm32_iwdg_info; > + wdd->ops = &stm32_iwdg_ops; > + wdd->min_timeout = ((RLR_MIN + 1) * 256) / wdt->rate; > + wdd->max_hw_heartbeat_ms = ((RLR_MAX + 1) * 256 * 1000) / wdt->rate; > + wdd->parent = &pdev->dev; > + > + watchdog_set_drvdata(wdd, wdt); > + watchdog_set_nowayout(wdd, WATCHDOG_NOWAYOUT); > + > + ret = watchdog_init_timeout(wdd, 0, &pdev->dev); > + if (ret) > + dev_warn(&pdev->dev, > + "unable to set timeout value, using default\n"); > + > + ret = watchdog_register_device(wdd); > + if (ret) { > + dev_err(&pdev->dev, "failed to register watchdog device\n"); > + goto err; > + } > + > + platform_set_drvdata(pdev, wdt); > + > + return 0; > +err: > + clk_disable_unprepare(clk); > + > + return ret; > +} > + > +static int stm32_iwdg_remove(struct platform_device *pdev) > +{ > + struct stm32_iwdg *wdt = platform_get_drvdata(pdev); > + > + watchdog_unregister_device(&wdt->wdd); > + clk_disable_unprepare(wdt->clk); > + > + return 0; > +} > + > +static const struct of_device_id stm32_iwdg_of_match[] = { > + { .compatible = "st,stm32-iwdg" }, > + { /* end node */ } > +}; > +MODULE_DEVICE_TABLE(of, stm32_iwdg_of_match); > + > +static struct platform_driver stm32_iwdg_driver = { > + .probe = stm32_iwdg_probe, > + .remove = stm32_iwdg_remove, > + .driver = { > + .name = "iwdg", > + .of_match_table = stm32_iwdg_of_match, > + }, > +}; > +module_platform_driver(stm32_iwdg_driver); > + > +MODULE_AUTHOR("Yannick Fertre <yannick.fertre-qxv4g6HH51o@public.gmane.org>"); > +MODULE_DESCRIPTION("STMicroelectronics STM32 Independent Watchdog Driver"); > +MODULE_LICENSE("GPL v2"); > -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v5 3/5] ARM: dts: stm32: Add watchdog support for STM32F429 SoC 2017-04-06 12:19 [PATCH v5 0/5] STM32 Independent watchdog Yannick Fertre [not found] ` <1491481168-22213-1-git-send-email-yannick.fertre-qxv4g6HH51o@public.gmane.org> 2017-04-06 12:19 ` [PATCH v5 2/5] drivers: watchdog: Add STM32 IWDG driver Yannick Fertre @ 2017-04-06 12:19 ` Yannick Fertre 2017-04-06 12:19 ` [PATCH v5 4/5] ARM: dts: stm32: Add watchdog support for STM32F429 eval board Yannick Fertre ` (2 subsequent siblings) 5 siblings, 0 replies; 9+ messages in thread From: Yannick Fertre @ 2017-04-06 12:19 UTC (permalink / raw) To: Wim Van Sebroeck, Guenter Roeck, Rob Herring, Alexandre TORGUE, Benjamin Gaignard, Yannick Fertre, Maxime Coquelin Cc: devicetree, linux-watchdog, Philippe Cornu, linux-kernel, Gabriel FERNANDEZ, linux-arm-kernel Add watchdog into DT for stm32f429 family. Signed-off-by: Yannick FERTRE <yannick.fertre@st.com> --- arch/arm/boot/dts/stm32f429.dtsi | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/stm32f429.dtsi b/arch/arm/boot/dts/stm32f429.dtsi index 89327d6..d84dd44 100644 --- a/arch/arm/boot/dts/stm32f429.dtsi +++ b/arch/arm/boot/dts/stm32f429.dtsi @@ -64,7 +64,7 @@ clock-frequency = <32768>; }; - clk-lsi { + clk_lsi: clk-lsi { #clock-cells = <0>; compatible = "fixed-clock"; clock-frequency = <32000>; @@ -306,6 +306,13 @@ status = "disabled"; }; + iwdg: watchdog@40003000 { + compatible = "st,stm32-iwdg"; + reg = <0x40003000 0x400>; + clocks = <&clk_lsi>; + status = "disabled"; + }; + usart2: serial@40004400 { compatible = "st,stm32-usart", "st,stm32-uart"; reg = <0x40004400 0x400>; -- 1.9.1 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v5 4/5] ARM: dts: stm32: Add watchdog support for STM32F429 eval board 2017-04-06 12:19 [PATCH v5 0/5] STM32 Independent watchdog Yannick Fertre ` (2 preceding siblings ...) 2017-04-06 12:19 ` [PATCH v5 3/5] ARM: dts: stm32: Add watchdog support for STM32F429 SoC Yannick Fertre @ 2017-04-06 12:19 ` Yannick Fertre 2017-04-06 12:19 ` [PATCH v5 5/5] ARM: configs: stm32: Add watchdog support in STM32 defconfig Yannick Fertre 2017-06-12 10:07 ` [PATCH v5 0/5] STM32 Independent watchdog Alexandre Torgue 5 siblings, 0 replies; 9+ messages in thread From: Yannick Fertre @ 2017-04-06 12:19 UTC (permalink / raw) To: Wim Van Sebroeck, Guenter Roeck, Rob Herring, Alexandre TORGUE, Benjamin Gaignard, Yannick Fertre, Maxime Coquelin Cc: devicetree, linux-watchdog, Philippe Cornu, linux-kernel, Gabriel FERNANDEZ, linux-arm-kernel This patch adds watchdog support for STM32x9I-Eval board. Signed-off-by: Yannick Fertre <yannick.fertre@st.com> --- arch/arm/boot/dts/stm32429i-eval.dts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm/boot/dts/stm32429i-eval.dts b/arch/arm/boot/dts/stm32429i-eval.dts index 6e4b42a..ff29980 100644 --- a/arch/arm/boot/dts/stm32429i-eval.dts +++ b/arch/arm/boot/dts/stm32429i-eval.dts @@ -144,6 +144,11 @@ }; }; +&iwdg { + status = "okay"; + timeout-sec = <32>; +}; + &adc { pinctrl-names = "default"; pinctrl-0 = <&adc3_in8_pin>; -- 1.9.1 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v5 5/5] ARM: configs: stm32: Add watchdog support in STM32 defconfig 2017-04-06 12:19 [PATCH v5 0/5] STM32 Independent watchdog Yannick Fertre ` (3 preceding siblings ...) 2017-04-06 12:19 ` [PATCH v5 4/5] ARM: dts: stm32: Add watchdog support for STM32F429 eval board Yannick Fertre @ 2017-04-06 12:19 ` Yannick Fertre 2017-06-12 10:07 ` [PATCH v5 0/5] STM32 Independent watchdog Alexandre Torgue 5 siblings, 0 replies; 9+ messages in thread From: Yannick Fertre @ 2017-04-06 12:19 UTC (permalink / raw) To: Wim Van Sebroeck, Guenter Roeck, Rob Herring, Alexandre TORGUE, Benjamin Gaignard, Yannick Fertre, Maxime Coquelin Cc: devicetree, linux-watchdog, Philippe Cornu, linux-kernel, Gabriel FERNANDEZ, linux-arm-kernel This patch adds STM32 watchdog support in stm32_defconfig file Signed-off-by: Yannick Fertre <yannick.fertre@st.com> --- arch/arm/configs/stm32_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/configs/stm32_defconfig b/arch/arm/configs/stm32_defconfig index 29ac5a4..1fb901c 100644 --- a/arch/arm/configs/stm32_defconfig +++ b/arch/arm/configs/stm32_defconfig @@ -51,6 +51,7 @@ CONFIG_I2C=y CONFIG_I2C_CHARDEV=y CONFIG_I2C_STM32F4=y # CONFIG_HWMON is not set +CONFIG_WATCHDOG=y CONFIG_REGULATOR=y CONFIG_REGULATOR_FIXED_VOLTAGE=y # CONFIG_USB_SUPPORT is not set -- 1.9.1 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v5 0/5] STM32 Independent watchdog 2017-04-06 12:19 [PATCH v5 0/5] STM32 Independent watchdog Yannick Fertre ` (4 preceding siblings ...) 2017-04-06 12:19 ` [PATCH v5 5/5] ARM: configs: stm32: Add watchdog support in STM32 defconfig Yannick Fertre @ 2017-06-12 10:07 ` Alexandre Torgue 5 siblings, 0 replies; 9+ messages in thread From: Alexandre Torgue @ 2017-06-12 10:07 UTC (permalink / raw) To: Yannick Fertre, Wim Van Sebroeck, Guenter Roeck, Rob Herring, Benjamin Gaignard, Maxime Coquelin Cc: devicetree, linux-watchdog, Philippe Cornu, linux-kernel, Gabriel FERNANDEZ, linux-arm-kernel Hi Yannick On 04/06/2017 02:19 PM, Yannick Fertre wrote: > Version 5: > - Update bindings (add field timeout-sec) > - Update driver (rework start, rework settings & remove max_timeout) > > Version 4: > - Update bindings (iwdg > watchdog) > - Update typo > - Update commit header > - remove gerrit tags > - Update driver (remove unnecessary tests) a add watchdog_init_timeout > > Version 3: > - Update typo into bindings file > - Reorder node in devicetree (ordering by address) > - Remove unnecessary lines in commits > > Version 2: > - Add commit messages > > Version 1: > - Initial commit > > The purpose of this set of patches is to add a new watchdog driver for > stm32f429. > This driver was developed and tested on evaluation board stm32429i. > > Yannick Fertre (5): > dt-bindings: watchdog: Document STM32 IWDG bindings > drivers: watchdog: Add STM32 IWDG driver > ARM: dts: stm32: Add watchdog support for STM32F429 SoC > ARM: dts: stm32: Add watchdog support for STM32F429 eval board > ARM: configs: stm32: Add watchdog support in STM32 defconfig > > .../devicetree/bindings/watchdog/st,stm32-iwdg.txt | 19 ++ > arch/arm/boot/dts/stm32429i-eval.dts | 5 + > arch/arm/boot/dts/stm32f429.dtsi | 9 +- > arch/arm/configs/stm32_defconfig | 1 + > drivers/watchdog/Kconfig | 12 + > drivers/watchdog/Makefile | 1 + > drivers/watchdog/stm32_iwdg.c | 253 +++++++++++++++++++++ > 7 files changed, 299 insertions(+), 1 deletion(-) > create mode 100644 Documentation/devicetree/bindings/watchdog/st,stm32-iwdg.txt > create mode 100644 drivers/watchdog/stm32_iwdg.c > Patches 3&4 applied on stm32-dt-for-v4.13 Patch 5 applied on stm32-defconfig-for-v4.13 regards Alex ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2017-06-12 10:07 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-04-06 12:19 [PATCH v5 0/5] STM32 Independent watchdog Yannick Fertre
[not found] ` <1491481168-22213-1-git-send-email-yannick.fertre-qxv4g6HH51o@public.gmane.org>
2017-04-06 12:19 ` [PATCH v5 1/5] dt-bindings: watchdog: Document STM32 IWDG bindings Yannick Fertre
[not found] ` <1491481168-22213-2-git-send-email-yannick.fertre-qxv4g6HH51o@public.gmane.org>
2017-04-10 18:25 ` Rob Herring
2017-04-06 12:19 ` [PATCH v5 2/5] drivers: watchdog: Add STM32 IWDG driver Yannick Fertre
[not found] ` <1491481168-22213-3-git-send-email-yannick.fertre-qxv4g6HH51o@public.gmane.org>
2017-04-17 1:11 ` Guenter Roeck
2017-04-06 12:19 ` [PATCH v5 3/5] ARM: dts: stm32: Add watchdog support for STM32F429 SoC Yannick Fertre
2017-04-06 12:19 ` [PATCH v5 4/5] ARM: dts: stm32: Add watchdog support for STM32F429 eval board Yannick Fertre
2017-04-06 12:19 ` [PATCH v5 5/5] ARM: configs: stm32: Add watchdog support in STM32 defconfig Yannick Fertre
2017-06-12 10:07 ` [PATCH v5 0/5] STM32 Independent watchdog Alexandre Torgue
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).