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(-) (limited to 'drivers') 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(+) (limited to 'drivers') 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 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(-) (limited to 'drivers') 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(+) (limited to 'drivers') 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(-) (limited to 'drivers') 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(-) (limited to 'drivers') 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(-) (limited to 'drivers') 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 --- drivers/watchdog/Kconfig | 10 +++ drivers/watchdog/Makefile | 1 + drivers/watchdog/menz69_wdt.c | 170 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 181 insertions(+) create mode 100644 drivers/watchdog/menz69_wdt.c (limited to 'drivers') 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(-) (limited to 'drivers') 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(-) (limited to 'drivers') 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