* [PATCH RESEND V3 0/3] Watchdog: OMAP3: bootstatus fix and changes for the current watchdog framework
@ 2012-07-15 7:44 ` Zumeng Chen
0 siblings, 0 replies; 21+ messages in thread
From: Zumeng Chen @ 2012-07-15 7:44 UTC (permalink / raw)
To: khilman, shubhrajyoti, linux-watchdog, hvaibhav
Cc: wim, linux-omap, tony, paul.gortmaker, linux-arm-kernel
Hello,
The following patches based on the 3.5-rc6 from Wim, which
focus on:
1. bootstatus fix for omap3,
2. omap-wdt framework update cater for the current framework
as Shubhrajyoti comments mentioned.
V3 changes:
1. New comments updated as Kevin mentioned in the third patch;
2. 3530evm works well,
AM33xx seems work well with the following changes:
+ if (cpu_is_am335x())
+ return omap2_prm_read_mod_reg(AM33XX_PRM_DEVICE_MOD,
+ AM33XX_PRM_RSTST_OFFSET) & 0x7f;
But since some definitions not ready for am33xx, so I don't
give the patch, if they have been updated, feel free to take these.
Regards,
Zumeng Chen (3):
Watchdog: Omap: Changes for the new watchdog framework
Watchdog: Omap: select watchdog core for framework change
Watchdog: Omap: get the bootstatus for OMAP34xx
arch/arm/mach-omap2/prcm.c | 9 +-
drivers/watchdog/Kconfig | 1 +
drivers/watchdog/omap_wdt.c | 342 ++++++++++++++++---------------------------
drivers/watchdog/omap_wdt.h | 5 +
4 files changed, 136 insertions(+), 221 deletions(-)
--
1.7.5.4
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH RESEND V3 0/3] Watchdog: OMAP3: bootstatus fix and changes for the current watchdog framework
@ 2012-07-15 7:44 ` Zumeng Chen
0 siblings, 0 replies; 21+ messages in thread
From: Zumeng Chen @ 2012-07-15 7:44 UTC (permalink / raw)
To: khilman, shubhrajyoti, linux-watchdog, hvaibhav
Cc: wim, linux-omap, tony, paul.gortmaker, linux-arm-kernel
Hello,
The following patches based on the 3.5-rc6 from Wim, which
focus on:
1. bootstatus fix for omap3,
2. omap-wdt framework update cater for the current framework
as Shubhrajyoti comments mentioned.
V3 changes:
1. New comments updated as Kevin mentioned in the third patch;
2. 3530evm works well,
AM33xx seems work well with the following changes:
+ if (cpu_is_am335x())
+ return omap2_prm_read_mod_reg(AM33XX_PRM_DEVICE_MOD,
+ AM33XX_PRM_RSTST_OFFSET) & 0x7f;
But since some definitions not ready for am33xx, so I don't
give the patch, if they have been updated, feel free to take these.
Regards,
Zumeng Chen (3):
Watchdog: Omap: Changes for the new watchdog framework
Watchdog: Omap: select watchdog core for framework change
Watchdog: Omap: get the bootstatus for OMAP34xx
arch/arm/mach-omap2/prcm.c | 9 +-
drivers/watchdog/Kconfig | 1 +
drivers/watchdog/omap_wdt.c | 342 ++++++++++++++++---------------------------
drivers/watchdog/omap_wdt.h | 5 +
4 files changed, 136 insertions(+), 221 deletions(-)
--
1.7.5.4
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH RESEND V3 0/3] Watchdog: OMAP3: bootstatus fix and changes for the current watchdog framework
@ 2012-07-15 7:44 ` Zumeng Chen
0 siblings, 0 replies; 21+ messages in thread
From: Zumeng Chen @ 2012-07-15 7:44 UTC (permalink / raw)
To: linux-arm-kernel
Hello,
The following patches based on the 3.5-rc6 from Wim, which
focus on:
1. bootstatus fix for omap3,
2. omap-wdt framework update cater for the current framework
as Shubhrajyoti comments mentioned.
V3 changes:
1. New comments updated as Kevin mentioned in the third patch;
2. 3530evm works well,
AM33xx seems work well with the following changes:
+ if (cpu_is_am335x())
+ return omap2_prm_read_mod_reg(AM33XX_PRM_DEVICE_MOD,
+ AM33XX_PRM_RSTST_OFFSET) & 0x7f;
But since some definitions not ready for am33xx, so I don't
give the patch, if they have been updated, feel free to take these.
Regards,
Zumeng Chen (3):
Watchdog: Omap: Changes for the new watchdog framework
Watchdog: Omap: select watchdog core for framework change
Watchdog: Omap: get the bootstatus for OMAP34xx
arch/arm/mach-omap2/prcm.c | 9 +-
drivers/watchdog/Kconfig | 1 +
drivers/watchdog/omap_wdt.c | 342 ++++++++++++++++---------------------------
drivers/watchdog/omap_wdt.h | 5 +
4 files changed, 136 insertions(+), 221 deletions(-)
--
1.7.5.4
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH RESEND v3 1/3] Watchdog: Omap: Changes for the new watchdog framework
2012-07-15 7:44 ` Zumeng Chen
(?)
@ 2012-07-15 7:44 ` Zumeng Chen
-1 siblings, 0 replies; 21+ messages in thread
From: Zumeng Chen @ 2012-07-15 7:44 UTC (permalink / raw)
To: khilman, shubhrajyoti, linux-watchdog, hvaibhav
Cc: wim, linux-omap, tony, paul.gortmaker, linux-arm-kernel
This patch implements the current watchdog framework for OMAP WDTimer,
which factored out the common components, so the driver can just focus
on the hardware related parts.
Signed-off-by: Zumeng Chen <zumeng.chen@windriver.com>
---
drivers/watchdog/omap_wdt.c | 342 ++++++++++++++++---------------------------
drivers/watchdog/omap_wdt.h | 5 +
2 files changed, 128 insertions(+), 219 deletions(-)
diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c
index 8285d65..cc5bc3e 100644
--- a/drivers/watchdog/omap_wdt.c
+++ b/drivers/watchdog/omap_wdt.c
@@ -24,6 +24,9 @@
*
* Copyright (c) 2005 David Brownell
* Use the driver model and standard identifiers; handle bigger timeouts.
+ *
+ * Copyright (c) 2012 WindRiver
+ * Changes cater for the current watchdog framework.
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@@ -33,7 +36,6 @@
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/mm.h>
-#include <linux/miscdevice.h>
#include <linux/watchdog.h>
#include <linux/reboot.h>
#include <linux/init.h>
@@ -50,8 +52,6 @@
#include "omap_wdt.h"
-static struct platform_device *omap_wdt_dev;
-
static unsigned timer_margin;
module_param(timer_margin, uint, 0);
MODULE_PARM_DESC(timer_margin, "initial watchdog timeout (in seconds)");
@@ -59,32 +59,14 @@ MODULE_PARM_DESC(timer_margin, "initial watchdog timeout (in seconds)");
static unsigned int wdt_trgr_pattern = 0x1234;
static DEFINE_SPINLOCK(wdt_lock);
-struct omap_wdt_dev {
+struct omap_wdt_drvdata {
+ struct watchdog_device wdt;
void __iomem *base; /* physical */
struct device *dev;
- int omap_wdt_users;
struct resource *mem;
- struct miscdevice omap_wdt_miscdev;
};
-static void omap_wdt_ping(struct omap_wdt_dev *wdev)
-{
- void __iomem *base = wdev->base;
-
- /* wait for posted write to complete */
- while ((__raw_readl(base + OMAP_WATCHDOG_WPS)) & 0x08)
- cpu_relax();
-
- wdt_trgr_pattern = ~wdt_trgr_pattern;
- __raw_writel(wdt_trgr_pattern, (base + OMAP_WATCHDOG_TGR));
-
- /* wait for posted write to complete */
- while ((__raw_readl(base + OMAP_WATCHDOG_WPS)) & 0x08)
- cpu_relax();
- /* reloaded WCRR from WLDR */
-}
-
-static void omap_wdt_enable(struct omap_wdt_dev *wdev)
+static void omap_wdt_enable(struct omap_wdt_drvdata *wdev)
{
void __iomem *base = wdev->base;
@@ -98,7 +80,7 @@ static void omap_wdt_enable(struct omap_wdt_dev *wdev)
cpu_relax();
}
-static void omap_wdt_disable(struct omap_wdt_dev *wdev)
+static void omap_wdt_disable(struct omap_wdt_drvdata *wdev)
{
void __iomem *base = wdev->base;
@@ -121,12 +103,19 @@ static void omap_wdt_adjust_timeout(unsigned new_timeout)
timer_margin = new_timeout;
}
-static void omap_wdt_set_timeout(struct omap_wdt_dev *wdev)
+static int omap_wdt_set_timeout(struct watchdog_device *wdt_dev,
+ unsigned int new_timeout)
{
- u32 pre_margin = GET_WLDR_VAL(timer_margin);
- void __iomem *base = wdev->base;
+ u32 pre_margin;
+ struct omap_wdt_drvdata *omap_wdev = watchdog_get_drvdata(wdt_dev);
+ void __iomem *base = omap_wdev->base;
- pm_runtime_get_sync(wdev->dev);
+ pm_runtime_get_sync(omap_wdev->dev);
+ omap_wdt_disable(omap_wdev);
+
+ /* adjust timeout based on the new timeout */
+ omap_wdt_adjust_timeout(new_timeout);
+ pre_margin = GET_WLDR_VAL(timer_margin);
/* just count up at 32 KHz */
while (__raw_readl(base + OMAP_WATCHDOG_WPS) & 0x04)
@@ -136,147 +125,88 @@ static void omap_wdt_set_timeout(struct omap_wdt_dev *wdev)
while (__raw_readl(base + OMAP_WATCHDOG_WPS) & 0x04)
cpu_relax();
- pm_runtime_put_sync(wdev->dev);
+ omap_wdt_enable(omap_wdev);
+ wdt_dev->timeout = new_timeout;
+ pm_runtime_put_sync(omap_wdev->dev);
+ return 0;
}
-/*
- * Allow only one task to hold it open
- */
-static int omap_wdt_open(struct inode *inode, struct file *file)
+static int omap_wdt_ping(struct watchdog_device *wdt_dev)
{
- struct omap_wdt_dev *wdev = platform_get_drvdata(omap_wdt_dev);
- void __iomem *base = wdev->base;
-
- if (test_and_set_bit(1, (unsigned long *)&(wdev->omap_wdt_users)))
- return -EBUSY;
-
- pm_runtime_get_sync(wdev->dev);
+ struct omap_wdt_drvdata *omap_wdev = watchdog_get_drvdata(wdt_dev);
+ void __iomem *base = omap_wdev->base;
- /* initialize prescaler */
- while (__raw_readl(base + OMAP_WATCHDOG_WPS) & 0x01)
- cpu_relax();
+ pm_runtime_get_sync(omap_wdev->dev);
+ spin_lock(&wdt_lock);
- __raw_writel((1 << 5) | (PTV << 2), base + OMAP_WATCHDOG_CNTRL);
- while (__raw_readl(base + OMAP_WATCHDOG_WPS) & 0x01)
+ /* wait for posted write to complete */
+ while ((__raw_readl(base + OMAP_WATCHDOG_WPS)) & 0x08)
cpu_relax();
- file->private_data = (void *) wdev;
+ wdt_trgr_pattern = ~wdt_trgr_pattern;
+ __raw_writel(wdt_trgr_pattern, (base + OMAP_WATCHDOG_TGR));
- omap_wdt_set_timeout(wdev);
- omap_wdt_ping(wdev); /* trigger loading of new timeout value */
- omap_wdt_enable(wdev);
+ /* wait for posted write to complete */
+ /* reloaded WCRR from WLDR */
+ while ((__raw_readl(base + OMAP_WATCHDOG_WPS)) & 0x08)
+ cpu_relax();
- pm_runtime_put_sync(wdev->dev);
+ spin_unlock(&wdt_lock);
+ pm_runtime_put_sync(omap_wdev->dev);
- return nonseekable_open(inode, file);
+ return 0;
}
-static int omap_wdt_release(struct inode *inode, struct file *file)
+static int omap_wdt_start(struct watchdog_device *wdt_dev)
{
- struct omap_wdt_dev *wdev = file->private_data;
+ struct omap_wdt_drvdata *omap_wdev = watchdog_get_drvdata(wdt_dev);
+ void __iomem *base = omap_wdev->base;
- /*
- * Shut off the timer unless NOWAYOUT is defined.
- */
-#ifndef CONFIG_WATCHDOG_NOWAYOUT
- pm_runtime_get_sync(wdev->dev);
+ pm_runtime_get_sync(omap_wdev->dev);
+ /* initialize prescaler */
+ while (__raw_readl(base + OMAP_WATCHDOG_WPS) & 0x01)
+ cpu_relax();
- omap_wdt_disable(wdev);
+ __raw_writel((1 << 5) | (PTV << 2), base + OMAP_WATCHDOG_CNTRL);
+ while (__raw_readl(base + OMAP_WATCHDOG_WPS) & 0x01)
+ cpu_relax();
- pm_runtime_put_sync(wdev->dev);
-#else
- pr_crit("Unexpected close, not stopping!\n");
-#endif
- wdev->omap_wdt_users = 0;
+ omap_wdt_set_timeout(&omap_wdev->wdt, timer_margin);
+ pm_runtime_put_sync(omap_wdev->dev);
return 0;
}
-static ssize_t omap_wdt_write(struct file *file, const char __user *data,
- size_t len, loff_t *ppos)
+static int omap_wdt_stop(struct watchdog_device *wdt_dev)
{
- struct omap_wdt_dev *wdev = file->private_data;
-
- /* Refresh LOAD_TIME. */
- if (len) {
- pm_runtime_get_sync(wdev->dev);
- spin_lock(&wdt_lock);
- omap_wdt_ping(wdev);
- spin_unlock(&wdt_lock);
- pm_runtime_put_sync(wdev->dev);
- }
- return len;
-}
+ struct omap_wdt_drvdata *omap_wdev = watchdog_get_drvdata(wdt_dev);
-static long omap_wdt_ioctl(struct file *file, unsigned int cmd,
- unsigned long arg)
-{
- struct omap_wdt_dev *wdev;
- int new_margin;
- static const struct watchdog_info ident = {
- .identity = "OMAP Watchdog",
- .options = WDIOF_SETTIMEOUT,
- .firmware_version = 0,
- };
-
- wdev = file->private_data;
-
- switch (cmd) {
- case WDIOC_GETSUPPORT:
- return copy_to_user((struct watchdog_info __user *)arg, &ident,
- sizeof(ident));
- case WDIOC_GETSTATUS:
- return put_user(0, (int __user *)arg);
- case WDIOC_GETBOOTSTATUS:
- if (cpu_is_omap16xx())
- return put_user(__raw_readw(ARM_SYSST),
- (int __user *)arg);
- if (cpu_is_omap24xx())
- return put_user(omap_prcm_get_reset_sources(),
- (int __user *)arg);
- return put_user(0, (int __user *)arg);
- case WDIOC_KEEPALIVE:
- pm_runtime_get_sync(wdev->dev);
- spin_lock(&wdt_lock);
- omap_wdt_ping(wdev);
- spin_unlock(&wdt_lock);
- pm_runtime_put_sync(wdev->dev);
- return 0;
- case WDIOC_SETTIMEOUT:
- if (get_user(new_margin, (int __user *)arg))
- return -EFAULT;
- omap_wdt_adjust_timeout(new_margin);
-
- pm_runtime_get_sync(wdev->dev);
- spin_lock(&wdt_lock);
- omap_wdt_disable(wdev);
- omap_wdt_set_timeout(wdev);
- omap_wdt_enable(wdev);
-
- omap_wdt_ping(wdev);
- spin_unlock(&wdt_lock);
- pm_runtime_put_sync(wdev->dev);
- /* Fall */
- case WDIOC_GETTIMEOUT:
- return put_user(timer_margin, (int __user *)arg);
- default:
- return -ENOTTY;
- }
+ pm_runtime_get_sync(omap_wdev->dev);
+ omap_wdt_disable(omap_wdev);
+ pm_runtime_put_sync(omap_wdev->dev);
+
+ return 0;
}
-static const struct file_operations omap_wdt_fops = {
+static const struct watchdog_ops omap_wdt_ops = {
.owner = THIS_MODULE,
- .write = omap_wdt_write,
- .unlocked_ioctl = omap_wdt_ioctl,
- .open = omap_wdt_open,
- .release = omap_wdt_release,
- .llseek = no_llseek,
+ .start = omap_wdt_start,
+ .stop = omap_wdt_stop,
+ .ping = omap_wdt_ping,
+ .set_timeout = omap_wdt_set_timeout,
+};
+
+static const struct watchdog_info omap_wdt_info = {
+ .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING |
+ WDIOF_CARDRESET,
+ .identity = "Omap Watchdog",
};
static int __devinit omap_wdt_probe(struct platform_device *pdev)
{
+ struct omap_wdt_drvdata *omap_drvdata;
+ struct watchdog_device *omap_wdev;
struct resource *res, *mem;
- struct omap_wdt_dev *wdev;
int ret;
/* reserve static register mappings */
@@ -286,68 +216,62 @@ static int __devinit omap_wdt_probe(struct platform_device *pdev)
goto err_get_resource;
}
- if (omap_wdt_dev) {
- ret = -EBUSY;
- goto err_busy;
- }
-
mem = request_mem_region(res->start, resource_size(res), pdev->name);
if (!mem) {
ret = -EBUSY;
goto err_busy;
}
- wdev = kzalloc(sizeof(struct omap_wdt_dev), GFP_KERNEL);
- if (!wdev) {
+ omap_drvdata = devm_kzalloc(&pdev->dev, sizeof(struct omap_wdt_drvdata),
+ GFP_KERNEL);
+ if (!omap_drvdata) {
+ dev_err(&pdev->dev, "Unable to allocate watchdog device\n");
ret = -ENOMEM;
goto err_kzalloc;
}
- wdev->omap_wdt_users = 0;
- wdev->mem = mem;
- wdev->dev = &pdev->dev;
+ omap_drvdata->dev = &pdev->dev;
+ omap_wdev = &omap_drvdata->wdt;
+ omap_wdev->info = &omap_wdt_info;
+ omap_wdev->ops = &omap_wdt_ops;
+ omap_wdev->timeout = TIMER_MARGIN_DEFAULT;
+ omap_wdev->min_timeout = 1;
+ omap_wdev->max_timeout = TIMER_MARGIN_MAX;
+#ifdef CONFIG_WATCHDOG_NOWAYOUT
+ watchdog_set_nowayout(omap_wdev, true);
+#endif
+ watchdog_set_drvdata(omap_wdev, omap_drvdata);
- wdev->base = ioremap(res->start, resource_size(res));
- if (!wdev->base) {
+ omap_drvdata->base = ioremap(res->start, resource_size(res));
+ if (!omap_drvdata->base) {
ret = -ENOMEM;
- goto err_ioremap;
+ goto err_kzalloc;
}
- platform_set_drvdata(pdev, wdev);
-
- pm_runtime_enable(wdev->dev);
- pm_runtime_get_sync(wdev->dev);
-
- omap_wdt_disable(wdev);
- omap_wdt_adjust_timeout(timer_margin);
-
- wdev->omap_wdt_miscdev.parent = &pdev->dev;
- wdev->omap_wdt_miscdev.minor = WATCHDOG_MINOR;
- wdev->omap_wdt_miscdev.name = "watchdog";
- wdev->omap_wdt_miscdev.fops = &omap_wdt_fops;
-
- ret = misc_register(&(wdev->omap_wdt_miscdev));
- if (ret)
- goto err_misc;
-
- pr_info("OMAP Watchdog Timer Rev 0x%02x: initial timeout %d sec\n",
- __raw_readl(wdev->base + OMAP_WATCHDOG_REV) & 0xFF,
- timer_margin);
-
- pm_runtime_put_sync(wdev->dev);
-
- omap_wdt_dev = pdev;
+ ret = watchdog_register_device(&omap_drvdata->wdt);
+ if (ret < 0)
+ goto err_register_wd;
+
+ pm_runtime_enable(&pdev->dev);
+ pm_runtime_get_sync(&pdev->dev);
+ omap_wdt_disable(omap_drvdata);
+ pm_runtime_put_sync(&pdev->dev);
+ platform_set_drvdata(pdev, omap_drvdata);
+
+ /* For omap16xx we just keep it original as-is */
+ if (cpu_is_omap16xx())
+ omap_wdev->bootstatus = __raw_readw(ARM_SYSST);
+ else
+ omap_wdev->bootstatus = (omap_prcm_get_reset_sources() & 0x10)
+ >> OMAP3_PRM_RSTST_WD_BIT;
+ pr_info("OMAP WDTimer Rev 0x%02x: Initial timeout %dsec status= 0x%x\n",
+ __raw_readl(omap_drvdata->base + OMAP_WATCHDOG_REV)
+ & 0xFF, timer_margin, omap_wdev->bootstatus);
return 0;
-err_misc:
- pm_runtime_disable(wdev->dev);
- platform_set_drvdata(pdev, NULL);
- iounmap(wdev->base);
-
-err_ioremap:
- wdev->base = NULL;
- kfree(wdev);
+err_register_wd:
+ iounmap(omap_drvdata->base);
err_kzalloc:
release_mem_region(res->start, resource_size(res));
@@ -358,34 +282,17 @@ err_get_resource:
return ret;
}
-static void omap_wdt_shutdown(struct platform_device *pdev)
-{
- struct omap_wdt_dev *wdev = platform_get_drvdata(pdev);
-
- if (wdev->omap_wdt_users) {
- pm_runtime_get_sync(wdev->dev);
- omap_wdt_disable(wdev);
- pm_runtime_put_sync(wdev->dev);
- }
-}
-
static int __devexit omap_wdt_remove(struct platform_device *pdev)
{
- struct omap_wdt_dev *wdev = platform_get_drvdata(pdev);
+ struct omap_wdt_drvdata *omap_wdev = platform_get_drvdata(pdev);
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- pm_runtime_disable(wdev->dev);
- if (!res)
- return -ENOENT;
+ pm_runtime_disable(&pdev->dev);
- misc_deregister(&(wdev->omap_wdt_miscdev));
release_mem_region(res->start, resource_size(res));
platform_set_drvdata(pdev, NULL);
- iounmap(wdev->base);
-
- kfree(wdev);
- omap_wdt_dev = NULL;
+ iounmap(omap_wdev->base);
return 0;
}
@@ -400,12 +307,12 @@ static int __devexit omap_wdt_remove(struct platform_device *pdev)
static int omap_wdt_suspend(struct platform_device *pdev, pm_message_t state)
{
- struct omap_wdt_dev *wdev = platform_get_drvdata(pdev);
+ struct omap_wdt_drvdata *omap_wdev = platform_get_drvdata(pdev);
- if (wdev->omap_wdt_users) {
- pm_runtime_get_sync(wdev->dev);
- omap_wdt_disable(wdev);
- pm_runtime_put_sync(wdev->dev);
+ if (test_bit(WDOG_DEV_OPEN, &omap_wdev->wdt.status)) {
+ pm_runtime_get_sync(&pdev->dev);
+ omap_wdt_disable(omap_wdev);
+ pm_runtime_put_sync(&pdev->dev);
}
return 0;
@@ -413,13 +320,12 @@ static int omap_wdt_suspend(struct platform_device *pdev, pm_message_t state)
static int omap_wdt_resume(struct platform_device *pdev)
{
- struct omap_wdt_dev *wdev = platform_get_drvdata(pdev);
-
- if (wdev->omap_wdt_users) {
- pm_runtime_get_sync(wdev->dev);
- omap_wdt_enable(wdev);
- omap_wdt_ping(wdev);
- pm_runtime_put_sync(wdev->dev);
+ struct omap_wdt_drvdata *omap_wdev = platform_get_drvdata(pdev);
+ if (test_bit(WDOG_DEV_OPEN, &omap_wdev->wdt.status)) {
+ pm_runtime_get_sync(&pdev->dev);
+ omap_wdt_enable(omap_wdev);
+ omap_wdt_ping(&omap_wdev->wdt);
+ pm_runtime_put_sync(&pdev->dev);
}
return 0;
@@ -433,7 +339,6 @@ static int omap_wdt_resume(struct platform_device *pdev)
static struct platform_driver omap_wdt_driver = {
.probe = omap_wdt_probe,
.remove = __devexit_p(omap_wdt_remove),
- .shutdown = omap_wdt_shutdown,
.suspend = omap_wdt_suspend,
.resume = omap_wdt_resume,
.driver = {
@@ -446,5 +351,4 @@ module_platform_driver(omap_wdt_driver);
MODULE_AUTHOR("George G. Davis");
MODULE_LICENSE("GPL");
-MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
MODULE_ALIAS("platform:omap_wdt");
diff --git a/drivers/watchdog/omap_wdt.h b/drivers/watchdog/omap_wdt.h
index 09b774c..cf5f037 100644
--- a/drivers/watchdog/omap_wdt.h
+++ b/drivers/watchdog/omap_wdt.h
@@ -51,4 +51,9 @@
#define PTV 0 /* prescale */
#define GET_WLDR_VAL(secs) (0xffffffff - ((secs) * (32768/(1<<PTV))) + 1)
+/* MPU_WD_RST bit in PRM_RSTST show Omap WDTimer reset event.
+ * 0x0 = 0x0 : No watchdog reset.
+ * 0x1 = 0x1 : watchdog reset has occurred. */
+#define OMAP3_PRM_RSTST_WD_BIT 4
+
#endif /* _OMAP_WATCHDOG_H */
--
1.7.5.4
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH RESEND v3 1/3] Watchdog: Omap: Changes for the new watchdog framework
@ 2012-07-15 7:44 ` Zumeng Chen
0 siblings, 0 replies; 21+ messages in thread
From: Zumeng Chen @ 2012-07-15 7:44 UTC (permalink / raw)
To: khilman, shubhrajyoti, linux-watchdog, hvaibhav
Cc: wim, linux-omap, tony, paul.gortmaker, linux-arm-kernel
This patch implements the current watchdog framework for OMAP WDTimer,
which factored out the common components, so the driver can just focus
on the hardware related parts.
Signed-off-by: Zumeng Chen <zumeng.chen@windriver.com>
---
drivers/watchdog/omap_wdt.c | 342 ++++++++++++++++---------------------------
drivers/watchdog/omap_wdt.h | 5 +
2 files changed, 128 insertions(+), 219 deletions(-)
diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c
index 8285d65..cc5bc3e 100644
--- a/drivers/watchdog/omap_wdt.c
+++ b/drivers/watchdog/omap_wdt.c
@@ -24,6 +24,9 @@
*
* Copyright (c) 2005 David Brownell
* Use the driver model and standard identifiers; handle bigger timeouts.
+ *
+ * Copyright (c) 2012 WindRiver
+ * Changes cater for the current watchdog framework.
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@@ -33,7 +36,6 @@
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/mm.h>
-#include <linux/miscdevice.h>
#include <linux/watchdog.h>
#include <linux/reboot.h>
#include <linux/init.h>
@@ -50,8 +52,6 @@
#include "omap_wdt.h"
-static struct platform_device *omap_wdt_dev;
-
static unsigned timer_margin;
module_param(timer_margin, uint, 0);
MODULE_PARM_DESC(timer_margin, "initial watchdog timeout (in seconds)");
@@ -59,32 +59,14 @@ MODULE_PARM_DESC(timer_margin, "initial watchdog timeout (in seconds)");
static unsigned int wdt_trgr_pattern = 0x1234;
static DEFINE_SPINLOCK(wdt_lock);
-struct omap_wdt_dev {
+struct omap_wdt_drvdata {
+ struct watchdog_device wdt;
void __iomem *base; /* physical */
struct device *dev;
- int omap_wdt_users;
struct resource *mem;
- struct miscdevice omap_wdt_miscdev;
};
-static void omap_wdt_ping(struct omap_wdt_dev *wdev)
-{
- void __iomem *base = wdev->base;
-
- /* wait for posted write to complete */
- while ((__raw_readl(base + OMAP_WATCHDOG_WPS)) & 0x08)
- cpu_relax();
-
- wdt_trgr_pattern = ~wdt_trgr_pattern;
- __raw_writel(wdt_trgr_pattern, (base + OMAP_WATCHDOG_TGR));
-
- /* wait for posted write to complete */
- while ((__raw_readl(base + OMAP_WATCHDOG_WPS)) & 0x08)
- cpu_relax();
- /* reloaded WCRR from WLDR */
-}
-
-static void omap_wdt_enable(struct omap_wdt_dev *wdev)
+static void omap_wdt_enable(struct omap_wdt_drvdata *wdev)
{
void __iomem *base = wdev->base;
@@ -98,7 +80,7 @@ static void omap_wdt_enable(struct omap_wdt_dev *wdev)
cpu_relax();
}
-static void omap_wdt_disable(struct omap_wdt_dev *wdev)
+static void omap_wdt_disable(struct omap_wdt_drvdata *wdev)
{
void __iomem *base = wdev->base;
@@ -121,12 +103,19 @@ static void omap_wdt_adjust_timeout(unsigned new_timeout)
timer_margin = new_timeout;
}
-static void omap_wdt_set_timeout(struct omap_wdt_dev *wdev)
+static int omap_wdt_set_timeout(struct watchdog_device *wdt_dev,
+ unsigned int new_timeout)
{
- u32 pre_margin = GET_WLDR_VAL(timer_margin);
- void __iomem *base = wdev->base;
+ u32 pre_margin;
+ struct omap_wdt_drvdata *omap_wdev = watchdog_get_drvdata(wdt_dev);
+ void __iomem *base = omap_wdev->base;
- pm_runtime_get_sync(wdev->dev);
+ pm_runtime_get_sync(omap_wdev->dev);
+ omap_wdt_disable(omap_wdev);
+
+ /* adjust timeout based on the new timeout */
+ omap_wdt_adjust_timeout(new_timeout);
+ pre_margin = GET_WLDR_VAL(timer_margin);
/* just count up at 32 KHz */
while (__raw_readl(base + OMAP_WATCHDOG_WPS) & 0x04)
@@ -136,147 +125,88 @@ static void omap_wdt_set_timeout(struct omap_wdt_dev *wdev)
while (__raw_readl(base + OMAP_WATCHDOG_WPS) & 0x04)
cpu_relax();
- pm_runtime_put_sync(wdev->dev);
+ omap_wdt_enable(omap_wdev);
+ wdt_dev->timeout = new_timeout;
+ pm_runtime_put_sync(omap_wdev->dev);
+ return 0;
}
-/*
- * Allow only one task to hold it open
- */
-static int omap_wdt_open(struct inode *inode, struct file *file)
+static int omap_wdt_ping(struct watchdog_device *wdt_dev)
{
- struct omap_wdt_dev *wdev = platform_get_drvdata(omap_wdt_dev);
- void __iomem *base = wdev->base;
-
- if (test_and_set_bit(1, (unsigned long *)&(wdev->omap_wdt_users)))
- return -EBUSY;
-
- pm_runtime_get_sync(wdev->dev);
+ struct omap_wdt_drvdata *omap_wdev = watchdog_get_drvdata(wdt_dev);
+ void __iomem *base = omap_wdev->base;
- /* initialize prescaler */
- while (__raw_readl(base + OMAP_WATCHDOG_WPS) & 0x01)
- cpu_relax();
+ pm_runtime_get_sync(omap_wdev->dev);
+ spin_lock(&wdt_lock);
- __raw_writel((1 << 5) | (PTV << 2), base + OMAP_WATCHDOG_CNTRL);
- while (__raw_readl(base + OMAP_WATCHDOG_WPS) & 0x01)
+ /* wait for posted write to complete */
+ while ((__raw_readl(base + OMAP_WATCHDOG_WPS)) & 0x08)
cpu_relax();
- file->private_data = (void *) wdev;
+ wdt_trgr_pattern = ~wdt_trgr_pattern;
+ __raw_writel(wdt_trgr_pattern, (base + OMAP_WATCHDOG_TGR));
- omap_wdt_set_timeout(wdev);
- omap_wdt_ping(wdev); /* trigger loading of new timeout value */
- omap_wdt_enable(wdev);
+ /* wait for posted write to complete */
+ /* reloaded WCRR from WLDR */
+ while ((__raw_readl(base + OMAP_WATCHDOG_WPS)) & 0x08)
+ cpu_relax();
- pm_runtime_put_sync(wdev->dev);
+ spin_unlock(&wdt_lock);
+ pm_runtime_put_sync(omap_wdev->dev);
- return nonseekable_open(inode, file);
+ return 0;
}
-static int omap_wdt_release(struct inode *inode, struct file *file)
+static int omap_wdt_start(struct watchdog_device *wdt_dev)
{
- struct omap_wdt_dev *wdev = file->private_data;
+ struct omap_wdt_drvdata *omap_wdev = watchdog_get_drvdata(wdt_dev);
+ void __iomem *base = omap_wdev->base;
- /*
- * Shut off the timer unless NOWAYOUT is defined.
- */
-#ifndef CONFIG_WATCHDOG_NOWAYOUT
- pm_runtime_get_sync(wdev->dev);
+ pm_runtime_get_sync(omap_wdev->dev);
+ /* initialize prescaler */
+ while (__raw_readl(base + OMAP_WATCHDOG_WPS) & 0x01)
+ cpu_relax();
- omap_wdt_disable(wdev);
+ __raw_writel((1 << 5) | (PTV << 2), base + OMAP_WATCHDOG_CNTRL);
+ while (__raw_readl(base + OMAP_WATCHDOG_WPS) & 0x01)
+ cpu_relax();
- pm_runtime_put_sync(wdev->dev);
-#else
- pr_crit("Unexpected close, not stopping!\n");
-#endif
- wdev->omap_wdt_users = 0;
+ omap_wdt_set_timeout(&omap_wdev->wdt, timer_margin);
+ pm_runtime_put_sync(omap_wdev->dev);
return 0;
}
-static ssize_t omap_wdt_write(struct file *file, const char __user *data,
- size_t len, loff_t *ppos)
+static int omap_wdt_stop(struct watchdog_device *wdt_dev)
{
- struct omap_wdt_dev *wdev = file->private_data;
-
- /* Refresh LOAD_TIME. */
- if (len) {
- pm_runtime_get_sync(wdev->dev);
- spin_lock(&wdt_lock);
- omap_wdt_ping(wdev);
- spin_unlock(&wdt_lock);
- pm_runtime_put_sync(wdev->dev);
- }
- return len;
-}
+ struct omap_wdt_drvdata *omap_wdev = watchdog_get_drvdata(wdt_dev);
-static long omap_wdt_ioctl(struct file *file, unsigned int cmd,
- unsigned long arg)
-{
- struct omap_wdt_dev *wdev;
- int new_margin;
- static const struct watchdog_info ident = {
- .identity = "OMAP Watchdog",
- .options = WDIOF_SETTIMEOUT,
- .firmware_version = 0,
- };
-
- wdev = file->private_data;
-
- switch (cmd) {
- case WDIOC_GETSUPPORT:
- return copy_to_user((struct watchdog_info __user *)arg, &ident,
- sizeof(ident));
- case WDIOC_GETSTATUS:
- return put_user(0, (int __user *)arg);
- case WDIOC_GETBOOTSTATUS:
- if (cpu_is_omap16xx())
- return put_user(__raw_readw(ARM_SYSST),
- (int __user *)arg);
- if (cpu_is_omap24xx())
- return put_user(omap_prcm_get_reset_sources(),
- (int __user *)arg);
- return put_user(0, (int __user *)arg);
- case WDIOC_KEEPALIVE:
- pm_runtime_get_sync(wdev->dev);
- spin_lock(&wdt_lock);
- omap_wdt_ping(wdev);
- spin_unlock(&wdt_lock);
- pm_runtime_put_sync(wdev->dev);
- return 0;
- case WDIOC_SETTIMEOUT:
- if (get_user(new_margin, (int __user *)arg))
- return -EFAULT;
- omap_wdt_adjust_timeout(new_margin);
-
- pm_runtime_get_sync(wdev->dev);
- spin_lock(&wdt_lock);
- omap_wdt_disable(wdev);
- omap_wdt_set_timeout(wdev);
- omap_wdt_enable(wdev);
-
- omap_wdt_ping(wdev);
- spin_unlock(&wdt_lock);
- pm_runtime_put_sync(wdev->dev);
- /* Fall */
- case WDIOC_GETTIMEOUT:
- return put_user(timer_margin, (int __user *)arg);
- default:
- return -ENOTTY;
- }
+ pm_runtime_get_sync(omap_wdev->dev);
+ omap_wdt_disable(omap_wdev);
+ pm_runtime_put_sync(omap_wdev->dev);
+
+ return 0;
}
-static const struct file_operations omap_wdt_fops = {
+static const struct watchdog_ops omap_wdt_ops = {
.owner = THIS_MODULE,
- .write = omap_wdt_write,
- .unlocked_ioctl = omap_wdt_ioctl,
- .open = omap_wdt_open,
- .release = omap_wdt_release,
- .llseek = no_llseek,
+ .start = omap_wdt_start,
+ .stop = omap_wdt_stop,
+ .ping = omap_wdt_ping,
+ .set_timeout = omap_wdt_set_timeout,
+};
+
+static const struct watchdog_info omap_wdt_info = {
+ .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING |
+ WDIOF_CARDRESET,
+ .identity = "Omap Watchdog",
};
static int __devinit omap_wdt_probe(struct platform_device *pdev)
{
+ struct omap_wdt_drvdata *omap_drvdata;
+ struct watchdog_device *omap_wdev;
struct resource *res, *mem;
- struct omap_wdt_dev *wdev;
int ret;
/* reserve static register mappings */
@@ -286,68 +216,62 @@ static int __devinit omap_wdt_probe(struct platform_device *pdev)
goto err_get_resource;
}
- if (omap_wdt_dev) {
- ret = -EBUSY;
- goto err_busy;
- }
-
mem = request_mem_region(res->start, resource_size(res), pdev->name);
if (!mem) {
ret = -EBUSY;
goto err_busy;
}
- wdev = kzalloc(sizeof(struct omap_wdt_dev), GFP_KERNEL);
- if (!wdev) {
+ omap_drvdata = devm_kzalloc(&pdev->dev, sizeof(struct omap_wdt_drvdata),
+ GFP_KERNEL);
+ if (!omap_drvdata) {
+ dev_err(&pdev->dev, "Unable to allocate watchdog device\n");
ret = -ENOMEM;
goto err_kzalloc;
}
- wdev->omap_wdt_users = 0;
- wdev->mem = mem;
- wdev->dev = &pdev->dev;
+ omap_drvdata->dev = &pdev->dev;
+ omap_wdev = &omap_drvdata->wdt;
+ omap_wdev->info = &omap_wdt_info;
+ omap_wdev->ops = &omap_wdt_ops;
+ omap_wdev->timeout = TIMER_MARGIN_DEFAULT;
+ omap_wdev->min_timeout = 1;
+ omap_wdev->max_timeout = TIMER_MARGIN_MAX;
+#ifdef CONFIG_WATCHDOG_NOWAYOUT
+ watchdog_set_nowayout(omap_wdev, true);
+#endif
+ watchdog_set_drvdata(omap_wdev, omap_drvdata);
- wdev->base = ioremap(res->start, resource_size(res));
- if (!wdev->base) {
+ omap_drvdata->base = ioremap(res->start, resource_size(res));
+ if (!omap_drvdata->base) {
ret = -ENOMEM;
- goto err_ioremap;
+ goto err_kzalloc;
}
- platform_set_drvdata(pdev, wdev);
-
- pm_runtime_enable(wdev->dev);
- pm_runtime_get_sync(wdev->dev);
-
- omap_wdt_disable(wdev);
- omap_wdt_adjust_timeout(timer_margin);
-
- wdev->omap_wdt_miscdev.parent = &pdev->dev;
- wdev->omap_wdt_miscdev.minor = WATCHDOG_MINOR;
- wdev->omap_wdt_miscdev.name = "watchdog";
- wdev->omap_wdt_miscdev.fops = &omap_wdt_fops;
-
- ret = misc_register(&(wdev->omap_wdt_miscdev));
- if (ret)
- goto err_misc;
-
- pr_info("OMAP Watchdog Timer Rev 0x%02x: initial timeout %d sec\n",
- __raw_readl(wdev->base + OMAP_WATCHDOG_REV) & 0xFF,
- timer_margin);
-
- pm_runtime_put_sync(wdev->dev);
-
- omap_wdt_dev = pdev;
+ ret = watchdog_register_device(&omap_drvdata->wdt);
+ if (ret < 0)
+ goto err_register_wd;
+
+ pm_runtime_enable(&pdev->dev);
+ pm_runtime_get_sync(&pdev->dev);
+ omap_wdt_disable(omap_drvdata);
+ pm_runtime_put_sync(&pdev->dev);
+ platform_set_drvdata(pdev, omap_drvdata);
+
+ /* For omap16xx we just keep it original as-is */
+ if (cpu_is_omap16xx())
+ omap_wdev->bootstatus = __raw_readw(ARM_SYSST);
+ else
+ omap_wdev->bootstatus = (omap_prcm_get_reset_sources() & 0x10)
+ >> OMAP3_PRM_RSTST_WD_BIT;
+ pr_info("OMAP WDTimer Rev 0x%02x: Initial timeout %dsec status= 0x%x\n",
+ __raw_readl(omap_drvdata->base + OMAP_WATCHDOG_REV)
+ & 0xFF, timer_margin, omap_wdev->bootstatus);
return 0;
-err_misc:
- pm_runtime_disable(wdev->dev);
- platform_set_drvdata(pdev, NULL);
- iounmap(wdev->base);
-
-err_ioremap:
- wdev->base = NULL;
- kfree(wdev);
+err_register_wd:
+ iounmap(omap_drvdata->base);
err_kzalloc:
release_mem_region(res->start, resource_size(res));
@@ -358,34 +282,17 @@ err_get_resource:
return ret;
}
-static void omap_wdt_shutdown(struct platform_device *pdev)
-{
- struct omap_wdt_dev *wdev = platform_get_drvdata(pdev);
-
- if (wdev->omap_wdt_users) {
- pm_runtime_get_sync(wdev->dev);
- omap_wdt_disable(wdev);
- pm_runtime_put_sync(wdev->dev);
- }
-}
-
static int __devexit omap_wdt_remove(struct platform_device *pdev)
{
- struct omap_wdt_dev *wdev = platform_get_drvdata(pdev);
+ struct omap_wdt_drvdata *omap_wdev = platform_get_drvdata(pdev);
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- pm_runtime_disable(wdev->dev);
- if (!res)
- return -ENOENT;
+ pm_runtime_disable(&pdev->dev);
- misc_deregister(&(wdev->omap_wdt_miscdev));
release_mem_region(res->start, resource_size(res));
platform_set_drvdata(pdev, NULL);
- iounmap(wdev->base);
-
- kfree(wdev);
- omap_wdt_dev = NULL;
+ iounmap(omap_wdev->base);
return 0;
}
@@ -400,12 +307,12 @@ static int __devexit omap_wdt_remove(struct platform_device *pdev)
static int omap_wdt_suspend(struct platform_device *pdev, pm_message_t state)
{
- struct omap_wdt_dev *wdev = platform_get_drvdata(pdev);
+ struct omap_wdt_drvdata *omap_wdev = platform_get_drvdata(pdev);
- if (wdev->omap_wdt_users) {
- pm_runtime_get_sync(wdev->dev);
- omap_wdt_disable(wdev);
- pm_runtime_put_sync(wdev->dev);
+ if (test_bit(WDOG_DEV_OPEN, &omap_wdev->wdt.status)) {
+ pm_runtime_get_sync(&pdev->dev);
+ omap_wdt_disable(omap_wdev);
+ pm_runtime_put_sync(&pdev->dev);
}
return 0;
@@ -413,13 +320,12 @@ static int omap_wdt_suspend(struct platform_device *pdev, pm_message_t state)
static int omap_wdt_resume(struct platform_device *pdev)
{
- struct omap_wdt_dev *wdev = platform_get_drvdata(pdev);
-
- if (wdev->omap_wdt_users) {
- pm_runtime_get_sync(wdev->dev);
- omap_wdt_enable(wdev);
- omap_wdt_ping(wdev);
- pm_runtime_put_sync(wdev->dev);
+ struct omap_wdt_drvdata *omap_wdev = platform_get_drvdata(pdev);
+ if (test_bit(WDOG_DEV_OPEN, &omap_wdev->wdt.status)) {
+ pm_runtime_get_sync(&pdev->dev);
+ omap_wdt_enable(omap_wdev);
+ omap_wdt_ping(&omap_wdev->wdt);
+ pm_runtime_put_sync(&pdev->dev);
}
return 0;
@@ -433,7 +339,6 @@ static int omap_wdt_resume(struct platform_device *pdev)
static struct platform_driver omap_wdt_driver = {
.probe = omap_wdt_probe,
.remove = __devexit_p(omap_wdt_remove),
- .shutdown = omap_wdt_shutdown,
.suspend = omap_wdt_suspend,
.resume = omap_wdt_resume,
.driver = {
@@ -446,5 +351,4 @@ module_platform_driver(omap_wdt_driver);
MODULE_AUTHOR("George G. Davis");
MODULE_LICENSE("GPL");
-MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
MODULE_ALIAS("platform:omap_wdt");
diff --git a/drivers/watchdog/omap_wdt.h b/drivers/watchdog/omap_wdt.h
index 09b774c..cf5f037 100644
--- a/drivers/watchdog/omap_wdt.h
+++ b/drivers/watchdog/omap_wdt.h
@@ -51,4 +51,9 @@
#define PTV 0 /* prescale */
#define GET_WLDR_VAL(secs) (0xffffffff - ((secs) * (32768/(1<<PTV))) + 1)
+/* MPU_WD_RST bit in PRM_RSTST show Omap WDTimer reset event.
+ * 0x0 = 0x0 : No watchdog reset.
+ * 0x1 = 0x1 : watchdog reset has occurred. */
+#define OMAP3_PRM_RSTST_WD_BIT 4
+
#endif /* _OMAP_WATCHDOG_H */
--
1.7.5.4
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH RESEND v3 1/3] Watchdog: Omap: Changes for the new watchdog framework
@ 2012-07-15 7:44 ` Zumeng Chen
0 siblings, 0 replies; 21+ messages in thread
From: Zumeng Chen @ 2012-07-15 7:44 UTC (permalink / raw)
To: linux-arm-kernel
This patch implements the current watchdog framework for OMAP WDTimer,
which factored out the common components, so the driver can just focus
on the hardware related parts.
Signed-off-by: Zumeng Chen <zumeng.chen@windriver.com>
---
drivers/watchdog/omap_wdt.c | 342 ++++++++++++++++---------------------------
drivers/watchdog/omap_wdt.h | 5 +
2 files changed, 128 insertions(+), 219 deletions(-)
diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c
index 8285d65..cc5bc3e 100644
--- a/drivers/watchdog/omap_wdt.c
+++ b/drivers/watchdog/omap_wdt.c
@@ -24,6 +24,9 @@
*
* Copyright (c) 2005 David Brownell
* Use the driver model and standard identifiers; handle bigger timeouts.
+ *
+ * Copyright (c) 2012 WindRiver
+ * Changes cater for the current watchdog framework.
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@@ -33,7 +36,6 @@
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/mm.h>
-#include <linux/miscdevice.h>
#include <linux/watchdog.h>
#include <linux/reboot.h>
#include <linux/init.h>
@@ -50,8 +52,6 @@
#include "omap_wdt.h"
-static struct platform_device *omap_wdt_dev;
-
static unsigned timer_margin;
module_param(timer_margin, uint, 0);
MODULE_PARM_DESC(timer_margin, "initial watchdog timeout (in seconds)");
@@ -59,32 +59,14 @@ MODULE_PARM_DESC(timer_margin, "initial watchdog timeout (in seconds)");
static unsigned int wdt_trgr_pattern = 0x1234;
static DEFINE_SPINLOCK(wdt_lock);
-struct omap_wdt_dev {
+struct omap_wdt_drvdata {
+ struct watchdog_device wdt;
void __iomem *base; /* physical */
struct device *dev;
- int omap_wdt_users;
struct resource *mem;
- struct miscdevice omap_wdt_miscdev;
};
-static void omap_wdt_ping(struct omap_wdt_dev *wdev)
-{
- void __iomem *base = wdev->base;
-
- /* wait for posted write to complete */
- while ((__raw_readl(base + OMAP_WATCHDOG_WPS)) & 0x08)
- cpu_relax();
-
- wdt_trgr_pattern = ~wdt_trgr_pattern;
- __raw_writel(wdt_trgr_pattern, (base + OMAP_WATCHDOG_TGR));
-
- /* wait for posted write to complete */
- while ((__raw_readl(base + OMAP_WATCHDOG_WPS)) & 0x08)
- cpu_relax();
- /* reloaded WCRR from WLDR */
-}
-
-static void omap_wdt_enable(struct omap_wdt_dev *wdev)
+static void omap_wdt_enable(struct omap_wdt_drvdata *wdev)
{
void __iomem *base = wdev->base;
@@ -98,7 +80,7 @@ static void omap_wdt_enable(struct omap_wdt_dev *wdev)
cpu_relax();
}
-static void omap_wdt_disable(struct omap_wdt_dev *wdev)
+static void omap_wdt_disable(struct omap_wdt_drvdata *wdev)
{
void __iomem *base = wdev->base;
@@ -121,12 +103,19 @@ static void omap_wdt_adjust_timeout(unsigned new_timeout)
timer_margin = new_timeout;
}
-static void omap_wdt_set_timeout(struct omap_wdt_dev *wdev)
+static int omap_wdt_set_timeout(struct watchdog_device *wdt_dev,
+ unsigned int new_timeout)
{
- u32 pre_margin = GET_WLDR_VAL(timer_margin);
- void __iomem *base = wdev->base;
+ u32 pre_margin;
+ struct omap_wdt_drvdata *omap_wdev = watchdog_get_drvdata(wdt_dev);
+ void __iomem *base = omap_wdev->base;
- pm_runtime_get_sync(wdev->dev);
+ pm_runtime_get_sync(omap_wdev->dev);
+ omap_wdt_disable(omap_wdev);
+
+ /* adjust timeout based on the new timeout */
+ omap_wdt_adjust_timeout(new_timeout);
+ pre_margin = GET_WLDR_VAL(timer_margin);
/* just count up at 32 KHz */
while (__raw_readl(base + OMAP_WATCHDOG_WPS) & 0x04)
@@ -136,147 +125,88 @@ static void omap_wdt_set_timeout(struct omap_wdt_dev *wdev)
while (__raw_readl(base + OMAP_WATCHDOG_WPS) & 0x04)
cpu_relax();
- pm_runtime_put_sync(wdev->dev);
+ omap_wdt_enable(omap_wdev);
+ wdt_dev->timeout = new_timeout;
+ pm_runtime_put_sync(omap_wdev->dev);
+ return 0;
}
-/*
- * Allow only one task to hold it open
- */
-static int omap_wdt_open(struct inode *inode, struct file *file)
+static int omap_wdt_ping(struct watchdog_device *wdt_dev)
{
- struct omap_wdt_dev *wdev = platform_get_drvdata(omap_wdt_dev);
- void __iomem *base = wdev->base;
-
- if (test_and_set_bit(1, (unsigned long *)&(wdev->omap_wdt_users)))
- return -EBUSY;
-
- pm_runtime_get_sync(wdev->dev);
+ struct omap_wdt_drvdata *omap_wdev = watchdog_get_drvdata(wdt_dev);
+ void __iomem *base = omap_wdev->base;
- /* initialize prescaler */
- while (__raw_readl(base + OMAP_WATCHDOG_WPS) & 0x01)
- cpu_relax();
+ pm_runtime_get_sync(omap_wdev->dev);
+ spin_lock(&wdt_lock);
- __raw_writel((1 << 5) | (PTV << 2), base + OMAP_WATCHDOG_CNTRL);
- while (__raw_readl(base + OMAP_WATCHDOG_WPS) & 0x01)
+ /* wait for posted write to complete */
+ while ((__raw_readl(base + OMAP_WATCHDOG_WPS)) & 0x08)
cpu_relax();
- file->private_data = (void *) wdev;
+ wdt_trgr_pattern = ~wdt_trgr_pattern;
+ __raw_writel(wdt_trgr_pattern, (base + OMAP_WATCHDOG_TGR));
- omap_wdt_set_timeout(wdev);
- omap_wdt_ping(wdev); /* trigger loading of new timeout value */
- omap_wdt_enable(wdev);
+ /* wait for posted write to complete */
+ /* reloaded WCRR from WLDR */
+ while ((__raw_readl(base + OMAP_WATCHDOG_WPS)) & 0x08)
+ cpu_relax();
- pm_runtime_put_sync(wdev->dev);
+ spin_unlock(&wdt_lock);
+ pm_runtime_put_sync(omap_wdev->dev);
- return nonseekable_open(inode, file);
+ return 0;
}
-static int omap_wdt_release(struct inode *inode, struct file *file)
+static int omap_wdt_start(struct watchdog_device *wdt_dev)
{
- struct omap_wdt_dev *wdev = file->private_data;
+ struct omap_wdt_drvdata *omap_wdev = watchdog_get_drvdata(wdt_dev);
+ void __iomem *base = omap_wdev->base;
- /*
- * Shut off the timer unless NOWAYOUT is defined.
- */
-#ifndef CONFIG_WATCHDOG_NOWAYOUT
- pm_runtime_get_sync(wdev->dev);
+ pm_runtime_get_sync(omap_wdev->dev);
+ /* initialize prescaler */
+ while (__raw_readl(base + OMAP_WATCHDOG_WPS) & 0x01)
+ cpu_relax();
- omap_wdt_disable(wdev);
+ __raw_writel((1 << 5) | (PTV << 2), base + OMAP_WATCHDOG_CNTRL);
+ while (__raw_readl(base + OMAP_WATCHDOG_WPS) & 0x01)
+ cpu_relax();
- pm_runtime_put_sync(wdev->dev);
-#else
- pr_crit("Unexpected close, not stopping!\n");
-#endif
- wdev->omap_wdt_users = 0;
+ omap_wdt_set_timeout(&omap_wdev->wdt, timer_margin);
+ pm_runtime_put_sync(omap_wdev->dev);
return 0;
}
-static ssize_t omap_wdt_write(struct file *file, const char __user *data,
- size_t len, loff_t *ppos)
+static int omap_wdt_stop(struct watchdog_device *wdt_dev)
{
- struct omap_wdt_dev *wdev = file->private_data;
-
- /* Refresh LOAD_TIME. */
- if (len) {
- pm_runtime_get_sync(wdev->dev);
- spin_lock(&wdt_lock);
- omap_wdt_ping(wdev);
- spin_unlock(&wdt_lock);
- pm_runtime_put_sync(wdev->dev);
- }
- return len;
-}
+ struct omap_wdt_drvdata *omap_wdev = watchdog_get_drvdata(wdt_dev);
-static long omap_wdt_ioctl(struct file *file, unsigned int cmd,
- unsigned long arg)
-{
- struct omap_wdt_dev *wdev;
- int new_margin;
- static const struct watchdog_info ident = {
- .identity = "OMAP Watchdog",
- .options = WDIOF_SETTIMEOUT,
- .firmware_version = 0,
- };
-
- wdev = file->private_data;
-
- switch (cmd) {
- case WDIOC_GETSUPPORT:
- return copy_to_user((struct watchdog_info __user *)arg, &ident,
- sizeof(ident));
- case WDIOC_GETSTATUS:
- return put_user(0, (int __user *)arg);
- case WDIOC_GETBOOTSTATUS:
- if (cpu_is_omap16xx())
- return put_user(__raw_readw(ARM_SYSST),
- (int __user *)arg);
- if (cpu_is_omap24xx())
- return put_user(omap_prcm_get_reset_sources(),
- (int __user *)arg);
- return put_user(0, (int __user *)arg);
- case WDIOC_KEEPALIVE:
- pm_runtime_get_sync(wdev->dev);
- spin_lock(&wdt_lock);
- omap_wdt_ping(wdev);
- spin_unlock(&wdt_lock);
- pm_runtime_put_sync(wdev->dev);
- return 0;
- case WDIOC_SETTIMEOUT:
- if (get_user(new_margin, (int __user *)arg))
- return -EFAULT;
- omap_wdt_adjust_timeout(new_margin);
-
- pm_runtime_get_sync(wdev->dev);
- spin_lock(&wdt_lock);
- omap_wdt_disable(wdev);
- omap_wdt_set_timeout(wdev);
- omap_wdt_enable(wdev);
-
- omap_wdt_ping(wdev);
- spin_unlock(&wdt_lock);
- pm_runtime_put_sync(wdev->dev);
- /* Fall */
- case WDIOC_GETTIMEOUT:
- return put_user(timer_margin, (int __user *)arg);
- default:
- return -ENOTTY;
- }
+ pm_runtime_get_sync(omap_wdev->dev);
+ omap_wdt_disable(omap_wdev);
+ pm_runtime_put_sync(omap_wdev->dev);
+
+ return 0;
}
-static const struct file_operations omap_wdt_fops = {
+static const struct watchdog_ops omap_wdt_ops = {
.owner = THIS_MODULE,
- .write = omap_wdt_write,
- .unlocked_ioctl = omap_wdt_ioctl,
- .open = omap_wdt_open,
- .release = omap_wdt_release,
- .llseek = no_llseek,
+ .start = omap_wdt_start,
+ .stop = omap_wdt_stop,
+ .ping = omap_wdt_ping,
+ .set_timeout = omap_wdt_set_timeout,
+};
+
+static const struct watchdog_info omap_wdt_info = {
+ .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING |
+ WDIOF_CARDRESET,
+ .identity = "Omap Watchdog",
};
static int __devinit omap_wdt_probe(struct platform_device *pdev)
{
+ struct omap_wdt_drvdata *omap_drvdata;
+ struct watchdog_device *omap_wdev;
struct resource *res, *mem;
- struct omap_wdt_dev *wdev;
int ret;
/* reserve static register mappings */
@@ -286,68 +216,62 @@ static int __devinit omap_wdt_probe(struct platform_device *pdev)
goto err_get_resource;
}
- if (omap_wdt_dev) {
- ret = -EBUSY;
- goto err_busy;
- }
-
mem = request_mem_region(res->start, resource_size(res), pdev->name);
if (!mem) {
ret = -EBUSY;
goto err_busy;
}
- wdev = kzalloc(sizeof(struct omap_wdt_dev), GFP_KERNEL);
- if (!wdev) {
+ omap_drvdata = devm_kzalloc(&pdev->dev, sizeof(struct omap_wdt_drvdata),
+ GFP_KERNEL);
+ if (!omap_drvdata) {
+ dev_err(&pdev->dev, "Unable to allocate watchdog device\n");
ret = -ENOMEM;
goto err_kzalloc;
}
- wdev->omap_wdt_users = 0;
- wdev->mem = mem;
- wdev->dev = &pdev->dev;
+ omap_drvdata->dev = &pdev->dev;
+ omap_wdev = &omap_drvdata->wdt;
+ omap_wdev->info = &omap_wdt_info;
+ omap_wdev->ops = &omap_wdt_ops;
+ omap_wdev->timeout = TIMER_MARGIN_DEFAULT;
+ omap_wdev->min_timeout = 1;
+ omap_wdev->max_timeout = TIMER_MARGIN_MAX;
+#ifdef CONFIG_WATCHDOG_NOWAYOUT
+ watchdog_set_nowayout(omap_wdev, true);
+#endif
+ watchdog_set_drvdata(omap_wdev, omap_drvdata);
- wdev->base = ioremap(res->start, resource_size(res));
- if (!wdev->base) {
+ omap_drvdata->base = ioremap(res->start, resource_size(res));
+ if (!omap_drvdata->base) {
ret = -ENOMEM;
- goto err_ioremap;
+ goto err_kzalloc;
}
- platform_set_drvdata(pdev, wdev);
-
- pm_runtime_enable(wdev->dev);
- pm_runtime_get_sync(wdev->dev);
-
- omap_wdt_disable(wdev);
- omap_wdt_adjust_timeout(timer_margin);
-
- wdev->omap_wdt_miscdev.parent = &pdev->dev;
- wdev->omap_wdt_miscdev.minor = WATCHDOG_MINOR;
- wdev->omap_wdt_miscdev.name = "watchdog";
- wdev->omap_wdt_miscdev.fops = &omap_wdt_fops;
-
- ret = misc_register(&(wdev->omap_wdt_miscdev));
- if (ret)
- goto err_misc;
-
- pr_info("OMAP Watchdog Timer Rev 0x%02x: initial timeout %d sec\n",
- __raw_readl(wdev->base + OMAP_WATCHDOG_REV) & 0xFF,
- timer_margin);
-
- pm_runtime_put_sync(wdev->dev);
-
- omap_wdt_dev = pdev;
+ ret = watchdog_register_device(&omap_drvdata->wdt);
+ if (ret < 0)
+ goto err_register_wd;
+
+ pm_runtime_enable(&pdev->dev);
+ pm_runtime_get_sync(&pdev->dev);
+ omap_wdt_disable(omap_drvdata);
+ pm_runtime_put_sync(&pdev->dev);
+ platform_set_drvdata(pdev, omap_drvdata);
+
+ /* For omap16xx we just keep it original as-is */
+ if (cpu_is_omap16xx())
+ omap_wdev->bootstatus = __raw_readw(ARM_SYSST);
+ else
+ omap_wdev->bootstatus = (omap_prcm_get_reset_sources() & 0x10)
+ >> OMAP3_PRM_RSTST_WD_BIT;
+ pr_info("OMAP WDTimer Rev 0x%02x: Initial timeout %dsec status= 0x%x\n",
+ __raw_readl(omap_drvdata->base + OMAP_WATCHDOG_REV)
+ & 0xFF, timer_margin, omap_wdev->bootstatus);
return 0;
-err_misc:
- pm_runtime_disable(wdev->dev);
- platform_set_drvdata(pdev, NULL);
- iounmap(wdev->base);
-
-err_ioremap:
- wdev->base = NULL;
- kfree(wdev);
+err_register_wd:
+ iounmap(omap_drvdata->base);
err_kzalloc:
release_mem_region(res->start, resource_size(res));
@@ -358,34 +282,17 @@ err_get_resource:
return ret;
}
-static void omap_wdt_shutdown(struct platform_device *pdev)
-{
- struct omap_wdt_dev *wdev = platform_get_drvdata(pdev);
-
- if (wdev->omap_wdt_users) {
- pm_runtime_get_sync(wdev->dev);
- omap_wdt_disable(wdev);
- pm_runtime_put_sync(wdev->dev);
- }
-}
-
static int __devexit omap_wdt_remove(struct platform_device *pdev)
{
- struct omap_wdt_dev *wdev = platform_get_drvdata(pdev);
+ struct omap_wdt_drvdata *omap_wdev = platform_get_drvdata(pdev);
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- pm_runtime_disable(wdev->dev);
- if (!res)
- return -ENOENT;
+ pm_runtime_disable(&pdev->dev);
- misc_deregister(&(wdev->omap_wdt_miscdev));
release_mem_region(res->start, resource_size(res));
platform_set_drvdata(pdev, NULL);
- iounmap(wdev->base);
-
- kfree(wdev);
- omap_wdt_dev = NULL;
+ iounmap(omap_wdev->base);
return 0;
}
@@ -400,12 +307,12 @@ static int __devexit omap_wdt_remove(struct platform_device *pdev)
static int omap_wdt_suspend(struct platform_device *pdev, pm_message_t state)
{
- struct omap_wdt_dev *wdev = platform_get_drvdata(pdev);
+ struct omap_wdt_drvdata *omap_wdev = platform_get_drvdata(pdev);
- if (wdev->omap_wdt_users) {
- pm_runtime_get_sync(wdev->dev);
- omap_wdt_disable(wdev);
- pm_runtime_put_sync(wdev->dev);
+ if (test_bit(WDOG_DEV_OPEN, &omap_wdev->wdt.status)) {
+ pm_runtime_get_sync(&pdev->dev);
+ omap_wdt_disable(omap_wdev);
+ pm_runtime_put_sync(&pdev->dev);
}
return 0;
@@ -413,13 +320,12 @@ static int omap_wdt_suspend(struct platform_device *pdev, pm_message_t state)
static int omap_wdt_resume(struct platform_device *pdev)
{
- struct omap_wdt_dev *wdev = platform_get_drvdata(pdev);
-
- if (wdev->omap_wdt_users) {
- pm_runtime_get_sync(wdev->dev);
- omap_wdt_enable(wdev);
- omap_wdt_ping(wdev);
- pm_runtime_put_sync(wdev->dev);
+ struct omap_wdt_drvdata *omap_wdev = platform_get_drvdata(pdev);
+ if (test_bit(WDOG_DEV_OPEN, &omap_wdev->wdt.status)) {
+ pm_runtime_get_sync(&pdev->dev);
+ omap_wdt_enable(omap_wdev);
+ omap_wdt_ping(&omap_wdev->wdt);
+ pm_runtime_put_sync(&pdev->dev);
}
return 0;
@@ -433,7 +339,6 @@ static int omap_wdt_resume(struct platform_device *pdev)
static struct platform_driver omap_wdt_driver = {
.probe = omap_wdt_probe,
.remove = __devexit_p(omap_wdt_remove),
- .shutdown = omap_wdt_shutdown,
.suspend = omap_wdt_suspend,
.resume = omap_wdt_resume,
.driver = {
@@ -446,5 +351,4 @@ module_platform_driver(omap_wdt_driver);
MODULE_AUTHOR("George G. Davis");
MODULE_LICENSE("GPL");
-MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
MODULE_ALIAS("platform:omap_wdt");
diff --git a/drivers/watchdog/omap_wdt.h b/drivers/watchdog/omap_wdt.h
index 09b774c..cf5f037 100644
--- a/drivers/watchdog/omap_wdt.h
+++ b/drivers/watchdog/omap_wdt.h
@@ -51,4 +51,9 @@
#define PTV 0 /* prescale */
#define GET_WLDR_VAL(secs) (0xffffffff - ((secs) * (32768/(1<<PTV))) + 1)
+/* MPU_WD_RST bit in PRM_RSTST show Omap WDTimer reset event.
+ * 0x0 = 0x0 : No watchdog reset.
+ * 0x1 = 0x1 : watchdog reset has occurred. */
+#define OMAP3_PRM_RSTST_WD_BIT 4
+
#endif /* _OMAP_WATCHDOG_H */
--
1.7.5.4
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH RESEND v3 2/3] Watchdog: Omap: select watchdog core for framework change
2012-07-15 7:44 ` Zumeng Chen
(?)
@ 2012-07-15 7:44 ` Zumeng Chen
-1 siblings, 0 replies; 21+ messages in thread
From: Zumeng Chen @ 2012-07-15 7:44 UTC (permalink / raw)
To: khilman, shubhrajyoti, linux-watchdog, hvaibhav
Cc: wim, linux-omap, tony, paul.gortmaker, linux-arm-kernel
Since the current watchdog framework depends on the watchdog core
so select it in Kconfig.
Signed-off-by: Zumeng Chen <zumeng.chen@windriver.com>
---
drivers/watchdog/Kconfig | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index fe819b7..fb5b108 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -232,6 +232,7 @@ config EP93XX_WATCHDOG
config OMAP_WATCHDOG
tristate "OMAP Watchdog"
depends on ARCH_OMAP16XX || ARCH_OMAP2PLUS
+ select WATCHDOG_CORE
help
Support for TI OMAP1610/OMAP1710/OMAP2420/OMAP3430/OMAP4430 watchdog. Say 'Y'
here to enable the OMAP1610/OMAP1710/OMAP2420/OMAP3430/OMAP4430 watchdog timer.
--
1.7.5.4
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH RESEND v3 2/3] Watchdog: Omap: select watchdog core for framework change
@ 2012-07-15 7:44 ` Zumeng Chen
0 siblings, 0 replies; 21+ messages in thread
From: Zumeng Chen @ 2012-07-15 7:44 UTC (permalink / raw)
To: khilman, shubhrajyoti, linux-watchdog, hvaibhav
Cc: wim, linux-omap, tony, paul.gortmaker, linux-arm-kernel
Since the current watchdog framework depends on the watchdog core
so select it in Kconfig.
Signed-off-by: Zumeng Chen <zumeng.chen@windriver.com>
---
drivers/watchdog/Kconfig | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index fe819b7..fb5b108 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -232,6 +232,7 @@ config EP93XX_WATCHDOG
config OMAP_WATCHDOG
tristate "OMAP Watchdog"
depends on ARCH_OMAP16XX || ARCH_OMAP2PLUS
+ select WATCHDOG_CORE
help
Support for TI OMAP1610/OMAP1710/OMAP2420/OMAP3430/OMAP4430 watchdog. Say 'Y'
here to enable the OMAP1610/OMAP1710/OMAP2420/OMAP3430/OMAP4430 watchdog timer.
--
1.7.5.4
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH RESEND v3 2/3] Watchdog: Omap: select watchdog core for framework change
@ 2012-07-15 7:44 ` Zumeng Chen
0 siblings, 0 replies; 21+ messages in thread
From: Zumeng Chen @ 2012-07-15 7:44 UTC (permalink / raw)
To: linux-arm-kernel
Since the current watchdog framework depends on the watchdog core
so select it in Kconfig.
Signed-off-by: Zumeng Chen <zumeng.chen@windriver.com>
---
drivers/watchdog/Kconfig | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index fe819b7..fb5b108 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -232,6 +232,7 @@ config EP93XX_WATCHDOG
config OMAP_WATCHDOG
tristate "OMAP Watchdog"
depends on ARCH_OMAP16XX || ARCH_OMAP2PLUS
+ select WATCHDOG_CORE
help
Support for TI OMAP1610/OMAP1710/OMAP2420/OMAP3430/OMAP4430 watchdog. Say 'Y'
here to enable the OMAP1610/OMAP1710/OMAP2420/OMAP3430/OMAP4430 watchdog timer.
--
1.7.5.4
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH RESEND v3 3/3] Watchdog: Omap: get the bootstatus for OMAP34xx
2012-07-15 7:44 ` Zumeng Chen
(?)
@ 2012-07-15 7:44 ` Zumeng Chen
-1 siblings, 0 replies; 21+ messages in thread
From: Zumeng Chen @ 2012-07-15 7:44 UTC (permalink / raw)
To: khilman, shubhrajyoti, linux-watchdog, hvaibhav
Cc: wim, linux-omap, tony, paul.gortmaker, linux-arm-kernel
The offset of WKUP_MOD is not right for the PRM_RSTST of OMAP3. So here
put the right one to match to the actual physical addr 0x48307258, which
defined in PRCM Registers section named as Global_Reg_PRM.
And there is a MPU_WD_RST bit in PRM_RSTST(0x48307258) holding the signal
from omap-wdt reboot, so that we can return WDIOF_CARDRESET if the board
wakes up from omap-wdt reboot for WDIOC_GETBOOTSTATUS ioctl.
Signed-off-by: Zumeng Chen <zumeng.chen@windriver.com>
---
arch/arm/mach-omap2/prcm.c | 9 +++++++--
1 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-omap2/prcm.c b/arch/arm/mach-omap2/prcm.c
index 480f40a..3ca8aa7 100644
--- a/arch/arm/mach-omap2/prcm.c
+++ b/arch/arm/mach-omap2/prcm.c
@@ -48,9 +48,14 @@ void __iomem *prcm_mpu_base;
u32 omap_prcm_get_reset_sources(void)
{
- /* XXX This presumably needs modification for 34XX */
- if (cpu_is_omap24xx() || cpu_is_omap34xx())
+ if (cpu_is_omap24xx())
return omap2_prm_read_mod_reg(WKUP_MOD, OMAP2_RM_RSTST) & 0x7f;
+
+ /* XXX This presumably needs modification for AM33XX when ready. */
+ if (cpu_is_omap34xx())
+ return omap2_prm_read_mod_reg(OMAP3430_GR_MOD, OMAP2_RM_RSTST) &
+ 0x7f;
+
if (cpu_is_omap44xx())
return omap2_prm_read_mod_reg(WKUP_MOD, OMAP4_RM_RSTST) & 0x7f;
--
1.7.5.4
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH RESEND v3 3/3] Watchdog: Omap: get the bootstatus for OMAP34xx
@ 2012-07-15 7:44 ` Zumeng Chen
0 siblings, 0 replies; 21+ messages in thread
From: Zumeng Chen @ 2012-07-15 7:44 UTC (permalink / raw)
To: khilman, shubhrajyoti, linux-watchdog, hvaibhav
Cc: wim, linux-omap, tony, paul.gortmaker, linux-arm-kernel
The offset of WKUP_MOD is not right for the PRM_RSTST of OMAP3. So here
put the right one to match to the actual physical addr 0x48307258, which
defined in PRCM Registers section named as Global_Reg_PRM.
And there is a MPU_WD_RST bit in PRM_RSTST(0x48307258) holding the signal
from omap-wdt reboot, so that we can return WDIOF_CARDRESET if the board
wakes up from omap-wdt reboot for WDIOC_GETBOOTSTATUS ioctl.
Signed-off-by: Zumeng Chen <zumeng.chen@windriver.com>
---
arch/arm/mach-omap2/prcm.c | 9 +++++++--
1 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-omap2/prcm.c b/arch/arm/mach-omap2/prcm.c
index 480f40a..3ca8aa7 100644
--- a/arch/arm/mach-omap2/prcm.c
+++ b/arch/arm/mach-omap2/prcm.c
@@ -48,9 +48,14 @@ void __iomem *prcm_mpu_base;
u32 omap_prcm_get_reset_sources(void)
{
- /* XXX This presumably needs modification for 34XX */
- if (cpu_is_omap24xx() || cpu_is_omap34xx())
+ if (cpu_is_omap24xx())
return omap2_prm_read_mod_reg(WKUP_MOD, OMAP2_RM_RSTST) & 0x7f;
+
+ /* XXX This presumably needs modification for AM33XX when ready. */
+ if (cpu_is_omap34xx())
+ return omap2_prm_read_mod_reg(OMAP3430_GR_MOD, OMAP2_RM_RSTST) &
+ 0x7f;
+
if (cpu_is_omap44xx())
return omap2_prm_read_mod_reg(WKUP_MOD, OMAP4_RM_RSTST) & 0x7f;
--
1.7.5.4
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH RESEND v3 3/3] Watchdog: Omap: get the bootstatus for OMAP34xx
@ 2012-07-15 7:44 ` Zumeng Chen
0 siblings, 0 replies; 21+ messages in thread
From: Zumeng Chen @ 2012-07-15 7:44 UTC (permalink / raw)
To: linux-arm-kernel
The offset of WKUP_MOD is not right for the PRM_RSTST of OMAP3. So here
put the right one to match to the actual physical addr 0x48307258, which
defined in PRCM Registers section named as Global_Reg_PRM.
And there is a MPU_WD_RST bit in PRM_RSTST(0x48307258) holding the signal
from omap-wdt reboot, so that we can return WDIOF_CARDRESET if the board
wakes up from omap-wdt reboot for WDIOC_GETBOOTSTATUS ioctl.
Signed-off-by: Zumeng Chen <zumeng.chen@windriver.com>
---
arch/arm/mach-omap2/prcm.c | 9 +++++++--
1 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-omap2/prcm.c b/arch/arm/mach-omap2/prcm.c
index 480f40a..3ca8aa7 100644
--- a/arch/arm/mach-omap2/prcm.c
+++ b/arch/arm/mach-omap2/prcm.c
@@ -48,9 +48,14 @@ void __iomem *prcm_mpu_base;
u32 omap_prcm_get_reset_sources(void)
{
- /* XXX This presumably needs modification for 34XX */
- if (cpu_is_omap24xx() || cpu_is_omap34xx())
+ if (cpu_is_omap24xx())
return omap2_prm_read_mod_reg(WKUP_MOD, OMAP2_RM_RSTST) & 0x7f;
+
+ /* XXX This presumably needs modification for AM33XX when ready. */
+ if (cpu_is_omap34xx())
+ return omap2_prm_read_mod_reg(OMAP3430_GR_MOD, OMAP2_RM_RSTST) &
+ 0x7f;
+
if (cpu_is_omap44xx())
return omap2_prm_read_mod_reg(WKUP_MOD, OMAP4_RM_RSTST) & 0x7f;
--
1.7.5.4
^ permalink raw reply related [flat|nested] 21+ messages in thread
* RE: [PATCH RESEND v3 1/3] Watchdog: Omap: Changes for the new watchdog framework
2012-07-15 7:44 ` Zumeng Chen
(?)
@ 2012-07-16 13:10 ` Hiremath, Vaibhav
-1 siblings, 0 replies; 21+ messages in thread
From: Hiremath, Vaibhav @ 2012-07-16 13:10 UTC (permalink / raw)
To: Zumeng Chen, Hilman, Kevin, Datta, Shubhrajyoti, linux-watchdog
Cc: wim, linux-omap, tony, paul.gortmaker, linux-arm-kernel
On Sun, Jul 15, 2012 at 13:14:04, Zumeng Chen wrote:
> This patch implements the current watchdog framework for OMAP WDTimer,
> which factored out the common components, so the driver can just focus
> on the hardware related parts.
>
> Signed-off-by: Zumeng Chen <zumeng.chen@windriver.com>
> ---
> drivers/watchdog/omap_wdt.c | 342 ++++++++++++++++---------------------------
> drivers/watchdog/omap_wdt.h | 5 +
> 2 files changed, 128 insertions(+), 219 deletions(-)
>
> diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c
> index 8285d65..cc5bc3e 100644
> --- a/drivers/watchdog/omap_wdt.c
> +++ b/drivers/watchdog/omap_wdt.c
> @@ -24,6 +24,9 @@
> *
> * Copyright (c) 2005 David Brownell
> * Use the driver model and standard identifiers; handle bigger timeouts.
> + *
> + * Copyright (c) 2012 WindRiver
> + * Changes cater for the current watchdog framework.
> */
>
> #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> @@ -33,7 +36,6 @@
> #include <linux/kernel.h>
> #include <linux/fs.h>
> #include <linux/mm.h>
> -#include <linux/miscdevice.h>
> #include <linux/watchdog.h>
> #include <linux/reboot.h>
> #include <linux/init.h>
> @@ -50,8 +52,6 @@
>
> #include "omap_wdt.h"
>
> -static struct platform_device *omap_wdt_dev;
> -
> static unsigned timer_margin;
> module_param(timer_margin, uint, 0);
> MODULE_PARM_DESC(timer_margin, "initial watchdog timeout (in seconds)");
> @@ -59,32 +59,14 @@ MODULE_PARM_DESC(timer_margin, "initial watchdog timeout (in seconds)");
> static unsigned int wdt_trgr_pattern = 0x1234;
> static DEFINE_SPINLOCK(wdt_lock);
>
> -struct omap_wdt_dev {
> +struct omap_wdt_drvdata {
> + struct watchdog_device wdt;
> void __iomem *base; /* physical */
> struct device *dev;
> - int omap_wdt_users;
> struct resource *mem;
> - struct miscdevice omap_wdt_miscdev;
> };
>
> -static void omap_wdt_ping(struct omap_wdt_dev *wdev)
> -{
> - void __iomem *base = wdev->base;
> -
> - /* wait for posted write to complete */
> - while ((__raw_readl(base + OMAP_WATCHDOG_WPS)) & 0x08)
> - cpu_relax();
> -
> - wdt_trgr_pattern = ~wdt_trgr_pattern;
> - __raw_writel(wdt_trgr_pattern, (base + OMAP_WATCHDOG_TGR));
> -
> - /* wait for posted write to complete */
> - while ((__raw_readl(base + OMAP_WATCHDOG_WPS)) & 0x08)
> - cpu_relax();
> - /* reloaded WCRR from WLDR */
> -}
> -
> -static void omap_wdt_enable(struct omap_wdt_dev *wdev)
> +static void omap_wdt_enable(struct omap_wdt_drvdata *wdev)
> {
> void __iomem *base = wdev->base;
>
> @@ -98,7 +80,7 @@ static void omap_wdt_enable(struct omap_wdt_dev *wdev)
> cpu_relax();
> }
>
> -static void omap_wdt_disable(struct omap_wdt_dev *wdev)
> +static void omap_wdt_disable(struct omap_wdt_drvdata *wdev)
> {
> void __iomem *base = wdev->base;
>
> @@ -121,12 +103,19 @@ static void omap_wdt_adjust_timeout(unsigned new_timeout)
> timer_margin = new_timeout;
> }
>
> -static void omap_wdt_set_timeout(struct omap_wdt_dev *wdev)
> +static int omap_wdt_set_timeout(struct watchdog_device *wdt_dev,
> + unsigned int new_timeout)
> {
> - u32 pre_margin = GET_WLDR_VAL(timer_margin);
> - void __iomem *base = wdev->base;
> + u32 pre_margin;
> + struct omap_wdt_drvdata *omap_wdev = watchdog_get_drvdata(wdt_dev);
> + void __iomem *base = omap_wdev->base;
>
> - pm_runtime_get_sync(wdev->dev);
> + pm_runtime_get_sync(omap_wdev->dev);
> + omap_wdt_disable(omap_wdev);
> +
> + /* adjust timeout based on the new timeout */
> + omap_wdt_adjust_timeout(new_timeout);
> + pre_margin = GET_WLDR_VAL(timer_margin);
>
> /* just count up at 32 KHz */
> while (__raw_readl(base + OMAP_WATCHDOG_WPS) & 0x04)
> @@ -136,147 +125,88 @@ static void omap_wdt_set_timeout(struct omap_wdt_dev *wdev)
> while (__raw_readl(base + OMAP_WATCHDOG_WPS) & 0x04)
> cpu_relax();
>
> - pm_runtime_put_sync(wdev->dev);
> + omap_wdt_enable(omap_wdev);
> + wdt_dev->timeout = new_timeout;
> + pm_runtime_put_sync(omap_wdev->dev);
> + return 0;
> }
>
> -/*
> - * Allow only one task to hold it open
> - */
> -static int omap_wdt_open(struct inode *inode, struct file *file)
> +static int omap_wdt_ping(struct watchdog_device *wdt_dev)
> {
> - struct omap_wdt_dev *wdev = platform_get_drvdata(omap_wdt_dev);
> - void __iomem *base = wdev->base;
> -
> - if (test_and_set_bit(1, (unsigned long *)&(wdev->omap_wdt_users)))
> - return -EBUSY;
> -
> - pm_runtime_get_sync(wdev->dev);
> + struct omap_wdt_drvdata *omap_wdev = watchdog_get_drvdata(wdt_dev);
> + void __iomem *base = omap_wdev->base;
>
> - /* initialize prescaler */
> - while (__raw_readl(base + OMAP_WATCHDOG_WPS) & 0x01)
> - cpu_relax();
> + pm_runtime_get_sync(omap_wdev->dev);
> + spin_lock(&wdt_lock);
>
> - __raw_writel((1 << 5) | (PTV << 2), base + OMAP_WATCHDOG_CNTRL);
> - while (__raw_readl(base + OMAP_WATCHDOG_WPS) & 0x01)
> + /* wait for posted write to complete */
> + while ((__raw_readl(base + OMAP_WATCHDOG_WPS)) & 0x08)
> cpu_relax();
>
> - file->private_data = (void *) wdev;
> + wdt_trgr_pattern = ~wdt_trgr_pattern;
> + __raw_writel(wdt_trgr_pattern, (base + OMAP_WATCHDOG_TGR));
>
> - omap_wdt_set_timeout(wdev);
> - omap_wdt_ping(wdev); /* trigger loading of new timeout value */
> - omap_wdt_enable(wdev);
> + /* wait for posted write to complete */
> + /* reloaded WCRR from WLDR */
> + while ((__raw_readl(base + OMAP_WATCHDOG_WPS)) & 0x08)
> + cpu_relax();
>
> - pm_runtime_put_sync(wdev->dev);
> + spin_unlock(&wdt_lock);
> + pm_runtime_put_sync(omap_wdev->dev);
>
> - return nonseekable_open(inode, file);
> + return 0;
> }
>
> -static int omap_wdt_release(struct inode *inode, struct file *file)
> +static int omap_wdt_start(struct watchdog_device *wdt_dev)
> {
> - struct omap_wdt_dev *wdev = file->private_data;
> + struct omap_wdt_drvdata *omap_wdev = watchdog_get_drvdata(wdt_dev);
> + void __iomem *base = omap_wdev->base;
>
> - /*
> - * Shut off the timer unless NOWAYOUT is defined.
> - */
> -#ifndef CONFIG_WATCHDOG_NOWAYOUT
> - pm_runtime_get_sync(wdev->dev);
> + pm_runtime_get_sync(omap_wdev->dev);
> + /* initialize prescaler */
> + while (__raw_readl(base + OMAP_WATCHDOG_WPS) & 0x01)
> + cpu_relax();
>
> - omap_wdt_disable(wdev);
> + __raw_writel((1 << 5) | (PTV << 2), base + OMAP_WATCHDOG_CNTRL);
> + while (__raw_readl(base + OMAP_WATCHDOG_WPS) & 0x01)
> + cpu_relax();
>
> - pm_runtime_put_sync(wdev->dev);
> -#else
> - pr_crit("Unexpected close, not stopping!\n");
> -#endif
> - wdev->omap_wdt_users = 0;
> + omap_wdt_set_timeout(&omap_wdev->wdt, timer_margin);
> + pm_runtime_put_sync(omap_wdev->dev);
>
> return 0;
> }
>
> -static ssize_t omap_wdt_write(struct file *file, const char __user *data,
> - size_t len, loff_t *ppos)
> +static int omap_wdt_stop(struct watchdog_device *wdt_dev)
> {
> - struct omap_wdt_dev *wdev = file->private_data;
> -
> - /* Refresh LOAD_TIME. */
> - if (len) {
> - pm_runtime_get_sync(wdev->dev);
> - spin_lock(&wdt_lock);
> - omap_wdt_ping(wdev);
> - spin_unlock(&wdt_lock);
> - pm_runtime_put_sync(wdev->dev);
> - }
> - return len;
> -}
> + struct omap_wdt_drvdata *omap_wdev = watchdog_get_drvdata(wdt_dev);
>
> -static long omap_wdt_ioctl(struct file *file, unsigned int cmd,
> - unsigned long arg)
> -{
> - struct omap_wdt_dev *wdev;
> - int new_margin;
> - static const struct watchdog_info ident = {
> - .identity = "OMAP Watchdog",
> - .options = WDIOF_SETTIMEOUT,
> - .firmware_version = 0,
> - };
> -
> - wdev = file->private_data;
> -
> - switch (cmd) {
> - case WDIOC_GETSUPPORT:
> - return copy_to_user((struct watchdog_info __user *)arg, &ident,
> - sizeof(ident));
> - case WDIOC_GETSTATUS:
> - return put_user(0, (int __user *)arg);
> - case WDIOC_GETBOOTSTATUS:
> - if (cpu_is_omap16xx())
> - return put_user(__raw_readw(ARM_SYSST),
> - (int __user *)arg);
> - if (cpu_is_omap24xx())
> - return put_user(omap_prcm_get_reset_sources(),
> - (int __user *)arg);
> - return put_user(0, (int __user *)arg);
> - case WDIOC_KEEPALIVE:
> - pm_runtime_get_sync(wdev->dev);
> - spin_lock(&wdt_lock);
> - omap_wdt_ping(wdev);
> - spin_unlock(&wdt_lock);
> - pm_runtime_put_sync(wdev->dev);
> - return 0;
> - case WDIOC_SETTIMEOUT:
> - if (get_user(new_margin, (int __user *)arg))
> - return -EFAULT;
> - omap_wdt_adjust_timeout(new_margin);
> -
> - pm_runtime_get_sync(wdev->dev);
> - spin_lock(&wdt_lock);
> - omap_wdt_disable(wdev);
> - omap_wdt_set_timeout(wdev);
> - omap_wdt_enable(wdev);
> -
> - omap_wdt_ping(wdev);
> - spin_unlock(&wdt_lock);
> - pm_runtime_put_sync(wdev->dev);
> - /* Fall */
> - case WDIOC_GETTIMEOUT:
> - return put_user(timer_margin, (int __user *)arg);
> - default:
> - return -ENOTTY;
> - }
> + pm_runtime_get_sync(omap_wdev->dev);
> + omap_wdt_disable(omap_wdev);
> + pm_runtime_put_sync(omap_wdev->dev);
> +
> + return 0;
> }
>
> -static const struct file_operations omap_wdt_fops = {
> +static const struct watchdog_ops omap_wdt_ops = {
> .owner = THIS_MODULE,
> - .write = omap_wdt_write,
> - .unlocked_ioctl = omap_wdt_ioctl,
> - .open = omap_wdt_open,
> - .release = omap_wdt_release,
> - .llseek = no_llseek,
> + .start = omap_wdt_start,
> + .stop = omap_wdt_stop,
> + .ping = omap_wdt_ping,
> + .set_timeout = omap_wdt_set_timeout,
> +};
> +
> +static const struct watchdog_info omap_wdt_info = {
> + .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING |
> + WDIOF_CARDRESET,
> + .identity = "Omap Watchdog",
> };
>
> static int __devinit omap_wdt_probe(struct platform_device *pdev)
> {
> + struct omap_wdt_drvdata *omap_drvdata;
> + struct watchdog_device *omap_wdev;
> struct resource *res, *mem;
> - struct omap_wdt_dev *wdev;
> int ret;
>
> /* reserve static register mappings */
> @@ -286,68 +216,62 @@ static int __devinit omap_wdt_probe(struct platform_device *pdev)
> goto err_get_resource;
> }
>
> - if (omap_wdt_dev) {
> - ret = -EBUSY;
> - goto err_busy;
> - }
> -
> mem = request_mem_region(res->start, resource_size(res), pdev->name);
> if (!mem) {
> ret = -EBUSY;
> goto err_busy;
> }
>
> - wdev = kzalloc(sizeof(struct omap_wdt_dev), GFP_KERNEL);
> - if (!wdev) {
> + omap_drvdata = devm_kzalloc(&pdev->dev, sizeof(struct omap_wdt_drvdata),
> + GFP_KERNEL);
> + if (!omap_drvdata) {
> + dev_err(&pdev->dev, "Unable to allocate watchdog device\n");
> ret = -ENOMEM;
> goto err_kzalloc;
> }
>
> - wdev->omap_wdt_users = 0;
> - wdev->mem = mem;
> - wdev->dev = &pdev->dev;
> + omap_drvdata->dev = &pdev->dev;
> + omap_wdev = &omap_drvdata->wdt;
> + omap_wdev->info = &omap_wdt_info;
> + omap_wdev->ops = &omap_wdt_ops;
> + omap_wdev->timeout = TIMER_MARGIN_DEFAULT;
> + omap_wdev->min_timeout = 1;
> + omap_wdev->max_timeout = TIMER_MARGIN_MAX;
> +#ifdef CONFIG_WATCHDOG_NOWAYOUT
> + watchdog_set_nowayout(omap_wdev, true);
> +#endif
> + watchdog_set_drvdata(omap_wdev, omap_drvdata);
>
> - wdev->base = ioremap(res->start, resource_size(res));
> - if (!wdev->base) {
> + omap_drvdata->base = ioremap(res->start, resource_size(res));
> + if (!omap_drvdata->base) {
> ret = -ENOMEM;
> - goto err_ioremap;
> + goto err_kzalloc;
> }
>
> - platform_set_drvdata(pdev, wdev);
> -
> - pm_runtime_enable(wdev->dev);
> - pm_runtime_get_sync(wdev->dev);
> -
> - omap_wdt_disable(wdev);
> - omap_wdt_adjust_timeout(timer_margin);
> -
> - wdev->omap_wdt_miscdev.parent = &pdev->dev;
> - wdev->omap_wdt_miscdev.minor = WATCHDOG_MINOR;
> - wdev->omap_wdt_miscdev.name = "watchdog";
> - wdev->omap_wdt_miscdev.fops = &omap_wdt_fops;
> -
> - ret = misc_register(&(wdev->omap_wdt_miscdev));
> - if (ret)
> - goto err_misc;
> -
> - pr_info("OMAP Watchdog Timer Rev 0x%02x: initial timeout %d sec\n",
> - __raw_readl(wdev->base + OMAP_WATCHDOG_REV) & 0xFF,
> - timer_margin);
> -
> - pm_runtime_put_sync(wdev->dev);
> -
> - omap_wdt_dev = pdev;
> + ret = watchdog_register_device(&omap_drvdata->wdt);
> + if (ret < 0)
> + goto err_register_wd;
> +
> + pm_runtime_enable(&pdev->dev);
> + pm_runtime_get_sync(&pdev->dev);
> + omap_wdt_disable(omap_drvdata);
> + pm_runtime_put_sync(&pdev->dev);
> + platform_set_drvdata(pdev, omap_drvdata);
> +
> + /* For omap16xx we just keep it original as-is */
> + if (cpu_is_omap16xx())
> + omap_wdev->bootstatus = __raw_readw(ARM_SYSST);
> + else
> + omap_wdev->bootstatus = (omap_prcm_get_reset_sources() & 0x10)
> + >> OMAP3_PRM_RSTST_WD_BIT;
CPU check is really not receommended in driver, you should avoid this.
I understand that, driver was already doing this, but can this be handled by
IP rev? if not, you may want to use pdata for this.
Also I understand that, this is tied to prcm code base as far as omap2 is concerned. May be Tony or others can comment on this.
Thanks,
Vaibhav
> + pr_info("OMAP WDTimer Rev 0x%02x: Initial timeout %dsec status= 0x%x\n",
> + __raw_readl(omap_drvdata->base + OMAP_WATCHDOG_REV)
> + & 0xFF, timer_margin, omap_wdev->bootstatus);
>
> return 0;
>
> -err_misc:
> - pm_runtime_disable(wdev->dev);
> - platform_set_drvdata(pdev, NULL);
> - iounmap(wdev->base);
> -
> -err_ioremap:
> - wdev->base = NULL;
> - kfree(wdev);
> +err_register_wd:
> + iounmap(omap_drvdata->base);
>
> err_kzalloc:
> release_mem_region(res->start, resource_size(res));
> @@ -358,34 +282,17 @@ err_get_resource:
> return ret;
> }
>
> -static void omap_wdt_shutdown(struct platform_device *pdev)
> -{
> - struct omap_wdt_dev *wdev = platform_get_drvdata(pdev);
> -
> - if (wdev->omap_wdt_users) {
> - pm_runtime_get_sync(wdev->dev);
> - omap_wdt_disable(wdev);
> - pm_runtime_put_sync(wdev->dev);
> - }
> -}
> -
> static int __devexit omap_wdt_remove(struct platform_device *pdev)
> {
> - struct omap_wdt_dev *wdev = platform_get_drvdata(pdev);
> + struct omap_wdt_drvdata *omap_wdev = platform_get_drvdata(pdev);
> struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>
> - pm_runtime_disable(wdev->dev);
> - if (!res)
> - return -ENOENT;
> + pm_runtime_disable(&pdev->dev);
>
> - misc_deregister(&(wdev->omap_wdt_miscdev));
> release_mem_region(res->start, resource_size(res));
> platform_set_drvdata(pdev, NULL);
>
> - iounmap(wdev->base);
> -
> - kfree(wdev);
> - omap_wdt_dev = NULL;
> + iounmap(omap_wdev->base);
>
> return 0;
> }
> @@ -400,12 +307,12 @@ static int __devexit omap_wdt_remove(struct platform_device *pdev)
>
> static int omap_wdt_suspend(struct platform_device *pdev, pm_message_t state)
> {
> - struct omap_wdt_dev *wdev = platform_get_drvdata(pdev);
> + struct omap_wdt_drvdata *omap_wdev = platform_get_drvdata(pdev);
>
> - if (wdev->omap_wdt_users) {
> - pm_runtime_get_sync(wdev->dev);
> - omap_wdt_disable(wdev);
> - pm_runtime_put_sync(wdev->dev);
> + if (test_bit(WDOG_DEV_OPEN, &omap_wdev->wdt.status)) {
> + pm_runtime_get_sync(&pdev->dev);
> + omap_wdt_disable(omap_wdev);
> + pm_runtime_put_sync(&pdev->dev);
> }
>
> return 0;
> @@ -413,13 +320,12 @@ static int omap_wdt_suspend(struct platform_device *pdev, pm_message_t state)
>
> static int omap_wdt_resume(struct platform_device *pdev)
> {
> - struct omap_wdt_dev *wdev = platform_get_drvdata(pdev);
> -
> - if (wdev->omap_wdt_users) {
> - pm_runtime_get_sync(wdev->dev);
> - omap_wdt_enable(wdev);
> - omap_wdt_ping(wdev);
> - pm_runtime_put_sync(wdev->dev);
> + struct omap_wdt_drvdata *omap_wdev = platform_get_drvdata(pdev);
> + if (test_bit(WDOG_DEV_OPEN, &omap_wdev->wdt.status)) {
> + pm_runtime_get_sync(&pdev->dev);
> + omap_wdt_enable(omap_wdev);
> + omap_wdt_ping(&omap_wdev->wdt);
> + pm_runtime_put_sync(&pdev->dev);
> }
>
> return 0;
> @@ -433,7 +339,6 @@ static int omap_wdt_resume(struct platform_device *pdev)
> static struct platform_driver omap_wdt_driver = {
> .probe = omap_wdt_probe,
> .remove = __devexit_p(omap_wdt_remove),
> - .shutdown = omap_wdt_shutdown,
> .suspend = omap_wdt_suspend,
> .resume = omap_wdt_resume,
> .driver = {
> @@ -446,5 +351,4 @@ module_platform_driver(omap_wdt_driver);
>
> MODULE_AUTHOR("George G. Davis");
> MODULE_LICENSE("GPL");
> -MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
> MODULE_ALIAS("platform:omap_wdt");
> diff --git a/drivers/watchdog/omap_wdt.h b/drivers/watchdog/omap_wdt.h
> index 09b774c..cf5f037 100644
> --- a/drivers/watchdog/omap_wdt.h
> +++ b/drivers/watchdog/omap_wdt.h
> @@ -51,4 +51,9 @@
> #define PTV 0 /* prescale */
> #define GET_WLDR_VAL(secs) (0xffffffff - ((secs) * (32768/(1<<PTV))) + 1)
>
> +/* MPU_WD_RST bit in PRM_RSTST show Omap WDTimer reset event.
> + * 0x0 = 0x0 : No watchdog reset.
> + * 0x1 = 0x1 : watchdog reset has occurred. */
> +#define OMAP3_PRM_RSTST_WD_BIT 4
> +
> #endif /* _OMAP_WATCHDOG_H */
> --
> 1.7.5.4
>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 21+ messages in thread
* RE: [PATCH RESEND v3 1/3] Watchdog: Omap: Changes for the new watchdog framework
@ 2012-07-16 13:10 ` Hiremath, Vaibhav
0 siblings, 0 replies; 21+ messages in thread
From: Hiremath, Vaibhav @ 2012-07-16 13:10 UTC (permalink / raw)
To: Zumeng Chen, Hilman, Kevin, Datta, Shubhrajyoti, linux-watchdog
Cc: wim, linux-omap, tony, paul.gortmaker, linux-arm-kernel
On Sun, Jul 15, 2012 at 13:14:04, Zumeng Chen wrote:
> This patch implements the current watchdog framework for OMAP WDTimer,
> which factored out the common components, so the driver can just focus
> on the hardware related parts.
>
> Signed-off-by: Zumeng Chen <zumeng.chen@windriver.com>
> ---
> drivers/watchdog/omap_wdt.c | 342 ++++++++++++++++---------------------------
> drivers/watchdog/omap_wdt.h | 5 +
> 2 files changed, 128 insertions(+), 219 deletions(-)
>
> diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c
> index 8285d65..cc5bc3e 100644
> --- a/drivers/watchdog/omap_wdt.c
> +++ b/drivers/watchdog/omap_wdt.c
> @@ -24,6 +24,9 @@
> *
> * Copyright (c) 2005 David Brownell
> * Use the driver model and standard identifiers; handle bigger timeouts.
> + *
> + * Copyright (c) 2012 WindRiver
> + * Changes cater for the current watchdog framework.
> */
>
> #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> @@ -33,7 +36,6 @@
> #include <linux/kernel.h>
> #include <linux/fs.h>
> #include <linux/mm.h>
> -#include <linux/miscdevice.h>
> #include <linux/watchdog.h>
> #include <linux/reboot.h>
> #include <linux/init.h>
> @@ -50,8 +52,6 @@
>
> #include "omap_wdt.h"
>
> -static struct platform_device *omap_wdt_dev;
> -
> static unsigned timer_margin;
> module_param(timer_margin, uint, 0);
> MODULE_PARM_DESC(timer_margin, "initial watchdog timeout (in seconds)");
> @@ -59,32 +59,14 @@ MODULE_PARM_DESC(timer_margin, "initial watchdog timeout (in seconds)");
> static unsigned int wdt_trgr_pattern = 0x1234;
> static DEFINE_SPINLOCK(wdt_lock);
>
> -struct omap_wdt_dev {
> +struct omap_wdt_drvdata {
> + struct watchdog_device wdt;
> void __iomem *base; /* physical */
> struct device *dev;
> - int omap_wdt_users;
> struct resource *mem;
> - struct miscdevice omap_wdt_miscdev;
> };
>
> -static void omap_wdt_ping(struct omap_wdt_dev *wdev)
> -{
> - void __iomem *base = wdev->base;
> -
> - /* wait for posted write to complete */
> - while ((__raw_readl(base + OMAP_WATCHDOG_WPS)) & 0x08)
> - cpu_relax();
> -
> - wdt_trgr_pattern = ~wdt_trgr_pattern;
> - __raw_writel(wdt_trgr_pattern, (base + OMAP_WATCHDOG_TGR));
> -
> - /* wait for posted write to complete */
> - while ((__raw_readl(base + OMAP_WATCHDOG_WPS)) & 0x08)
> - cpu_relax();
> - /* reloaded WCRR from WLDR */
> -}
> -
> -static void omap_wdt_enable(struct omap_wdt_dev *wdev)
> +static void omap_wdt_enable(struct omap_wdt_drvdata *wdev)
> {
> void __iomem *base = wdev->base;
>
> @@ -98,7 +80,7 @@ static void omap_wdt_enable(struct omap_wdt_dev *wdev)
> cpu_relax();
> }
>
> -static void omap_wdt_disable(struct omap_wdt_dev *wdev)
> +static void omap_wdt_disable(struct omap_wdt_drvdata *wdev)
> {
> void __iomem *base = wdev->base;
>
> @@ -121,12 +103,19 @@ static void omap_wdt_adjust_timeout(unsigned new_timeout)
> timer_margin = new_timeout;
> }
>
> -static void omap_wdt_set_timeout(struct omap_wdt_dev *wdev)
> +static int omap_wdt_set_timeout(struct watchdog_device *wdt_dev,
> + unsigned int new_timeout)
> {
> - u32 pre_margin = GET_WLDR_VAL(timer_margin);
> - void __iomem *base = wdev->base;
> + u32 pre_margin;
> + struct omap_wdt_drvdata *omap_wdev = watchdog_get_drvdata(wdt_dev);
> + void __iomem *base = omap_wdev->base;
>
> - pm_runtime_get_sync(wdev->dev);
> + pm_runtime_get_sync(omap_wdev->dev);
> + omap_wdt_disable(omap_wdev);
> +
> + /* adjust timeout based on the new timeout */
> + omap_wdt_adjust_timeout(new_timeout);
> + pre_margin = GET_WLDR_VAL(timer_margin);
>
> /* just count up at 32 KHz */
> while (__raw_readl(base + OMAP_WATCHDOG_WPS) & 0x04)
> @@ -136,147 +125,88 @@ static void omap_wdt_set_timeout(struct omap_wdt_dev *wdev)
> while (__raw_readl(base + OMAP_WATCHDOG_WPS) & 0x04)
> cpu_relax();
>
> - pm_runtime_put_sync(wdev->dev);
> + omap_wdt_enable(omap_wdev);
> + wdt_dev->timeout = new_timeout;
> + pm_runtime_put_sync(omap_wdev->dev);
> + return 0;
> }
>
> -/*
> - * Allow only one task to hold it open
> - */
> -static int omap_wdt_open(struct inode *inode, struct file *file)
> +static int omap_wdt_ping(struct watchdog_device *wdt_dev)
> {
> - struct omap_wdt_dev *wdev = platform_get_drvdata(omap_wdt_dev);
> - void __iomem *base = wdev->base;
> -
> - if (test_and_set_bit(1, (unsigned long *)&(wdev->omap_wdt_users)))
> - return -EBUSY;
> -
> - pm_runtime_get_sync(wdev->dev);
> + struct omap_wdt_drvdata *omap_wdev = watchdog_get_drvdata(wdt_dev);
> + void __iomem *base = omap_wdev->base;
>
> - /* initialize prescaler */
> - while (__raw_readl(base + OMAP_WATCHDOG_WPS) & 0x01)
> - cpu_relax();
> + pm_runtime_get_sync(omap_wdev->dev);
> + spin_lock(&wdt_lock);
>
> - __raw_writel((1 << 5) | (PTV << 2), base + OMAP_WATCHDOG_CNTRL);
> - while (__raw_readl(base + OMAP_WATCHDOG_WPS) & 0x01)
> + /* wait for posted write to complete */
> + while ((__raw_readl(base + OMAP_WATCHDOG_WPS)) & 0x08)
> cpu_relax();
>
> - file->private_data = (void *) wdev;
> + wdt_trgr_pattern = ~wdt_trgr_pattern;
> + __raw_writel(wdt_trgr_pattern, (base + OMAP_WATCHDOG_TGR));
>
> - omap_wdt_set_timeout(wdev);
> - omap_wdt_ping(wdev); /* trigger loading of new timeout value */
> - omap_wdt_enable(wdev);
> + /* wait for posted write to complete */
> + /* reloaded WCRR from WLDR */
> + while ((__raw_readl(base + OMAP_WATCHDOG_WPS)) & 0x08)
> + cpu_relax();
>
> - pm_runtime_put_sync(wdev->dev);
> + spin_unlock(&wdt_lock);
> + pm_runtime_put_sync(omap_wdev->dev);
>
> - return nonseekable_open(inode, file);
> + return 0;
> }
>
> -static int omap_wdt_release(struct inode *inode, struct file *file)
> +static int omap_wdt_start(struct watchdog_device *wdt_dev)
> {
> - struct omap_wdt_dev *wdev = file->private_data;
> + struct omap_wdt_drvdata *omap_wdev = watchdog_get_drvdata(wdt_dev);
> + void __iomem *base = omap_wdev->base;
>
> - /*
> - * Shut off the timer unless NOWAYOUT is defined.
> - */
> -#ifndef CONFIG_WATCHDOG_NOWAYOUT
> - pm_runtime_get_sync(wdev->dev);
> + pm_runtime_get_sync(omap_wdev->dev);
> + /* initialize prescaler */
> + while (__raw_readl(base + OMAP_WATCHDOG_WPS) & 0x01)
> + cpu_relax();
>
> - omap_wdt_disable(wdev);
> + __raw_writel((1 << 5) | (PTV << 2), base + OMAP_WATCHDOG_CNTRL);
> + while (__raw_readl(base + OMAP_WATCHDOG_WPS) & 0x01)
> + cpu_relax();
>
> - pm_runtime_put_sync(wdev->dev);
> -#else
> - pr_crit("Unexpected close, not stopping!\n");
> -#endif
> - wdev->omap_wdt_users = 0;
> + omap_wdt_set_timeout(&omap_wdev->wdt, timer_margin);
> + pm_runtime_put_sync(omap_wdev->dev);
>
> return 0;
> }
>
> -static ssize_t omap_wdt_write(struct file *file, const char __user *data,
> - size_t len, loff_t *ppos)
> +static int omap_wdt_stop(struct watchdog_device *wdt_dev)
> {
> - struct omap_wdt_dev *wdev = file->private_data;
> -
> - /* Refresh LOAD_TIME. */
> - if (len) {
> - pm_runtime_get_sync(wdev->dev);
> - spin_lock(&wdt_lock);
> - omap_wdt_ping(wdev);
> - spin_unlock(&wdt_lock);
> - pm_runtime_put_sync(wdev->dev);
> - }
> - return len;
> -}
> + struct omap_wdt_drvdata *omap_wdev = watchdog_get_drvdata(wdt_dev);
>
> -static long omap_wdt_ioctl(struct file *file, unsigned int cmd,
> - unsigned long arg)
> -{
> - struct omap_wdt_dev *wdev;
> - int new_margin;
> - static const struct watchdog_info ident = {
> - .identity = "OMAP Watchdog",
> - .options = WDIOF_SETTIMEOUT,
> - .firmware_version = 0,
> - };
> -
> - wdev = file->private_data;
> -
> - switch (cmd) {
> - case WDIOC_GETSUPPORT:
> - return copy_to_user((struct watchdog_info __user *)arg, &ident,
> - sizeof(ident));
> - case WDIOC_GETSTATUS:
> - return put_user(0, (int __user *)arg);
> - case WDIOC_GETBOOTSTATUS:
> - if (cpu_is_omap16xx())
> - return put_user(__raw_readw(ARM_SYSST),
> - (int __user *)arg);
> - if (cpu_is_omap24xx())
> - return put_user(omap_prcm_get_reset_sources(),
> - (int __user *)arg);
> - return put_user(0, (int __user *)arg);
> - case WDIOC_KEEPALIVE:
> - pm_runtime_get_sync(wdev->dev);
> - spin_lock(&wdt_lock);
> - omap_wdt_ping(wdev);
> - spin_unlock(&wdt_lock);
> - pm_runtime_put_sync(wdev->dev);
> - return 0;
> - case WDIOC_SETTIMEOUT:
> - if (get_user(new_margin, (int __user *)arg))
> - return -EFAULT;
> - omap_wdt_adjust_timeout(new_margin);
> -
> - pm_runtime_get_sync(wdev->dev);
> - spin_lock(&wdt_lock);
> - omap_wdt_disable(wdev);
> - omap_wdt_set_timeout(wdev);
> - omap_wdt_enable(wdev);
> -
> - omap_wdt_ping(wdev);
> - spin_unlock(&wdt_lock);
> - pm_runtime_put_sync(wdev->dev);
> - /* Fall */
> - case WDIOC_GETTIMEOUT:
> - return put_user(timer_margin, (int __user *)arg);
> - default:
> - return -ENOTTY;
> - }
> + pm_runtime_get_sync(omap_wdev->dev);
> + omap_wdt_disable(omap_wdev);
> + pm_runtime_put_sync(omap_wdev->dev);
> +
> + return 0;
> }
>
> -static const struct file_operations omap_wdt_fops = {
> +static const struct watchdog_ops omap_wdt_ops = {
> .owner = THIS_MODULE,
> - .write = omap_wdt_write,
> - .unlocked_ioctl = omap_wdt_ioctl,
> - .open = omap_wdt_open,
> - .release = omap_wdt_release,
> - .llseek = no_llseek,
> + .start = omap_wdt_start,
> + .stop = omap_wdt_stop,
> + .ping = omap_wdt_ping,
> + .set_timeout = omap_wdt_set_timeout,
> +};
> +
> +static const struct watchdog_info omap_wdt_info = {
> + .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING |
> + WDIOF_CARDRESET,
> + .identity = "Omap Watchdog",
> };
>
> static int __devinit omap_wdt_probe(struct platform_device *pdev)
> {
> + struct omap_wdt_drvdata *omap_drvdata;
> + struct watchdog_device *omap_wdev;
> struct resource *res, *mem;
> - struct omap_wdt_dev *wdev;
> int ret;
>
> /* reserve static register mappings */
> @@ -286,68 +216,62 @@ static int __devinit omap_wdt_probe(struct platform_device *pdev)
> goto err_get_resource;
> }
>
> - if (omap_wdt_dev) {
> - ret = -EBUSY;
> - goto err_busy;
> - }
> -
> mem = request_mem_region(res->start, resource_size(res), pdev->name);
> if (!mem) {
> ret = -EBUSY;
> goto err_busy;
> }
>
> - wdev = kzalloc(sizeof(struct omap_wdt_dev), GFP_KERNEL);
> - if (!wdev) {
> + omap_drvdata = devm_kzalloc(&pdev->dev, sizeof(struct omap_wdt_drvdata),
> + GFP_KERNEL);
> + if (!omap_drvdata) {
> + dev_err(&pdev->dev, "Unable to allocate watchdog device\n");
> ret = -ENOMEM;
> goto err_kzalloc;
> }
>
> - wdev->omap_wdt_users = 0;
> - wdev->mem = mem;
> - wdev->dev = &pdev->dev;
> + omap_drvdata->dev = &pdev->dev;
> + omap_wdev = &omap_drvdata->wdt;
> + omap_wdev->info = &omap_wdt_info;
> + omap_wdev->ops = &omap_wdt_ops;
> + omap_wdev->timeout = TIMER_MARGIN_DEFAULT;
> + omap_wdev->min_timeout = 1;
> + omap_wdev->max_timeout = TIMER_MARGIN_MAX;
> +#ifdef CONFIG_WATCHDOG_NOWAYOUT
> + watchdog_set_nowayout(omap_wdev, true);
> +#endif
> + watchdog_set_drvdata(omap_wdev, omap_drvdata);
>
> - wdev->base = ioremap(res->start, resource_size(res));
> - if (!wdev->base) {
> + omap_drvdata->base = ioremap(res->start, resource_size(res));
> + if (!omap_drvdata->base) {
> ret = -ENOMEM;
> - goto err_ioremap;
> + goto err_kzalloc;
> }
>
> - platform_set_drvdata(pdev, wdev);
> -
> - pm_runtime_enable(wdev->dev);
> - pm_runtime_get_sync(wdev->dev);
> -
> - omap_wdt_disable(wdev);
> - omap_wdt_adjust_timeout(timer_margin);
> -
> - wdev->omap_wdt_miscdev.parent = &pdev->dev;
> - wdev->omap_wdt_miscdev.minor = WATCHDOG_MINOR;
> - wdev->omap_wdt_miscdev.name = "watchdog";
> - wdev->omap_wdt_miscdev.fops = &omap_wdt_fops;
> -
> - ret = misc_register(&(wdev->omap_wdt_miscdev));
> - if (ret)
> - goto err_misc;
> -
> - pr_info("OMAP Watchdog Timer Rev 0x%02x: initial timeout %d sec\n",
> - __raw_readl(wdev->base + OMAP_WATCHDOG_REV) & 0xFF,
> - timer_margin);
> -
> - pm_runtime_put_sync(wdev->dev);
> -
> - omap_wdt_dev = pdev;
> + ret = watchdog_register_device(&omap_drvdata->wdt);
> + if (ret < 0)
> + goto err_register_wd;
> +
> + pm_runtime_enable(&pdev->dev);
> + pm_runtime_get_sync(&pdev->dev);
> + omap_wdt_disable(omap_drvdata);
> + pm_runtime_put_sync(&pdev->dev);
> + platform_set_drvdata(pdev, omap_drvdata);
> +
> + /* For omap16xx we just keep it original as-is */
> + if (cpu_is_omap16xx())
> + omap_wdev->bootstatus = __raw_readw(ARM_SYSST);
> + else
> + omap_wdev->bootstatus = (omap_prcm_get_reset_sources() & 0x10)
> + >> OMAP3_PRM_RSTST_WD_BIT;
CPU check is really not receommended in driver, you should avoid this.
I understand that, driver was already doing this, but can this be handled by
IP rev? if not, you may want to use pdata for this.
Also I understand that, this is tied to prcm code base as far as omap2 is concerned. May be Tony or others can comment on this.
Thanks,
Vaibhav
> + pr_info("OMAP WDTimer Rev 0x%02x: Initial timeout %dsec status= 0x%x\n",
> + __raw_readl(omap_drvdata->base + OMAP_WATCHDOG_REV)
> + & 0xFF, timer_margin, omap_wdev->bootstatus);
>
> return 0;
>
> -err_misc:
> - pm_runtime_disable(wdev->dev);
> - platform_set_drvdata(pdev, NULL);
> - iounmap(wdev->base);
> -
> -err_ioremap:
> - wdev->base = NULL;
> - kfree(wdev);
> +err_register_wd:
> + iounmap(omap_drvdata->base);
>
> err_kzalloc:
> release_mem_region(res->start, resource_size(res));
> @@ -358,34 +282,17 @@ err_get_resource:
> return ret;
> }
>
> -static void omap_wdt_shutdown(struct platform_device *pdev)
> -{
> - struct omap_wdt_dev *wdev = platform_get_drvdata(pdev);
> -
> - if (wdev->omap_wdt_users) {
> - pm_runtime_get_sync(wdev->dev);
> - omap_wdt_disable(wdev);
> - pm_runtime_put_sync(wdev->dev);
> - }
> -}
> -
> static int __devexit omap_wdt_remove(struct platform_device *pdev)
> {
> - struct omap_wdt_dev *wdev = platform_get_drvdata(pdev);
> + struct omap_wdt_drvdata *omap_wdev = platform_get_drvdata(pdev);
> struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>
> - pm_runtime_disable(wdev->dev);
> - if (!res)
> - return -ENOENT;
> + pm_runtime_disable(&pdev->dev);
>
> - misc_deregister(&(wdev->omap_wdt_miscdev));
> release_mem_region(res->start, resource_size(res));
> platform_set_drvdata(pdev, NULL);
>
> - iounmap(wdev->base);
> -
> - kfree(wdev);
> - omap_wdt_dev = NULL;
> + iounmap(omap_wdev->base);
>
> return 0;
> }
> @@ -400,12 +307,12 @@ static int __devexit omap_wdt_remove(struct platform_device *pdev)
>
> static int omap_wdt_suspend(struct platform_device *pdev, pm_message_t state)
> {
> - struct omap_wdt_dev *wdev = platform_get_drvdata(pdev);
> + struct omap_wdt_drvdata *omap_wdev = platform_get_drvdata(pdev);
>
> - if (wdev->omap_wdt_users) {
> - pm_runtime_get_sync(wdev->dev);
> - omap_wdt_disable(wdev);
> - pm_runtime_put_sync(wdev->dev);
> + if (test_bit(WDOG_DEV_OPEN, &omap_wdev->wdt.status)) {
> + pm_runtime_get_sync(&pdev->dev);
> + omap_wdt_disable(omap_wdev);
> + pm_runtime_put_sync(&pdev->dev);
> }
>
> return 0;
> @@ -413,13 +320,12 @@ static int omap_wdt_suspend(struct platform_device *pdev, pm_message_t state)
>
> static int omap_wdt_resume(struct platform_device *pdev)
> {
> - struct omap_wdt_dev *wdev = platform_get_drvdata(pdev);
> -
> - if (wdev->omap_wdt_users) {
> - pm_runtime_get_sync(wdev->dev);
> - omap_wdt_enable(wdev);
> - omap_wdt_ping(wdev);
> - pm_runtime_put_sync(wdev->dev);
> + struct omap_wdt_drvdata *omap_wdev = platform_get_drvdata(pdev);
> + if (test_bit(WDOG_DEV_OPEN, &omap_wdev->wdt.status)) {
> + pm_runtime_get_sync(&pdev->dev);
> + omap_wdt_enable(omap_wdev);
> + omap_wdt_ping(&omap_wdev->wdt);
> + pm_runtime_put_sync(&pdev->dev);
> }
>
> return 0;
> @@ -433,7 +339,6 @@ static int omap_wdt_resume(struct platform_device *pdev)
> static struct platform_driver omap_wdt_driver = {
> .probe = omap_wdt_probe,
> .remove = __devexit_p(omap_wdt_remove),
> - .shutdown = omap_wdt_shutdown,
> .suspend = omap_wdt_suspend,
> .resume = omap_wdt_resume,
> .driver = {
> @@ -446,5 +351,4 @@ module_platform_driver(omap_wdt_driver);
>
> MODULE_AUTHOR("George G. Davis");
> MODULE_LICENSE("GPL");
> -MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
> MODULE_ALIAS("platform:omap_wdt");
> diff --git a/drivers/watchdog/omap_wdt.h b/drivers/watchdog/omap_wdt.h
> index 09b774c..cf5f037 100644
> --- a/drivers/watchdog/omap_wdt.h
> +++ b/drivers/watchdog/omap_wdt.h
> @@ -51,4 +51,9 @@
> #define PTV 0 /* prescale */
> #define GET_WLDR_VAL(secs) (0xffffffff - ((secs) * (32768/(1<<PTV))) + 1)
>
> +/* MPU_WD_RST bit in PRM_RSTST show Omap WDTimer reset event.
> + * 0x0 = 0x0 : No watchdog reset.
> + * 0x1 = 0x1 : watchdog reset has occurred. */
> +#define OMAP3_PRM_RSTST_WD_BIT 4
> +
> #endif /* _OMAP_WATCHDOG_H */
> --
> 1.7.5.4
>
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH RESEND v3 1/3] Watchdog: Omap: Changes for the new watchdog framework
@ 2012-07-16 13:10 ` Hiremath, Vaibhav
0 siblings, 0 replies; 21+ messages in thread
From: Hiremath, Vaibhav @ 2012-07-16 13:10 UTC (permalink / raw)
To: linux-arm-kernel
On Sun, Jul 15, 2012 at 13:14:04, Zumeng Chen wrote:
> This patch implements the current watchdog framework for OMAP WDTimer,
> which factored out the common components, so the driver can just focus
> on the hardware related parts.
>
> Signed-off-by: Zumeng Chen <zumeng.chen@windriver.com>
> ---
> drivers/watchdog/omap_wdt.c | 342 ++++++++++++++++---------------------------
> drivers/watchdog/omap_wdt.h | 5 +
> 2 files changed, 128 insertions(+), 219 deletions(-)
>
> diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c
> index 8285d65..cc5bc3e 100644
> --- a/drivers/watchdog/omap_wdt.c
> +++ b/drivers/watchdog/omap_wdt.c
> @@ -24,6 +24,9 @@
> *
> * Copyright (c) 2005 David Brownell
> * Use the driver model and standard identifiers; handle bigger timeouts.
> + *
> + * Copyright (c) 2012 WindRiver
> + * Changes cater for the current watchdog framework.
> */
>
> #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> @@ -33,7 +36,6 @@
> #include <linux/kernel.h>
> #include <linux/fs.h>
> #include <linux/mm.h>
> -#include <linux/miscdevice.h>
> #include <linux/watchdog.h>
> #include <linux/reboot.h>
> #include <linux/init.h>
> @@ -50,8 +52,6 @@
>
> #include "omap_wdt.h"
>
> -static struct platform_device *omap_wdt_dev;
> -
> static unsigned timer_margin;
> module_param(timer_margin, uint, 0);
> MODULE_PARM_DESC(timer_margin, "initial watchdog timeout (in seconds)");
> @@ -59,32 +59,14 @@ MODULE_PARM_DESC(timer_margin, "initial watchdog timeout (in seconds)");
> static unsigned int wdt_trgr_pattern = 0x1234;
> static DEFINE_SPINLOCK(wdt_lock);
>
> -struct omap_wdt_dev {
> +struct omap_wdt_drvdata {
> + struct watchdog_device wdt;
> void __iomem *base; /* physical */
> struct device *dev;
> - int omap_wdt_users;
> struct resource *mem;
> - struct miscdevice omap_wdt_miscdev;
> };
>
> -static void omap_wdt_ping(struct omap_wdt_dev *wdev)
> -{
> - void __iomem *base = wdev->base;
> -
> - /* wait for posted write to complete */
> - while ((__raw_readl(base + OMAP_WATCHDOG_WPS)) & 0x08)
> - cpu_relax();
> -
> - wdt_trgr_pattern = ~wdt_trgr_pattern;
> - __raw_writel(wdt_trgr_pattern, (base + OMAP_WATCHDOG_TGR));
> -
> - /* wait for posted write to complete */
> - while ((__raw_readl(base + OMAP_WATCHDOG_WPS)) & 0x08)
> - cpu_relax();
> - /* reloaded WCRR from WLDR */
> -}
> -
> -static void omap_wdt_enable(struct omap_wdt_dev *wdev)
> +static void omap_wdt_enable(struct omap_wdt_drvdata *wdev)
> {
> void __iomem *base = wdev->base;
>
> @@ -98,7 +80,7 @@ static void omap_wdt_enable(struct omap_wdt_dev *wdev)
> cpu_relax();
> }
>
> -static void omap_wdt_disable(struct omap_wdt_dev *wdev)
> +static void omap_wdt_disable(struct omap_wdt_drvdata *wdev)
> {
> void __iomem *base = wdev->base;
>
> @@ -121,12 +103,19 @@ static void omap_wdt_adjust_timeout(unsigned new_timeout)
> timer_margin = new_timeout;
> }
>
> -static void omap_wdt_set_timeout(struct omap_wdt_dev *wdev)
> +static int omap_wdt_set_timeout(struct watchdog_device *wdt_dev,
> + unsigned int new_timeout)
> {
> - u32 pre_margin = GET_WLDR_VAL(timer_margin);
> - void __iomem *base = wdev->base;
> + u32 pre_margin;
> + struct omap_wdt_drvdata *omap_wdev = watchdog_get_drvdata(wdt_dev);
> + void __iomem *base = omap_wdev->base;
>
> - pm_runtime_get_sync(wdev->dev);
> + pm_runtime_get_sync(omap_wdev->dev);
> + omap_wdt_disable(omap_wdev);
> +
> + /* adjust timeout based on the new timeout */
> + omap_wdt_adjust_timeout(new_timeout);
> + pre_margin = GET_WLDR_VAL(timer_margin);
>
> /* just count up at 32 KHz */
> while (__raw_readl(base + OMAP_WATCHDOG_WPS) & 0x04)
> @@ -136,147 +125,88 @@ static void omap_wdt_set_timeout(struct omap_wdt_dev *wdev)
> while (__raw_readl(base + OMAP_WATCHDOG_WPS) & 0x04)
> cpu_relax();
>
> - pm_runtime_put_sync(wdev->dev);
> + omap_wdt_enable(omap_wdev);
> + wdt_dev->timeout = new_timeout;
> + pm_runtime_put_sync(omap_wdev->dev);
> + return 0;
> }
>
> -/*
> - * Allow only one task to hold it open
> - */
> -static int omap_wdt_open(struct inode *inode, struct file *file)
> +static int omap_wdt_ping(struct watchdog_device *wdt_dev)
> {
> - struct omap_wdt_dev *wdev = platform_get_drvdata(omap_wdt_dev);
> - void __iomem *base = wdev->base;
> -
> - if (test_and_set_bit(1, (unsigned long *)&(wdev->omap_wdt_users)))
> - return -EBUSY;
> -
> - pm_runtime_get_sync(wdev->dev);
> + struct omap_wdt_drvdata *omap_wdev = watchdog_get_drvdata(wdt_dev);
> + void __iomem *base = omap_wdev->base;
>
> - /* initialize prescaler */
> - while (__raw_readl(base + OMAP_WATCHDOG_WPS) & 0x01)
> - cpu_relax();
> + pm_runtime_get_sync(omap_wdev->dev);
> + spin_lock(&wdt_lock);
>
> - __raw_writel((1 << 5) | (PTV << 2), base + OMAP_WATCHDOG_CNTRL);
> - while (__raw_readl(base + OMAP_WATCHDOG_WPS) & 0x01)
> + /* wait for posted write to complete */
> + while ((__raw_readl(base + OMAP_WATCHDOG_WPS)) & 0x08)
> cpu_relax();
>
> - file->private_data = (void *) wdev;
> + wdt_trgr_pattern = ~wdt_trgr_pattern;
> + __raw_writel(wdt_trgr_pattern, (base + OMAP_WATCHDOG_TGR));
>
> - omap_wdt_set_timeout(wdev);
> - omap_wdt_ping(wdev); /* trigger loading of new timeout value */
> - omap_wdt_enable(wdev);
> + /* wait for posted write to complete */
> + /* reloaded WCRR from WLDR */
> + while ((__raw_readl(base + OMAP_WATCHDOG_WPS)) & 0x08)
> + cpu_relax();
>
> - pm_runtime_put_sync(wdev->dev);
> + spin_unlock(&wdt_lock);
> + pm_runtime_put_sync(omap_wdev->dev);
>
> - return nonseekable_open(inode, file);
> + return 0;
> }
>
> -static int omap_wdt_release(struct inode *inode, struct file *file)
> +static int omap_wdt_start(struct watchdog_device *wdt_dev)
> {
> - struct omap_wdt_dev *wdev = file->private_data;
> + struct omap_wdt_drvdata *omap_wdev = watchdog_get_drvdata(wdt_dev);
> + void __iomem *base = omap_wdev->base;
>
> - /*
> - * Shut off the timer unless NOWAYOUT is defined.
> - */
> -#ifndef CONFIG_WATCHDOG_NOWAYOUT
> - pm_runtime_get_sync(wdev->dev);
> + pm_runtime_get_sync(omap_wdev->dev);
> + /* initialize prescaler */
> + while (__raw_readl(base + OMAP_WATCHDOG_WPS) & 0x01)
> + cpu_relax();
>
> - omap_wdt_disable(wdev);
> + __raw_writel((1 << 5) | (PTV << 2), base + OMAP_WATCHDOG_CNTRL);
> + while (__raw_readl(base + OMAP_WATCHDOG_WPS) & 0x01)
> + cpu_relax();
>
> - pm_runtime_put_sync(wdev->dev);
> -#else
> - pr_crit("Unexpected close, not stopping!\n");
> -#endif
> - wdev->omap_wdt_users = 0;
> + omap_wdt_set_timeout(&omap_wdev->wdt, timer_margin);
> + pm_runtime_put_sync(omap_wdev->dev);
>
> return 0;
> }
>
> -static ssize_t omap_wdt_write(struct file *file, const char __user *data,
> - size_t len, loff_t *ppos)
> +static int omap_wdt_stop(struct watchdog_device *wdt_dev)
> {
> - struct omap_wdt_dev *wdev = file->private_data;
> -
> - /* Refresh LOAD_TIME. */
> - if (len) {
> - pm_runtime_get_sync(wdev->dev);
> - spin_lock(&wdt_lock);
> - omap_wdt_ping(wdev);
> - spin_unlock(&wdt_lock);
> - pm_runtime_put_sync(wdev->dev);
> - }
> - return len;
> -}
> + struct omap_wdt_drvdata *omap_wdev = watchdog_get_drvdata(wdt_dev);
>
> -static long omap_wdt_ioctl(struct file *file, unsigned int cmd,
> - unsigned long arg)
> -{
> - struct omap_wdt_dev *wdev;
> - int new_margin;
> - static const struct watchdog_info ident = {
> - .identity = "OMAP Watchdog",
> - .options = WDIOF_SETTIMEOUT,
> - .firmware_version = 0,
> - };
> -
> - wdev = file->private_data;
> -
> - switch (cmd) {
> - case WDIOC_GETSUPPORT:
> - return copy_to_user((struct watchdog_info __user *)arg, &ident,
> - sizeof(ident));
> - case WDIOC_GETSTATUS:
> - return put_user(0, (int __user *)arg);
> - case WDIOC_GETBOOTSTATUS:
> - if (cpu_is_omap16xx())
> - return put_user(__raw_readw(ARM_SYSST),
> - (int __user *)arg);
> - if (cpu_is_omap24xx())
> - return put_user(omap_prcm_get_reset_sources(),
> - (int __user *)arg);
> - return put_user(0, (int __user *)arg);
> - case WDIOC_KEEPALIVE:
> - pm_runtime_get_sync(wdev->dev);
> - spin_lock(&wdt_lock);
> - omap_wdt_ping(wdev);
> - spin_unlock(&wdt_lock);
> - pm_runtime_put_sync(wdev->dev);
> - return 0;
> - case WDIOC_SETTIMEOUT:
> - if (get_user(new_margin, (int __user *)arg))
> - return -EFAULT;
> - omap_wdt_adjust_timeout(new_margin);
> -
> - pm_runtime_get_sync(wdev->dev);
> - spin_lock(&wdt_lock);
> - omap_wdt_disable(wdev);
> - omap_wdt_set_timeout(wdev);
> - omap_wdt_enable(wdev);
> -
> - omap_wdt_ping(wdev);
> - spin_unlock(&wdt_lock);
> - pm_runtime_put_sync(wdev->dev);
> - /* Fall */
> - case WDIOC_GETTIMEOUT:
> - return put_user(timer_margin, (int __user *)arg);
> - default:
> - return -ENOTTY;
> - }
> + pm_runtime_get_sync(omap_wdev->dev);
> + omap_wdt_disable(omap_wdev);
> + pm_runtime_put_sync(omap_wdev->dev);
> +
> + return 0;
> }
>
> -static const struct file_operations omap_wdt_fops = {
> +static const struct watchdog_ops omap_wdt_ops = {
> .owner = THIS_MODULE,
> - .write = omap_wdt_write,
> - .unlocked_ioctl = omap_wdt_ioctl,
> - .open = omap_wdt_open,
> - .release = omap_wdt_release,
> - .llseek = no_llseek,
> + .start = omap_wdt_start,
> + .stop = omap_wdt_stop,
> + .ping = omap_wdt_ping,
> + .set_timeout = omap_wdt_set_timeout,
> +};
> +
> +static const struct watchdog_info omap_wdt_info = {
> + .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING |
> + WDIOF_CARDRESET,
> + .identity = "Omap Watchdog",
> };
>
> static int __devinit omap_wdt_probe(struct platform_device *pdev)
> {
> + struct omap_wdt_drvdata *omap_drvdata;
> + struct watchdog_device *omap_wdev;
> struct resource *res, *mem;
> - struct omap_wdt_dev *wdev;
> int ret;
>
> /* reserve static register mappings */
> @@ -286,68 +216,62 @@ static int __devinit omap_wdt_probe(struct platform_device *pdev)
> goto err_get_resource;
> }
>
> - if (omap_wdt_dev) {
> - ret = -EBUSY;
> - goto err_busy;
> - }
> -
> mem = request_mem_region(res->start, resource_size(res), pdev->name);
> if (!mem) {
> ret = -EBUSY;
> goto err_busy;
> }
>
> - wdev = kzalloc(sizeof(struct omap_wdt_dev), GFP_KERNEL);
> - if (!wdev) {
> + omap_drvdata = devm_kzalloc(&pdev->dev, sizeof(struct omap_wdt_drvdata),
> + GFP_KERNEL);
> + if (!omap_drvdata) {
> + dev_err(&pdev->dev, "Unable to allocate watchdog device\n");
> ret = -ENOMEM;
> goto err_kzalloc;
> }
>
> - wdev->omap_wdt_users = 0;
> - wdev->mem = mem;
> - wdev->dev = &pdev->dev;
> + omap_drvdata->dev = &pdev->dev;
> + omap_wdev = &omap_drvdata->wdt;
> + omap_wdev->info = &omap_wdt_info;
> + omap_wdev->ops = &omap_wdt_ops;
> + omap_wdev->timeout = TIMER_MARGIN_DEFAULT;
> + omap_wdev->min_timeout = 1;
> + omap_wdev->max_timeout = TIMER_MARGIN_MAX;
> +#ifdef CONFIG_WATCHDOG_NOWAYOUT
> + watchdog_set_nowayout(omap_wdev, true);
> +#endif
> + watchdog_set_drvdata(omap_wdev, omap_drvdata);
>
> - wdev->base = ioremap(res->start, resource_size(res));
> - if (!wdev->base) {
> + omap_drvdata->base = ioremap(res->start, resource_size(res));
> + if (!omap_drvdata->base) {
> ret = -ENOMEM;
> - goto err_ioremap;
> + goto err_kzalloc;
> }
>
> - platform_set_drvdata(pdev, wdev);
> -
> - pm_runtime_enable(wdev->dev);
> - pm_runtime_get_sync(wdev->dev);
> -
> - omap_wdt_disable(wdev);
> - omap_wdt_adjust_timeout(timer_margin);
> -
> - wdev->omap_wdt_miscdev.parent = &pdev->dev;
> - wdev->omap_wdt_miscdev.minor = WATCHDOG_MINOR;
> - wdev->omap_wdt_miscdev.name = "watchdog";
> - wdev->omap_wdt_miscdev.fops = &omap_wdt_fops;
> -
> - ret = misc_register(&(wdev->omap_wdt_miscdev));
> - if (ret)
> - goto err_misc;
> -
> - pr_info("OMAP Watchdog Timer Rev 0x%02x: initial timeout %d sec\n",
> - __raw_readl(wdev->base + OMAP_WATCHDOG_REV) & 0xFF,
> - timer_margin);
> -
> - pm_runtime_put_sync(wdev->dev);
> -
> - omap_wdt_dev = pdev;
> + ret = watchdog_register_device(&omap_drvdata->wdt);
> + if (ret < 0)
> + goto err_register_wd;
> +
> + pm_runtime_enable(&pdev->dev);
> + pm_runtime_get_sync(&pdev->dev);
> + omap_wdt_disable(omap_drvdata);
> + pm_runtime_put_sync(&pdev->dev);
> + platform_set_drvdata(pdev, omap_drvdata);
> +
> + /* For omap16xx we just keep it original as-is */
> + if (cpu_is_omap16xx())
> + omap_wdev->bootstatus = __raw_readw(ARM_SYSST);
> + else
> + omap_wdev->bootstatus = (omap_prcm_get_reset_sources() & 0x10)
> + >> OMAP3_PRM_RSTST_WD_BIT;
CPU check is really not receommended in driver, you should avoid this.
I understand that, driver was already doing this, but can this be handled by
IP rev? if not, you may want to use pdata for this.
Also I understand that, this is tied to prcm code base as far as omap2 is concerned. May be Tony or others can comment on this.
Thanks,
Vaibhav
> + pr_info("OMAP WDTimer Rev 0x%02x: Initial timeout %dsec status= 0x%x\n",
> + __raw_readl(omap_drvdata->base + OMAP_WATCHDOG_REV)
> + & 0xFF, timer_margin, omap_wdev->bootstatus);
>
> return 0;
>
> -err_misc:
> - pm_runtime_disable(wdev->dev);
> - platform_set_drvdata(pdev, NULL);
> - iounmap(wdev->base);
> -
> -err_ioremap:
> - wdev->base = NULL;
> - kfree(wdev);
> +err_register_wd:
> + iounmap(omap_drvdata->base);
>
> err_kzalloc:
> release_mem_region(res->start, resource_size(res));
> @@ -358,34 +282,17 @@ err_get_resource:
> return ret;
> }
>
> -static void omap_wdt_shutdown(struct platform_device *pdev)
> -{
> - struct omap_wdt_dev *wdev = platform_get_drvdata(pdev);
> -
> - if (wdev->omap_wdt_users) {
> - pm_runtime_get_sync(wdev->dev);
> - omap_wdt_disable(wdev);
> - pm_runtime_put_sync(wdev->dev);
> - }
> -}
> -
> static int __devexit omap_wdt_remove(struct platform_device *pdev)
> {
> - struct omap_wdt_dev *wdev = platform_get_drvdata(pdev);
> + struct omap_wdt_drvdata *omap_wdev = platform_get_drvdata(pdev);
> struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>
> - pm_runtime_disable(wdev->dev);
> - if (!res)
> - return -ENOENT;
> + pm_runtime_disable(&pdev->dev);
>
> - misc_deregister(&(wdev->omap_wdt_miscdev));
> release_mem_region(res->start, resource_size(res));
> platform_set_drvdata(pdev, NULL);
>
> - iounmap(wdev->base);
> -
> - kfree(wdev);
> - omap_wdt_dev = NULL;
> + iounmap(omap_wdev->base);
>
> return 0;
> }
> @@ -400,12 +307,12 @@ static int __devexit omap_wdt_remove(struct platform_device *pdev)
>
> static int omap_wdt_suspend(struct platform_device *pdev, pm_message_t state)
> {
> - struct omap_wdt_dev *wdev = platform_get_drvdata(pdev);
> + struct omap_wdt_drvdata *omap_wdev = platform_get_drvdata(pdev);
>
> - if (wdev->omap_wdt_users) {
> - pm_runtime_get_sync(wdev->dev);
> - omap_wdt_disable(wdev);
> - pm_runtime_put_sync(wdev->dev);
> + if (test_bit(WDOG_DEV_OPEN, &omap_wdev->wdt.status)) {
> + pm_runtime_get_sync(&pdev->dev);
> + omap_wdt_disable(omap_wdev);
> + pm_runtime_put_sync(&pdev->dev);
> }
>
> return 0;
> @@ -413,13 +320,12 @@ static int omap_wdt_suspend(struct platform_device *pdev, pm_message_t state)
>
> static int omap_wdt_resume(struct platform_device *pdev)
> {
> - struct omap_wdt_dev *wdev = platform_get_drvdata(pdev);
> -
> - if (wdev->omap_wdt_users) {
> - pm_runtime_get_sync(wdev->dev);
> - omap_wdt_enable(wdev);
> - omap_wdt_ping(wdev);
> - pm_runtime_put_sync(wdev->dev);
> + struct omap_wdt_drvdata *omap_wdev = platform_get_drvdata(pdev);
> + if (test_bit(WDOG_DEV_OPEN, &omap_wdev->wdt.status)) {
> + pm_runtime_get_sync(&pdev->dev);
> + omap_wdt_enable(omap_wdev);
> + omap_wdt_ping(&omap_wdev->wdt);
> + pm_runtime_put_sync(&pdev->dev);
> }
>
> return 0;
> @@ -433,7 +339,6 @@ static int omap_wdt_resume(struct platform_device *pdev)
> static struct platform_driver omap_wdt_driver = {
> .probe = omap_wdt_probe,
> .remove = __devexit_p(omap_wdt_remove),
> - .shutdown = omap_wdt_shutdown,
> .suspend = omap_wdt_suspend,
> .resume = omap_wdt_resume,
> .driver = {
> @@ -446,5 +351,4 @@ module_platform_driver(omap_wdt_driver);
>
> MODULE_AUTHOR("George G. Davis");
> MODULE_LICENSE("GPL");
> -MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
> MODULE_ALIAS("platform:omap_wdt");
> diff --git a/drivers/watchdog/omap_wdt.h b/drivers/watchdog/omap_wdt.h
> index 09b774c..cf5f037 100644
> --- a/drivers/watchdog/omap_wdt.h
> +++ b/drivers/watchdog/omap_wdt.h
> @@ -51,4 +51,9 @@
> #define PTV 0 /* prescale */
> #define GET_WLDR_VAL(secs) (0xffffffff - ((secs) * (32768/(1<<PTV))) + 1)
>
> +/* MPU_WD_RST bit in PRM_RSTST show Omap WDTimer reset event.
> + * 0x0 = 0x0 : No watchdog reset.
> + * 0x1 = 0x1 : watchdog reset has occurred. */
> +#define OMAP3_PRM_RSTST_WD_BIT 4
> +
> #endif /* _OMAP_WATCHDOG_H */
> --
> 1.7.5.4
>
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* RE: [PATCH RESEND V3 0/3] Watchdog: OMAP3: bootstatus fix and changes for the current watchdog framework
2012-07-15 7:44 ` Zumeng Chen
(?)
@ 2012-07-16 13:10 ` Hiremath, Vaibhav
-1 siblings, 0 replies; 21+ messages in thread
From: Hiremath, Vaibhav @ 2012-07-16 13:10 UTC (permalink / raw)
To: Zumeng Chen, Hilman, Kevin, Datta, Shubhrajyoti, linux-watchdog
Cc: wim, linux-omap, tony, paul.gortmaker, linux-arm-kernel
On Sun, Jul 15, 2012 at 13:14:03, Zumeng Chen wrote:
> Hello,
>
> The following patches based on the 3.5-rc6 from Wim, which
> focus on:
>
> 1. bootstatus fix for omap3,
>
> 2. omap-wdt framework update cater for the current framework
> as Shubhrajyoti comments mentioned.
>
> V3 changes:
>
> 1. New comments updated as Kevin mentioned in the third patch;
> 2. 3530evm works well,
> AM33xx seems work well with the following changes:
> + if (cpu_is_am335x())
> + return omap2_prm_read_mod_reg(AM33XX_PRM_DEVICE_MOD,
> + AM33XX_PRM_RSTST_OFFSET) & 0x7f;
> But since some definitions not ready for am33xx, so I don't
> give the patch, if they have been updated, feel free to take these.
>
Did you test it on any of AM33xx platform? If you use linux-omap/master pr
linux-next branch as a baseline you should have basic things (except hwmod
data) available.
I will test it and send a patch for this on your behalf (if you are ok with
it).
Note: Change in convention, cpu_is_am335x() => soc_is_am335x()
Thanks,
Vaibhav
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 21+ messages in thread
* RE: [PATCH RESEND V3 0/3] Watchdog: OMAP3: bootstatus fix and changes for the current watchdog framework
@ 2012-07-16 13:10 ` Hiremath, Vaibhav
0 siblings, 0 replies; 21+ messages in thread
From: Hiremath, Vaibhav @ 2012-07-16 13:10 UTC (permalink / raw)
To: Zumeng Chen, Hilman, Kevin, Datta, Shubhrajyoti, linux-watchdog
Cc: wim, linux-omap, tony, paul.gortmaker, linux-arm-kernel
On Sun, Jul 15, 2012 at 13:14:03, Zumeng Chen wrote:
> Hello,
>
> The following patches based on the 3.5-rc6 from Wim, which
> focus on:
>
> 1. bootstatus fix for omap3,
>
> 2. omap-wdt framework update cater for the current framework
> as Shubhrajyoti comments mentioned.
>
> V3 changes:
>
> 1. New comments updated as Kevin mentioned in the third patch;
> 2. 3530evm works well,
> AM33xx seems work well with the following changes:
> + if (cpu_is_am335x())
> + return omap2_prm_read_mod_reg(AM33XX_PRM_DEVICE_MOD,
> + AM33XX_PRM_RSTST_OFFSET) & 0x7f;
> But since some definitions not ready for am33xx, so I don't
> give the patch, if they have been updated, feel free to take these.
>
Did you test it on any of AM33xx platform? If you use linux-omap/master pr
linux-next branch as a baseline you should have basic things (except hwmod
data) available.
I will test it and send a patch for this on your behalf (if you are ok with
it).
Note: Change in convention, cpu_is_am335x() => soc_is_am335x()
Thanks,
Vaibhav
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH RESEND V3 0/3] Watchdog: OMAP3: bootstatus fix and changes for the current watchdog framework
@ 2012-07-16 13:10 ` Hiremath, Vaibhav
0 siblings, 0 replies; 21+ messages in thread
From: Hiremath, Vaibhav @ 2012-07-16 13:10 UTC (permalink / raw)
To: linux-arm-kernel
On Sun, Jul 15, 2012 at 13:14:03, Zumeng Chen wrote:
> Hello,
>
> The following patches based on the 3.5-rc6 from Wim, which
> focus on:
>
> 1. bootstatus fix for omap3,
>
> 2. omap-wdt framework update cater for the current framework
> as Shubhrajyoti comments mentioned.
>
> V3 changes:
>
> 1. New comments updated as Kevin mentioned in the third patch;
> 2. 3530evm works well,
> AM33xx seems work well with the following changes:
> + if (cpu_is_am335x())
> + return omap2_prm_read_mod_reg(AM33XX_PRM_DEVICE_MOD,
> + AM33XX_PRM_RSTST_OFFSET) & 0x7f;
> But since some definitions not ready for am33xx, so I don't
> give the patch, if they have been updated, feel free to take these.
>
Did you test it on any of AM33xx platform? If you use linux-omap/master pr
linux-next branch as a baseline you should have basic things (except hwmod
data) available.
I will test it and send a patch for this on your behalf (if you are ok with
it).
Note: Change in convention, cpu_is_am335x() => soc_is_am335x()
Thanks,
Vaibhav
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH RESEND V3 0/3] Watchdog: OMAP3: bootstatus fix and changes for the current watchdog framework
2012-07-16 13:10 ` Hiremath, Vaibhav
(?)
@ 2012-07-16 14:55 ` zumeng.chen
-1 siblings, 0 replies; 21+ messages in thread
From: zumeng.chen @ 2012-07-16 14:55 UTC (permalink / raw)
To: Hiremath, Vaibhav
Cc: Zumeng Chen, Hilman, Kevin, Datta, Shubhrajyoti, linux-watchdog,
wim, linux-omap, tony, paul.gortmaker, linux-arm-kernel
On 2012年07月16日 21:10, Hiremath, Vaibhav wrote:
> On Sun, Jul 15, 2012 at 13:14:03, Zumeng Chen wrote:
>> Hello,
>>
>> The following patches based on the 3.5-rc6 from Wim, which
>> focus on:
>>
>> 1. bootstatus fix for omap3,
>>
>> 2. omap-wdt framework update cater for the current framework
>> as Shubhrajyoti comments mentioned.
>>
>> V3 changes:
>>
>> 1. New comments updated as Kevin mentioned in the third patch;
>> 2. 3530evm works well,
>> AM33xx seems work well with the following changes:
>> + if (cpu_is_am335x())
>> + return omap2_prm_read_mod_reg(AM33XX_PRM_DEVICE_MOD,
>> + AM33XX_PRM_RSTST_OFFSET)& 0x7f;
>> But since some definitions not ready for am33xx, so I don't
>> give the patch, if they have been updated, feel free to take these.
>>
> Did you test it on any of AM33xx platform?
Yes. I ever did in v2 as follows shown:
The same case works well on am335xevm but with a new patch in
mach-omap2/prcm.c
I'll send it later.
root@ti-omap3:~# uname -a
Linux ti-omap3 3.4.3-00635-g82d1d26-dirty #32 Wed Jul 11 16:02:12 CST
2012 armv7l GNU/Linux
root@ti-omap3:~# dmesg|grep WDT
[ 1.921173] omap_wdt: OMAP WDTimer Rev 0x01: Initial timeout 0sec status= 0x1
root@ti-omap3:~# ./a.out -i 20; for i in `seq 1 20`; do echo $i ; sleep
1;done
Set watchdog interval to 20
Current watchdog interval is 20
Last boot is caused by : Watchdog
Use:
<w> to kick through writing over device file
<i> to kick through IOCTL
<x> to exit the program
x
1
2
[snip]
U-Boot SPL 2011.09 (Feb 09 2012 - 15:38:59)
Texas Instruments Revision detection unimplemented
U-Boot 2011.09 (Feb 09 2012 - 15:11:31)
I2C: ready
DRAM: 256 MiB
WARNING: Caches not enabled
Found a daughter card connected
NAND: HW ECC Hamming Code selected
256 MiB
MMC: OMAP SD/MMC: 0
Net: cpsw
Hit any key to stop autoboot: 0
U-Boot#
> If you use linux-omap/master pr
> linux-next branch as a baseline you should have basic things (except hwmod
> data) available.
>
> I will test it and send a patch for this on your behalf (if you are ok with
> it).
I'm OK for this, thanks Vaibhav.
>
> Note: Change in convention, cpu_is_am335x() => soc_is_am335x()
Yes, agreed.
Regards,
Zumeng
> Thanks,
> Vaibhav
>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH RESEND V3 0/3] Watchdog: OMAP3: bootstatus fix and changes for the current watchdog framework
@ 2012-07-16 14:55 ` zumeng.chen
0 siblings, 0 replies; 21+ messages in thread
From: zumeng.chen @ 2012-07-16 14:55 UTC (permalink / raw)
To: Hiremath, Vaibhav
Cc: Zumeng Chen, Hilman, Kevin, Datta, Shubhrajyoti, linux-watchdog,
wim, linux-omap, tony, paul.gortmaker, linux-arm-kernel
On 2012年07月16日 21:10, Hiremath, Vaibhav wrote:
> On Sun, Jul 15, 2012 at 13:14:03, Zumeng Chen wrote:
>> Hello,
>>
>> The following patches based on the 3.5-rc6 from Wim, which
>> focus on:
>>
>> 1. bootstatus fix for omap3,
>>
>> 2. omap-wdt framework update cater for the current framework
>> as Shubhrajyoti comments mentioned.
>>
>> V3 changes:
>>
>> 1. New comments updated as Kevin mentioned in the third patch;
>> 2. 3530evm works well,
>> AM33xx seems work well with the following changes:
>> + if (cpu_is_am335x())
>> + return omap2_prm_read_mod_reg(AM33XX_PRM_DEVICE_MOD,
>> + AM33XX_PRM_RSTST_OFFSET)& 0x7f;
>> But since some definitions not ready for am33xx, so I don't
>> give the patch, if they have been updated, feel free to take these.
>>
> Did you test it on any of AM33xx platform?
Yes. I ever did in v2 as follows shown:
The same case works well on am335xevm but with a new patch in
mach-omap2/prcm.c
I'll send it later.
root@ti-omap3:~# uname -a
Linux ti-omap3 3.4.3-00635-g82d1d26-dirty #32 Wed Jul 11 16:02:12 CST
2012 armv7l GNU/Linux
root@ti-omap3:~# dmesg|grep WDT
[ 1.921173] omap_wdt: OMAP WDTimer Rev 0x01: Initial timeout 0sec status= 0x1
root@ti-omap3:~# ./a.out -i 20; for i in `seq 1 20`; do echo $i ; sleep
1;done
Set watchdog interval to 20
Current watchdog interval is 20
Last boot is caused by : Watchdog
Use:
<w> to kick through writing over device file
<i> to kick through IOCTL
<x> to exit the program
x
1
2
[snip]
U-Boot SPL 2011.09 (Feb 09 2012 - 15:38:59)
Texas Instruments Revision detection unimplemented
U-Boot 2011.09 (Feb 09 2012 - 15:11:31)
I2C: ready
DRAM: 256 MiB
WARNING: Caches not enabled
Found a daughter card connected
NAND: HW ECC Hamming Code selected
256 MiB
MMC: OMAP SD/MMC: 0
Net: cpsw
Hit any key to stop autoboot: 0
U-Boot#
> If you use linux-omap/master pr
> linux-next branch as a baseline you should have basic things (except hwmod
> data) available.
>
> I will test it and send a patch for this on your behalf (if you are ok with
> it).
I'm OK for this, thanks Vaibhav.
>
> Note: Change in convention, cpu_is_am335x() => soc_is_am335x()
Yes, agreed.
Regards,
Zumeng
> Thanks,
> Vaibhav
>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH RESEND V3 0/3] Watchdog: OMAP3: bootstatus fix and changes for the current watchdog framework
@ 2012-07-16 14:55 ` zumeng.chen
0 siblings, 0 replies; 21+ messages in thread
From: zumeng.chen @ 2012-07-16 14:55 UTC (permalink / raw)
To: linux-arm-kernel
On 2012?07?16? 21:10, Hiremath, Vaibhav wrote:
> On Sun, Jul 15, 2012 at 13:14:03, Zumeng Chen wrote:
>> Hello,
>>
>> The following patches based on the 3.5-rc6 from Wim, which
>> focus on:
>>
>> 1. bootstatus fix for omap3,
>>
>> 2. omap-wdt framework update cater for the current framework
>> as Shubhrajyoti comments mentioned.
>>
>> V3 changes:
>>
>> 1. New comments updated as Kevin mentioned in the third patch;
>> 2. 3530evm works well,
>> AM33xx seems work well with the following changes:
>> + if (cpu_is_am335x())
>> + return omap2_prm_read_mod_reg(AM33XX_PRM_DEVICE_MOD,
>> + AM33XX_PRM_RSTST_OFFSET)& 0x7f;
>> But since some definitions not ready for am33xx, so I don't
>> give the patch, if they have been updated, feel free to take these.
>>
> Did you test it on any of AM33xx platform?
Yes. I ever did in v2 as follows shown:
The same case works well on am335xevm but with a new patch in
mach-omap2/prcm.c
I'll send it later.
root at ti-omap3:~# uname -a
Linux ti-omap3 3.4.3-00635-g82d1d26-dirty #32 Wed Jul 11 16:02:12 CST
2012 armv7l GNU/Linux
root at ti-omap3:~# dmesg|grep WDT
[ 1.921173] omap_wdt: OMAP WDTimer Rev 0x01: Initial timeout 0sec status= 0x1
root at ti-omap3:~# ./a.out -i 20; for i in `seq 1 20`; do echo $i ; sleep
1;done
Set watchdog interval to 20
Current watchdog interval is 20
Last boot is caused by : Watchdog
Use:
<w> to kick through writing over device file
<i> to kick through IOCTL
<x> to exit the program
x
1
2
[snip]
U-Boot SPL 2011.09 (Feb 09 2012 - 15:38:59)
Texas Instruments Revision detection unimplemented
U-Boot 2011.09 (Feb 09 2012 - 15:11:31)
I2C: ready
DRAM: 256 MiB
WARNING: Caches not enabled
Found a daughter card connected
NAND: HW ECC Hamming Code selected
256 MiB
MMC: OMAP SD/MMC: 0
Net: cpsw
Hit any key to stop autoboot: 0
U-Boot#
> If you use linux-omap/master pr
> linux-next branch as a baseline you should have basic things (except hwmod
> data) available.
>
> I will test it and send a patch for this on your behalf (if you are ok with
> it).
I'm OK for this, thanks Vaibhav.
>
> Note: Change in convention, cpu_is_am335x() => soc_is_am335x()
Yes, agreed.
Regards,
Zumeng
> Thanks,
> Vaibhav
>
>
^ permalink raw reply [flat|nested] 21+ messages in thread
end of thread, other threads:[~2012-07-16 14:56 UTC | newest]
Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-07-15 7:44 [PATCH RESEND V3 0/3] Watchdog: OMAP3: bootstatus fix and changes for the current watchdog framework Zumeng Chen
2012-07-15 7:44 ` Zumeng Chen
2012-07-15 7:44 ` Zumeng Chen
2012-07-15 7:44 ` [PATCH RESEND v3 1/3] Watchdog: Omap: Changes for the new " Zumeng Chen
2012-07-15 7:44 ` Zumeng Chen
2012-07-15 7:44 ` Zumeng Chen
2012-07-16 13:10 ` Hiremath, Vaibhav
2012-07-16 13:10 ` Hiremath, Vaibhav
2012-07-16 13:10 ` Hiremath, Vaibhav
2012-07-15 7:44 ` [PATCH RESEND v3 2/3] Watchdog: Omap: select watchdog core for framework change Zumeng Chen
2012-07-15 7:44 ` Zumeng Chen
2012-07-15 7:44 ` Zumeng Chen
2012-07-15 7:44 ` [PATCH RESEND v3 3/3] Watchdog: Omap: get the bootstatus for OMAP34xx Zumeng Chen
2012-07-15 7:44 ` Zumeng Chen
2012-07-15 7:44 ` Zumeng Chen
2012-07-16 13:10 ` [PATCH RESEND V3 0/3] Watchdog: OMAP3: bootstatus fix and changes for the current watchdog framework Hiremath, Vaibhav
2012-07-16 13:10 ` Hiremath, Vaibhav
2012-07-16 13:10 ` Hiremath, Vaibhav
2012-07-16 14:55 ` zumeng.chen
2012-07-16 14:55 ` zumeng.chen
2012-07-16 14:55 ` zumeng.chen
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.