[PATCH 09/11] watchdog: ftwdt010/aspeed: Merge Aspeed into FTWDT010

Guenter Roeck linux at roeck-us.net
Mon Aug 14 08:04:34 PDT 2017


On Sat, Aug 12, 2017 at 08:43:16PM +0200, Linus Walleij wrote:
> These two drivers is for the almost the same hardware,
> the only differences are:
> - The Aspeed IP block has been hacked to use a different
>   magic value.
> - The Aspeed has hard-wired 1MHz to the EXTCLK and
>   apparently even disabled the use of PCLK for clocking
>   the block on AST2500.
> 
Confused. I thought the ast2500 is an EC. Am I missing something ?

Guenter

> Delete the old Aspeed driver and augment the FTWDT010 to
> probe on this platform too. Select the driver by default
> for ARCH_ASPEED to make a smooth transition of the platform.
> 
> Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
> ---
>  drivers/watchdog/Kconfig        |  18 +---
>  drivers/watchdog/Makefile       |   1 -
>  drivers/watchdog/aspeed_wdt.c   | 200 ----------------------------------------
>  drivers/watchdog/ftwdt010_wdt.c |  25 ++++-
>  4 files changed, 25 insertions(+), 219 deletions(-)
>  delete mode 100644 drivers/watchdog/aspeed_wdt.c
> 
> diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
> index beef6bb5c6d9..0296fab14c35 100644
> --- a/drivers/watchdog/Kconfig
> +++ b/drivers/watchdog/Kconfig
> @@ -327,10 +327,11 @@ config FTWDT010_WATCHDOG
>  	select WATCHDOG_CORE
>  	default ARCH_GEMINI
>  	default ARCH_MOXART
> +	default ARCH_ASPEED
>  	help
>  	  Say Y here if to include support for the Faraday Technology
> -	  FTWDT010 watchdog timer embedded in the Cortina Systems Gemini
> -	  family of devices.
> +	  FTWDT010 watchdog timer embedded in the Cortina Systems Gemini,
> +	  MOXA ART and Aspeed families of devices.
>  
>  	  To compile this driver as a module, choose M here: the
>  	  module will be called ftwdt010_wdt.
> @@ -733,19 +734,6 @@ config RENESAS_RZAWDT
>  	  This driver adds watchdog support for the integrated watchdogs in the
>  	  Renesas RZ/A SoCs. These watchdogs can be used to reset a system.
>  
> -config ASPEED_WATCHDOG
> -	tristate "Aspeed 2400 watchdog support"
> -	depends on ARCH_ASPEED || COMPILE_TEST
> -	select WATCHDOG_CORE
> -	help
> -	  Say Y here to include support for the watchdog timer
> -	  in Apseed BMC SoCs.
> -
> -	  This driver is required to reboot the SoC.
> -
> -	  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
> diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
> index fcab71f0a1c7..a9701d39928d 100644
> --- a/drivers/watchdog/Makefile
> +++ b/drivers/watchdog/Makefile
> @@ -82,7 +82,6 @@ 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
>  obj-$(CONFIG_ZX2967_WATCHDOG) += zx2967_wdt.o
>  obj-$(CONFIG_STM32_WATCHDOG) += stm32_iwdg.o
>  obj-$(CONFIG_UNIPHIER_WATCHDOG) += uniphier_wdt.o
> diff --git a/drivers/watchdog/aspeed_wdt.c b/drivers/watchdog/aspeed_wdt.c
> deleted file mode 100644
> index 1c652582de40..000000000000
> --- a/drivers/watchdog/aspeed_wdt.c
> +++ /dev/null
> @@ -1,200 +0,0 @@
> -/*
> - * Copyright 2016 IBM Corporation
> - *
> - * Joel Stanley <joel at jms.id.au>
> - *
> - * This program is free software; you can redistribute it and/or
> - * modify it under the terms of the GNU General Public License
> - * as published by the Free Software Foundation; either version
> - * 2 of the License, or (at your option) any later version.
> - */
> -
> -#include <linux/delay.h>
> -#include <linux/io.h>
> -#include <linux/kernel.h>
> -#include <linux/module.h>
> -#include <linux/of.h>
> -#include <linux/platform_device.h>
> -#include <linux/watchdog.h>
> -
> -struct aspeed_wdt {
> -	struct watchdog_device	wdd;
> -	void __iomem		*base;
> -	u32			ctrl;
> -};
> -
> -static const struct of_device_id aspeed_wdt_of_table[] = {
> -	{ .compatible = "aspeed,ast2400-wdt" },
> -	{ .compatible = "aspeed,ast2500-wdt" },
> -	{ },
> -};
> -MODULE_DEVICE_TABLE(of, aspeed_wdt_of_table);
> -
> -#define WDT_STATUS		0x00
> -#define WDT_RELOAD_VALUE	0x04
> -#define WDT_RESTART		0x08
> -#define WDT_CTRL		0x0C
> -#define   WDT_CTRL_RESET_MODE_SOC	(0x00 << 5)
> -#define   WDT_CTRL_RESET_MODE_FULL_CHIP	(0x01 << 5)
> -#define   WDT_CTRL_1MHZ_CLK		BIT(4)
> -#define   WDT_CTRL_WDT_EXT		BIT(3)
> -#define   WDT_CTRL_WDT_INTR		BIT(2)
> -#define   WDT_CTRL_RESET_SYSTEM		BIT(1)
> -#define   WDT_CTRL_ENABLE		BIT(0)
> -
> -#define WDT_RESTART_MAGIC	0x4755
> -
> -/* 32 bits at 1MHz, in milliseconds */
> -#define WDT_MAX_TIMEOUT_MS	4294967
> -#define WDT_DEFAULT_TIMEOUT	30
> -#define WDT_RATE_1MHZ		1000000
> -
> -static struct aspeed_wdt *to_aspeed_wdt(struct watchdog_device *wdd)
> -{
> -	return container_of(wdd, struct aspeed_wdt, wdd);
> -}
> -
> -static void aspeed_wdt_enable(struct aspeed_wdt *wdt, int count)
> -{
> -	wdt->ctrl |= WDT_CTRL_ENABLE;
> -
> -	writel(0, wdt->base + WDT_CTRL);
> -	writel(count, wdt->base + WDT_RELOAD_VALUE);
> -	writel(WDT_RESTART_MAGIC, wdt->base + WDT_RESTART);
> -	writel(wdt->ctrl, wdt->base + WDT_CTRL);
> -}
> -
> -static int aspeed_wdt_start(struct watchdog_device *wdd)
> -{
> -	struct aspeed_wdt *wdt = to_aspeed_wdt(wdd);
> -
> -	aspeed_wdt_enable(wdt, wdd->timeout * WDT_RATE_1MHZ);
> -
> -	return 0;
> -}
> -
> -static int aspeed_wdt_stop(struct watchdog_device *wdd)
> -{
> -	struct aspeed_wdt *wdt = to_aspeed_wdt(wdd);
> -
> -	wdt->ctrl &= ~WDT_CTRL_ENABLE;
> -	writel(wdt->ctrl, wdt->base + WDT_CTRL);
> -
> -	return 0;
> -}
> -
> -static int aspeed_wdt_ping(struct watchdog_device *wdd)
> -{
> -	struct aspeed_wdt *wdt = to_aspeed_wdt(wdd);
> -
> -	writel(WDT_RESTART_MAGIC, wdt->base + WDT_RESTART);
> -
> -	return 0;
> -}
> -
> -static int aspeed_wdt_set_timeout(struct watchdog_device *wdd,
> -				  unsigned int timeout)
> -{
> -	struct aspeed_wdt *wdt = to_aspeed_wdt(wdd);
> -	u32 actual;
> -
> -	wdd->timeout = timeout;
> -
> -	actual = min(timeout, wdd->max_hw_heartbeat_ms * 1000);
> -
> -	writel(actual * WDT_RATE_1MHZ, wdt->base + WDT_RELOAD_VALUE);
> -	writel(WDT_RESTART_MAGIC, wdt->base + WDT_RESTART);
> -
> -	return 0;
> -}
> -
> -static int aspeed_wdt_restart(struct watchdog_device *wdd,
> -			      unsigned long action, void *data)
> -{
> -	struct aspeed_wdt *wdt = to_aspeed_wdt(wdd);
> -
> -	aspeed_wdt_enable(wdt, 128 * WDT_RATE_1MHZ / 1000);
> -
> -	mdelay(1000);
> -
> -	return 0;
> -}
> -
> -static const struct watchdog_ops aspeed_wdt_ops = {
> -	.start		= aspeed_wdt_start,
> -	.stop		= aspeed_wdt_stop,
> -	.ping		= aspeed_wdt_ping,
> -	.set_timeout	= aspeed_wdt_set_timeout,
> -	.restart	= aspeed_wdt_restart,
> -	.owner		= THIS_MODULE,
> -};
> -
> -static const struct watchdog_info aspeed_wdt_info = {
> -	.options	= WDIOF_KEEPALIVEPING
> -			| WDIOF_MAGICCLOSE
> -			| WDIOF_SETTIMEOUT,
> -	.identity	= KBUILD_MODNAME,
> -};
> -
> -static int aspeed_wdt_probe(struct platform_device *pdev)
> -{
> -	struct aspeed_wdt *wdt;
> -	struct resource *res;
> -	int ret;
> -
> -	wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
> -	if (!wdt)
> -		return -ENOMEM;
> -
> -	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> -	wdt->base = devm_ioremap_resource(&pdev->dev, res);
> -	if (IS_ERR(wdt->base))
> -		return PTR_ERR(wdt->base);
> -
> -	/*
> -	 * The ast2400 wdt can run at PCLK, or 1MHz. The ast2500 only
> -	 * runs at 1MHz. We chose to always run at 1MHz, as there's no
> -	 * good reason to have a faster watchdog counter.
> -	 */
> -	wdt->wdd.info = &aspeed_wdt_info;
> -	wdt->wdd.ops = &aspeed_wdt_ops;
> -	wdt->wdd.max_hw_heartbeat_ms = WDT_MAX_TIMEOUT_MS;
> -	wdt->wdd.parent = &pdev->dev;
> -
> -	wdt->wdd.timeout = WDT_DEFAULT_TIMEOUT;
> -	watchdog_init_timeout(&wdt->wdd, 0, &pdev->dev);
> -
> -	/*
> -	 * Control reset on a per-device basis to ensure the
> -	 * host is not affected by a BMC reboot, so only reset
> -	 * the SOC and not the full chip
> -	 */
> -	wdt->ctrl = WDT_CTRL_RESET_MODE_SOC |
> -		WDT_CTRL_1MHZ_CLK |
> -		WDT_CTRL_RESET_SYSTEM;
> -
> -	if (readl(wdt->base + WDT_CTRL) & WDT_CTRL_ENABLE)  {
> -		aspeed_wdt_start(&wdt->wdd);
> -		set_bit(WDOG_HW_RUNNING, &wdt->wdd.status);
> -	}
> -
> -	ret = devm_watchdog_register_device(&pdev->dev, &wdt->wdd);
> -	if (ret) {
> -		dev_err(&pdev->dev, "failed to register\n");
> -		return ret;
> -	}
> -
> -	return 0;
> -}
> -
> -static struct platform_driver aspeed_watchdog_driver = {
> -	.probe = aspeed_wdt_probe,
> -	.driver = {
> -		.name = KBUILD_MODNAME,
> -		.of_match_table = of_match_ptr(aspeed_wdt_of_table),
> -	},
> -};
> -module_platform_driver(aspeed_watchdog_driver);
> -
> -MODULE_DESCRIPTION("Aspeed Watchdog Driver");
> -MODULE_LICENSE("GPL");
> diff --git a/drivers/watchdog/ftwdt010_wdt.c b/drivers/watchdog/ftwdt010_wdt.c
> index 912b55e67110..072da594bcbd 100644
> --- a/drivers/watchdog/ftwdt010_wdt.c
> +++ b/drivers/watchdog/ftwdt010_wdt.c
> @@ -7,6 +7,8 @@
>   * Copyright (C) 2009 Paulius Zaleckas <paulius.zaleckas at teltonika.lt>
>   * Inspired by the MOXA ART driver from Jonas Jensen:
>   * Copyright (C) 2013 Jonas Jensen <jonas.jensen at gmail.com>
> + * Inspired by the Aspeed driver from Joel Stanley <joel at jms.id.au>:
> + * Copyright 2016 IBM Corporation
>   *
>   * 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
> @@ -32,7 +34,9 @@
>  #define FTWDT010_WDCR		0xC
>  
>  #define WDRESTART_MAGIC		0x5AB9
> +#define ASPEED_MAGIC		0x4755
>  
> +#define ASPEED_RESET_FULL_CHIP	BIT(5)
>  #define WDCR_EXTCLK		BIT(4)
>  #define WDCR_WDEXT		BIT(3)
>  #define WDCR_WDINTR		BIT(2)
> @@ -48,6 +52,7 @@ struct ftwdt010_wdt {
>  	struct clk		*extclk;
>  	unsigned int		clk_freq;
>  	bool			use_extclk;
> +	u32			magic;
>  };
>  
>  static inline
> @@ -63,7 +68,7 @@ static int ftwdt010_wdt_restart(struct watchdog_device *wdd,
>  	u32 enable;
>  
>  	writel(1, gwdt->base + FTWDT010_WDLOAD);
> -	writel(WDRESTART_MAGIC, gwdt->base + FTWDT010_WDRESTART);
> +	writel(gwdt->magic, gwdt->base + FTWDT010_WDRESTART);
>  	enable = WDCR_SYS_RST | WDCR_ENABLE;
>  	if (gwdt->use_extclk)
>  		enable |= WDCR_EXTCLK;
> @@ -78,7 +83,7 @@ static int ftwdt010_wdt_start(struct watchdog_device *wdd)
>  	u32 enable;
>  
>  	writel(wdd->timeout * gwdt->clk_freq, gwdt->base + FTWDT010_WDLOAD);
> -	writel(WDRESTART_MAGIC, gwdt->base + FTWDT010_WDRESTART);
> +	writel(gwdt->magic, gwdt->base + FTWDT010_WDRESTART);
>  	/* set clock before enabling */
>  	enable = WDCR_SYS_RST;
>  	if (gwdt->use_extclk)
> @@ -105,7 +110,7 @@ static int ftwdt010_wdt_ping(struct watchdog_device *wdd)
>  {
>  	struct ftwdt010_wdt *gwdt = to_ftwdt010_wdt(wdd);
>  
> -	writel(WDRESTART_MAGIC, gwdt->base + FTWDT010_WDRESTART);
> +	writel(gwdt->magic, gwdt->base + FTWDT010_WDRESTART);
>  
>  	return 0;
>  }
> @@ -153,6 +158,7 @@ static int ftwdt010_wdt_probe(struct platform_device *pdev)
>  	struct resource *res;
>  	struct ftwdt010_wdt *gwdt;
>  	unsigned int reg;
> +	bool is_aspeed;
>  	int irq;
>  	int ret;
>  
> @@ -167,6 +173,10 @@ static int ftwdt010_wdt_probe(struct platform_device *pdev)
>  
>  	gwdt->use_extclk = of_property_read_bool(np, "faraday,use-extclk");
>  
> +	/* We want to know if we are aspeed */
> +	is_aspeed = of_device_is_compatible(np, "aspeed,ast2400-wdt") ||
> +		of_device_is_compatible(np, "aspeed,ast2500-wdt");
> +
>  	gwdt->pclk = devm_clk_get(dev, "PCLK");
>  	if (!IS_ERR(gwdt->pclk)) {
>  		ret = clk_prepare_enable(gwdt->pclk);
> @@ -198,6 +208,11 @@ static int ftwdt010_wdt_probe(struct platform_device *pdev)
>  			gwdt->use_extclk = true;
>  			dev_info(dev, "assume 5MHz EXTCLK on Gemini\n");
>  		}
> +		if (is_aspeed) {
> +			gwdt->clk_freq = 1000000;
> +			gwdt->use_extclk = true;
> +			dev_info(dev, "assume 1MHz EXTCLK on Aspeed\n");
> +		}
>  	}
>  
>  	if (gwdt->clk_freq == 0) {
> @@ -211,6 +226,10 @@ static int ftwdt010_wdt_probe(struct platform_device *pdev)
>  	gwdt->wdd.min_timeout = 1;
>  	gwdt->wdd.max_timeout = UINT_MAX / gwdt->clk_freq;
>  	gwdt->wdd.parent = dev;
> +	if (is_aspeed)
> +		gwdt->magic = ASPEED_MAGIC;
> +	else
> +		gwdt->magic = WDRESTART_MAGIC;
>  
>  	/*
>  	 * If 'timeout-sec' unspecified in devicetree, assume a 13 second
> -- 
> 2.13.4
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html



More information about the linux-arm-kernel mailing list