From 9b255782b58d8dfb683018761925bca597f80895 Mon Sep 17 00:00:00 2001 From: Masaharu Hayakawa Date: Fri, 6 Jul 2018 10:55:08 +0200 Subject: dt-bindings: watchdog: renesas-wdt: Add support for the R8A77990 wdt Document support for the Watchdog Timer (WDT) Controller in the Renesas R-Car E3 (R8A77990) SoC. No driver update is needed. Signed-off-by: Masaharu Hayakawa Signed-off-by: Geert Uytterhoeven Reviewed-by: Guenter Roeck Acked-by: Rob Herring Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- Documentation/devicetree/bindings/watchdog/renesas-wdt.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/watchdog/renesas-wdt.txt b/Documentation/devicetree/bindings/watchdog/renesas-wdt.txt index f24d802b8056..5d47a262474c 100644 --- a/Documentation/devicetree/bindings/watchdog/renesas-wdt.txt +++ b/Documentation/devicetree/bindings/watchdog/renesas-wdt.txt @@ -16,6 +16,7 @@ Required properties: - "renesas,r8a7796-wdt" (R-Car M3-W) - "renesas,r8a77965-wdt" (R-Car M3-N) - "renesas,r8a77970-wdt" (R-Car V3M) + - "renesas,r8a77990-wdt" (R-Car E3) - "renesas,r8a77995-wdt" (R-Car D3) - "renesas,r7s72100-wdt" (RZ/A1) The generic compatible string must be: -- cgit v1.2.3 From e454652eb21535055337ae8908e164daed355ee7 Mon Sep 17 00:00:00 2001 From: Ludovic Barre Date: Mon, 25 Jun 2018 17:42:59 +0200 Subject: dt-bindings: watchdog: add stm32mp1 support This patch adds support of stm32mp1. stm32mp1 requires 2 clocks lsi and pclk. Signed-off-by: Ludovic Barre Reviewed-by: Rob Herring Reviewed-by: Guenter Roeck Linux@roeck-us.net> Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- .../devicetree/bindings/watchdog/st,stm32-iwdg.txt | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/watchdog/st,stm32-iwdg.txt b/Documentation/devicetree/bindings/watchdog/st,stm32-iwdg.txt index cc13b10a3f82..d8f4430b0a13 100644 --- a/Documentation/devicetree/bindings/watchdog/st,stm32-iwdg.txt +++ b/Documentation/devicetree/bindings/watchdog/st,stm32-iwdg.txt @@ -2,9 +2,15 @@ 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 +- compatible: Should be either: + - "st,stm32-iwdg" + - "st,stm32mp1-iwdg" +- reg: Physical base address and length of the registers set for the device +- clocks: Reference to the clock entry lsi. Additional pclk clock entry + is required only for st,stm32mp1-iwdg. +- clock-names: Name of the clocks used. + "lsi" for st,stm32-iwdg + "lsi", "pclk" for st,stm32mp1-iwdg Optional Properties: - timeout-sec: Watchdog timeout value in seconds. @@ -15,5 +21,6 @@ iwdg: watchdog@40003000 { compatible = "st,stm32-iwdg"; reg = <0x40003000 0x400>; clocks = <&clk_lsi>; + clock-names = "lsi"; timeout-sec = <32>; }; -- cgit v1.2.3 From c2cf466cca87e2072bd6616f751f4c385c2ab71e Mon Sep 17 00:00:00 2001 From: Ludovic Barre Date: Mon, 25 Jun 2018 17:43:00 +0200 Subject: watchdog: stm32: add pclk feature for stm32mp1 This patch adds compatible data to manage pclk clock by compatible. Adds stm32mp1 support which requires pclk clock. Signed-off-by: Ludovic Barre Acked-by: Alexandre TORGUE Reviewed-by: Guenter Roeck Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/stm32_iwdg.c | 116 +++++++++++++++++++++++++++--------------- 1 file changed, 74 insertions(+), 42 deletions(-) diff --git a/drivers/watchdog/stm32_iwdg.c b/drivers/watchdog/stm32_iwdg.c index c97ad5619cb0..e00e3b3526c6 100644 --- a/drivers/watchdog/stm32_iwdg.c +++ b/drivers/watchdog/stm32_iwdg.c @@ -11,12 +11,13 @@ #include #include -#include -#include #include #include #include +#include +#include #include +#include #include #include @@ -54,11 +55,15 @@ #define TIMEOUT_US 100000 #define SLEEP_US 1000 +#define HAS_PCLK true + struct stm32_iwdg { struct watchdog_device wdd; void __iomem *regs; - struct clk *clk; + struct clk *clk_lsi; + struct clk *clk_pclk; unsigned int rate; + bool has_pclk; }; static inline u32 reg_read(void __iomem *base, u32 reg) @@ -133,6 +138,44 @@ static int stm32_iwdg_set_timeout(struct watchdog_device *wdd, return 0; } +static int stm32_iwdg_clk_init(struct platform_device *pdev, + struct stm32_iwdg *wdt) +{ + u32 ret; + + wdt->clk_lsi = devm_clk_get(&pdev->dev, "lsi"); + if (IS_ERR(wdt->clk_lsi)) { + dev_err(&pdev->dev, "Unable to get lsi clock\n"); + return PTR_ERR(wdt->clk_lsi); + } + + /* optional peripheral clock */ + if (wdt->has_pclk) { + wdt->clk_pclk = devm_clk_get(&pdev->dev, "pclk"); + if (IS_ERR(wdt->clk_pclk)) { + dev_err(&pdev->dev, "Unable to get pclk clock\n"); + return PTR_ERR(wdt->clk_pclk); + } + + ret = clk_prepare_enable(wdt->clk_pclk); + if (ret) { + dev_err(&pdev->dev, "Unable to prepare pclk clock\n"); + return ret; + } + } + + ret = clk_prepare_enable(wdt->clk_lsi); + if (ret) { + dev_err(&pdev->dev, "Unable to prepare lsi clock\n"); + clk_disable_unprepare(wdt->clk_pclk); + return ret; + } + + wdt->rate = clk_get_rate(wdt->clk_lsi); + + return 0; +} + static const struct watchdog_info stm32_iwdg_info = { .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | @@ -147,49 +190,42 @@ static const struct watchdog_ops stm32_iwdg_ops = { .set_timeout = stm32_iwdg_set_timeout, }; +static const struct of_device_id stm32_iwdg_of_match[] = { + { .compatible = "st,stm32-iwdg", .data = (void *)!HAS_PCLK }, + { .compatible = "st,stm32mp1-iwdg", .data = (void *)HAS_PCLK }, + { /* end node */ } +}; +MODULE_DEVICE_TABLE(of, stm32_iwdg_of_match); + static int stm32_iwdg_probe(struct platform_device *pdev) { struct watchdog_device *wdd; + const struct of_device_id *match; struct stm32_iwdg *wdt; struct resource *res; - void __iomem *regs; - struct clk *clk; int ret; + match = of_match_device(stm32_iwdg_of_match, &pdev->dev); + if (!match) + return -ENODEV; + + wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL); + if (!wdt) + return -ENOMEM; + + wdt->has_pclk = match->data; + /* This is the timer base. */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - regs = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(regs)) { + wdt->regs = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(wdt->regs)) { dev_err(&pdev->dev, "Could not get resource\n"); - return PTR_ERR(regs); + return PTR_ERR(wdt->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); + ret = stm32_iwdg_clk_init(pdev, wdt); + if (ret) 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; @@ -217,7 +253,8 @@ static int stm32_iwdg_probe(struct platform_device *pdev) return 0; err: - clk_disable_unprepare(clk); + clk_disable_unprepare(wdt->clk_lsi); + clk_disable_unprepare(wdt->clk_pclk); return ret; } @@ -227,23 +264,18 @@ 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); + clk_disable_unprepare(wdt->clk_lsi); + clk_disable_unprepare(wdt->clk_pclk); 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, + .of_match_table = of_match_ptr(stm32_iwdg_of_match), }, }; module_platform_driver(stm32_iwdg_driver); -- cgit v1.2.3 From 2421cfd55a80af3272c261a28864cc5c3c67155c Mon Sep 17 00:00:00 2001 From: Maxim Kochetkov Date: Thu, 7 Jun 2018 16:54:37 +0300 Subject: watchdog: orion_wdt: Mark watchdog as active when running at probe If the watchdog is fully enabled and running at probe, mark it as such so the watchdog core can handle it until the watchdog device is opened. Signed-off-by: Maxim Kochetkov Reviewed-by: Guenter Roeck [groeck: Updated subject and description] Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/orion_wdt.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/watchdog/orion_wdt.c b/drivers/watchdog/orion_wdt.c index ea676d233e1e..9db3b09f7568 100644 --- a/drivers/watchdog/orion_wdt.c +++ b/drivers/watchdog/orion_wdt.c @@ -581,6 +581,8 @@ static int orion_wdt_probe(struct platform_device *pdev) */ if (!orion_wdt_enabled(&dev->wdt)) orion_wdt_stop(&dev->wdt); + else + set_bit(WDOG_HW_RUNNING, &dev->wdt.status); /* Request the IRQ only after the watchdog is disabled */ irq = platform_get_irq(pdev, 0); -- cgit v1.2.3 From fb18d30f86245e17d3b450abd6c7b73423781091 Mon Sep 17 00:00:00 2001 From: Ray Jui Date: Mon, 28 May 2018 11:01:32 -0700 Subject: dt-bindings: watchdog: Consolidate SP805 binding docs Consolidate two SP805 binding documents "arm,sp805.txt" and "sp805-wdt.txt" into "arm,sp805.txt" that matches the naming of the desired compatible string to be used Signed-off-by: Ray Jui Reviewed-by: Rob Herring Reviewed-by: Guenter Roeck Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- .../devicetree/bindings/watchdog/arm,sp805.txt | 27 ++++++++++++++----- .../devicetree/bindings/watchdog/sp805-wdt.txt | 31 ---------------------- 2 files changed, 20 insertions(+), 38 deletions(-) delete mode 100644 Documentation/devicetree/bindings/watchdog/sp805-wdt.txt diff --git a/Documentation/devicetree/bindings/watchdog/arm,sp805.txt b/Documentation/devicetree/bindings/watchdog/arm,sp805.txt index ca99d64e6211..0fa3629dbe70 100644 --- a/Documentation/devicetree/bindings/watchdog/arm,sp805.txt +++ b/Documentation/devicetree/bindings/watchdog/arm,sp805.txt @@ -1,17 +1,30 @@ ARM AMBA Primecell SP805 Watchdog +SP805 WDT is a ARM Primecell Peripheral and has a standard-id register that +can be used to identify the peripheral type, vendor, and revision. +This value can be used for driver matching. + +As SP805 WDT is a primecell IP, it follows the base bindings specified in +'arm/primecell.txt' + Required properties: -- compatible: Should be "arm,sp805" & "arm,primecell" -- reg: Should contain location and length for watchdog timer register. -- interrupts: Should contain the list of watchdog timer interrupts. -- clocks: clocks driving the watchdog timer hardware. This list should be 2 - clocks. With 2 clocks, the order is wdogclk clock, apb_pclk. +- compatible: Should be "arm,sp805" & "arm,primecell" +- reg: Should contain location and length for watchdog timer register +- clocks: Clocks driving the watchdog timer hardware. This list should be + 2 clocks. With 2 clocks, the order is wdog_clk, apb_pclk + wdog_clk can be equal to or be a sub-multiple of the apb_pclk + frequency +- clock-names: Shall be "wdog_clk" for first clock and "apb_pclk" for the + second one + +Optional properties: +- interrupts: Should specify WDT interrupt number Example: watchdog@66090000 { compatible = "arm,sp805", "arm,primecell"; reg = <0x66090000 0x1000>; interrupts = ; - clocks = <&apb_pclk>,<&apb_pclk>; - clock-names = "wdogclk", "apb_pclk"; + clocks = <&wdt_clk>, <&apb_pclk>; + clock-names = "wdog_clk", "apb_pclk"; }; diff --git a/Documentation/devicetree/bindings/watchdog/sp805-wdt.txt b/Documentation/devicetree/bindings/watchdog/sp805-wdt.txt deleted file mode 100644 index edc4f0ea54a3..000000000000 --- a/Documentation/devicetree/bindings/watchdog/sp805-wdt.txt +++ /dev/null @@ -1,31 +0,0 @@ -* ARM SP805 Watchdog Timer (WDT) Controller - -SP805 WDT is a ARM Primecell Peripheral and has a standard-id register that -can be used to identify the peripheral type, vendor, and revision. -This value can be used for driver matching. - -As SP805 WDT is a primecell IP, it follows the base bindings specified in -'arm/primecell.txt' - -Required properties: -- compatible : Should be "arm,sp805-wdt", "arm,primecell" -- reg : Base address and size of the watchdog timer registers. -- clocks : From common clock binding. - First clock is PCLK and the second is WDOGCLK. - WDOGCLK can be equal to or be a sub-multiple of the PCLK frequency. -- clock-names : From common clock binding. - Shall be "apb_pclk" for first clock and "wdog_clk" for the - second one. - -Optional properties: -- interrupts : Should specify WDT interrupt number. - -Examples: - - cluster1_core0_watchdog: wdt@c000000 { - compatible = "arm,sp805-wdt", "arm,primecell"; - reg = <0x0 0xc000000 0x0 0x1000>; - clocks = <&clockgen 4 3>, <&clockgen 4 3>; - clock-names = "apb_pclk", "wdog_clk"; - }; - -- cgit v1.2.3 From 42bf5c4442badc524a92d66b0d881ea82396dfab Mon Sep 17 00:00:00 2001 From: Ray Jui Date: Mon, 28 May 2018 11:01:33 -0700 Subject: dt-bindings: watchdog: Add optional 'timeout-sec' property for sp805 Update the SP805 binding document to add optional 'timeout-sec' devicetree property Signed-off-by: Ray Jui Reviewed-by: Rob Herring Reviewed-by: Guenter Roeck Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- Documentation/devicetree/bindings/watchdog/arm,sp805.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/watchdog/arm,sp805.txt b/Documentation/devicetree/bindings/watchdog/arm,sp805.txt index 0fa3629dbe70..bee6f1f0e41b 100644 --- a/Documentation/devicetree/bindings/watchdog/arm,sp805.txt +++ b/Documentation/devicetree/bindings/watchdog/arm,sp805.txt @@ -19,6 +19,8 @@ Required properties: Optional properties: - interrupts: Should specify WDT interrupt number +- timeout-sec: Should specify default WDT timeout in seconds. If unset, the + default timeout is determined by the driver Example: watchdog@66090000 { -- cgit v1.2.3 From b800885888406f33edfec0eb1cb752292f23de83 Mon Sep 17 00:00:00 2001 From: Ray Jui Date: Mon, 28 May 2018 11:01:34 -0700 Subject: watchdog: sp805: add 'timeout-sec' DT property support Add support for optional devicetree property 'timeout-sec'. 'timeout-sec' is used in the driver if specified in devicetree. Otherwise, fall back to driver default, i.e., 60 seconds Signed-off-by: Ray Jui Reviewed-by: Scott Branden Reviewed-by: Guenter Roeck Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/sp805_wdt.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/watchdog/sp805_wdt.c b/drivers/watchdog/sp805_wdt.c index 9849db0743a7..b240195597c1 100644 --- a/drivers/watchdog/sp805_wdt.c +++ b/drivers/watchdog/sp805_wdt.c @@ -244,7 +244,14 @@ sp805_wdt_probe(struct amba_device *adev, const struct amba_id *id) watchdog_set_nowayout(&wdt->wdd, nowayout); watchdog_set_drvdata(&wdt->wdd, wdt); watchdog_set_restart_priority(&wdt->wdd, 128); - wdt_setload(&wdt->wdd, DEFAULT_TIMEOUT); + + /* + * If 'timeout-sec' devicetree property is specified, use that. + * Otherwise, use DEFAULT_TIMEOUT + */ + wdt->wdd.timeout = DEFAULT_TIMEOUT; + watchdog_init_timeout(&wdt->wdd, 0, &adev->dev); + wdt_setload(&wdt->wdd, wdt->wdd.timeout); ret = watchdog_register_device(&wdt->wdd); if (ret) { -- cgit v1.2.3 From fa5072ed8f530df5a04511721d19b61a6cf8c96c Mon Sep 17 00:00:00 2001 From: Ray Jui Date: Mon, 28 May 2018 11:01:35 -0700 Subject: watchdog: sp805: set WDOG_HW_RUNNING when appropriate If the watchdog hardware is already enabled during the boot process, when the Linux watchdog driver loads, it should reset the watchdog and tell the watchdog framework. As a result, ping can be generated from the watchdog framework, until the userspace watchdog daemon takes over control Signed-off-by: Ray Jui Reviewed-by: Vladimir Olovyannikov Reviewed-by: Scott Branden Reviewed-by: Guenter Roeck Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/sp805_wdt.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/drivers/watchdog/sp805_wdt.c b/drivers/watchdog/sp805_wdt.c index b240195597c1..b202138b7ecb 100644 --- a/drivers/watchdog/sp805_wdt.c +++ b/drivers/watchdog/sp805_wdt.c @@ -42,6 +42,7 @@ /* control register masks */ #define INT_ENABLE (1 << 0) #define RESET_ENABLE (1 << 1) + #define ENABLE_MASK (INT_ENABLE | RESET_ENABLE) #define WDTINTCLR 0x00C #define WDTRIS 0x010 #define WDTMIS 0x014 @@ -74,6 +75,15 @@ module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Set to 1 to keep watchdog running after device release"); +/* returns true if wdt is running; otherwise returns false */ +static bool wdt_is_running(struct watchdog_device *wdd) +{ + struct sp805_wdt *wdt = watchdog_get_drvdata(wdd); + u32 wdtcontrol = readl_relaxed(wdt->base + WDTCONTROL); + + return (wdtcontrol & ENABLE_MASK) == ENABLE_MASK; +} + /* This routine finds load value that will reset system in required timout */ static int wdt_setload(struct watchdog_device *wdd, unsigned int timeout) { @@ -253,6 +263,15 @@ sp805_wdt_probe(struct amba_device *adev, const struct amba_id *id) watchdog_init_timeout(&wdt->wdd, 0, &adev->dev); wdt_setload(&wdt->wdd, wdt->wdd.timeout); + /* + * If HW is already running, enable/reset the wdt and set the running + * bit to tell the wdt subsystem + */ + if (wdt_is_running(&wdt->wdd)) { + wdt_enable(&wdt->wdd); + set_bit(WDOG_HW_RUNNING, &wdt->wdd.status); + } + ret = watchdog_register_device(&wdt->wdd); if (ret) { dev_err(&adev->dev, "watchdog_register_device() failed: %d\n", -- cgit v1.2.3 From cd6100fcebaf9ef5fc0f0f1c9f2afada35a71a91 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Tue, 10 Jul 2018 11:21:22 -0300 Subject: watchdog: imx2_wdt: Switch to SPDX identifier Adopt the SPDX license identifier headers to ease license compliance management. Signed-off-by: Fabio Estevam Reviewed-by: Guenter Roeck Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/imx2_wdt.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/watchdog/imx2_wdt.c b/drivers/watchdog/imx2_wdt.c index f07850d2c977..2b52514eaa86 100644 --- a/drivers/watchdog/imx2_wdt.c +++ b/drivers/watchdog/imx2_wdt.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Watchdog driver for IMX2 and later processors * @@ -7,10 +8,6 @@ * some parts adapted by similar drivers from Darius Augulis and Vladimir * Zapolskiy, additional improvements by Wim Van Sebroeck. * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * * NOTE: MX1 has a slightly different Watchdog than MX2 and later: * * MX1: MX2+: -- cgit v1.2.3 From 2671a3a31b7d6a933af240e574d0e6cfd2d13364 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Tue, 10 Jul 2018 11:21:23 -0300 Subject: watchdog: stmp3xxx: Switch to SPDX identifier Adopt the SPDX license identifier headers to ease license compliance management. Signed-off-by: Fabio Estevam Reviewed-by: Guenter Roeck Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/stmp3xxx_rtc_wdt.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/watchdog/stmp3xxx_rtc_wdt.c b/drivers/watchdog/stmp3xxx_rtc_wdt.c index d8b11eb269ad..994c54cc68e9 100644 --- a/drivers/watchdog/stmp3xxx_rtc_wdt.c +++ b/drivers/watchdog/stmp3xxx_rtc_wdt.c @@ -1,13 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Watchdog driver for the RTC based watchdog in STMP3xxx and i.MX23/28 * * Author: Wolfram Sang * * Copyright (C) 2011-12 Wolfram Sang, Pengutronix - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. */ #include #include -- cgit v1.2.3 From 28e65edd73f963e7a0838bf3a62106be55dcb925 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Wed, 11 Jul 2018 13:17:55 +0000 Subject: watchdog: sprd_wdt: Remove redundant dev_err call in sprd_wdt_probe() There is a error message within devm_ioremap_resource already, so remove the dev_err call to avoid redundant error message. Signed-off-by: Wei Yongjun Reviewed-by: Guenter Roeck Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/sprd_wdt.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/watchdog/sprd_wdt.c b/drivers/watchdog/sprd_wdt.c index b4d484a42b70..ff9397d9638a 100644 --- a/drivers/watchdog/sprd_wdt.c +++ b/drivers/watchdog/sprd_wdt.c @@ -279,10 +279,8 @@ static int sprd_wdt_probe(struct platform_device *pdev) wdt_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); wdt->base = devm_ioremap_resource(&pdev->dev, wdt_res); - if (IS_ERR(wdt->base)) { - dev_err(&pdev->dev, "failed to map memory resource\n"); + if (IS_ERR(wdt->base)) return PTR_ERR(wdt->base); - } wdt->enable = devm_clk_get(&pdev->dev, "enable"); if (IS_ERR(wdt->enable)) { -- cgit v1.2.3 From 81ceed41d0c2b2c9300de7bc30c1451680257f52 Mon Sep 17 00:00:00 2001 From: Johannes Thumshirn Date: Mon, 16 Jul 2018 09:25:10 +0200 Subject: watchdog: add driver for the MEN 16z069 IP-Core Add a driver for the MEN 16z069 Watchdog and Reset Controller IP-Core. Signed-off-by: Johannes Thumshirn Reviewed-by: Michael Moese Reviewed-by: Guenter Roeck Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- MAINTAINERS | 6 ++ drivers/watchdog/Kconfig | 10 +++ drivers/watchdog/Makefile | 1 + drivers/watchdog/menz69_wdt.c | 170 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 187 insertions(+) create mode 100644 drivers/watchdog/menz69_wdt.c diff --git a/MAINTAINERS b/MAINTAINERS index 192d7f73fd01..0b1015de1462 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -9299,6 +9299,12 @@ F: drivers/leds/leds-menf21bmc.c F: drivers/hwmon/menf21bmc_hwmon.c F: Documentation/hwmon/menf21bmc +MEN Z069 WATCHDOG DRIVER +M: Johannes Thumshirn +L: linux-watchdog@vger.kernel.org +S: Maintained +F: drivers/watchdog/menz069_wdt.c + MESON AO CEC DRIVER FOR AMLOGIC SOCS M: Neil Armstrong L: linux-media@lists.freedesktop.org diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 9af07fd92763..df55d65bbb1c 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -161,6 +161,16 @@ config MENF21BMC_WATCHDOG This driver can also be built as a module. If so the module will be called menf21bmc_wdt. +config MENZ069_WATCHDOG + tristate "MEN 16Z069 Watchdog" + depends on MCB || COMPILE_TEST + select WATCHDOG_CORE + help + Say Y here to include support for the MEN 16Z069 Watchdog. + + This driver can also be built as a module. If so the module + will be called menz069_wdt. + config TANGOX_WATCHDOG tristate "Sigma Designs SMP86xx/SMP87xx watchdog" select WATCHDOG_CORE diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 1d3c6b094fe5..bf92e7bf9ce0 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -215,4 +215,5 @@ obj-$(CONFIG_MAX77620_WATCHDOG) += max77620_wdt.o obj-$(CONFIG_ZIIRAVE_WATCHDOG) += ziirave_wdt.o obj-$(CONFIG_SOFT_WATCHDOG) += softdog.o obj-$(CONFIG_MENF21BMC_WATCHDOG) += menf21bmc_wdt.o +obj-$(CONFIG_MENZ069_WATCHDOG) += menz69_wdt.o obj-$(CONFIG_RAVE_SP_WATCHDOG) += rave-sp-wdt.o diff --git a/drivers/watchdog/menz69_wdt.c b/drivers/watchdog/menz69_wdt.c new file mode 100644 index 000000000000..ed18238c5407 --- /dev/null +++ b/drivers/watchdog/menz69_wdt.c @@ -0,0 +1,170 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Watchdog driver for the MEN z069 IP-Core + * + * Copyright (C) 2018 Johannes Thumshirn + */ +#include +#include +#include +#include +#include + +struct men_z069_drv { + struct watchdog_device wdt; + void __iomem *base; + struct resource *mem; +}; + +#define MEN_Z069_WTR 0x10 +#define MEN_Z069_WTR_WDEN BIT(15) +#define MEN_Z069_WTR_WDET_MASK 0x7fff +#define MEN_Z069_WVR 0x14 + +#define MEN_Z069_TIMER_FREQ 500 /* 500 Hz */ +#define MEN_Z069_WDT_COUNTER_MIN 1 +#define MEN_Z069_WDT_COUNTER_MAX 0x7fff +#define MEN_Z069_DEFAULT_TIMEOUT 30 + +static bool nowayout = WATCHDOG_NOWAYOUT; +module_param(nowayout, bool, 0); +MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" + __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + +static int men_z069_wdt_start(struct watchdog_device *wdt) +{ + struct men_z069_drv *drv = watchdog_get_drvdata(wdt); + u16 val; + + val = readw(drv->base + MEN_Z069_WTR); + val |= MEN_Z069_WTR_WDEN; + writew(val, drv->base + MEN_Z069_WTR); + + return 0; +} + +static int men_z069_wdt_stop(struct watchdog_device *wdt) +{ + struct men_z069_drv *drv = watchdog_get_drvdata(wdt); + u16 val; + + val = readw(drv->base + MEN_Z069_WTR); + val &= ~MEN_Z069_WTR_WDEN; + writew(val, drv->base + MEN_Z069_WTR); + + return 0; +} + +static int men_z069_wdt_ping(struct watchdog_device *wdt) +{ + struct men_z069_drv *drv = watchdog_get_drvdata(wdt); + u16 val; + + /* The watchdog trigger value toggles between 0x5555 and 0xaaaa */ + val = readw(drv->base + MEN_Z069_WVR); + val ^= 0xffff; + writew(val, drv->base + MEN_Z069_WVR); + + return 0; +} + +static int men_z069_wdt_set_timeout(struct watchdog_device *wdt, + unsigned int timeout) +{ + struct men_z069_drv *drv = watchdog_get_drvdata(wdt); + u16 reg, val, ena; + + wdt->timeout = timeout; + val = timeout * MEN_Z069_TIMER_FREQ; + + reg = readw(drv->base + MEN_Z069_WVR); + ena = reg & MEN_Z069_WTR_WDEN; + reg = ena | val; + writew(reg, drv->base + MEN_Z069_WTR); + + return 0; +} + +static const struct watchdog_info men_z069_info = { + .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, + .identity = "MEN z069 Watchdog", +}; + +static const struct watchdog_ops men_z069_ops = { + .owner = THIS_MODULE, + .start = men_z069_wdt_start, + .stop = men_z069_wdt_stop, + .ping = men_z069_wdt_ping, + .set_timeout = men_z069_wdt_set_timeout, +}; + +static struct watchdog_device men_z069_wdt = { + .info = &men_z069_info, + .ops = &men_z069_ops, + .timeout = MEN_Z069_DEFAULT_TIMEOUT, + .min_timeout = 1, + .max_timeout = MEN_Z069_WDT_COUNTER_MAX / MEN_Z069_TIMER_FREQ, +}; + +static int men_z069_probe(struct mcb_device *dev, + const struct mcb_device_id *id) +{ + struct men_z069_drv *drv; + struct resource *mem; + + drv = devm_kzalloc(&dev->dev, sizeof(struct men_z069_drv), GFP_KERNEL); + if (!drv) + return -ENOMEM; + + mem = mcb_request_mem(dev, "z069-wdt"); + if (IS_ERR(mem)) + return PTR_ERR(mem); + + drv->base = devm_ioremap(&dev->dev, mem->start, resource_size(mem)); + if (drv->base == NULL) + goto release_mem; + + drv->mem = mem; + + drv->wdt = men_z069_wdt; + watchdog_init_timeout(&drv->wdt, 0, &dev->dev); + watchdog_set_nowayout(&drv->wdt, nowayout); + watchdog_set_drvdata(&drv->wdt, drv); + drv->wdt.parent = &dev->dev; + mcb_set_drvdata(dev, drv); + + return watchdog_register_device(&men_z069_wdt); + +release_mem: + mcb_release_mem(mem); + return -ENOMEM; +} + +static void men_z069_remove(struct mcb_device *dev) +{ + struct men_z069_drv *drv = mcb_get_drvdata(dev); + + watchdog_unregister_device(&drv->wdt); + mcb_release_mem(drv->mem); +} + +static const struct mcb_device_id men_z069_ids[] = { + { .device = 0x45 }, + { } +}; +MODULE_DEVICE_TABLE(mcb, men_z069_ids); + +static struct mcb_driver men_z069_driver = { + .driver = { + .name = "z069-wdt", + .owner = THIS_MODULE, + }, + .probe = men_z069_probe, + .remove = men_z069_remove, + .id_table = men_z069_ids, +}; +module_mcb_driver(men_z069_driver); + +MODULE_AUTHOR("Johannes Thumshirn "); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("mcb:16z069"); -- cgit v1.2.3 From dc0e4a3bb7dcd087e9d338acbe6ef3f3667b278b Mon Sep 17 00:00:00 2001 From: Srinath Mannam Date: Thu, 26 Jul 2018 10:28:42 +0530 Subject: watchdog: sp805: Add clock-frequency property Use clock-frequency property given in _DSD object of ACPI device to calculate Watchdog rate as binding clock devices are not available as device tree. Note: There is no formal review process for _DSD properties Signed-off-by: Srinath Mannam Reviewed-by: Guenter Roeck Reviewed-by: Ray Jui Reviewed-by: Scott Branden Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/sp805_wdt.c | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/drivers/watchdog/sp805_wdt.c b/drivers/watchdog/sp805_wdt.c index b202138b7ecb..072986d461b7 100644 --- a/drivers/watchdog/sp805_wdt.c +++ b/drivers/watchdog/sp805_wdt.c @@ -11,6 +11,7 @@ * warranty of any kind, whether express or implied. */ +#include #include #include #include @@ -22,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -66,6 +68,7 @@ struct sp805_wdt { spinlock_t lock; void __iomem *base; struct clk *clk; + u64 rate; struct amba_device *adev; unsigned int load_val; }; @@ -90,7 +93,7 @@ static int wdt_setload(struct watchdog_device *wdd, unsigned int timeout) struct sp805_wdt *wdt = watchdog_get_drvdata(wdd); u64 load, rate; - rate = clk_get_rate(wdt->clk); + rate = wdt->rate; /* * sp805 runs counter with given value twice, after the end of first @@ -116,9 +119,7 @@ static int wdt_setload(struct watchdog_device *wdd, unsigned int timeout) static unsigned int wdt_timeleft(struct watchdog_device *wdd) { struct sp805_wdt *wdt = watchdog_get_drvdata(wdd); - u64 load, rate; - - rate = clk_get_rate(wdt->clk); + u64 load; spin_lock(&wdt->lock); load = readl_relaxed(wdt->base + WDTVALUE); @@ -128,7 +129,7 @@ static unsigned int wdt_timeleft(struct watchdog_device *wdd) load += wdt->load_val + 1; spin_unlock(&wdt->lock); - return div_u64(load, rate); + return div_u64(load, wdt->rate); } static int @@ -238,11 +239,25 @@ sp805_wdt_probe(struct amba_device *adev, const struct amba_id *id) if (IS_ERR(wdt->base)) return PTR_ERR(wdt->base); - wdt->clk = devm_clk_get(&adev->dev, NULL); - if (IS_ERR(wdt->clk)) { - dev_warn(&adev->dev, "Clock not found\n"); - ret = PTR_ERR(wdt->clk); - goto err; + if (adev->dev.of_node) { + wdt->clk = devm_clk_get(&adev->dev, NULL); + if (IS_ERR(wdt->clk)) { + dev_err(&adev->dev, "Clock not found\n"); + return PTR_ERR(wdt->clk); + } + wdt->rate = clk_get_rate(wdt->clk); + } else if (has_acpi_companion(&adev->dev)) { + /* + * When Driver probe with ACPI device, clock devices + * are not available, so watchdog rate get from + * clock-frequency property given in _DSD object. + */ + device_property_read_u64(&adev->dev, "clock-frequency", + &wdt->rate); + if (!wdt->rate) { + dev_err(&adev->dev, "no clock-frequency property\n"); + return -ENODEV; + } } wdt->adev = adev; -- cgit v1.2.3 From 12aea518a202bc7c947553840f1d93f8129b41b2 Mon Sep 17 00:00:00 2001 From: Johannes Thumshirn Date: Fri, 3 Aug 2018 18:35:17 +0200 Subject: watchdog: fix dependencies of menz69_wdt.o Currently menz69_wdt.ko has a dependency on MCB or COMPILE_TEST. But it actually needs symbols exported by MCB so the || COMPILE_TEST is wrong. Signed-off-by: Johannes Thumshirn Reported-by: Randy Dunlap Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index df55d65bbb1c..5ea8909a41f9 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -163,7 +163,7 @@ config MENF21BMC_WATCHDOG config MENZ069_WATCHDOG tristate "MEN 16Z069 Watchdog" - depends on MCB || COMPILE_TEST + depends on MCB select WATCHDOG_CORE help Say Y here to include support for the MEN 16Z069 Watchdog. -- cgit v1.2.3