Re: [PATCH v2 3/3] watchdog: Add tegra watchdog
On 02/03/2014 05:17 PM, Andrew Chew wrote: > Add a driver for the hardware watchdogs in NVIDIA Tegra SoCs (tegra30 and s/tegra30/Tegra30/ > later). This driver will configure one watchdog timer that will reset the > system in the case of a watchdog timeout. > > This driver binds to the nvidia,tegra30-timer device node and gets its > register base from there. > diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig > +config TEGRA_WATCHDOG > + tristate "Tegra watchdog" > + depends on ARCH_TEGRA || COMPILE_TEST ? > diff --git a/drivers/watchdog/tegra_wdt.c b/drivers/watchdog/tegra_wdt.c > +static int tegra_wdt_probe(struct platform_device *pdev) > + /* This is the timer base. */ > + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); > + if (!res) { ... > + mem = devm_request_mem_region(>dev, res->start, > + resource_size(res), > + pdev->name); > + if (!mem) { ... > + regs = devm_ioremap(>dev, mem->start, > + resource_size(mem)); > + if (!regs) { ... I forget exactly which of those, but I think at least one/some of those don't need to be error-checked, since the later functions will detect an error input, and return an appropriate error code, so they can be chained together while only error-checking the final result. > +static int tegra_wdt_remove(struct platform_device *pdev) > + platform_set_drvdata(pdev, NULL); There's no need to do that; the value of drvdata is irrelevant when the device isn't probed, so there's no need for it to be NULL. > +static struct platform_driver tegra_wdt_driver = { > + .probe = tegra_wdt_probe, > + .remove = tegra_wdt_remove, > +#ifdef CONFIG_PM > + .suspend= tegra_wdt_suspend, > + .resume = tegra_wdt_resume, > +#endif I think for suspend/resume, you'd usually set it up like: static const struct dev_pm_ops tegra20_i2s_pm_ops = { SET_RUNTIME_PM_OPS(tegra20_i2s_runtime_suspend, tegra20_i2s_runtime_resume, NULL) }; static struct platform_driver tegra20_i2s_driver = { .driver = { ... .pm = _i2s_pm_ops, }, ... }; > + .driver = { > + .owner = THIS_MODULE, > + .name = "tegra-wdt", > + .of_match_table = tegra_wdt_of_match, > + }, > +}; > + > +module_platform_driver(tegra_wdt_driver); No need for the blank line before module_platform_driver(). > +MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); > +MODULE_ALIAS("platform:tegra-wdt"); You don't need at least that second alias; everything binds to the MODULE_DEVICE_TABLE() now with DT. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v2 3/3] watchdog: Add tegra watchdog
On 02/03/2014 05:17 PM, Andrew Chew wrote: Add a driver for the hardware watchdogs in NVIDIA Tegra SoCs (tegra30 and s/tegra30/Tegra30/ later). This driver will configure one watchdog timer that will reset the system in the case of a watchdog timeout. This driver binds to the nvidia,tegra30-timer device node and gets its register base from there. diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig +config TEGRA_WATCHDOG + tristate Tegra watchdog + depends on ARCH_TEGRA || COMPILE_TEST ? diff --git a/drivers/watchdog/tegra_wdt.c b/drivers/watchdog/tegra_wdt.c +static int tegra_wdt_probe(struct platform_device *pdev) + /* This is the timer base. */ + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { ... + mem = devm_request_mem_region(pdev-dev, res-start, + resource_size(res), + pdev-name); + if (!mem) { ... + regs = devm_ioremap(pdev-dev, mem-start, + resource_size(mem)); + if (!regs) { ... I forget exactly which of those, but I think at least one/some of those don't need to be error-checked, since the later functions will detect an error input, and return an appropriate error code, so they can be chained together while only error-checking the final result. +static int tegra_wdt_remove(struct platform_device *pdev) + platform_set_drvdata(pdev, NULL); There's no need to do that; the value of drvdata is irrelevant when the device isn't probed, so there's no need for it to be NULL. +static struct platform_driver tegra_wdt_driver = { + .probe = tegra_wdt_probe, + .remove = tegra_wdt_remove, +#ifdef CONFIG_PM + .suspend= tegra_wdt_suspend, + .resume = tegra_wdt_resume, +#endif I think for suspend/resume, you'd usually set it up like: static const struct dev_pm_ops tegra20_i2s_pm_ops = { SET_RUNTIME_PM_OPS(tegra20_i2s_runtime_suspend, tegra20_i2s_runtime_resume, NULL) }; static struct platform_driver tegra20_i2s_driver = { .driver = { ... .pm = tegra20_i2s_pm_ops, }, ... }; + .driver = { + .owner = THIS_MODULE, + .name = tegra-wdt, + .of_match_table = tegra_wdt_of_match, + }, +}; + +module_platform_driver(tegra_wdt_driver); No need for the blank line before module_platform_driver(). +MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); +MODULE_ALIAS(platform:tegra-wdt); You don't need at least that second alias; everything binds to the MODULE_DEVICE_TABLE() now with DT. -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 3/3] watchdog: Add tegra watchdog
Add a driver for the hardware watchdogs in NVIDIA Tegra SoCs (tegra30 and later). This driver will configure one watchdog timer that will reset the system in the case of a watchdog timeout. This driver binds to the nvidia,tegra30-timer device node and gets its register base from there. Signed-off-by: Andrew Chew --- Documentation/watchdog/watchdog-parameters.txt | 5 + drivers/watchdog/Kconfig | 11 + drivers/watchdog/Makefile | 1 + drivers/watchdog/tegra_wdt.c | 372 + 4 files changed, 389 insertions(+) create mode 100644 drivers/watchdog/tegra_wdt.c diff --git a/Documentation/watchdog/watchdog-parameters.txt b/Documentation/watchdog/watchdog-parameters.txt index f9492fe..b39f355 100644 --- a/Documentation/watchdog/watchdog-parameters.txt +++ b/Documentation/watchdog/watchdog-parameters.txt @@ -325,6 +325,11 @@ soft_noboot: Softdog action, set to 1 to ignore reboots, 0 to reboot stmp3xxx_wdt: heartbeat: Watchdog heartbeat period in seconds from 1 to 4194304, default 19 - +tegra_wdt: +heartbeat: Watchdog heartbeats in seconds. (default = 120) +nowayout: Watchdog cannot be stopped once started + (default=kernel config parameter) +- ts72xx_wdt: timeout: Watchdog timeout in seconds. (1 <= timeout <= 8, default=8) nowayout: Disable watchdog shutdown on close diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 4c4c566..2852447 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -420,6 +420,17 @@ config SIRFSOC_WATCHDOG Support for CSR SiRFprimaII and SiRFatlasVI watchdog. When the watchdog triggers the system will be reset. +config TEGRA_WATCHDOG + tristate "Tegra watchdog" + depends on ARCH_TEGRA + select WATCHDOG_CORE + help + Say Y here to include support for the watchdog timer + embedded in NVIDIA Tegra SoCs. + + To compile this driver as a module, choose M here: the + module will be called tegra_wdt. + # AVR32 Architecture config AT32AP700X_WDT diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 985a66c..1b5f3d5 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -58,6 +58,7 @@ obj-$(CONFIG_BCM2835_WDT) += bcm2835_wdt.o obj-$(CONFIG_MOXART_WDT) += moxart_wdt.o obj-$(CONFIG_SIRFSOC_WATCHDOG) += sirfsoc_wdt.o obj-$(CONFIG_BCM_KONA_WDT) += bcm_kona_wdt.o +obj-$(CONFIG_TEGRA_WATCHDOG) += tegra_wdt.o # AVR32 Architecture obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o diff --git a/drivers/watchdog/tegra_wdt.c b/drivers/watchdog/tegra_wdt.c new file mode 100644 index 000..eebe7fc --- /dev/null +++ b/drivers/watchdog/tegra_wdt.c @@ -0,0 +1,372 @@ +/* + * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* minimum and maximum watchdog trigger timeout, in seconds */ +#define MIN_WDT_TIMEOUT1 +#define MAX_WDT_TIMEOUT255 + +/* + * Base of the WDT registers, from the timer base address. There are + * actually 5 watchdogs that can be configured (by pairing with an available + * timer), at bases 0x100 + (WDT ID) * 0x20, where WDT ID is 0 through 4. + * This driver only configures the first watchdog (WDT ID 0). + */ +#define WDT_BASE 0x100 +#define WDT_ID 0 +#define WDT_TIMER_BASE TEGRA30_TIMER_WDT_BASE +#define WDT_TIMER_ID TEGRA30_TIMER_WDT_ID + +/* WDT registers */ +#define WDT_CFG0x0 +#define WDT_CFG_PERIOD_SHIFT 4 +#define WDT_CFG_PERIOD_MASK0xff +#define WDT_CFG_INT_EN (1 << 12) +#define WDT_CFG_PMC2CAR_RST_EN (1 << 15) +#define WDT_STS0x4 +#define WDT_STS_COUNT_SHIFT4 +#define WDT_STS_COUNT_MASK 0xff +#define WDT_STS_EXP_SHIFT 12 +#define WDT_STS_EXP_MASK 0x3 +#define WDT_CMD0x8 +#define WDT_CMD_START_COUNTER (1 << 0) +#define WDT_CMD_DISABLE_COUNTER(1 << 1) +#define WDT_UNLOCK (0xc) +#define WDT_UNLOCK_PATTERN (0xc45a << 0) + +/* Timer registers */ +#define TIMER_PTV 0x0
[PATCH v2 3/3] watchdog: Add tegra watchdog
Add a driver for the hardware watchdogs in NVIDIA Tegra SoCs (tegra30 and later). This driver will configure one watchdog timer that will reset the system in the case of a watchdog timeout. This driver binds to the nvidia,tegra30-timer device node and gets its register base from there. Signed-off-by: Andrew Chew ac...@nvidia.com --- Documentation/watchdog/watchdog-parameters.txt | 5 + drivers/watchdog/Kconfig | 11 + drivers/watchdog/Makefile | 1 + drivers/watchdog/tegra_wdt.c | 372 + 4 files changed, 389 insertions(+) create mode 100644 drivers/watchdog/tegra_wdt.c diff --git a/Documentation/watchdog/watchdog-parameters.txt b/Documentation/watchdog/watchdog-parameters.txt index f9492fe..b39f355 100644 --- a/Documentation/watchdog/watchdog-parameters.txt +++ b/Documentation/watchdog/watchdog-parameters.txt @@ -325,6 +325,11 @@ soft_noboot: Softdog action, set to 1 to ignore reboots, 0 to reboot stmp3xxx_wdt: heartbeat: Watchdog heartbeat period in seconds from 1 to 4194304, default 19 - +tegra_wdt: +heartbeat: Watchdog heartbeats in seconds. (default = 120) +nowayout: Watchdog cannot be stopped once started + (default=kernel config parameter) +- ts72xx_wdt: timeout: Watchdog timeout in seconds. (1 = timeout = 8, default=8) nowayout: Disable watchdog shutdown on close diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 4c4c566..2852447 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -420,6 +420,17 @@ config SIRFSOC_WATCHDOG Support for CSR SiRFprimaII and SiRFatlasVI watchdog. When the watchdog triggers the system will be reset. +config TEGRA_WATCHDOG + tristate Tegra watchdog + depends on ARCH_TEGRA + select WATCHDOG_CORE + help + Say Y here to include support for the watchdog timer + embedded in NVIDIA Tegra SoCs. + + To compile this driver as a module, choose M here: the + module will be called tegra_wdt. + # AVR32 Architecture config AT32AP700X_WDT diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 985a66c..1b5f3d5 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -58,6 +58,7 @@ obj-$(CONFIG_BCM2835_WDT) += bcm2835_wdt.o obj-$(CONFIG_MOXART_WDT) += moxart_wdt.o obj-$(CONFIG_SIRFSOC_WATCHDOG) += sirfsoc_wdt.o obj-$(CONFIG_BCM_KONA_WDT) += bcm_kona_wdt.o +obj-$(CONFIG_TEGRA_WATCHDOG) += tegra_wdt.o # AVR32 Architecture obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o diff --git a/drivers/watchdog/tegra_wdt.c b/drivers/watchdog/tegra_wdt.c new file mode 100644 index 000..eebe7fc --- /dev/null +++ b/drivers/watchdog/tegra_wdt.c @@ -0,0 +1,372 @@ +/* + * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include linux/kernel.h +#include linux/module.h +#include linux/interrupt.h +#include linux/io.h +#include linux/of.h +#include linux/platform_device.h +#include linux/miscdevice.h +#include linux/watchdog.h + +#include clocksource/tegra_timer.h + +/* minimum and maximum watchdog trigger timeout, in seconds */ +#define MIN_WDT_TIMEOUT1 +#define MAX_WDT_TIMEOUT255 + +/* + * Base of the WDT registers, from the timer base address. There are + * actually 5 watchdogs that can be configured (by pairing with an available + * timer), at bases 0x100 + (WDT ID) * 0x20, where WDT ID is 0 through 4. + * This driver only configures the first watchdog (WDT ID 0). + */ +#define WDT_BASE 0x100 +#define WDT_ID 0 +#define WDT_TIMER_BASE TEGRA30_TIMER_WDT_BASE +#define WDT_TIMER_ID TEGRA30_TIMER_WDT_ID + +/* WDT registers */ +#define WDT_CFG0x0 +#define WDT_CFG_PERIOD_SHIFT 4 +#define WDT_CFG_PERIOD_MASK0xff +#define WDT_CFG_INT_EN (1 12) +#define WDT_CFG_PMC2CAR_RST_EN (1 15) +#define WDT_STS0x4 +#define WDT_STS_COUNT_SHIFT4 +#define WDT_STS_COUNT_MASK 0xff +#define WDT_STS_EXP_SHIFT 12 +#define WDT_STS_EXP_MASK 0x3 +#define WDT_CMD0x8 +#define WDT_CMD_START_COUNTER (1 0) +#define WDT_CMD_DISABLE_COUNTER(1 1) +#define