Re: [PATCH v2 3/3] watchdog: Add tegra watchdog

2014-02-05 Thread Stephen Warren
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

2014-02-05 Thread Stephen Warren
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

2014-02-03 Thread Andrew Chew
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

2014-02-03 Thread Andrew Chew
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