From 4957a7d5333d70f78b6d916f08d901da764c8a9c Mon Sep 17 00:00:00 2001 From: Tom Rix Date: Fri, 15 Jan 2021 07:32:37 -0800 Subject: watchdog: it8712f_wdt: remove definition of DEBUG Defining DEBUG should only be done in development. So remove DEBUG. Signed-off-by: Tom Rix Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20210115153237.131357-1-trix@redhat.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/it8712f_wdt.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/watchdog') diff --git a/drivers/watchdog/it8712f_wdt.c b/drivers/watchdog/it8712f_wdt.c index 9b89d2f09568..3ce6a58bd81e 100644 --- a/drivers/watchdog/it8712f_wdt.c +++ b/drivers/watchdog/it8712f_wdt.c @@ -31,7 +31,6 @@ #include #include -#define DEBUG #define NAME "it8712f_wdt" MODULE_AUTHOR("Jorge Boncompte - DTI2 "); -- cgit v1.2.3 From fa0f8d51e90d2202be9f4f02b9a95347389a5959 Mon Sep 17 00:00:00 2001 From: Vijayakannan Ayyathurai Date: Thu, 17 Dec 2020 02:32:48 +0800 Subject: watchdog: Add watchdog driver for Intel Keembay Soc Intel Keembay Soc requires watchdog timer support. Add watchdog driver to enable this. Acked-by: Mark Gross Acked-by: Andy Shevchenko Signed-off-by: Vijayakannan Ayyathurai Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/26d74f46ce74488424371dd3e16aa38508fa6c2e.1608141131.git.vijayakannan.ayyathurai@intel.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/Kconfig | 13 ++ drivers/watchdog/Makefile | 1 + drivers/watchdog/keembay_wdt.c | 286 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 300 insertions(+) create mode 100644 drivers/watchdog/keembay_wdt.c (limited to 'drivers/watchdog') diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 7ff941e71b79..e95827790877 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -2155,4 +2155,17 @@ config USBPCWATCHDOG Most people will say N. +config KEEMBAY_WATCHDOG + tristate "Intel Keem Bay SoC non-secure watchdog" + depends on ARCH_KEEMBAY || (ARM64 && COMPILE_TEST) + select WATCHDOG_CORE + help + This option enable support for an In-secure watchdog timer driver for + Intel Keem Bay SoC. This WDT has a 32 bit timer and decrements in every + count unit. An interrupt will be triggered, when the count crosses + the thershold configured in the register. + + To compile this driver as a module, choose M here: the + module will be called keembay_wdt. + endif # WATCHDOG diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 5c74ee19d441..aeaa74182096 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -146,6 +146,7 @@ obj-$(CONFIG_INTEL_MEI_WDT) += mei_wdt.o obj-$(CONFIG_NI903X_WDT) += ni903x_wdt.o obj-$(CONFIG_NIC7018_WDT) += nic7018_wdt.o obj-$(CONFIG_MLX_WDT) += mlx_wdt.o +obj-$(CONFIG_KEEMBAY_WATCHDOG) += keembay_wdt.o # M68K Architecture obj-$(CONFIG_M54xx_WATCHDOG) += m54xx_wdt.o diff --git a/drivers/watchdog/keembay_wdt.c b/drivers/watchdog/keembay_wdt.c new file mode 100644 index 000000000000..547d3fea33ff --- /dev/null +++ b/drivers/watchdog/keembay_wdt.c @@ -0,0 +1,286 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Watchdog driver for Intel Keem Bay non-secure watchdog. + * + * Copyright (C) 2020 Intel Corporation + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Non-secure watchdog register offsets */ +#define TIM_WATCHDOG 0x0 +#define TIM_WATCHDOG_INT_THRES 0x4 +#define TIM_WDOG_EN 0x8 +#define TIM_SAFE 0xc + +#define WDT_ISR_MASK GENMASK(9, 8) +#define WDT_ISR_CLEAR 0x8200ff18 +#define WDT_UNLOCK 0xf1d0dead +#define WDT_LOAD_MAX U32_MAX +#define WDT_LOAD_MIN 1 +#define WDT_TIMEOUT 5 + +static unsigned int timeout = WDT_TIMEOUT; +module_param(timeout, int, 0); +MODULE_PARM_DESC(timeout, "Watchdog timeout period in seconds (default = " + __MODULE_STRING(WDT_TIMEOUT) ")"); + +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) ")"); + +struct keembay_wdt { + struct watchdog_device wdd; + struct clk *clk; + unsigned int rate; + int to_irq; + int th_irq; + void __iomem *base; +}; + +static inline u32 keembay_wdt_readl(struct keembay_wdt *wdt, u32 offset) +{ + return readl(wdt->base + offset); +} + +static inline void keembay_wdt_writel(struct keembay_wdt *wdt, u32 offset, u32 val) +{ + writel(WDT_UNLOCK, wdt->base + TIM_SAFE); + writel(val, wdt->base + offset); +} + +static void keembay_wdt_set_timeout_reg(struct watchdog_device *wdog) +{ + struct keembay_wdt *wdt = watchdog_get_drvdata(wdog); + + keembay_wdt_writel(wdt, TIM_WATCHDOG, wdog->timeout * wdt->rate); +} + +static void keembay_wdt_set_pretimeout_reg(struct watchdog_device *wdog) +{ + struct keembay_wdt *wdt = watchdog_get_drvdata(wdog); + u32 th_val = 0; + + if (wdog->pretimeout) + th_val = wdog->timeout - wdog->pretimeout; + + keembay_wdt_writel(wdt, TIM_WATCHDOG_INT_THRES, th_val * wdt->rate); +} + +static int keembay_wdt_start(struct watchdog_device *wdog) +{ + struct keembay_wdt *wdt = watchdog_get_drvdata(wdog); + + keembay_wdt_set_timeout_reg(wdog); + keembay_wdt_writel(wdt, TIM_WDOG_EN, 1); + + return 0; +} + +static int keembay_wdt_stop(struct watchdog_device *wdog) +{ + struct keembay_wdt *wdt = watchdog_get_drvdata(wdog); + + keembay_wdt_writel(wdt, TIM_WDOG_EN, 0); + + return 0; +} + +static int keembay_wdt_ping(struct watchdog_device *wdog) +{ + keembay_wdt_set_timeout_reg(wdog); + + return 0; +} + +static int keembay_wdt_set_timeout(struct watchdog_device *wdog, u32 t) +{ + wdog->timeout = t; + keembay_wdt_set_timeout_reg(wdog); + + return 0; +} + +static int keembay_wdt_set_pretimeout(struct watchdog_device *wdog, u32 t) +{ + if (t > wdog->timeout) + return -EINVAL; + + wdog->pretimeout = t; + keembay_wdt_set_pretimeout_reg(wdog); + + return 0; +} + +static unsigned int keembay_wdt_get_timeleft(struct watchdog_device *wdog) +{ + struct keembay_wdt *wdt = watchdog_get_drvdata(wdog); + + return keembay_wdt_readl(wdt, TIM_WATCHDOG) / wdt->rate; +} + +/* + * SMC call is used to clear the interrupt bits, because the TIM_GEN_CONFIG + * register is in the secure bank. + */ +static irqreturn_t keembay_wdt_to_isr(int irq, void *dev_id) +{ + struct keembay_wdt *wdt = dev_id; + struct arm_smccc_res res; + + keembay_wdt_writel(wdt, TIM_WATCHDOG, 1); + arm_smccc_smc(WDT_ISR_CLEAR, WDT_ISR_MASK, 0, 0, 0, 0, 0, 0, &res); + dev_crit(wdt->wdd.parent, "Intel Keem Bay non-sec wdt timeout.\n"); + emergency_restart(); + + return IRQ_HANDLED; +} + +static irqreturn_t keembay_wdt_th_isr(int irq, void *dev_id) +{ + struct keembay_wdt *wdt = dev_id; + struct arm_smccc_res res; + + arm_smccc_smc(WDT_ISR_CLEAR, WDT_ISR_MASK, 0, 0, 0, 0, 0, 0, &res); + dev_crit(wdt->wdd.parent, "Intel Keem Bay non-sec wdt pre-timeout.\n"); + watchdog_notify_pretimeout(&wdt->wdd); + + return IRQ_HANDLED; +} + +static const struct watchdog_info keembay_wdt_info = { + .identity = "Intel Keem Bay Watchdog Timer", + .options = WDIOF_SETTIMEOUT | + WDIOF_PRETIMEOUT | + WDIOF_MAGICCLOSE | + WDIOF_KEEPALIVEPING, +}; + +static const struct watchdog_ops keembay_wdt_ops = { + .owner = THIS_MODULE, + .start = keembay_wdt_start, + .stop = keembay_wdt_stop, + .ping = keembay_wdt_ping, + .set_timeout = keembay_wdt_set_timeout, + .set_pretimeout = keembay_wdt_set_pretimeout, + .get_timeleft = keembay_wdt_get_timeleft, +}; + +static int keembay_wdt_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct keembay_wdt *wdt; + int ret; + + wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL); + if (!wdt) + return -ENOMEM; + + wdt->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(wdt->base)) + return PTR_ERR(wdt->base); + + /* we do not need to enable the clock as it is enabled by default */ + wdt->clk = devm_clk_get(dev, NULL); + if (IS_ERR(wdt->clk)) + return dev_err_probe(dev, PTR_ERR(wdt->clk), "Failed to get clock\n"); + + wdt->rate = clk_get_rate(wdt->clk); + if (!wdt->rate) + return dev_err_probe(dev, -EINVAL, "Failed to get clock rate\n"); + + wdt->th_irq = platform_get_irq_byname(pdev, "threshold"); + if (wdt->th_irq < 0) + return dev_err_probe(dev, wdt->th_irq, "Failed to get IRQ for threshold\n"); + + ret = devm_request_irq(dev, wdt->th_irq, keembay_wdt_th_isr, 0, + "keembay-wdt", wdt); + if (ret) + return dev_err_probe(dev, ret, "Failed to request IRQ for threshold\n"); + + wdt->to_irq = platform_get_irq_byname(pdev, "timeout"); + if (wdt->to_irq < 0) + return dev_err_probe(dev, wdt->to_irq, "Failed to get IRQ for timeout\n"); + + ret = devm_request_irq(dev, wdt->to_irq, keembay_wdt_to_isr, 0, + "keembay-wdt", wdt); + if (ret) + return dev_err_probe(dev, ret, "Failed to request IRQ for timeout\n"); + + wdt->wdd.parent = dev; + wdt->wdd.info = &keembay_wdt_info; + wdt->wdd.ops = &keembay_wdt_ops; + wdt->wdd.min_timeout = WDT_LOAD_MIN; + wdt->wdd.max_timeout = WDT_LOAD_MAX / wdt->rate; + wdt->wdd.timeout = WDT_TIMEOUT; + + watchdog_set_drvdata(&wdt->wdd, wdt); + watchdog_set_nowayout(&wdt->wdd, nowayout); + watchdog_init_timeout(&wdt->wdd, timeout, dev); + keembay_wdt_set_timeout(&wdt->wdd, wdt->wdd.timeout); + + ret = devm_watchdog_register_device(dev, &wdt->wdd); + if (ret) + return dev_err_probe(dev, ret, "Failed to register watchdog device.\n"); + + platform_set_drvdata(pdev, wdt); + dev_info(dev, "Initial timeout %d sec%s.\n", + wdt->wdd.timeout, nowayout ? ", nowayout" : ""); + + return 0; +} + +static int __maybe_unused keembay_wdt_suspend(struct device *dev) +{ + struct keembay_wdt *wdt = dev_get_drvdata(dev); + + if (watchdog_active(&wdt->wdd)) + return keembay_wdt_stop(&wdt->wdd); + + return 0; +} + +static int __maybe_unused keembay_wdt_resume(struct device *dev) +{ + struct keembay_wdt *wdt = dev_get_drvdata(dev); + + if (watchdog_active(&wdt->wdd)) + return keembay_wdt_start(&wdt->wdd); + + return 0; +} + +static SIMPLE_DEV_PM_OPS(keembay_wdt_pm_ops, keembay_wdt_suspend, + keembay_wdt_resume); + +static const struct of_device_id keembay_wdt_match[] = { + { .compatible = "intel,keembay-wdt" }, + { } +}; +MODULE_DEVICE_TABLE(of, keembay_wdt_match); + +static struct platform_driver keembay_wdt_driver = { + .probe = keembay_wdt_probe, + .driver = { + .name = "keembay_wdt", + .of_match_table = keembay_wdt_match, + .pm = &keembay_wdt_pm_ops, + }, +}; + +module_platform_driver(keembay_wdt_driver); + +MODULE_DESCRIPTION("Intel Keem Bay SoC watchdog driver"); +MODULE_AUTHOR("Wan Ahmad Zainie Date: Wed, 20 Jan 2021 15:48:10 +0800 Subject: watchdog: hpwdt: Assign boolean values to a bool variable Fix the following coccicheck warnings: ./drivers/watchdog/hpwdt.c:345:2-12: WARNING: Assignment of 0/1 to bool variable. ./drivers/watchdog/hpwdt.c:126:2-12: WARNING: Assignment of 0/1 to bool variable. Reported-by: Abaci Robot Signed-off-by: Jiapeng Zhong Reviewed-by: Jerry Hoemann Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/1611128890-79204-1-git-send-email-abaci-bugfix@linux.alibaba.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/hpwdt.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/watchdog') diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c index cbd1498ff015..22ddba3802ef 100644 --- a/drivers/watchdog/hpwdt.c +++ b/drivers/watchdog/hpwdt.c @@ -123,7 +123,7 @@ static int hpwdt_settimeout(struct watchdog_device *wdd, unsigned int val) if (val <= wdd->pretimeout) { dev_dbg(wdd->parent, "pretimeout < timeout. Setting to zero\n"); wdd->pretimeout = 0; - pretimeout = 0; + pretimeout = false; if (watchdog_active(wdd)) hpwdt_start(wdd); } @@ -336,13 +336,13 @@ static int hpwdt_init_one(struct pci_dev *dev, watchdog_init_timeout(&hpwdt_dev, soft_margin, NULL); if (is_kdump_kernel()) { - pretimeout = 0; + pretimeout = false; kdumptimeout = 0; } if (pretimeout && hpwdt_dev.timeout <= PRETIMEOUT_SEC) { dev_warn(&dev->dev, "timeout <= pretimeout. Setting pretimeout to zero\n"); - pretimeout = 0; + pretimeout = false; } hpwdt_dev.pretimeout = pretimeout ? PRETIMEOUT_SEC : 0; kdumptimeout = min(kdumptimeout, HPWDT_MAX_TIMER); -- cgit v1.2.3 From fa01fa70039cd969acde606672e2b9846205bd0f Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Sat, 19 Dec 2020 18:34:15 +0100 Subject: watchdog: renesas_wdt: don't sleep in atomic context MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In the restart handler, we hit multiple OOPSes. One because of usleep_range() and one because of RPM. So, instead of re-using rwdt_start(), we implement an atomic version of it in the restart handler. As a little bonus, reboot will occur sooner because we can now use the smallest divider in the custom restart routine. Signed-off-by: Wolfram Sang Reviewed-by: Guenter Roeck Reviewed-by: Geert Uytterhoeven Reviewed-by: Niklas Söderlund Link: https://lore.kernel.org/r/20201219173415.21848-1-wsa+renesas@sang-engineering.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/renesas_wdt.c | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) (limited to 'drivers/watchdog') diff --git a/drivers/watchdog/renesas_wdt.c b/drivers/watchdog/renesas_wdt.c index 47fce4de0110..d2b5074bca65 100644 --- a/drivers/watchdog/renesas_wdt.c +++ b/drivers/watchdog/renesas_wdt.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -50,6 +51,7 @@ struct rwdt_priv { struct watchdog_device wdev; unsigned long clk_rate; u8 cks; + struct clk *clk; }; static void rwdt_write(struct rwdt_priv *priv, u32 val, unsigned int reg) @@ -125,13 +127,30 @@ static unsigned int rwdt_get_timeleft(struct watchdog_device *wdev) return DIV_BY_CLKS_PER_SEC(priv, 65536 - val); } +/* needs to be atomic - no RPM, no usleep_range, no scheduling! */ static int rwdt_restart(struct watchdog_device *wdev, unsigned long action, void *data) { struct rwdt_priv *priv = watchdog_get_drvdata(wdev); + u8 val; + + clk_prepare_enable(priv->clk); + + /* Stop the timer before we modify any register */ + val = readb_relaxed(priv->base + RWTCSRA) & ~RWTCSRA_TME; + rwdt_write(priv, val, RWTCSRA); + /* Delay 2 cycles before setting watchdog counter */ + udelay(DIV_ROUND_UP(2 * 1000000, priv->clk_rate)); - rwdt_start(wdev); rwdt_write(priv, 0xffff, RWTCNT); + /* smallest divider to reboot soon */ + rwdt_write(priv, 0, RWTCSRA); + + readb_poll_timeout_atomic(priv->base + RWTCSRA, val, + !(val & RWTCSRA_WRFLG), 1, 100); + + rwdt_write(priv, RWTCSRA_TME, RWTCSRA); + return 0; } @@ -191,7 +210,6 @@ static int rwdt_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct rwdt_priv *priv; - struct clk *clk; unsigned long clks_per_sec; int ret, i; u8 csra; @@ -207,13 +225,13 @@ static int rwdt_probe(struct platform_device *pdev) if (IS_ERR(priv->base)) return PTR_ERR(priv->base); - clk = devm_clk_get(dev, NULL); - if (IS_ERR(clk)) - return PTR_ERR(clk); + priv->clk = devm_clk_get(dev, NULL); + if (IS_ERR(priv->clk)) + return PTR_ERR(priv->clk); pm_runtime_enable(dev); pm_runtime_get_sync(dev); - priv->clk_rate = clk_get_rate(clk); + priv->clk_rate = clk_get_rate(priv->clk); csra = readb_relaxed(priv->base + RWTCSRA); priv->wdev.bootstatus = csra & RWTCSRA_WOVF ? WDIOF_CARDRESET : 0; pm_runtime_put(dev); -- cgit v1.2.3 From fbf376056d16010dcba84aa89c2ac320b443163d Mon Sep 17 00:00:00 2001 From: Tian Tao Date: Fri, 25 Dec 2020 16:49:14 +0800 Subject: watchdog: ziirave_wdt: remove unused including Remove including that don't need it. Signed-off-by: Tian Tao Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/1608886154-55309-1-git-send-email-tiantao6@hisilicon.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/ziirave_wdt.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/watchdog') diff --git a/drivers/watchdog/ziirave_wdt.c b/drivers/watchdog/ziirave_wdt.c index cab86a08456b..4297280807ca 100644 --- a/drivers/watchdog/ziirave_wdt.c +++ b/drivers/watchdog/ziirave_wdt.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include -- cgit v1.2.3 From ac288a7b1a98a11e3269573b1de05fb35b80e051 Mon Sep 17 00:00:00 2001 From: Zhao Qiang Date: Thu, 14 Jan 2021 16:26:51 +0800 Subject: watchdog: stop wdd when watchdog hw running in reboot_notifier In watchdog_reboot_notifier, wdd should be stopped when the device is in hw_running state Signed-off-by: Zhao Qiang Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20210114082651.17162-1-qiang.zhao@nxp.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/watchdog_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/watchdog') diff --git a/drivers/watchdog/watchdog_core.c b/drivers/watchdog/watchdog_core.c index 0e9a99559609..5df0a22e2cb4 100644 --- a/drivers/watchdog/watchdog_core.c +++ b/drivers/watchdog/watchdog_core.c @@ -158,7 +158,7 @@ static int watchdog_reboot_notifier(struct notifier_block *nb, wdd = container_of(nb, struct watchdog_device, reboot_nb); if (code == SYS_DOWN || code == SYS_HALT) { - if (watchdog_active(wdd)) { + if (watchdog_active(wdd) || watchdog_hw_running(wdd)) { int ret; ret = wdd->ops->stop(wdd); -- cgit v1.2.3 From e007372bfb5f19d22ebfbbcb7c56346321398077 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 18 Jan 2021 10:45:58 +0100 Subject: watchdog: renesas_wdt: add grace period before rebooting arm64 does not have a grace period after calling reset handlers. It is rightfully assumed that watchdog drivers should wait because they know the time needed. Implement this for the Renesas watchdog driver. Signed-off-by: Wolfram Sang Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20210118094558.36814-1-wsa+renesas@sang-engineering.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/renesas_wdt.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/watchdog') diff --git a/drivers/watchdog/renesas_wdt.c b/drivers/watchdog/renesas_wdt.c index d2b5074bca65..5791198960e6 100644 --- a/drivers/watchdog/renesas_wdt.c +++ b/drivers/watchdog/renesas_wdt.c @@ -151,6 +151,9 @@ static int rwdt_restart(struct watchdog_device *wdev, unsigned long action, rwdt_write(priv, RWTCSRA_TME, RWTCSRA); + /* wait 2 cycles, so watchdog will trigger */ + udelay(DIV_ROUND_UP(2 * 1000000, priv->clk_rate)); + return 0; } -- cgit v1.2.3 From bbece05c0d3a96817483e0b249ad1e302ba95117 Mon Sep 17 00:00:00 2001 From: "freddy.hsin" Date: Wed, 30 Dec 2020 16:15:57 +0800 Subject: watchdog: mtk_wdt: Remove mtk_wdt_stop() in probe() to prevent the system freeze and it doesn't reboot by watchdog problem Before user space daemon start to access the watchdog device, there is a time interval that watchdog is disabled in the original flow. If the system freezing at this interval, it cannot be rebooted by watchdog hardware automatically. In order to solve this problem, the watchdog hardware should be kept working, and start hrtimer in framework to ping it by setting max_hw_heartbeat_ms and HW_RUNNING used in watchdog_need_worker to determine whether the worker should be started or not. Besides the redundant setting of max_timeout is also removed. Signed-off-by: freddy.hsin Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/1609316157-3748-1-git-send-email-freddy.hsin@mediatek.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/mtk_wdt.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'drivers/watchdog') diff --git a/drivers/watchdog/mtk_wdt.c b/drivers/watchdog/mtk_wdt.c index d6a6393f609d..0c869b770502 100644 --- a/drivers/watchdog/mtk_wdt.c +++ b/drivers/watchdog/mtk_wdt.c @@ -195,6 +195,19 @@ static int mtk_wdt_set_timeout(struct watchdog_device *wdt_dev, return 0; } +static void mtk_wdt_init(struct watchdog_device *wdt_dev) +{ + struct mtk_wdt_dev *mtk_wdt = watchdog_get_drvdata(wdt_dev); + void __iomem *wdt_base; + + wdt_base = mtk_wdt->wdt_base; + + if (readl(wdt_base + WDT_MODE) & WDT_MODE_EN) { + set_bit(WDOG_HW_RUNNING, &wdt_dev->status); + mtk_wdt_set_timeout(wdt_dev, wdt_dev->timeout); + } +} + static int mtk_wdt_stop(struct watchdog_device *wdt_dev) { struct mtk_wdt_dev *mtk_wdt = watchdog_get_drvdata(wdt_dev); @@ -264,7 +277,7 @@ static int mtk_wdt_probe(struct platform_device *pdev) mtk_wdt->wdt_dev.info = &mtk_wdt_info; mtk_wdt->wdt_dev.ops = &mtk_wdt_ops; mtk_wdt->wdt_dev.timeout = WDT_MAX_TIMEOUT; - mtk_wdt->wdt_dev.max_timeout = WDT_MAX_TIMEOUT; + mtk_wdt->wdt_dev.max_hw_heartbeat_ms = WDT_MAX_TIMEOUT * 1000; mtk_wdt->wdt_dev.min_timeout = WDT_MIN_TIMEOUT; mtk_wdt->wdt_dev.parent = dev; @@ -274,7 +287,7 @@ static int mtk_wdt_probe(struct platform_device *pdev) watchdog_set_drvdata(&mtk_wdt->wdt_dev, mtk_wdt); - mtk_wdt_stop(&mtk_wdt->wdt_dev); + mtk_wdt_init(&mtk_wdt->wdt_dev); watchdog_stop_on_reboot(&mtk_wdt->wdt_dev); err = devm_watchdog_register_device(dev, &mtk_wdt->wdt_dev); -- cgit v1.2.3 From adc318a3406681758b9865558952fd92a42c2d6f Mon Sep 17 00:00:00 2001 From: Crystal Guo Date: Wed, 14 Oct 2020 21:19:36 +0800 Subject: watchdog: mt8192: add wdt support Add support for watchdog device found in MT8192 SoC Signed-off-by: Crystal Guo Reviewed-by: Matthias Brugger Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20201014131936.20584-5-crystal.guo@mediatek.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/mtk_wdt.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers/watchdog') diff --git a/drivers/watchdog/mtk_wdt.c b/drivers/watchdog/mtk_wdt.c index 0c869b770502..97ca993bd009 100644 --- a/drivers/watchdog/mtk_wdt.c +++ b/drivers/watchdog/mtk_wdt.c @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -76,6 +77,10 @@ static const struct mtk_wdt_data mt8183_data = { .toprgu_sw_rst_num = MT8183_TOPRGU_SW_RST_NUM, }; +static const struct mtk_wdt_data mt8192_data = { + .toprgu_sw_rst_num = MT8192_TOPRGU_SW_RST_NUM, +}; + static int toprgu_reset_update(struct reset_controller_dev *rcdev, unsigned long id, bool assert) { @@ -335,6 +340,7 @@ static const struct of_device_id mtk_wdt_dt_ids[] = { { .compatible = "mediatek,mt2712-wdt", .data = &mt2712_data }, { .compatible = "mediatek,mt6589-wdt" }, { .compatible = "mediatek,mt8183-wdt", .data = &mt8183_data }, + { .compatible = "mediatek,mt8192-wdt", .data = &mt8192_data }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, mtk_wdt_dt_ids); -- cgit v1.2.3 From b4b12b48458fcec2b90ac4b3e4e017f813f22959 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 20 Jan 2021 17:27:41 +0100 Subject: watchdog: remove sirf prima driver The CSR SiRF prima2/atlas platforms are getting removed, so this driver is no longer needed. Cc: Barry Song Signed-off-by: Arnd Bergmann Reviewed-by: Guenter Roeck Acked-by: Barry Song Link: https://lore.kernel.org/r/20210120162745.61268-2-arnd@kernel.org Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- .../devicetree/bindings/watchdog/sirfsoc_wdt.txt | 18 -- drivers/watchdog/Kconfig | 10 - drivers/watchdog/Makefile | 1 - drivers/watchdog/sirfsoc_wdt.c | 216 --------------------- 4 files changed, 245 deletions(-) delete mode 100644 Documentation/devicetree/bindings/watchdog/sirfsoc_wdt.txt delete mode 100644 drivers/watchdog/sirfsoc_wdt.c (limited to 'drivers/watchdog') diff --git a/Documentation/devicetree/bindings/watchdog/sirfsoc_wdt.txt b/Documentation/devicetree/bindings/watchdog/sirfsoc_wdt.txt deleted file mode 100644 index 0dce5e3100b4..000000000000 --- a/Documentation/devicetree/bindings/watchdog/sirfsoc_wdt.txt +++ /dev/null @@ -1,18 +0,0 @@ -SiRFSoC Timer and Watchdog Timer(WDT) Controller - -Required properties: -- compatible: "sirf,prima2-tick" -- reg: Address range of tick timer/WDT register set -- interrupts: interrupt number to the cpu - -Optional properties: -- timeout-sec : Contains the watchdog timeout in seconds - -Example: - -timer@b0020000 { - compatible = "sirf,prima2-tick"; - reg = <0xb0020000 0x1000>; - interrupts = <0>; - timeout-sec = <30>; -}; diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index e95827790877..081b3d9768e2 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -788,16 +788,6 @@ config MOXART_WDT To compile this driver as a module, choose M here: the module will be called moxart_wdt. -config SIRFSOC_WATCHDOG - tristate "SiRFSOC watchdog" - depends on HAS_IOMEM - depends on ARCH_SIRF || COMPILE_TEST - select WATCHDOG_CORE - default y - help - Support for CSR SiRFprimaII and SiRFatlasVI watchdog. When - the watchdog triggers the system will be reset. - config ST_LPC_WATCHDOG tristate "STMicroelectronics LPC Watchdog" depends on ARCH_STI || COMPILE_TEST diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index aeaa74182096..8f78458a96c0 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -73,7 +73,6 @@ obj-$(CONFIG_UX500_WATCHDOG) += ux500_wdt.o obj-$(CONFIG_RETU_WATCHDOG) += retu_wdt.o obj-$(CONFIG_BCM2835_WDT) += bcm2835_wdt.o obj-$(CONFIG_MOXART_WDT) += moxart_wdt.o -obj-$(CONFIG_SIRFSOC_WATCHDOG) += sirfsoc_wdt.o obj-$(CONFIG_ST_LPC_WATCHDOG) += st_lpc_wdt.o obj-$(CONFIG_QCOM_WDT) += qcom-wdt.o obj-$(CONFIG_BCM_KONA_WDT) += bcm_kona_wdt.o diff --git a/drivers/watchdog/sirfsoc_wdt.c b/drivers/watchdog/sirfsoc_wdt.c deleted file mode 100644 index 734cf2966ecb..000000000000 --- a/drivers/watchdog/sirfsoc_wdt.c +++ /dev/null @@ -1,216 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Watchdog driver for CSR SiRFprimaII and SiRFatlasVI - * - * Copyright (c) 2013 Cambridge Silicon Radio Limited, a CSR plc group company. - */ - -#include -#include -#include -#include -#include -#include -#include - -#define CLOCK_FREQ 1000000 - -#define SIRFSOC_TIMER_COUNTER_LO 0x0000 -#define SIRFSOC_TIMER_MATCH_0 0x0008 -#define SIRFSOC_TIMER_INT_EN 0x0024 -#define SIRFSOC_TIMER_WATCHDOG_EN 0x0028 -#define SIRFSOC_TIMER_LATCH 0x0030 -#define SIRFSOC_TIMER_LATCHED_LO 0x0034 - -#define SIRFSOC_TIMER_WDT_INDEX 5 - -#define SIRFSOC_WDT_MIN_TIMEOUT 30 /* 30 secs */ -#define SIRFSOC_WDT_MAX_TIMEOUT (10 * 60) /* 10 mins */ -#define SIRFSOC_WDT_DEFAULT_TIMEOUT 30 /* 30 secs */ - -static unsigned int timeout; -static bool nowayout = WATCHDOG_NOWAYOUT; - -module_param(timeout, uint, 0); -module_param(nowayout, bool, 0); - -MODULE_PARM_DESC(timeout, "Default watchdog timeout (in seconds)"); -MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); - -static void __iomem *sirfsoc_wdt_base(struct watchdog_device *wdd) -{ - return (void __iomem __force *)watchdog_get_drvdata(wdd); -} - -static unsigned int sirfsoc_wdt_gettimeleft(struct watchdog_device *wdd) -{ - u32 counter, match; - void __iomem *wdt_base; - int time_left; - - wdt_base = sirfsoc_wdt_base(wdd); - counter = readl(wdt_base + SIRFSOC_TIMER_COUNTER_LO); - match = readl(wdt_base + - SIRFSOC_TIMER_MATCH_0 + (SIRFSOC_TIMER_WDT_INDEX << 2)); - - time_left = match - counter; - - return time_left / CLOCK_FREQ; -} - -static int sirfsoc_wdt_updatetimeout(struct watchdog_device *wdd) -{ - u32 counter, timeout_ticks; - void __iomem *wdt_base; - - timeout_ticks = wdd->timeout * CLOCK_FREQ; - wdt_base = sirfsoc_wdt_base(wdd); - - /* Enable the latch before reading the LATCH_LO register */ - writel(1, wdt_base + SIRFSOC_TIMER_LATCH); - - /* Set the TO value */ - counter = readl(wdt_base + SIRFSOC_TIMER_LATCHED_LO); - - counter += timeout_ticks; - - writel(counter, wdt_base + - SIRFSOC_TIMER_MATCH_0 + (SIRFSOC_TIMER_WDT_INDEX << 2)); - - return 0; -} - -static int sirfsoc_wdt_enable(struct watchdog_device *wdd) -{ - void __iomem *wdt_base = sirfsoc_wdt_base(wdd); - sirfsoc_wdt_updatetimeout(wdd); - - /* - * NOTE: If interrupt is not enabled - * then WD-Reset doesn't get generated at all. - */ - writel(readl(wdt_base + SIRFSOC_TIMER_INT_EN) - | (1 << SIRFSOC_TIMER_WDT_INDEX), - wdt_base + SIRFSOC_TIMER_INT_EN); - writel(1, wdt_base + SIRFSOC_TIMER_WATCHDOG_EN); - - return 0; -} - -static int sirfsoc_wdt_disable(struct watchdog_device *wdd) -{ - void __iomem *wdt_base = sirfsoc_wdt_base(wdd); - - writel(0, wdt_base + SIRFSOC_TIMER_WATCHDOG_EN); - writel(readl(wdt_base + SIRFSOC_TIMER_INT_EN) - & (~(1 << SIRFSOC_TIMER_WDT_INDEX)), - wdt_base + SIRFSOC_TIMER_INT_EN); - - return 0; -} - -static int sirfsoc_wdt_settimeout(struct watchdog_device *wdd, unsigned int to) -{ - wdd->timeout = to; - sirfsoc_wdt_updatetimeout(wdd); - - return 0; -} - -#define OPTIONS (WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE) - -static const struct watchdog_info sirfsoc_wdt_ident = { - .options = OPTIONS, - .firmware_version = 0, - .identity = "SiRFSOC Watchdog", -}; - -static const struct watchdog_ops sirfsoc_wdt_ops = { - .owner = THIS_MODULE, - .start = sirfsoc_wdt_enable, - .stop = sirfsoc_wdt_disable, - .get_timeleft = sirfsoc_wdt_gettimeleft, - .ping = sirfsoc_wdt_updatetimeout, - .set_timeout = sirfsoc_wdt_settimeout, -}; - -static struct watchdog_device sirfsoc_wdd = { - .info = &sirfsoc_wdt_ident, - .ops = &sirfsoc_wdt_ops, - .timeout = SIRFSOC_WDT_DEFAULT_TIMEOUT, - .min_timeout = SIRFSOC_WDT_MIN_TIMEOUT, - .max_timeout = SIRFSOC_WDT_MAX_TIMEOUT, -}; - -static int sirfsoc_wdt_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - int ret; - void __iomem *base; - - base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(base)) - return PTR_ERR(base); - - watchdog_set_drvdata(&sirfsoc_wdd, (__force void *)base); - - watchdog_init_timeout(&sirfsoc_wdd, timeout, dev); - watchdog_set_nowayout(&sirfsoc_wdd, nowayout); - sirfsoc_wdd.parent = dev; - - watchdog_stop_on_reboot(&sirfsoc_wdd); - watchdog_stop_on_unregister(&sirfsoc_wdd); - ret = devm_watchdog_register_device(dev, &sirfsoc_wdd); - if (ret) - return ret; - - platform_set_drvdata(pdev, &sirfsoc_wdd); - - return 0; -} - -#ifdef CONFIG_PM_SLEEP -static int sirfsoc_wdt_suspend(struct device *dev) -{ - return 0; -} - -static int sirfsoc_wdt_resume(struct device *dev) -{ - struct watchdog_device *wdd = dev_get_drvdata(dev); - - /* - * NOTE: Since timer controller registers settings are saved - * and restored back by the timer-prima2.c, so we need not - * update WD settings except refreshing timeout. - */ - sirfsoc_wdt_updatetimeout(wdd); - - return 0; -} -#endif - -static SIMPLE_DEV_PM_OPS(sirfsoc_wdt_pm_ops, - sirfsoc_wdt_suspend, sirfsoc_wdt_resume); - -static const struct of_device_id sirfsoc_wdt_of_match[] = { - { .compatible = "sirf,prima2-tick"}, - {}, -}; -MODULE_DEVICE_TABLE(of, sirfsoc_wdt_of_match); - -static struct platform_driver sirfsoc_wdt_driver = { - .driver = { - .name = "sirfsoc-wdt", - .pm = &sirfsoc_wdt_pm_ops, - .of_match_table = sirfsoc_wdt_of_match, - }, - .probe = sirfsoc_wdt_probe, -}; -module_platform_driver(sirfsoc_wdt_driver); - -MODULE_DESCRIPTION("SiRF SoC watchdog driver"); -MODULE_AUTHOR("Xianglong Du "); -MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("platform:sirfsoc-wdt"); -- cgit v1.2.3 From 011eda8c67e02d9a6d2449f2bbc9448435db93ea Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 20 Jan 2021 17:27:42 +0100 Subject: watchdog: remove sirf atlas driver The CSR SiRF prima2/atlas platforms are getting removed, so this driver is no longer needed. Cc: Barry Song Signed-off-by: Arnd Bergmann Reviewed-by: Guenter Roeck Acked-by: Barry Song Link: https://lore.kernel.org/r/20210120162745.61268-3-arnd@kernel.org Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/Kconfig | 10 -- drivers/watchdog/Makefile | 1 - drivers/watchdog/atlas7_wdt.c | 221 ------------------------------------------ 3 files changed, 232 deletions(-) delete mode 100644 drivers/watchdog/atlas7_wdt.c (limited to 'drivers/watchdog') diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 081b3d9768e2..d787138cc8fe 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -890,16 +890,6 @@ config LPC18XX_WATCHDOG To compile this driver as a module, choose M here: the module will be called lpc18xx_wdt. -config ATLAS7_WATCHDOG - tristate "CSRatlas7 watchdog" - depends on ARCH_ATLAS7 || COMPILE_TEST - help - Say Y here to include Watchdog timer support for the watchdog - existing on the CSRatlas7 series platforms. - - To compile this driver as a module, choose M here: the - module will be called atlas7_wdt. - config RENESAS_WDT tristate "Renesas WDT Watchdog" depends on ARCH_RENESAS || COMPILE_TEST diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 8f78458a96c0..69517fffbedb 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -83,7 +83,6 @@ obj-$(CONFIG_MEDIATEK_WATCHDOG) += mtk_wdt.o obj-$(CONFIG_DIGICOLOR_WATCHDOG) += digicolor_wdt.o obj-$(CONFIG_LPC18XX_WATCHDOG) += lpc18xx_wdt.o obj-$(CONFIG_BCM7038_WDT) += bcm7038_wdt.o -obj-$(CONFIG_ATLAS7_WATCHDOG) += atlas7_wdt.o obj-$(CONFIG_RENESAS_WDT) += renesas_wdt.o obj-$(CONFIG_RENESAS_RZAWDT) += rza_wdt.o obj-$(CONFIG_ASPEED_WATCHDOG) += aspeed_wdt.o diff --git a/drivers/watchdog/atlas7_wdt.c b/drivers/watchdog/atlas7_wdt.c deleted file mode 100644 index 9bfe650d802f..000000000000 --- a/drivers/watchdog/atlas7_wdt.c +++ /dev/null @@ -1,221 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Watchdog driver for CSR Atlas7 - * - * Copyright (c) 2015 Cambridge Silicon Radio Limited, a CSR plc group company. - */ - -#include -#include -#include -#include -#include -#include -#include - -#define ATLAS7_TIMER_WDT_INDEX 5 -#define ATLAS7_WDT_DEFAULT_TIMEOUT 20 - -#define ATLAS7_WDT_CNT_CTRL (0 + 4 * ATLAS7_TIMER_WDT_INDEX) -#define ATLAS7_WDT_CNT_MATCH (0x18 + 4 * ATLAS7_TIMER_WDT_INDEX) -#define ATLAS7_WDT_CNT (0x48 + 4 * ATLAS7_TIMER_WDT_INDEX) -#define ATLAS7_WDT_CNT_EN (BIT(0) | BIT(1)) -#define ATLAS7_WDT_EN 0x64 - -static unsigned int timeout = ATLAS7_WDT_DEFAULT_TIMEOUT; -static bool nowayout = WATCHDOG_NOWAYOUT; - -module_param(timeout, uint, 0); -module_param(nowayout, bool, 0); - -MODULE_PARM_DESC(timeout, "Default watchdog timeout (in seconds)"); -MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); - -struct atlas7_wdog { - struct device *dev; - void __iomem *base; - unsigned long tick_rate; - struct clk *clk; -}; - -static unsigned int atlas7_wdt_gettimeleft(struct watchdog_device *wdd) -{ - struct atlas7_wdog *wdt = watchdog_get_drvdata(wdd); - u32 counter, match, delta; - - counter = readl(wdt->base + ATLAS7_WDT_CNT); - match = readl(wdt->base + ATLAS7_WDT_CNT_MATCH); - delta = match - counter; - - return delta / wdt->tick_rate; -} - -static int atlas7_wdt_ping(struct watchdog_device *wdd) -{ - struct atlas7_wdog *wdt = watchdog_get_drvdata(wdd); - u32 counter, match, delta; - - counter = readl(wdt->base + ATLAS7_WDT_CNT); - delta = wdd->timeout * wdt->tick_rate; - match = counter + delta; - - writel(match, wdt->base + ATLAS7_WDT_CNT_MATCH); - - return 0; -} - -static int atlas7_wdt_enable(struct watchdog_device *wdd) -{ - struct atlas7_wdog *wdt = watchdog_get_drvdata(wdd); - - atlas7_wdt_ping(wdd); - - writel(readl(wdt->base + ATLAS7_WDT_CNT_CTRL) | ATLAS7_WDT_CNT_EN, - wdt->base + ATLAS7_WDT_CNT_CTRL); - writel(1, wdt->base + ATLAS7_WDT_EN); - - return 0; -} - -static int atlas7_wdt_disable(struct watchdog_device *wdd) -{ - struct atlas7_wdog *wdt = watchdog_get_drvdata(wdd); - - writel(0, wdt->base + ATLAS7_WDT_EN); - writel(readl(wdt->base + ATLAS7_WDT_CNT_CTRL) & ~ATLAS7_WDT_CNT_EN, - wdt->base + ATLAS7_WDT_CNT_CTRL); - - return 0; -} - -static int atlas7_wdt_settimeout(struct watchdog_device *wdd, unsigned int to) -{ - wdd->timeout = to; - - return 0; -} - -#define OPTIONS (WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE) - -static const struct watchdog_info atlas7_wdt_ident = { - .options = OPTIONS, - .firmware_version = 0, - .identity = "atlas7 Watchdog", -}; - -static const struct watchdog_ops atlas7_wdt_ops = { - .owner = THIS_MODULE, - .start = atlas7_wdt_enable, - .stop = atlas7_wdt_disable, - .get_timeleft = atlas7_wdt_gettimeleft, - .ping = atlas7_wdt_ping, - .set_timeout = atlas7_wdt_settimeout, -}; - -static struct watchdog_device atlas7_wdd = { - .info = &atlas7_wdt_ident, - .ops = &atlas7_wdt_ops, - .timeout = ATLAS7_WDT_DEFAULT_TIMEOUT, -}; - -static const struct of_device_id atlas7_wdt_ids[] = { - { .compatible = "sirf,atlas7-tick"}, - {} -}; - -static void atlas7_clk_disable_unprepare(void *data) -{ - clk_disable_unprepare(data); -} - -static int atlas7_wdt_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct atlas7_wdog *wdt; - struct clk *clk; - int ret; - - wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL); - if (!wdt) - return -ENOMEM; - wdt->base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(wdt->base)) - return PTR_ERR(wdt->base); - - clk = devm_clk_get(dev, NULL); - if (IS_ERR(clk)) - return PTR_ERR(clk); - ret = clk_prepare_enable(clk); - if (ret) { - dev_err(dev, "clk enable failed\n"); - return ret; - } - ret = devm_add_action_or_reset(dev, atlas7_clk_disable_unprepare, clk); - if (ret) - return ret; - - /* disable watchdog hardware */ - writel(0, wdt->base + ATLAS7_WDT_CNT_CTRL); - - wdt->tick_rate = clk_get_rate(clk); - if (!wdt->tick_rate) - return -EINVAL; - - wdt->clk = clk; - atlas7_wdd.min_timeout = 1; - atlas7_wdd.max_timeout = UINT_MAX / wdt->tick_rate; - - watchdog_init_timeout(&atlas7_wdd, 0, dev); - watchdog_set_nowayout(&atlas7_wdd, nowayout); - - watchdog_set_drvdata(&atlas7_wdd, wdt); - platform_set_drvdata(pdev, &atlas7_wdd); - - watchdog_stop_on_reboot(&atlas7_wdd); - watchdog_stop_on_unregister(&atlas7_wdd); - return devm_watchdog_register_device(dev, &atlas7_wdd); -} - -static int __maybe_unused atlas7_wdt_suspend(struct device *dev) -{ - /* - * NOTE:timer controller registers settings are saved - * and restored back by the timer-atlas7.c - */ - return 0; -} - -static int __maybe_unused atlas7_wdt_resume(struct device *dev) -{ - struct watchdog_device *wdd = dev_get_drvdata(dev); - - /* - * NOTE: Since timer controller registers settings are saved - * and restored back by the timer-atlas7.c, so we need not - * update WD settings except refreshing timeout. - */ - atlas7_wdt_ping(wdd); - - return 0; -} - -static SIMPLE_DEV_PM_OPS(atlas7_wdt_pm_ops, - atlas7_wdt_suspend, atlas7_wdt_resume); - -MODULE_DEVICE_TABLE(of, atlas7_wdt_ids); - -static struct platform_driver atlas7_wdt_driver = { - .driver = { - .name = "atlas7-wdt", - .pm = &atlas7_wdt_pm_ops, - .of_match_table = atlas7_wdt_ids, - }, - .probe = atlas7_wdt_probe, -}; -module_platform_driver(atlas7_wdt_driver); - -MODULE_DESCRIPTION("CSRatlas7 watchdog driver"); -MODULE_AUTHOR("Guo Zeng "); -MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("platform:atlas7-wdt"); -- cgit v1.2.3 From 30f1ec70ddf5afd6a8d4c0e1ce9f21a4aea936be Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 20 Jan 2021 17:27:43 +0100 Subject: watchdog: remove zte zx driver The zte zx platform is getting removed, so this driver is no longer needed. Cc: Jun Nie Cc: Shawn Guo Signed-off-by: Arnd Bergmann Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20210120162745.61268-4-arnd@kernel.org Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- .../bindings/watchdog/zte,zx2967-wdt.txt | 32 --- drivers/watchdog/Kconfig | 10 - drivers/watchdog/Makefile | 1 - drivers/watchdog/zx2967_wdt.c | 279 --------------------- 4 files changed, 322 deletions(-) delete mode 100644 Documentation/devicetree/bindings/watchdog/zte,zx2967-wdt.txt delete mode 100644 drivers/watchdog/zx2967_wdt.c (limited to 'drivers/watchdog') diff --git a/Documentation/devicetree/bindings/watchdog/zte,zx2967-wdt.txt b/Documentation/devicetree/bindings/watchdog/zte,zx2967-wdt.txt deleted file mode 100644 index 06ce67766756..000000000000 --- a/Documentation/devicetree/bindings/watchdog/zte,zx2967-wdt.txt +++ /dev/null @@ -1,32 +0,0 @@ -ZTE zx2967 Watchdog timer - -Required properties: - -- compatible : should be one of the following. - * zte,zx296718-wdt -- reg : Specifies base physical address and size of the registers. -- clocks : Pairs of phandle and specifier referencing the controller's clocks. -- resets : Reference to the reset controller controlling the watchdog - controller. - -Optional properties: - -- timeout-sec : Contains the watchdog timeout in seconds. -- zte,wdt-reset-sysctrl : Directs how to reset system by the watchdog. - if we don't want to restart system when watchdog been triggered, - it's not required, vice versa. - It should include following fields. - * phandle of aon-sysctrl. - * offset of register that be written, should be 0xb0. - * configure value that be written to aon-sysctrl. - * bit mask, corresponding bits will be affected. - -Example: - -wdt: watchdog@1465000 { - compatible = "zte,zx296718-wdt"; - reg = <0x1465000 0x1000>; - clocks = <&topcrm WDT_WCLK>; - resets = <&toprst 35>; - zte,wdt-reset-sysctrl = <&aon_sysctrl 0xb0 1 0x115>; -}; diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index d787138cc8fe..5d47a702f936 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -919,16 +919,6 @@ config ASPEED_WATCHDOG To compile this driver as a module, choose M here: the module will be called aspeed_wdt. -config ZX2967_WATCHDOG - tristate "ZTE zx2967 SoCs watchdog support" - depends on ARCH_ZX - select WATCHDOG_CORE - help - Say Y here to include support for the watchdog timer - in ZTE zx2967 SoCs. - 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 diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 69517fffbedb..d7678d8d9893 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -86,7 +86,6 @@ obj-$(CONFIG_BCM7038_WDT) += bcm7038_wdt.o obj-$(CONFIG_RENESAS_WDT) += renesas_wdt.o obj-$(CONFIG_RENESAS_RZAWDT) += rza_wdt.o obj-$(CONFIG_ASPEED_WATCHDOG) += aspeed_wdt.o -obj-$(CONFIG_ZX2967_WATCHDOG) += zx2967_wdt.o obj-$(CONFIG_STM32_WATCHDOG) += stm32_iwdg.o obj-$(CONFIG_UNIPHIER_WATCHDOG) += uniphier_wdt.o obj-$(CONFIG_RTD119X_WATCHDOG) += rtd119x_wdt.o diff --git a/drivers/watchdog/zx2967_wdt.c b/drivers/watchdog/zx2967_wdt.c deleted file mode 100644 index bf183e73671a..000000000000 --- a/drivers/watchdog/zx2967_wdt.c +++ /dev/null @@ -1,279 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * watchdog driver for ZTE's zx2967 family - * - * Copyright (C) 2017 ZTE Ltd. - * - * Author: Baoyou Xie - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define ZX2967_WDT_CFG_REG 0x4 -#define ZX2967_WDT_LOAD_REG 0x8 -#define ZX2967_WDT_REFRESH_REG 0x18 -#define ZX2967_WDT_START_REG 0x1c - -#define ZX2967_WDT_REFRESH_MASK GENMASK(5, 0) - -#define ZX2967_WDT_CFG_DIV(n) ((((n) & 0xff) - 1) << 8) -#define ZX2967_WDT_START_EN 0x1 - -/* - * Hardware magic number. - * When watchdog reg is written, the lowest 16 bits are valid, but - * the highest 16 bits should be always this number. - */ -#define ZX2967_WDT_WRITEKEY (0x1234 << 16) -#define ZX2967_WDT_VAL_MASK GENMASK(15, 0) - -#define ZX2967_WDT_DIV_DEFAULT 16 -#define ZX2967_WDT_DEFAULT_TIMEOUT 32 -#define ZX2967_WDT_MIN_TIMEOUT 1 -#define ZX2967_WDT_MAX_TIMEOUT 524 -#define ZX2967_WDT_MAX_COUNT 0xffff - -#define ZX2967_WDT_CLK_FREQ 0x8000 - -#define ZX2967_WDT_FLAG_REBOOT_MON BIT(0) - -struct zx2967_wdt { - struct watchdog_device wdt_device; - void __iomem *reg_base; - struct clk *clock; -}; - -static inline u32 zx2967_wdt_readl(struct zx2967_wdt *wdt, u16 reg) -{ - return readl_relaxed(wdt->reg_base + reg); -} - -static inline void zx2967_wdt_writel(struct zx2967_wdt *wdt, u16 reg, u32 val) -{ - writel_relaxed(val | ZX2967_WDT_WRITEKEY, wdt->reg_base + reg); -} - -static void zx2967_wdt_refresh(struct zx2967_wdt *wdt) -{ - u32 val; - - val = zx2967_wdt_readl(wdt, ZX2967_WDT_REFRESH_REG); - /* - * Bit 4-5, 1 and 2: refresh config info - * Bit 2-3, 1 and 2: refresh counter - * Bit 0-1, 1 and 2: refresh int-value - * we shift each group value between 1 and 2 to refresh all data. - */ - val ^= ZX2967_WDT_REFRESH_MASK; - zx2967_wdt_writel(wdt, ZX2967_WDT_REFRESH_REG, - val & ZX2967_WDT_VAL_MASK); -} - -static int -zx2967_wdt_set_timeout(struct watchdog_device *wdd, unsigned int timeout) -{ - struct zx2967_wdt *wdt = watchdog_get_drvdata(wdd); - unsigned int divisor = ZX2967_WDT_DIV_DEFAULT; - u32 count; - - count = timeout * ZX2967_WDT_CLK_FREQ; - if (count > divisor * ZX2967_WDT_MAX_COUNT) - divisor = DIV_ROUND_UP(count, ZX2967_WDT_MAX_COUNT); - count = DIV_ROUND_UP(count, divisor); - zx2967_wdt_writel(wdt, ZX2967_WDT_CFG_REG, - ZX2967_WDT_CFG_DIV(divisor) & ZX2967_WDT_VAL_MASK); - zx2967_wdt_writel(wdt, ZX2967_WDT_LOAD_REG, - count & ZX2967_WDT_VAL_MASK); - zx2967_wdt_refresh(wdt); - wdd->timeout = (count * divisor) / ZX2967_WDT_CLK_FREQ; - - return 0; -} - -static void __zx2967_wdt_start(struct zx2967_wdt *wdt) -{ - u32 val; - - val = zx2967_wdt_readl(wdt, ZX2967_WDT_START_REG); - val |= ZX2967_WDT_START_EN; - zx2967_wdt_writel(wdt, ZX2967_WDT_START_REG, - val & ZX2967_WDT_VAL_MASK); -} - -static void __zx2967_wdt_stop(struct zx2967_wdt *wdt) -{ - u32 val; - - val = zx2967_wdt_readl(wdt, ZX2967_WDT_START_REG); - val &= ~ZX2967_WDT_START_EN; - zx2967_wdt_writel(wdt, ZX2967_WDT_START_REG, - val & ZX2967_WDT_VAL_MASK); -} - -static int zx2967_wdt_start(struct watchdog_device *wdd) -{ - struct zx2967_wdt *wdt = watchdog_get_drvdata(wdd); - - zx2967_wdt_set_timeout(wdd, wdd->timeout); - __zx2967_wdt_start(wdt); - - return 0; -} - -static int zx2967_wdt_stop(struct watchdog_device *wdd) -{ - struct zx2967_wdt *wdt = watchdog_get_drvdata(wdd); - - __zx2967_wdt_stop(wdt); - - return 0; -} - -static int zx2967_wdt_keepalive(struct watchdog_device *wdd) -{ - struct zx2967_wdt *wdt = watchdog_get_drvdata(wdd); - - zx2967_wdt_refresh(wdt); - - return 0; -} - -#define ZX2967_WDT_OPTIONS \ - (WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE) -static const struct watchdog_info zx2967_wdt_ident = { - .options = ZX2967_WDT_OPTIONS, - .identity = "zx2967 watchdog", -}; - -static const struct watchdog_ops zx2967_wdt_ops = { - .owner = THIS_MODULE, - .start = zx2967_wdt_start, - .stop = zx2967_wdt_stop, - .ping = zx2967_wdt_keepalive, - .set_timeout = zx2967_wdt_set_timeout, -}; - -static void zx2967_wdt_reset_sysctrl(struct device *dev) -{ - int ret; - void __iomem *regmap; - unsigned int offset, mask, config; - struct of_phandle_args out_args; - - ret = of_parse_phandle_with_fixed_args(dev->of_node, - "zte,wdt-reset-sysctrl", 3, 0, &out_args); - if (ret) - return; - - offset = out_args.args[0]; - config = out_args.args[1]; - mask = out_args.args[2]; - - regmap = syscon_node_to_regmap(out_args.np); - if (IS_ERR(regmap)) { - of_node_put(out_args.np); - return; - } - - regmap_update_bits(regmap, offset, mask, config); - of_node_put(out_args.np); -} - -static void zx2967_clk_disable_unprepare(void *data) -{ - clk_disable_unprepare(data); -} - -static int zx2967_wdt_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct zx2967_wdt *wdt; - int ret; - struct reset_control *rstc; - - wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL); - if (!wdt) - return -ENOMEM; - - platform_set_drvdata(pdev, wdt); - - wdt->wdt_device.info = &zx2967_wdt_ident; - wdt->wdt_device.ops = &zx2967_wdt_ops; - wdt->wdt_device.timeout = ZX2967_WDT_DEFAULT_TIMEOUT; - wdt->wdt_device.max_timeout = ZX2967_WDT_MAX_TIMEOUT; - wdt->wdt_device.min_timeout = ZX2967_WDT_MIN_TIMEOUT; - wdt->wdt_device.parent = dev; - - wdt->reg_base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(wdt->reg_base)) - return PTR_ERR(wdt->reg_base); - - zx2967_wdt_reset_sysctrl(dev); - - wdt->clock = devm_clk_get(dev, NULL); - if (IS_ERR(wdt->clock)) { - dev_err(dev, "failed to find watchdog clock source\n"); - return PTR_ERR(wdt->clock); - } - - ret = clk_prepare_enable(wdt->clock); - if (ret < 0) { - dev_err(dev, "failed to enable clock\n"); - return ret; - } - ret = devm_add_action_or_reset(dev, zx2967_clk_disable_unprepare, - wdt->clock); - if (ret) - return ret; - clk_set_rate(wdt->clock, ZX2967_WDT_CLK_FREQ); - - rstc = devm_reset_control_get_exclusive(dev, NULL); - if (IS_ERR(rstc)) { - dev_err(dev, "failed to get rstc"); - return PTR_ERR(rstc); - } - - reset_control_assert(rstc); - reset_control_deassert(rstc); - - watchdog_set_drvdata(&wdt->wdt_device, wdt); - watchdog_init_timeout(&wdt->wdt_device, - ZX2967_WDT_DEFAULT_TIMEOUT, dev); - watchdog_set_nowayout(&wdt->wdt_device, WATCHDOG_NOWAYOUT); - - ret = devm_watchdog_register_device(dev, &wdt->wdt_device); - if (ret) - return ret; - - dev_info(dev, "watchdog enabled (timeout=%d sec, nowayout=%d)", - wdt->wdt_device.timeout, WATCHDOG_NOWAYOUT); - - return 0; -} - -static const struct of_device_id zx2967_wdt_match[] = { - { .compatible = "zte,zx296718-wdt", }, - {} -}; -MODULE_DEVICE_TABLE(of, zx2967_wdt_match); - -static struct platform_driver zx2967_wdt_driver = { - .probe = zx2967_wdt_probe, - .driver = { - .name = "zx2967-wdt", - .of_match_table = of_match_ptr(zx2967_wdt_match), - }, -}; -module_platform_driver(zx2967_wdt_driver); - -MODULE_AUTHOR("Baoyou Xie "); -MODULE_DESCRIPTION("ZTE zx2967 Watchdog Device Driver"); -MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From c1b50b55b00daa373379bb1062afab5ce279cad1 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 20 Jan 2021 17:27:44 +0100 Subject: watchdog: remove tango driver The tango platform is getting removed, so the driver is no longer needed. Cc: Marc Gonzalez Cc: Mans Rullgard Signed-off-by: Arnd Bergmann Reviewed-by: Guenter Roeck Acked-by: Mans Rullgard Link: https://lore.kernel.org/r/20210120162745.61268-5-arnd@kernel.org [groeck: Removed devicetree bindings] Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- .../bindings/watchdog/sigma,smp8642-wdt.txt | 18 -- drivers/watchdog/Kconfig | 11 -- drivers/watchdog/Makefile | 1 - drivers/watchdog/tangox_wdt.c | 209 --------------------- 4 files changed, 239 deletions(-) delete mode 100644 Documentation/devicetree/bindings/watchdog/sigma,smp8642-wdt.txt delete mode 100644 drivers/watchdog/tangox_wdt.c (limited to 'drivers/watchdog') diff --git a/Documentation/devicetree/bindings/watchdog/sigma,smp8642-wdt.txt b/Documentation/devicetree/bindings/watchdog/sigma,smp8642-wdt.txt deleted file mode 100644 index 5b7ec2c707d8..000000000000 --- a/Documentation/devicetree/bindings/watchdog/sigma,smp8642-wdt.txt +++ /dev/null @@ -1,18 +0,0 @@ -Sigma Designs SMP86xx/SMP87xx watchdog - -Required properties: -- compatible: Should be "sigma,smp8642-wdt" -- reg: Specifies the physical address region -- clocks: Should be a phandle to the clock - -Optional properties: -- timeout-sec: watchdog timeout in seconds - -Example: - -watchdog@1fd00 { - compatible = "sigma,smp8642-wdt"; - reg = <0x1fd00 8>; - clocks = <&xtal_in_clk>; - timeout-sec = <30>; -}; diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 5d47a702f936..dc191725b4e5 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -254,17 +254,6 @@ config MENZ069_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 - depends on ARCH_TANGO || COMPILE_TEST - depends on HAS_IOMEM - help - Support for the watchdog in Sigma Designs SMP86xx (tango3) - and SMP87xx (tango4) family chips. - - This driver can be built as a module. The module name is tangox_wdt. - config WDAT_WDT tristate "ACPI Watchdog Action Table (WDAT)" depends on ACPI diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index d7678d8d9893..59ab621720ab 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -211,7 +211,6 @@ obj-$(CONFIG_DA9055_WATCHDOG) += da9055_wdt.o obj-$(CONFIG_DA9062_WATCHDOG) += da9062_wdt.o obj-$(CONFIG_DA9063_WATCHDOG) += da9063_wdt.o obj-$(CONFIG_GPIO_WATCHDOG) += gpio_wdt.o -obj-$(CONFIG_TANGOX_WATCHDOG) += tangox_wdt.o obj-$(CONFIG_WDAT_WDT) += wdat_wdt.o obj-$(CONFIG_WM831X_WATCHDOG) += wm831x_wdt.o obj-$(CONFIG_WM8350_WATCHDOG) += wm8350_wdt.o diff --git a/drivers/watchdog/tangox_wdt.c b/drivers/watchdog/tangox_wdt.c deleted file mode 100644 index 1afb0e9d808c..000000000000 --- a/drivers/watchdog/tangox_wdt.c +++ /dev/null @@ -1,209 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright (C) 2015 Mans Rullgard - * SMP86xx/SMP87xx Watchdog driver - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define 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 unsigned int timeout; -module_param(timeout, int, 0); -MODULE_PARM_DESC(timeout, "Watchdog timeout"); - -/* - * Counter counts down from programmed value. Reset asserts when - * the counter reaches 1. - */ -#define WD_COUNTER 0 - -#define WD_CONFIG 4 -#define WD_CONFIG_XTAL_IN BIT(0) -#define WD_CONFIG_DISABLE BIT(31) - -struct tangox_wdt_device { - struct watchdog_device wdt; - void __iomem *base; - unsigned long clk_rate; - struct clk *clk; -}; - -static int tangox_wdt_set_timeout(struct watchdog_device *wdt, - unsigned int new_timeout) -{ - wdt->timeout = new_timeout; - - return 0; -} - -static int tangox_wdt_start(struct watchdog_device *wdt) -{ - struct tangox_wdt_device *dev = watchdog_get_drvdata(wdt); - u32 ticks; - - ticks = 1 + wdt->timeout * dev->clk_rate; - writel(ticks, dev->base + WD_COUNTER); - - return 0; -} - -static int tangox_wdt_stop(struct watchdog_device *wdt) -{ - struct tangox_wdt_device *dev = watchdog_get_drvdata(wdt); - - writel(0, dev->base + WD_COUNTER); - - return 0; -} - -static unsigned int tangox_wdt_get_timeleft(struct watchdog_device *wdt) -{ - struct tangox_wdt_device *dev = watchdog_get_drvdata(wdt); - u32 count; - - count = readl(dev->base + WD_COUNTER); - - if (!count) - return 0; - - return (count - 1) / dev->clk_rate; -} - -static const struct watchdog_info tangox_wdt_info = { - .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, - .identity = "tangox watchdog", -}; - -static int tangox_wdt_restart(struct watchdog_device *wdt, - unsigned long action, void *data) -{ - struct tangox_wdt_device *dev = watchdog_get_drvdata(wdt); - - writel(1, dev->base + WD_COUNTER); - - return 0; -} - -static const struct watchdog_ops tangox_wdt_ops = { - .start = tangox_wdt_start, - .stop = tangox_wdt_stop, - .set_timeout = tangox_wdt_set_timeout, - .get_timeleft = tangox_wdt_get_timeleft, - .restart = tangox_wdt_restart, -}; - -static void tangox_clk_disable_unprepare(void *data) -{ - clk_disable_unprepare(data); -} - -static int tangox_wdt_probe(struct platform_device *pdev) -{ - struct tangox_wdt_device *dev; - u32 config; - int err; - - dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); - if (!dev) - return -ENOMEM; - - dev->base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(dev->base)) - return PTR_ERR(dev->base); - - dev->clk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(dev->clk)) - return PTR_ERR(dev->clk); - - err = clk_prepare_enable(dev->clk); - if (err) - return err; - err = devm_add_action_or_reset(&pdev->dev, - tangox_clk_disable_unprepare, dev->clk); - if (err) - return err; - - dev->clk_rate = clk_get_rate(dev->clk); - if (!dev->clk_rate) - return -EINVAL; - - dev->wdt.parent = &pdev->dev; - dev->wdt.info = &tangox_wdt_info; - dev->wdt.ops = &tangox_wdt_ops; - dev->wdt.timeout = DEFAULT_TIMEOUT; - dev->wdt.min_timeout = 1; - dev->wdt.max_hw_heartbeat_ms = (U32_MAX - 1) / dev->clk_rate; - - watchdog_init_timeout(&dev->wdt, timeout, &pdev->dev); - watchdog_set_nowayout(&dev->wdt, nowayout); - watchdog_set_drvdata(&dev->wdt, dev); - - /* - * Deactivate counter if disable bit is set to avoid - * accidental reset. - */ - config = readl(dev->base + WD_CONFIG); - if (config & WD_CONFIG_DISABLE) - writel(0, dev->base + WD_COUNTER); - - writel(WD_CONFIG_XTAL_IN, dev->base + WD_CONFIG); - - /* - * Mark as active and restart with configured timeout if - * already running. - */ - if (readl(dev->base + WD_COUNTER)) { - set_bit(WDOG_HW_RUNNING, &dev->wdt.status); - tangox_wdt_start(&dev->wdt); - } - - watchdog_set_restart_priority(&dev->wdt, 128); - - watchdog_stop_on_unregister(&dev->wdt); - err = devm_watchdog_register_device(&pdev->dev, &dev->wdt); - if (err) - return err; - - platform_set_drvdata(pdev, dev); - - dev_info(&pdev->dev, "SMP86xx/SMP87xx watchdog registered\n"); - - return 0; -} - -static const struct of_device_id tangox_wdt_dt_ids[] = { - { .compatible = "sigma,smp8642-wdt" }, - { .compatible = "sigma,smp8759-wdt" }, - { } -}; -MODULE_DEVICE_TABLE(of, tangox_wdt_dt_ids); - -static struct platform_driver tangox_wdt_driver = { - .probe = tangox_wdt_probe, - .driver = { - .name = "tangox-wdt", - .of_match_table = tangox_wdt_dt_ids, - }, -}; - -module_platform_driver(tangox_wdt_driver); - -MODULE_AUTHOR("Mans Rullgard "); -MODULE_DESCRIPTION("SMP86xx/SMP87xx Watchdog driver"); -MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 5ecd125b4b2a55a394a459df331a0b6380c773fa Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 20 Jan 2021 17:27:45 +0100 Subject: watchdog: remove coh901 driver The ST-Ericsson U300 platform is getting removed, so this driver is no longer needed. Cc: Linus Walleij Signed-off-by: Arnd Bergmann Reviewed-by: Guenter Roeck Reviewed-by: Linus Walleij Link: https://lore.kernel.org/r/20210120162745.61268-6-arnd@kernel.org Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- .../bindings/watchdog/stericsson-coh901327.txt | 19 - drivers/watchdog/Kconfig | 11 - drivers/watchdog/Makefile | 1 - drivers/watchdog/coh901327_wdt.c | 408 --------------------- 4 files changed, 439 deletions(-) delete mode 100644 Documentation/devicetree/bindings/watchdog/stericsson-coh901327.txt delete mode 100644 drivers/watchdog/coh901327_wdt.c (limited to 'drivers/watchdog') diff --git a/Documentation/devicetree/bindings/watchdog/stericsson-coh901327.txt b/Documentation/devicetree/bindings/watchdog/stericsson-coh901327.txt deleted file mode 100644 index 8ffb88e39e76..000000000000 --- a/Documentation/devicetree/bindings/watchdog/stericsson-coh901327.txt +++ /dev/null @@ -1,19 +0,0 @@ -ST-Ericsson COH 901 327 Watchdog timer - -Required properties: -- compatible: must be "stericsson,coh901327". -- reg: physical base address of the controller and length of memory mapped - region. -- interrupts: the interrupt used for the watchdog timeout warning. - -Optional properties: -- timeout-sec: contains the watchdog timeout in seconds. - -Example: - -watchdog: watchdog@c0012000 { - compatible = "stericsson,coh901327"; - reg = <0xc0012000 0x1000>; - interrupts = <3>; - timeout-sec = <60>; -}; diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index dc191725b4e5..0470dc15c085 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -619,17 +619,6 @@ config SUNXI_WATCHDOG To compile this driver as a module, choose M here: the module will be called sunxi_wdt. -config COH901327_WATCHDOG - bool "ST-Ericsson COH 901 327 watchdog" - depends on ARCH_U300 || (ARM && COMMON_CLK && COMPILE_TEST) - default y if MACH_U300 - select WATCHDOG_CORE - help - Say Y here to include Watchdog timer support for the - watchdog embedded into the ST-Ericsson U300 series platforms. - This watchdog is used to reset the system and thus cannot be - compiled as a module. - config NPCM7XX_WATCHDOG tristate "Nuvoton NPCM750 watchdog" depends on ARCH_NPCM || COMPILE_TEST diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 59ab621720ab..57058b81af73 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -61,7 +61,6 @@ obj-$(CONFIG_K3_RTI_WATCHDOG) += rti_wdt.o obj-$(CONFIG_ORION_WATCHDOG) += orion_wdt.o obj-$(CONFIG_SUNXI_WATCHDOG) += sunxi_wdt.o obj-$(CONFIG_RN5T618_WATCHDOG) += rn5t618_wdt.o -obj-$(CONFIG_COH901327_WATCHDOG) += coh901327_wdt.o obj-$(CONFIG_NPCM7XX_WATCHDOG) += npcm_wdt.o obj-$(CONFIG_STMP3XXX_RTC_WATCHDOG) += stmp3xxx_rtc_wdt.o obj-$(CONFIG_TS4800_WATCHDOG) += ts4800_wdt.o diff --git a/drivers/watchdog/coh901327_wdt.c b/drivers/watchdog/coh901327_wdt.c deleted file mode 100644 index 260c50b08483..000000000000 --- a/drivers/watchdog/coh901327_wdt.c +++ /dev/null @@ -1,408 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * coh901327_wdt.c - * - * Copyright (C) 2008-2009 ST-Ericsson AB - * Watchdog driver for the ST-Ericsson AB COH 901 327 IP core - * Author: Linus Walleij - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DRV_NAME "WDOG COH 901 327" - -/* - * COH 901 327 register definitions - */ - -/* WDOG_FEED Register 32bit (-/W) */ -#define U300_WDOG_FR 0x00 -#define U300_WDOG_FR_FEED_RESTART_TIMER 0xFEEDU -/* WDOG_TIMEOUT Register 32bit (R/W) */ -#define U300_WDOG_TR 0x04 -#define U300_WDOG_TR_TIMEOUT_MASK 0x7FFFU -/* WDOG_DISABLE1 Register 32bit (-/W) */ -#define U300_WDOG_D1R 0x08 -#define U300_WDOG_D1R_DISABLE1_DISABLE_TIMER 0x2BADU -/* WDOG_DISABLE2 Register 32bit (R/W) */ -#define U300_WDOG_D2R 0x0C -#define U300_WDOG_D2R_DISABLE2_DISABLE_TIMER 0xCAFEU -#define U300_WDOG_D2R_DISABLE_STATUS_DISABLED 0xDABEU -#define U300_WDOG_D2R_DISABLE_STATUS_ENABLED 0x0000U -/* WDOG_STATUS Register 32bit (R/W) */ -#define U300_WDOG_SR 0x10 -#define U300_WDOG_SR_STATUS_TIMED_OUT 0xCFE8U -#define U300_WDOG_SR_STATUS_NORMAL 0x0000U -#define U300_WDOG_SR_RESET_STATUS_RESET 0xE8B4U -/* WDOG_COUNT Register 32bit (R/-) */ -#define U300_WDOG_CR 0x14 -#define U300_WDOG_CR_VALID_IND 0x8000U -#define U300_WDOG_CR_VALID_STABLE 0x0000U -#define U300_WDOG_CR_COUNT_VALUE_MASK 0x7FFFU -/* WDOG_JTAGOVR Register 32bit (R/W) */ -#define U300_WDOG_JOR 0x18 -#define U300_WDOG_JOR_JTAG_MODE_IND 0x0002U -#define U300_WDOG_JOR_JTAG_WATCHDOG_ENABLE 0x0001U -/* WDOG_RESTART Register 32bit (-/W) */ -#define U300_WDOG_RR 0x1C -#define U300_WDOG_RR_RESTART_VALUE_RESUME 0xACEDU -/* WDOG_IRQ_EVENT Register 32bit (R/W) */ -#define U300_WDOG_IER 0x20 -#define U300_WDOG_IER_WILL_BARK_IRQ_EVENT_IND 0x0001U -#define U300_WDOG_IER_WILL_BARK_IRQ_ACK_ENABLE 0x0001U -/* WDOG_IRQ_MASK Register 32bit (R/W) */ -#define U300_WDOG_IMR 0x24 -#define U300_WDOG_IMR_WILL_BARK_IRQ_ENABLE 0x0001U -/* WDOG_IRQ_FORCE Register 32bit (R/W) */ -#define U300_WDOG_IFR 0x28 -#define U300_WDOG_IFR_WILL_BARK_IRQ_FORCE_ENABLE 0x0001U - -/* Default timeout in seconds = 1 minute */ -#define U300_WDOG_DEFAULT_TIMEOUT 60 - -static unsigned int margin; -static int irq; -static void __iomem *virtbase; -static struct device *parent; - -static struct clk *clk; - -/* - * Enabling and disabling functions. - */ -static void coh901327_enable(u16 timeout) -{ - u16 val; - unsigned long freq; - unsigned long delay_ns; - - /* Restart timer if it is disabled */ - val = readw(virtbase + U300_WDOG_D2R); - if (val == U300_WDOG_D2R_DISABLE_STATUS_DISABLED) - writew(U300_WDOG_RR_RESTART_VALUE_RESUME, - virtbase + U300_WDOG_RR); - /* Acknowledge any pending interrupt so it doesn't just fire off */ - writew(U300_WDOG_IER_WILL_BARK_IRQ_ACK_ENABLE, - virtbase + U300_WDOG_IER); - /* - * The interrupt is cleared in the 32 kHz clock domain. - * Wait 3 32 kHz cycles for it to take effect - */ - freq = clk_get_rate(clk); - delay_ns = DIV_ROUND_UP(1000000000, freq); /* Freq to ns and round up */ - delay_ns = 3 * delay_ns; /* Wait 3 cycles */ - ndelay(delay_ns); - /* Enable the watchdog interrupt */ - writew(U300_WDOG_IMR_WILL_BARK_IRQ_ENABLE, virtbase + U300_WDOG_IMR); - /* Activate the watchdog timer */ - writew(timeout, virtbase + U300_WDOG_TR); - /* Start the watchdog timer */ - writew(U300_WDOG_FR_FEED_RESTART_TIMER, virtbase + U300_WDOG_FR); - /* - * Extra read so that this change propagate in the watchdog. - */ - (void) readw(virtbase + U300_WDOG_CR); - val = readw(virtbase + U300_WDOG_D2R); - if (val != U300_WDOG_D2R_DISABLE_STATUS_ENABLED) - dev_err(parent, - "%s(): watchdog not enabled! D2R value %04x\n", - __func__, val); -} - -static void coh901327_disable(void) -{ - u16 val; - - /* Disable the watchdog interrupt if it is active */ - writew(0x0000U, virtbase + U300_WDOG_IMR); - /* If the watchdog is currently enabled, attempt to disable it */ - val = readw(virtbase + U300_WDOG_D2R); - if (val != U300_WDOG_D2R_DISABLE_STATUS_DISABLED) { - writew(U300_WDOG_D1R_DISABLE1_DISABLE_TIMER, - virtbase + U300_WDOG_D1R); - writew(U300_WDOG_D2R_DISABLE2_DISABLE_TIMER, - virtbase + U300_WDOG_D2R); - /* Write this twice (else problems occur) */ - writew(U300_WDOG_D2R_DISABLE2_DISABLE_TIMER, - virtbase + U300_WDOG_D2R); - } - val = readw(virtbase + U300_WDOG_D2R); - if (val != U300_WDOG_D2R_DISABLE_STATUS_DISABLED) - dev_err(parent, - "%s(): watchdog not disabled! D2R value %04x\n", - __func__, val); -} - -static int coh901327_start(struct watchdog_device *wdt_dev) -{ - coh901327_enable(wdt_dev->timeout * 100); - return 0; -} - -static int coh901327_stop(struct watchdog_device *wdt_dev) -{ - coh901327_disable(); - return 0; -} - -static int coh901327_ping(struct watchdog_device *wdd) -{ - /* Feed the watchdog */ - writew(U300_WDOG_FR_FEED_RESTART_TIMER, - virtbase + U300_WDOG_FR); - return 0; -} - -static int coh901327_settimeout(struct watchdog_device *wdt_dev, - unsigned int time) -{ - wdt_dev->timeout = time; - /* Set new timeout value */ - writew(time * 100, virtbase + U300_WDOG_TR); - /* Feed the dog */ - writew(U300_WDOG_FR_FEED_RESTART_TIMER, - virtbase + U300_WDOG_FR); - return 0; -} - -static unsigned int coh901327_gettimeleft(struct watchdog_device *wdt_dev) -{ - u16 val; - - /* Read repeatedly until the value is stable! */ - val = readw(virtbase + U300_WDOG_CR); - while (val & U300_WDOG_CR_VALID_IND) - val = readw(virtbase + U300_WDOG_CR); - val &= U300_WDOG_CR_COUNT_VALUE_MASK; - if (val != 0) - val /= 100; - - return val; -} - -/* - * This interrupt occurs 10 ms before the watchdog WILL bark. - */ -static irqreturn_t coh901327_interrupt(int irq, void *data) -{ - u16 val; - - /* - * Ack IRQ? If this occurs we're FUBAR anyway, so - * just acknowledge, disable the interrupt and await the imminent end. - * If you at some point need a host of callbacks to be called - * when the system is about to watchdog-reset, add them here! - * - * NOTE: on future versions of this IP-block, it will be possible - * to prevent a watchdog reset by feeding the watchdog at this - * point. - */ - val = readw(virtbase + U300_WDOG_IER); - if (val == U300_WDOG_IER_WILL_BARK_IRQ_EVENT_IND) - writew(U300_WDOG_IER_WILL_BARK_IRQ_ACK_ENABLE, - virtbase + U300_WDOG_IER); - writew(0x0000U, virtbase + U300_WDOG_IMR); - dev_crit(parent, "watchdog is barking!\n"); - return IRQ_HANDLED; -} - -static const struct watchdog_info coh901327_ident = { - .options = WDIOF_CARDRESET | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, - .identity = DRV_NAME, -}; - -static const struct watchdog_ops coh901327_ops = { - .owner = THIS_MODULE, - .start = coh901327_start, - .stop = coh901327_stop, - .ping = coh901327_ping, - .set_timeout = coh901327_settimeout, - .get_timeleft = coh901327_gettimeleft, -}; - -static struct watchdog_device coh901327_wdt = { - .info = &coh901327_ident, - .ops = &coh901327_ops, - /* - * Max timeout is 327 since the 10ms - * timeout register is max - * 0x7FFF = 327670ms ~= 327s. - */ - .min_timeout = 1, - .max_timeout = 327, - .timeout = U300_WDOG_DEFAULT_TIMEOUT, -}; - -static int __init coh901327_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - int ret; - u16 val; - - parent = dev; - - virtbase = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(virtbase)) - return PTR_ERR(virtbase); - - clk = clk_get(dev, NULL); - if (IS_ERR(clk)) { - ret = PTR_ERR(clk); - dev_err(dev, "could not get clock\n"); - return ret; - } - ret = clk_prepare_enable(clk); - if (ret) { - dev_err(dev, "could not prepare and enable clock\n"); - goto out_no_clk_enable; - } - - val = readw(virtbase + U300_WDOG_SR); - switch (val) { - case U300_WDOG_SR_STATUS_TIMED_OUT: - dev_info(dev, "watchdog timed out since last chip reset!\n"); - coh901327_wdt.bootstatus |= WDIOF_CARDRESET; - /* Status will be cleared below */ - break; - case U300_WDOG_SR_STATUS_NORMAL: - dev_info(dev, "in normal status, no timeouts have occurred.\n"); - break; - default: - dev_info(dev, "contains an illegal status code (%08x)\n", val); - break; - } - - val = readw(virtbase + U300_WDOG_D2R); - switch (val) { - case U300_WDOG_D2R_DISABLE_STATUS_DISABLED: - dev_info(dev, "currently disabled.\n"); - break; - case U300_WDOG_D2R_DISABLE_STATUS_ENABLED: - dev_info(dev, "currently enabled! (disabling it now)\n"); - coh901327_disable(); - break; - default: - dev_err(dev, "contains an illegal enable/disable code (%08x)\n", - val); - break; - } - - /* Reset the watchdog */ - writew(U300_WDOG_SR_RESET_STATUS_RESET, virtbase + U300_WDOG_SR); - - irq = platform_get_irq(pdev, 0); - if (request_irq(irq, coh901327_interrupt, 0, - DRV_NAME " Bark", pdev)) { - ret = -EIO; - goto out_no_irq; - } - - watchdog_init_timeout(&coh901327_wdt, margin, dev); - - coh901327_wdt.parent = dev; - ret = watchdog_register_device(&coh901327_wdt); - if (ret) - goto out_no_wdog; - - dev_info(dev, "initialized. (timeout=%d sec)\n", - coh901327_wdt.timeout); - return 0; - -out_no_wdog: - free_irq(irq, pdev); -out_no_irq: - clk_disable_unprepare(clk); -out_no_clk_enable: - clk_put(clk); - return ret; -} - -#ifdef CONFIG_PM - -static u16 wdogenablestore; -static u16 irqmaskstore; - -static int coh901327_suspend(struct platform_device *pdev, pm_message_t state) -{ - irqmaskstore = readw(virtbase + U300_WDOG_IMR) & 0x0001U; - wdogenablestore = readw(virtbase + U300_WDOG_D2R); - /* If watchdog is on, disable it here and now */ - if (wdogenablestore == U300_WDOG_D2R_DISABLE_STATUS_ENABLED) - coh901327_disable(); - return 0; -} - -static int coh901327_resume(struct platform_device *pdev) -{ - /* Restore the watchdog interrupt */ - writew(irqmaskstore, virtbase + U300_WDOG_IMR); - if (wdogenablestore == U300_WDOG_D2R_DISABLE_STATUS_ENABLED) { - /* Restart the watchdog timer */ - writew(U300_WDOG_RR_RESTART_VALUE_RESUME, - virtbase + U300_WDOG_RR); - writew(U300_WDOG_FR_FEED_RESTART_TIMER, - virtbase + U300_WDOG_FR); - } - return 0; -} -#else -#define coh901327_suspend NULL -#define coh901327_resume NULL -#endif - -/* - * Mistreating the watchdog is the only way to perform a software reset of the - * system on EMP platforms. So we implement this and export a symbol for it. - */ -void coh901327_watchdog_reset(void) -{ - /* Enable even if on JTAG too */ - writew(U300_WDOG_JOR_JTAG_WATCHDOG_ENABLE, - virtbase + U300_WDOG_JOR); - /* - * Timeout = 5s, we have to wait for the watchdog reset to - * actually take place: the watchdog will be reloaded with the - * default value immediately, so we HAVE to reboot and get back - * into the kernel in 30s, or the device will reboot again! - * The boot loader will typically deactivate the watchdog, so we - * need time enough for the boot loader to get to the point of - * deactivating the watchdog before it is shut down by it. - * - * NOTE: on future versions of the watchdog, this restriction is - * gone: the watchdog will be reloaded with a default value (1 min) - * instead of last value, and you can conveniently set the watchdog - * timeout to 10ms (value = 1) without any problems. - */ - coh901327_enable(500); - /* Return and await doom */ -} - -static const struct of_device_id coh901327_dt_match[] = { - { .compatible = "stericsson,coh901327" }, - {}, -}; - -static struct platform_driver coh901327_driver = { - .driver = { - .name = "coh901327_wdog", - .of_match_table = coh901327_dt_match, - .suppress_bind_attrs = true, - }, - .suspend = coh901327_suspend, - .resume = coh901327_resume, -}; -builtin_platform_driver_probe(coh901327_driver, coh901327_probe); - -/* not really modular, but ... */ -module_param(margin, uint, 0); -MODULE_PARM_DESC(margin, "Watchdog margin in seconds (default 60s)"); -- cgit v1.2.3 From 740c0a57b8f1e36301218bf549f3c9cc833a60be Mon Sep 17 00:00:00 2001 From: Alexander Usyskin Date: Sun, 24 Jan 2021 13:49:38 +0200 Subject: watchdog: mei_wdt: request stop on unregister The MEI bus has a special behavior on suspend it destroys all the attached devices, this is due to the fact that also firmware context is not persistent across power flows. If watchdog on MEI bus is ticking before suspending the firmware times out and reports that the OS is missing watchdog tick. Send the stop command to the firmware on watchdog unregistered to eliminate the false event on suspend. This does not make the things worse from the user-space perspective as a user-space should re-open watchdog device after suspending before this patch. Cc: Signed-off-by: Alexander Usyskin Signed-off-by: Tomas Winkler Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20210124114938.373885-1-tomas.winkler@intel.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/mei_wdt.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/watchdog') diff --git a/drivers/watchdog/mei_wdt.c b/drivers/watchdog/mei_wdt.c index 5391bf3e6b11..c5967d8b4256 100644 --- a/drivers/watchdog/mei_wdt.c +++ b/drivers/watchdog/mei_wdt.c @@ -382,6 +382,7 @@ static int mei_wdt_register(struct mei_wdt *wdt) watchdog_set_drvdata(&wdt->wdd, wdt); watchdog_stop_on_reboot(&wdt->wdd); + watchdog_stop_on_unregister(&wdt->wdd); ret = watchdog_register_device(&wdt->wdd); if (ret) -- cgit v1.2.3 From a4f3407c41605d14f09e490045d0609990cd5d94 Mon Sep 17 00:00:00 2001 From: Sai Prakash Ranjan Date: Tue, 26 Jan 2021 20:32:41 +0530 Subject: watchdog: qcom: Remove incorrect usage of QCOM_WDT_ENABLE_IRQ As per register documentation, QCOM_WDT_ENABLE_IRQ which is BIT(1) of watchdog control register is wakeup interrupt enable bit and not related to bark interrupt at all, BIT(0) is used for that. So remove incorrect usage of this bit when supporting bark irq for pre-timeout notification. Currently with this bit set and bark interrupt specified, pre-timeout notification and/or watchdog reset/bite does not occur. Fixes: 36375491a439 ("watchdog: qcom: support pre-timeout when the bark irq is available") Cc: stable@vger.kernel.org Signed-off-by: Sai Prakash Ranjan Reviewed-by: Guenter Roeck Reviewed-by: Stephen Boyd Link: https://lore.kernel.org/r/20210126150241.10009-1-saiprakash.ranjan@codeaurora.org Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/qcom-wdt.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'drivers/watchdog') diff --git a/drivers/watchdog/qcom-wdt.c b/drivers/watchdog/qcom-wdt.c index 7cf0f2ec649b..e38a87ffe5f5 100644 --- a/drivers/watchdog/qcom-wdt.c +++ b/drivers/watchdog/qcom-wdt.c @@ -22,7 +22,6 @@ enum wdt_reg { }; #define QCOM_WDT_ENABLE BIT(0) -#define QCOM_WDT_ENABLE_IRQ BIT(1) static const u32 reg_offset_data_apcs_tmr[] = { [WDT_RST] = 0x38, @@ -63,16 +62,6 @@ struct qcom_wdt *to_qcom_wdt(struct watchdog_device *wdd) return container_of(wdd, struct qcom_wdt, wdd); } -static inline int qcom_get_enable(struct watchdog_device *wdd) -{ - int enable = QCOM_WDT_ENABLE; - - if (wdd->pretimeout) - enable |= QCOM_WDT_ENABLE_IRQ; - - return enable; -} - static irqreturn_t qcom_wdt_isr(int irq, void *arg) { struct watchdog_device *wdd = arg; @@ -91,7 +80,7 @@ static int qcom_wdt_start(struct watchdog_device *wdd) writel(1, wdt_addr(wdt, WDT_RST)); writel(bark * wdt->rate, wdt_addr(wdt, WDT_BARK_TIME)); writel(wdd->timeout * wdt->rate, wdt_addr(wdt, WDT_BITE_TIME)); - writel(qcom_get_enable(wdd), wdt_addr(wdt, WDT_EN)); + writel(QCOM_WDT_ENABLE, wdt_addr(wdt, WDT_EN)); return 0; } -- cgit v1.2.3