* [PATCH V2 00/22] watchdog: ARM watchdogs: sp805 & mpcore updates & fixes
@ 2012-03-12 4:21 ` Viresh Kumar
0 siblings, 0 replies; 56+ messages in thread
From: Viresh Kumar @ 2012-03-12 4:21 UTC (permalink / raw)
To: wim
Cc: linux-watchdog, spear-devel, viresh.linux, linux-arm-kernel,
srinidhi.kasagar, linus.walleij, alan, w.sang, sshtylyov,
Viresh Kumar
Hello,
This patchset contains fixes and updates for ARM watchdog drivers sp805 and
mpcore.
Changes since V1:
- Included patches for sp805 driver.
- Removed: wdt->clk = NULL from mpcore driver, and use IS_ERR() to check if
clock is supported or not.
- Adapted to watchdog core for both the drivers.
- two patches for watchdog core added
- add patch to use __raw_readl{writel} instead of readl{writel}
- taken care of few more review comments.
Changes are mentioned in following patch list:
watchdog/mpcore: updates & fixes
Viresh Kumar (22):
watchdog: Add is_wdt_active() routine
watchdog: Add support for WDIOC_GETTIMELEFT IOCTL in watchdog core
watchdog/mpcore_wdt: Rename dev to pdev for pointing to struct
platform_device
watchdog/mpcore_wdt: Use devm routines
watchdog/mpcore_wdt: Allow platform_get_irq() to fail
watchdog/mpcore_wdt: convert to watchdog core
watchdog/mpcore_wdt: Fix multiline comments
watchdog/mpcore_wdt: Arrange #includes in alphabetical order
watchdog/mpcore_wdt: Set default heartbeat in probe instead of init
watchdog/mpcore_wdt: Use dev_(crit, err, info) instead of dev_printk
watchdog/mpcore_wdt: convert to use module_platform_driver()
watchdog/mpcore_wdt: Add support for dev_pm_ops interface
watchdog/mpcore_wdt: disable wdt in suspend only if it is busy
watchdog/mpcore_wdt: replace (__raw_)readl/writel with lighter
*_relaxed variants
watchdog/mpcore_wdt: Add support for WDIOC_GETBOOTSTATUS IOCTL
watchdog/mpcore_wdt: Add clock framework support
watchdog/mpcore_wdt: use correct clk_rate to program timeout
watchdog/sp805: Fix documentation style comment
watchdog/sp805: replace readl/writel with lighter _relaxed variants
watchdog/sp805: Use devm routines
watchdog/sp805: convert to watchdog core
watchdog/sp805: Add clk_{un}prepare support
.../watchdog/convert_drivers_to_kernel_api.txt | 4 +
Documentation/watchdog/watchdog-kernel-api.txt | 2 +
arch/arm/include/asm/smp_twd.h | 12 +
drivers/watchdog/Kconfig | 2 +
drivers/watchdog/mpcore_wdt.c | 573 +++++++++-----------
drivers/watchdog/sp805_wdt.c | 309 ++++-------
drivers/watchdog/via_wdt.c | 2 +-
drivers/watchdog/watchdog_dev.c | 11 +-
include/linux/watchdog.h | 7 +
9 files changed, 408 insertions(+), 514 deletions(-)
--
1.7.8.110.g4cb5d
^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH V2 00/22] watchdog: ARM watchdogs: sp805 & mpcore updates & fixes
@ 2012-03-12 4:21 ` Viresh Kumar
0 siblings, 0 replies; 56+ messages in thread
From: Viresh Kumar @ 2012-03-12 4:21 UTC (permalink / raw)
To: linux-arm-kernel
Hello,
This patchset contains fixes and updates for ARM watchdog drivers sp805 and
mpcore.
Changes since V1:
- Included patches for sp805 driver.
- Removed: wdt->clk = NULL from mpcore driver, and use IS_ERR() to check if
clock is supported or not.
- Adapted to watchdog core for both the drivers.
- two patches for watchdog core added
- add patch to use __raw_readl{writel} instead of readl{writel}
- taken care of few more review comments.
Changes are mentioned in following patch list:
watchdog/mpcore: updates & fixes
Viresh Kumar (22):
watchdog: Add is_wdt_active() routine
watchdog: Add support for WDIOC_GETTIMELEFT IOCTL in watchdog core
watchdog/mpcore_wdt: Rename dev to pdev for pointing to struct
platform_device
watchdog/mpcore_wdt: Use devm routines
watchdog/mpcore_wdt: Allow platform_get_irq() to fail
watchdog/mpcore_wdt: convert to watchdog core
watchdog/mpcore_wdt: Fix multiline comments
watchdog/mpcore_wdt: Arrange #includes in alphabetical order
watchdog/mpcore_wdt: Set default heartbeat in probe instead of init
watchdog/mpcore_wdt: Use dev_(crit, err, info) instead of dev_printk
watchdog/mpcore_wdt: convert to use module_platform_driver()
watchdog/mpcore_wdt: Add support for dev_pm_ops interface
watchdog/mpcore_wdt: disable wdt in suspend only if it is busy
watchdog/mpcore_wdt: replace (__raw_)readl/writel with lighter
*_relaxed variants
watchdog/mpcore_wdt: Add support for WDIOC_GETBOOTSTATUS IOCTL
watchdog/mpcore_wdt: Add clock framework support
watchdog/mpcore_wdt: use correct clk_rate to program timeout
watchdog/sp805: Fix documentation style comment
watchdog/sp805: replace readl/writel with lighter _relaxed variants
watchdog/sp805: Use devm routines
watchdog/sp805: convert to watchdog core
watchdog/sp805: Add clk_{un}prepare support
.../watchdog/convert_drivers_to_kernel_api.txt | 4 +
Documentation/watchdog/watchdog-kernel-api.txt | 2 +
arch/arm/include/asm/smp_twd.h | 12 +
drivers/watchdog/Kconfig | 2 +
drivers/watchdog/mpcore_wdt.c | 573 +++++++++-----------
drivers/watchdog/sp805_wdt.c | 309 ++++-------
drivers/watchdog/via_wdt.c | 2 +-
drivers/watchdog/watchdog_dev.c | 11 +-
include/linux/watchdog.h | 7 +
9 files changed, 408 insertions(+), 514 deletions(-)
--
1.7.8.110.g4cb5d
^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH V2 01/22] watchdog: Add is_wdt_active() routine
2012-03-12 4:21 ` Viresh Kumar
@ 2012-03-12 4:21 ` Viresh Kumar
-1 siblings, 0 replies; 56+ messages in thread
From: Viresh Kumar @ 2012-03-12 4:21 UTC (permalink / raw)
To: wim
Cc: linux-watchdog, spear-devel, viresh.linux, linux-arm-kernel,
srinidhi.kasagar, linus.walleij, alan, w.sang, sshtylyov,
Viresh Kumar
Some watchdog may need to check if watchdog is ACTIVE or not, for example in
their suspend/resume hooks.
This patch adds this routine and changes the core drivers to use it.
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
drivers/watchdog/via_wdt.c | 2 +-
drivers/watchdog/watchdog_dev.c | 6 +++---
include/linux/watchdog.h | 5 +++++
3 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/drivers/watchdog/via_wdt.c b/drivers/watchdog/via_wdt.c
index 8f07dd4..62fed64 100644
--- a/drivers/watchdog/via_wdt.c
+++ b/drivers/watchdog/via_wdt.c
@@ -88,7 +88,7 @@ static inline void wdt_reset(void)
static void wdt_timer_tick(unsigned long data)
{
if (time_before(jiffies, next_heartbeat) ||
- (!test_bit(WDOG_ACTIVE, &wdt_dev.status))) {
+ (!is_wdd_active(&wdt_dev))) {
wdt_reset();
mod_timer(&timer, jiffies + WDT_HEARTBEAT);
} else
diff --git a/drivers/watchdog/watchdog_dev.c b/drivers/watchdog/watchdog_dev.c
index 1199da0f..9668253 100644
--- a/drivers/watchdog/watchdog_dev.c
+++ b/drivers/watchdog/watchdog_dev.c
@@ -59,7 +59,7 @@ static struct watchdog_device *wdd;
static int watchdog_ping(struct watchdog_device *wddev)
{
- if (test_bit(WDOG_ACTIVE, &wddev->status)) {
+ if (is_wdd_active(wddev)) {
if (wddev->ops->ping)
return wddev->ops->ping(wddev); /* ping the watchdog */
else
@@ -81,7 +81,7 @@ static int watchdog_start(struct watchdog_device *wddev)
{
int err;
- if (!test_bit(WDOG_ACTIVE, &wddev->status)) {
+ if (!is_wdd_active(wddev)) {
err = wddev->ops->start(wddev);
if (err < 0)
return err;
@@ -111,7 +111,7 @@ static int watchdog_stop(struct watchdog_device *wddev)
return err;
}
- if (test_bit(WDOG_ACTIVE, &wddev->status)) {
+ if (is_wdd_active(wddev)) {
err = wddev->ops->stop(wddev);
if (err < 0)
return err;
diff --git a/include/linux/watchdog.h b/include/linux/watchdog.h
index 43ba5b3..4fc57b2 100644
--- a/include/linux/watchdog.h
+++ b/include/linux/watchdog.h
@@ -118,6 +118,11 @@ struct watchdog_device {
#define WDOG_NO_WAY_OUT 3 /* Is 'nowayout' feature set ? */
};
+static inline bool is_wdd_active(struct watchdog_device *wdd)
+{
+ return test_bit(WDOG_ACTIVE, &wdd->status);
+}
+
#ifdef CONFIG_WATCHDOG_NOWAYOUT
#define WATCHDOG_NOWAYOUT 1
#define WATCHDOG_NOWAYOUT_INIT_STATUS (1 << WDOG_NO_WAY_OUT)
--
1.7.8.110.g4cb5d
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH V2 01/22] watchdog: Add is_wdt_active() routine
@ 2012-03-12 4:21 ` Viresh Kumar
0 siblings, 0 replies; 56+ messages in thread
From: Viresh Kumar @ 2012-03-12 4:21 UTC (permalink / raw)
To: linux-arm-kernel
Some watchdog may need to check if watchdog is ACTIVE or not, for example in
their suspend/resume hooks.
This patch adds this routine and changes the core drivers to use it.
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
drivers/watchdog/via_wdt.c | 2 +-
drivers/watchdog/watchdog_dev.c | 6 +++---
include/linux/watchdog.h | 5 +++++
3 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/drivers/watchdog/via_wdt.c b/drivers/watchdog/via_wdt.c
index 8f07dd4..62fed64 100644
--- a/drivers/watchdog/via_wdt.c
+++ b/drivers/watchdog/via_wdt.c
@@ -88,7 +88,7 @@ static inline void wdt_reset(void)
static void wdt_timer_tick(unsigned long data)
{
if (time_before(jiffies, next_heartbeat) ||
- (!test_bit(WDOG_ACTIVE, &wdt_dev.status))) {
+ (!is_wdd_active(&wdt_dev))) {
wdt_reset();
mod_timer(&timer, jiffies + WDT_HEARTBEAT);
} else
diff --git a/drivers/watchdog/watchdog_dev.c b/drivers/watchdog/watchdog_dev.c
index 1199da0f..9668253 100644
--- a/drivers/watchdog/watchdog_dev.c
+++ b/drivers/watchdog/watchdog_dev.c
@@ -59,7 +59,7 @@ static struct watchdog_device *wdd;
static int watchdog_ping(struct watchdog_device *wddev)
{
- if (test_bit(WDOG_ACTIVE, &wddev->status)) {
+ if (is_wdd_active(wddev)) {
if (wddev->ops->ping)
return wddev->ops->ping(wddev); /* ping the watchdog */
else
@@ -81,7 +81,7 @@ static int watchdog_start(struct watchdog_device *wddev)
{
int err;
- if (!test_bit(WDOG_ACTIVE, &wddev->status)) {
+ if (!is_wdd_active(wddev)) {
err = wddev->ops->start(wddev);
if (err < 0)
return err;
@@ -111,7 +111,7 @@ static int watchdog_stop(struct watchdog_device *wddev)
return err;
}
- if (test_bit(WDOG_ACTIVE, &wddev->status)) {
+ if (is_wdd_active(wddev)) {
err = wddev->ops->stop(wddev);
if (err < 0)
return err;
diff --git a/include/linux/watchdog.h b/include/linux/watchdog.h
index 43ba5b3..4fc57b2 100644
--- a/include/linux/watchdog.h
+++ b/include/linux/watchdog.h
@@ -118,6 +118,11 @@ struct watchdog_device {
#define WDOG_NO_WAY_OUT 3 /* Is 'nowayout' feature set ? */
};
+static inline bool is_wdd_active(struct watchdog_device *wdd)
+{
+ return test_bit(WDOG_ACTIVE, &wdd->status);
+}
+
#ifdef CONFIG_WATCHDOG_NOWAYOUT
#define WATCHDOG_NOWAYOUT 1
#define WATCHDOG_NOWAYOUT_INIT_STATUS (1 << WDOG_NO_WAY_OUT)
--
1.7.8.110.g4cb5d
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH V2 02/22] watchdog: Add support for WDIOC_GETTIMELEFT IOCTL in watchdog core
2012-03-12 4:21 ` Viresh Kumar
@ 2012-03-12 4:21 ` Viresh Kumar
-1 siblings, 0 replies; 56+ messages in thread
From: Viresh Kumar @ 2012-03-12 4:21 UTC (permalink / raw)
To: wim
Cc: linux-watchdog, spear-devel, viresh.linux, linux-arm-kernel,
srinidhi.kasagar, linus.walleij, alan, w.sang, sshtylyov,
Viresh Kumar
This patch adds support for WDIOC_GETTIMELEFT IOCTL in watchdog core. So, there
is another function pointer added to struct watchdog_ops, which can be passed by
drivers to support this IOCTL.
Related documentation is updated too.
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
.../watchdog/convert_drivers_to_kernel_api.txt | 4 ++++
Documentation/watchdog/watchdog-kernel-api.txt | 2 ++
drivers/watchdog/watchdog_dev.c | 5 +++++
include/linux/watchdog.h | 2 ++
4 files changed, 13 insertions(+), 0 deletions(-)
diff --git a/Documentation/watchdog/convert_drivers_to_kernel_api.txt b/Documentation/watchdog/convert_drivers_to_kernel_api.txt
index be8119b..271b885 100644
--- a/Documentation/watchdog/convert_drivers_to_kernel_api.txt
+++ b/Documentation/watchdog/convert_drivers_to_kernel_api.txt
@@ -59,6 +59,10 @@ Here is a overview of the functions and probably needed actions:
WDIOC_GETTIMEOUT:
No preparations needed
+ WDIOC_GETTIMELEFT:
+ It needs get_timeleft() callback to be defined. Otherwise it
+ will return EOPNOTSUPP
+
Other IOCTLs can be served using the ioctl-callback. Note that this is mainly
intended for porting old drivers; new drivers should not invent private IOCTLs.
Private IOCTLs are processed first. When the callback returns with
diff --git a/Documentation/watchdog/watchdog-kernel-api.txt b/Documentation/watchdog/watchdog-kernel-api.txt
index 9e16246..24d9a35 100644
--- a/Documentation/watchdog/watchdog-kernel-api.txt
+++ b/Documentation/watchdog/watchdog-kernel-api.txt
@@ -77,6 +77,7 @@ struct watchdog_ops {
int (*ping)(struct watchdog_device *);
unsigned int (*status)(struct watchdog_device *);
int (*set_timeout)(struct watchdog_device *, unsigned int);
+ unsigned int (*get_timeleft)(struct watchdog_device *);
long (*ioctl)(struct watchdog_device *, unsigned int, unsigned long);
};
@@ -122,6 +123,7 @@ they are supported. These optional routines/operations are:
to re-program the watchdog timer device.
(Note: the WDIOF_SETTIMEOUT needs to be set in the options field of the
watchdog's info structure).
+* get_timeleft: this routines returns the time left for reset.
* ioctl: if this routine is present then it will be called first before we do
our own internal ioctl call handling. This routine should return -ENOIOCTLCMD
if a command is not supported. The parameters that are passed to the ioctl
diff --git a/drivers/watchdog/watchdog_dev.c b/drivers/watchdog/watchdog_dev.c
index 9668253..6206e1b 100644
--- a/drivers/watchdog/watchdog_dev.c
+++ b/drivers/watchdog/watchdog_dev.c
@@ -237,6 +237,11 @@ static long watchdog_ioctl(struct file *file, unsigned int cmd,
if (wdd->timeout == 0)
return -EOPNOTSUPP;
return put_user(wdd->timeout, p);
+ case WDIOC_GETTIMELEFT:
+ if (!wdd->ops->get_timeleft)
+ return -EOPNOTSUPP;
+
+ return put_user(wdd->ops->get_timeleft(wdd), p);
default:
return -ENOTTY;
}
diff --git a/include/linux/watchdog.h b/include/linux/watchdog.h
index 4fc57b2..6b4e918 100644
--- a/include/linux/watchdog.h
+++ b/include/linux/watchdog.h
@@ -66,6 +66,7 @@ struct watchdog_device;
* @ping: The routine that sends a keepalive ping to the watchdog device.
* @status: The routine that shows the status of the watchdog device.
* @set_timeout:The routine for setting the watchdog devices timeout value.
+ * @get_timeleft:The routine for getting the watchdog device's timeleft value.
* @ioctl: The routines that handles extra ioctl calls.
*
* The watchdog_ops structure contains a list of low-level operations
@@ -82,6 +83,7 @@ struct watchdog_ops {
int (*ping)(struct watchdog_device *);
unsigned int (*status)(struct watchdog_device *);
int (*set_timeout)(struct watchdog_device *, unsigned int);
+ unsigned int (*get_timeleft)(struct watchdog_device *);
long (*ioctl)(struct watchdog_device *, unsigned int, unsigned long);
};
--
1.7.8.110.g4cb5d
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH V2 02/22] watchdog: Add support for WDIOC_GETTIMELEFT IOCTL in watchdog core
@ 2012-03-12 4:21 ` Viresh Kumar
0 siblings, 0 replies; 56+ messages in thread
From: Viresh Kumar @ 2012-03-12 4:21 UTC (permalink / raw)
To: linux-arm-kernel
This patch adds support for WDIOC_GETTIMELEFT IOCTL in watchdog core. So, there
is another function pointer added to struct watchdog_ops, which can be passed by
drivers to support this IOCTL.
Related documentation is updated too.
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
.../watchdog/convert_drivers_to_kernel_api.txt | 4 ++++
Documentation/watchdog/watchdog-kernel-api.txt | 2 ++
drivers/watchdog/watchdog_dev.c | 5 +++++
include/linux/watchdog.h | 2 ++
4 files changed, 13 insertions(+), 0 deletions(-)
diff --git a/Documentation/watchdog/convert_drivers_to_kernel_api.txt b/Documentation/watchdog/convert_drivers_to_kernel_api.txt
index be8119b..271b885 100644
--- a/Documentation/watchdog/convert_drivers_to_kernel_api.txt
+++ b/Documentation/watchdog/convert_drivers_to_kernel_api.txt
@@ -59,6 +59,10 @@ Here is a overview of the functions and probably needed actions:
WDIOC_GETTIMEOUT:
No preparations needed
+ WDIOC_GETTIMELEFT:
+ It needs get_timeleft() callback to be defined. Otherwise it
+ will return EOPNOTSUPP
+
Other IOCTLs can be served using the ioctl-callback. Note that this is mainly
intended for porting old drivers; new drivers should not invent private IOCTLs.
Private IOCTLs are processed first. When the callback returns with
diff --git a/Documentation/watchdog/watchdog-kernel-api.txt b/Documentation/watchdog/watchdog-kernel-api.txt
index 9e16246..24d9a35 100644
--- a/Documentation/watchdog/watchdog-kernel-api.txt
+++ b/Documentation/watchdog/watchdog-kernel-api.txt
@@ -77,6 +77,7 @@ struct watchdog_ops {
int (*ping)(struct watchdog_device *);
unsigned int (*status)(struct watchdog_device *);
int (*set_timeout)(struct watchdog_device *, unsigned int);
+ unsigned int (*get_timeleft)(struct watchdog_device *);
long (*ioctl)(struct watchdog_device *, unsigned int, unsigned long);
};
@@ -122,6 +123,7 @@ they are supported. These optional routines/operations are:
to re-program the watchdog timer device.
(Note: the WDIOF_SETTIMEOUT needs to be set in the options field of the
watchdog's info structure).
+* get_timeleft: this routines returns the time left for reset.
* ioctl: if this routine is present then it will be called first before we do
our own internal ioctl call handling. This routine should return -ENOIOCTLCMD
if a command is not supported. The parameters that are passed to the ioctl
diff --git a/drivers/watchdog/watchdog_dev.c b/drivers/watchdog/watchdog_dev.c
index 9668253..6206e1b 100644
--- a/drivers/watchdog/watchdog_dev.c
+++ b/drivers/watchdog/watchdog_dev.c
@@ -237,6 +237,11 @@ static long watchdog_ioctl(struct file *file, unsigned int cmd,
if (wdd->timeout == 0)
return -EOPNOTSUPP;
return put_user(wdd->timeout, p);
+ case WDIOC_GETTIMELEFT:
+ if (!wdd->ops->get_timeleft)
+ return -EOPNOTSUPP;
+
+ return put_user(wdd->ops->get_timeleft(wdd), p);
default:
return -ENOTTY;
}
diff --git a/include/linux/watchdog.h b/include/linux/watchdog.h
index 4fc57b2..6b4e918 100644
--- a/include/linux/watchdog.h
+++ b/include/linux/watchdog.h
@@ -66,6 +66,7 @@ struct watchdog_device;
* @ping: The routine that sends a keepalive ping to the watchdog device.
* @status: The routine that shows the status of the watchdog device.
* @set_timeout:The routine for setting the watchdog devices timeout value.
+ * @get_timeleft:The routine for getting the watchdog device's timeleft value.
* @ioctl: The routines that handles extra ioctl calls.
*
* The watchdog_ops structure contains a list of low-level operations
@@ -82,6 +83,7 @@ struct watchdog_ops {
int (*ping)(struct watchdog_device *);
unsigned int (*status)(struct watchdog_device *);
int (*set_timeout)(struct watchdog_device *, unsigned int);
+ unsigned int (*get_timeleft)(struct watchdog_device *);
long (*ioctl)(struct watchdog_device *, unsigned int, unsigned long);
};
--
1.7.8.110.g4cb5d
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH V2 03/22] watchdog/mpcore_wdt: Rename dev to pdev for pointing to struct platform_device
2012-03-12 4:21 ` Viresh Kumar
@ 2012-03-12 4:21 ` Viresh Kumar
-1 siblings, 0 replies; 56+ messages in thread
From: Viresh Kumar @ 2012-03-12 4:21 UTC (permalink / raw)
To: wim
Cc: linux-watchdog, spear-devel, viresh.linux, linux-arm-kernel,
srinidhi.kasagar, linus.walleij, alan, w.sang, sshtylyov,
Viresh Kumar
Pointer to struct platform_device is named as dev, which makes it confusing when
we write statements like dev->dev to access struct device within it.
This patch renames such names to pdev.
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
drivers/watchdog/mpcore_wdt.c | 40 ++++++++++++++++++++--------------------
1 files changed, 20 insertions(+), 20 deletions(-)
diff --git a/drivers/watchdog/mpcore_wdt.c b/drivers/watchdog/mpcore_wdt.c
index 82ccd36..fd9f91b 100644
--- a/drivers/watchdog/mpcore_wdt.c
+++ b/drivers/watchdog/mpcore_wdt.c
@@ -44,7 +44,7 @@ struct mpcore_wdt {
char expect_close;
};
-static struct platform_device *mpcore_wdt_dev;
+static struct platform_device *mpcore_wdt_pdev;
static DEFINE_SPINLOCK(wdt_lock);
#define TIMER_MARGIN 60
@@ -148,7 +148,7 @@ static int mpcore_wdt_set_heartbeat(int t)
*/
static int mpcore_wdt_open(struct inode *inode, struct file *file)
{
- struct mpcore_wdt *wdt = platform_get_drvdata(mpcore_wdt_dev);
+ struct mpcore_wdt *wdt = platform_get_drvdata(mpcore_wdt_pdev);
if (test_and_set_bit(0, &wdt->timer_alive))
return -EBUSY;
@@ -298,9 +298,9 @@ static long mpcore_wdt_ioctl(struct file *file, unsigned int cmd,
* System shutdown handler. Turn off the watchdog if we're
* restarting or halting the system.
*/
-static void mpcore_wdt_shutdown(struct platform_device *dev)
+static void mpcore_wdt_shutdown(struct platform_device *pdev)
{
- struct mpcore_wdt *wdt = platform_get_drvdata(dev);
+ struct mpcore_wdt *wdt = platform_get_drvdata(pdev);
if (system_state == SYSTEM_RESTART || system_state == SYSTEM_HALT)
mpcore_wdt_stop(wdt);
@@ -324,17 +324,17 @@ static struct miscdevice mpcore_wdt_miscdev = {
.fops = &mpcore_wdt_fops,
};
-static int __devinit mpcore_wdt_probe(struct platform_device *dev)
+static int __devinit mpcore_wdt_probe(struct platform_device *pdev)
{
struct mpcore_wdt *wdt;
struct resource *res;
int ret;
/* We only accept one device, and it must have an id of -1 */
- if (dev->id != -1)
+ if (pdev->id != -1)
return -ENODEV;
- res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
ret = -ENODEV;
goto err_out;
@@ -346,8 +346,8 @@ static int __devinit mpcore_wdt_probe(struct platform_device *dev)
goto err_out;
}
- wdt->dev = &dev->dev;
- wdt->irq = platform_get_irq(dev, 0);
+ wdt->dev = &pdev->dev;
+ wdt->irq = platform_get_irq(pdev, 0);
if (wdt->irq < 0) {
ret = -ENXIO;
goto err_free;
@@ -358,7 +358,7 @@ static int __devinit mpcore_wdt_probe(struct platform_device *dev)
goto err_free;
}
- mpcore_wdt_miscdev.parent = &dev->dev;
+ mpcore_wdt_miscdev.parent = &pdev->dev;
ret = misc_register(&mpcore_wdt_miscdev);
if (ret) {
dev_printk(KERN_ERR, wdt->dev,
@@ -375,8 +375,8 @@ static int __devinit mpcore_wdt_probe(struct platform_device *dev)
}
mpcore_wdt_stop(wdt);
- platform_set_drvdata(dev, wdt);
- mpcore_wdt_dev = dev;
+ platform_set_drvdata(pdev, wdt);
+ mpcore_wdt_pdev = pdev;
return 0;
@@ -390,15 +390,15 @@ err_out:
return ret;
}
-static int __devexit mpcore_wdt_remove(struct platform_device *dev)
+static int __devexit mpcore_wdt_remove(struct platform_device *pdev)
{
- struct mpcore_wdt *wdt = platform_get_drvdata(dev);
+ struct mpcore_wdt *wdt = platform_get_drvdata(pdev);
- platform_set_drvdata(dev, NULL);
+ platform_set_drvdata(pdev, NULL);
misc_deregister(&mpcore_wdt_miscdev);
- mpcore_wdt_dev = NULL;
+ mpcore_wdt_pdev = NULL;
free_irq(wdt->irq, wdt);
iounmap(wdt->base);
@@ -407,16 +407,16 @@ static int __devexit mpcore_wdt_remove(struct platform_device *dev)
}
#ifdef CONFIG_PM
-static int mpcore_wdt_suspend(struct platform_device *dev, pm_message_t msg)
+static int mpcore_wdt_suspend(struct platform_device *pdev, pm_message_t msg)
{
- struct mpcore_wdt *wdt = platform_get_drvdata(dev);
+ struct mpcore_wdt *wdt = platform_get_drvdata(pdev);
mpcore_wdt_stop(wdt); /* Turn the WDT off */
return 0;
}
-static int mpcore_wdt_resume(struct platform_device *dev)
+static int mpcore_wdt_resume(struct platform_device *pdev)
{
- struct mpcore_wdt *wdt = platform_get_drvdata(dev);
+ struct mpcore_wdt *wdt = platform_get_drvdata(pdev);
/* re-activate timer */
if (test_bit(0, &wdt->timer_alive))
mpcore_wdt_start(wdt);
--
1.7.8.110.g4cb5d
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH V2 03/22] watchdog/mpcore_wdt: Rename dev to pdev for pointing to struct platform_device
@ 2012-03-12 4:21 ` Viresh Kumar
0 siblings, 0 replies; 56+ messages in thread
From: Viresh Kumar @ 2012-03-12 4:21 UTC (permalink / raw)
To: linux-arm-kernel
Pointer to struct platform_device is named as dev, which makes it confusing when
we write statements like dev->dev to access struct device within it.
This patch renames such names to pdev.
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
drivers/watchdog/mpcore_wdt.c | 40 ++++++++++++++++++++--------------------
1 files changed, 20 insertions(+), 20 deletions(-)
diff --git a/drivers/watchdog/mpcore_wdt.c b/drivers/watchdog/mpcore_wdt.c
index 82ccd36..fd9f91b 100644
--- a/drivers/watchdog/mpcore_wdt.c
+++ b/drivers/watchdog/mpcore_wdt.c
@@ -44,7 +44,7 @@ struct mpcore_wdt {
char expect_close;
};
-static struct platform_device *mpcore_wdt_dev;
+static struct platform_device *mpcore_wdt_pdev;
static DEFINE_SPINLOCK(wdt_lock);
#define TIMER_MARGIN 60
@@ -148,7 +148,7 @@ static int mpcore_wdt_set_heartbeat(int t)
*/
static int mpcore_wdt_open(struct inode *inode, struct file *file)
{
- struct mpcore_wdt *wdt = platform_get_drvdata(mpcore_wdt_dev);
+ struct mpcore_wdt *wdt = platform_get_drvdata(mpcore_wdt_pdev);
if (test_and_set_bit(0, &wdt->timer_alive))
return -EBUSY;
@@ -298,9 +298,9 @@ static long mpcore_wdt_ioctl(struct file *file, unsigned int cmd,
* System shutdown handler. Turn off the watchdog if we're
* restarting or halting the system.
*/
-static void mpcore_wdt_shutdown(struct platform_device *dev)
+static void mpcore_wdt_shutdown(struct platform_device *pdev)
{
- struct mpcore_wdt *wdt = platform_get_drvdata(dev);
+ struct mpcore_wdt *wdt = platform_get_drvdata(pdev);
if (system_state == SYSTEM_RESTART || system_state == SYSTEM_HALT)
mpcore_wdt_stop(wdt);
@@ -324,17 +324,17 @@ static struct miscdevice mpcore_wdt_miscdev = {
.fops = &mpcore_wdt_fops,
};
-static int __devinit mpcore_wdt_probe(struct platform_device *dev)
+static int __devinit mpcore_wdt_probe(struct platform_device *pdev)
{
struct mpcore_wdt *wdt;
struct resource *res;
int ret;
/* We only accept one device, and it must have an id of -1 */
- if (dev->id != -1)
+ if (pdev->id != -1)
return -ENODEV;
- res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
ret = -ENODEV;
goto err_out;
@@ -346,8 +346,8 @@ static int __devinit mpcore_wdt_probe(struct platform_device *dev)
goto err_out;
}
- wdt->dev = &dev->dev;
- wdt->irq = platform_get_irq(dev, 0);
+ wdt->dev = &pdev->dev;
+ wdt->irq = platform_get_irq(pdev, 0);
if (wdt->irq < 0) {
ret = -ENXIO;
goto err_free;
@@ -358,7 +358,7 @@ static int __devinit mpcore_wdt_probe(struct platform_device *dev)
goto err_free;
}
- mpcore_wdt_miscdev.parent = &dev->dev;
+ mpcore_wdt_miscdev.parent = &pdev->dev;
ret = misc_register(&mpcore_wdt_miscdev);
if (ret) {
dev_printk(KERN_ERR, wdt->dev,
@@ -375,8 +375,8 @@ static int __devinit mpcore_wdt_probe(struct platform_device *dev)
}
mpcore_wdt_stop(wdt);
- platform_set_drvdata(dev, wdt);
- mpcore_wdt_dev = dev;
+ platform_set_drvdata(pdev, wdt);
+ mpcore_wdt_pdev = pdev;
return 0;
@@ -390,15 +390,15 @@ err_out:
return ret;
}
-static int __devexit mpcore_wdt_remove(struct platform_device *dev)
+static int __devexit mpcore_wdt_remove(struct platform_device *pdev)
{
- struct mpcore_wdt *wdt = platform_get_drvdata(dev);
+ struct mpcore_wdt *wdt = platform_get_drvdata(pdev);
- platform_set_drvdata(dev, NULL);
+ platform_set_drvdata(pdev, NULL);
misc_deregister(&mpcore_wdt_miscdev);
- mpcore_wdt_dev = NULL;
+ mpcore_wdt_pdev = NULL;
free_irq(wdt->irq, wdt);
iounmap(wdt->base);
@@ -407,16 +407,16 @@ static int __devexit mpcore_wdt_remove(struct platform_device *dev)
}
#ifdef CONFIG_PM
-static int mpcore_wdt_suspend(struct platform_device *dev, pm_message_t msg)
+static int mpcore_wdt_suspend(struct platform_device *pdev, pm_message_t msg)
{
- struct mpcore_wdt *wdt = platform_get_drvdata(dev);
+ struct mpcore_wdt *wdt = platform_get_drvdata(pdev);
mpcore_wdt_stop(wdt); /* Turn the WDT off */
return 0;
}
-static int mpcore_wdt_resume(struct platform_device *dev)
+static int mpcore_wdt_resume(struct platform_device *pdev)
{
- struct mpcore_wdt *wdt = platform_get_drvdata(dev);
+ struct mpcore_wdt *wdt = platform_get_drvdata(pdev);
/* re-activate timer */
if (test_bit(0, &wdt->timer_alive))
mpcore_wdt_start(wdt);
--
1.7.8.110.g4cb5d
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH V2 04/22] watchdog/mpcore_wdt: Use devm routines
2012-03-12 4:21 ` Viresh Kumar
@ 2012-03-12 4:21 ` Viresh Kumar
-1 siblings, 0 replies; 56+ messages in thread
From: Viresh Kumar @ 2012-03-12 4:21 UTC (permalink / raw)
To: wim
Cc: linux-watchdog, spear-devel, viresh.linux, linux-arm-kernel,
srinidhi.kasagar, linus.walleij, alan, w.sang, sshtylyov,
Viresh Kumar
mpcore_wdt driver currently uses normal kzalloc, request_irq, ioremap, etc
routines. This patch replaces these routines with devm_kzalloc and
devm_request_mem_region etc, so that we don't need to handle freeing of
resources for error cases and module removal routine.
Also, request_irq is moved before registering misc device, so that we are ready
for irq as soon as device is registered.
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
drivers/watchdog/mpcore_wdt.c | 58 +++++++++++++---------------------------
1 files changed, 19 insertions(+), 39 deletions(-)
diff --git a/drivers/watchdog/mpcore_wdt.c b/drivers/watchdog/mpcore_wdt.c
index fd9f91b..63bd161 100644
--- a/drivers/watchdog/mpcore_wdt.c
+++ b/drivers/watchdog/mpcore_wdt.c
@@ -335,43 +335,37 @@ static int __devinit mpcore_wdt_probe(struct platform_device *pdev)
return -ENODEV;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- ret = -ENODEV;
- goto err_out;
- }
+ if (!res)
+ return -ENODEV;
- wdt = kzalloc(sizeof(struct mpcore_wdt), GFP_KERNEL);
- if (!wdt) {
- ret = -ENOMEM;
- goto err_out;
- }
+ wdt = devm_kzalloc(&pdev->dev, sizeof(struct mpcore_wdt), GFP_KERNEL);
+ if (!wdt)
+ return -ENOMEM;
wdt->dev = &pdev->dev;
wdt->irq = platform_get_irq(pdev, 0);
- if (wdt->irq < 0) {
- ret = -ENXIO;
- goto err_free;
- }
- wdt->base = ioremap(res->start, resource_size(res));
- if (!wdt->base) {
- ret = -ENOMEM;
- goto err_free;
+ if (wdt->irq < 0)
+ return -ENXIO;
+
+ ret = devm_request_irq(wdt->dev, wdt->irq, mpcore_wdt_fire, 0,
+ "mpcore_wdt", wdt);
+ if (ret) {
+ dev_printk(KERN_ERR, wdt->dev,
+ "cannot register IRQ%d for watchdog\n", wdt->irq);
+ return ret;
}
+ wdt->base = devm_ioremap(wdt->dev, res->start, resource_size(res));
+ if (!wdt->base)
+ return -ENOMEM;
+
mpcore_wdt_miscdev.parent = &pdev->dev;
ret = misc_register(&mpcore_wdt_miscdev);
if (ret) {
dev_printk(KERN_ERR, wdt->dev,
"cannot register miscdev on minor=%d (err=%d)\n",
WATCHDOG_MINOR, ret);
- goto err_misc;
- }
-
- ret = request_irq(wdt->irq, mpcore_wdt_fire, 0, "mpcore_wdt", wdt);
- if (ret) {
- dev_printk(KERN_ERR, wdt->dev,
- "cannot register IRQ%d for watchdog\n", wdt->irq);
- goto err_irq;
+ return ret;
}
mpcore_wdt_stop(wdt);
@@ -379,30 +373,16 @@ static int __devinit mpcore_wdt_probe(struct platform_device *pdev)
mpcore_wdt_pdev = pdev;
return 0;
-
-err_irq:
- misc_deregister(&mpcore_wdt_miscdev);
-err_misc:
- iounmap(wdt->base);
-err_free:
- kfree(wdt);
-err_out:
- return ret;
}
static int __devexit mpcore_wdt_remove(struct platform_device *pdev)
{
- struct mpcore_wdt *wdt = platform_get_drvdata(pdev);
-
platform_set_drvdata(pdev, NULL);
misc_deregister(&mpcore_wdt_miscdev);
mpcore_wdt_pdev = NULL;
- free_irq(wdt->irq, wdt);
- iounmap(wdt->base);
- kfree(wdt);
return 0;
}
--
1.7.8.110.g4cb5d
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH V2 04/22] watchdog/mpcore_wdt: Use devm routines
@ 2012-03-12 4:21 ` Viresh Kumar
0 siblings, 0 replies; 56+ messages in thread
From: Viresh Kumar @ 2012-03-12 4:21 UTC (permalink / raw)
To: linux-arm-kernel
mpcore_wdt driver currently uses normal kzalloc, request_irq, ioremap, etc
routines. This patch replaces these routines with devm_kzalloc and
devm_request_mem_region etc, so that we don't need to handle freeing of
resources for error cases and module removal routine.
Also, request_irq is moved before registering misc device, so that we are ready
for irq as soon as device is registered.
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
drivers/watchdog/mpcore_wdt.c | 58 +++++++++++++---------------------------
1 files changed, 19 insertions(+), 39 deletions(-)
diff --git a/drivers/watchdog/mpcore_wdt.c b/drivers/watchdog/mpcore_wdt.c
index fd9f91b..63bd161 100644
--- a/drivers/watchdog/mpcore_wdt.c
+++ b/drivers/watchdog/mpcore_wdt.c
@@ -335,43 +335,37 @@ static int __devinit mpcore_wdt_probe(struct platform_device *pdev)
return -ENODEV;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- ret = -ENODEV;
- goto err_out;
- }
+ if (!res)
+ return -ENODEV;
- wdt = kzalloc(sizeof(struct mpcore_wdt), GFP_KERNEL);
- if (!wdt) {
- ret = -ENOMEM;
- goto err_out;
- }
+ wdt = devm_kzalloc(&pdev->dev, sizeof(struct mpcore_wdt), GFP_KERNEL);
+ if (!wdt)
+ return -ENOMEM;
wdt->dev = &pdev->dev;
wdt->irq = platform_get_irq(pdev, 0);
- if (wdt->irq < 0) {
- ret = -ENXIO;
- goto err_free;
- }
- wdt->base = ioremap(res->start, resource_size(res));
- if (!wdt->base) {
- ret = -ENOMEM;
- goto err_free;
+ if (wdt->irq < 0)
+ return -ENXIO;
+
+ ret = devm_request_irq(wdt->dev, wdt->irq, mpcore_wdt_fire, 0,
+ "mpcore_wdt", wdt);
+ if (ret) {
+ dev_printk(KERN_ERR, wdt->dev,
+ "cannot register IRQ%d for watchdog\n", wdt->irq);
+ return ret;
}
+ wdt->base = devm_ioremap(wdt->dev, res->start, resource_size(res));
+ if (!wdt->base)
+ return -ENOMEM;
+
mpcore_wdt_miscdev.parent = &pdev->dev;
ret = misc_register(&mpcore_wdt_miscdev);
if (ret) {
dev_printk(KERN_ERR, wdt->dev,
"cannot register miscdev on minor=%d (err=%d)\n",
WATCHDOG_MINOR, ret);
- goto err_misc;
- }
-
- ret = request_irq(wdt->irq, mpcore_wdt_fire, 0, "mpcore_wdt", wdt);
- if (ret) {
- dev_printk(KERN_ERR, wdt->dev,
- "cannot register IRQ%d for watchdog\n", wdt->irq);
- goto err_irq;
+ return ret;
}
mpcore_wdt_stop(wdt);
@@ -379,30 +373,16 @@ static int __devinit mpcore_wdt_probe(struct platform_device *pdev)
mpcore_wdt_pdev = pdev;
return 0;
-
-err_irq:
- misc_deregister(&mpcore_wdt_miscdev);
-err_misc:
- iounmap(wdt->base);
-err_free:
- kfree(wdt);
-err_out:
- return ret;
}
static int __devexit mpcore_wdt_remove(struct platform_device *pdev)
{
- struct mpcore_wdt *wdt = platform_get_drvdata(pdev);
-
platform_set_drvdata(pdev, NULL);
misc_deregister(&mpcore_wdt_miscdev);
mpcore_wdt_pdev = NULL;
- free_irq(wdt->irq, wdt);
- iounmap(wdt->base);
- kfree(wdt);
return 0;
}
--
1.7.8.110.g4cb5d
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH V2 05/22] watchdog/mpcore_wdt: Allow platform_get_irq() to fail
2012-03-12 4:21 ` Viresh Kumar
@ 2012-03-12 4:22 ` Viresh Kumar
-1 siblings, 0 replies; 56+ messages in thread
From: Viresh Kumar @ 2012-03-12 4:22 UTC (permalink / raw)
To: wim
Cc: linux-watchdog, spear-devel, viresh.linux, linux-arm-kernel,
srinidhi.kasagar, linus.walleij, alan, w.sang, sshtylyov,
Viresh Kumar
irq is not necessary for mpcore wdt. Don't return error if it is not passed. But
if it is passed, then request_irq must pass.
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
drivers/watchdog/mpcore_wdt.c | 18 +++++++++---------
1 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/drivers/watchdog/mpcore_wdt.c b/drivers/watchdog/mpcore_wdt.c
index 63bd161..1d2f1a1 100644
--- a/drivers/watchdog/mpcore_wdt.c
+++ b/drivers/watchdog/mpcore_wdt.c
@@ -344,15 +344,15 @@ static int __devinit mpcore_wdt_probe(struct platform_device *pdev)
wdt->dev = &pdev->dev;
wdt->irq = platform_get_irq(pdev, 0);
- if (wdt->irq < 0)
- return -ENXIO;
-
- ret = devm_request_irq(wdt->dev, wdt->irq, mpcore_wdt_fire, 0,
- "mpcore_wdt", wdt);
- if (ret) {
- dev_printk(KERN_ERR, wdt->dev,
- "cannot register IRQ%d for watchdog\n", wdt->irq);
- return ret;
+ if (wdt->irq >= 0) {
+ ret = devm_request_irq(wdt->dev, wdt->irq, mpcore_wdt_fire, 0,
+ "mpcore_wdt", wdt);
+ if (ret) {
+ dev_printk(KERN_ERR, wdt->dev,
+ "cannot register IRQ%d for watchdog\n",
+ wdt->irq);
+ return ret;
+ }
}
wdt->base = devm_ioremap(wdt->dev, res->start, resource_size(res));
--
1.7.8.110.g4cb5d
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH V2 05/22] watchdog/mpcore_wdt: Allow platform_get_irq() to fail
@ 2012-03-12 4:22 ` Viresh Kumar
0 siblings, 0 replies; 56+ messages in thread
From: Viresh Kumar @ 2012-03-12 4:22 UTC (permalink / raw)
To: linux-arm-kernel
irq is not necessary for mpcore wdt. Don't return error if it is not passed. But
if it is passed, then request_irq must pass.
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
drivers/watchdog/mpcore_wdt.c | 18 +++++++++---------
1 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/drivers/watchdog/mpcore_wdt.c b/drivers/watchdog/mpcore_wdt.c
index 63bd161..1d2f1a1 100644
--- a/drivers/watchdog/mpcore_wdt.c
+++ b/drivers/watchdog/mpcore_wdt.c
@@ -344,15 +344,15 @@ static int __devinit mpcore_wdt_probe(struct platform_device *pdev)
wdt->dev = &pdev->dev;
wdt->irq = platform_get_irq(pdev, 0);
- if (wdt->irq < 0)
- return -ENXIO;
-
- ret = devm_request_irq(wdt->dev, wdt->irq, mpcore_wdt_fire, 0,
- "mpcore_wdt", wdt);
- if (ret) {
- dev_printk(KERN_ERR, wdt->dev,
- "cannot register IRQ%d for watchdog\n", wdt->irq);
- return ret;
+ if (wdt->irq >= 0) {
+ ret = devm_request_irq(wdt->dev, wdt->irq, mpcore_wdt_fire, 0,
+ "mpcore_wdt", wdt);
+ if (ret) {
+ dev_printk(KERN_ERR, wdt->dev,
+ "cannot register IRQ%d for watchdog\n",
+ wdt->irq);
+ return ret;
+ }
}
wdt->base = devm_ioremap(wdt->dev, res->start, resource_size(res));
--
1.7.8.110.g4cb5d
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH V2 06/22] watchdog/mpcore_wdt: convert to watchdog core
2012-03-12 4:21 ` Viresh Kumar
@ 2012-03-12 4:22 ` Viresh Kumar
-1 siblings, 0 replies; 56+ messages in thread
From: Viresh Kumar @ 2012-03-12 4:22 UTC (permalink / raw)
To: wim
Cc: linux-watchdog, spear-devel, viresh.linux, linux-arm-kernel,
srinidhi.kasagar, linus.walleij, alan, w.sang, sshtylyov,
Viresh Kumar
This patch converts existing mpcore watchdog driver to use already in place
common infrastructure present in watchdog core. With this lot of code goes away.
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
drivers/watchdog/Kconfig | 1 +
drivers/watchdog/mpcore_wdt.c | 281 ++++++++++-------------------------------
2 files changed, 71 insertions(+), 211 deletions(-)
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index ee27f57..f66617a 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -208,6 +208,7 @@ config DW_WATCHDOG
config MPCORE_WATCHDOG
tristate "MPcore watchdog"
depends on HAVE_ARM_TWD
+ select WATCHDOG_CORE
help
Watchdog timer embedded into the MPcore system.
diff --git a/drivers/watchdog/mpcore_wdt.c b/drivers/watchdog/mpcore_wdt.c
index 1d2f1a1..953044a 100644
--- a/drivers/watchdog/mpcore_wdt.c
+++ b/drivers/watchdog/mpcore_wdt.c
@@ -22,31 +22,27 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/types.h>
-#include <linux/miscdevice.h>
#include <linux/watchdog.h>
-#include <linux/fs.h>
#include <linux/reboot.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
-#include <linux/uaccess.h>
#include <linux/slab.h>
#include <linux/io.h>
#include <asm/smp_twd.h>
struct mpcore_wdt {
- unsigned long timer_alive;
+ struct watchdog_device wdd;
struct device *dev;
void __iomem *base;
+ spinlock_t lock;
int irq;
unsigned int perturb;
- char expect_close;
};
-static struct platform_device *mpcore_wdt_pdev;
-static DEFINE_SPINLOCK(wdt_lock);
-
+#define MIN_TIME 0x0001
+#define MAX_TIME 0xFFFF
#define TIMER_MARGIN 60
static int mpcore_margin = TIMER_MARGIN;
module_param(mpcore_margin, int, 0);
@@ -87,17 +83,18 @@ static irqreturn_t mpcore_wdt_fire(int irq, void *arg)
}
/*
- * mpcore_wdt_keepalive - reload the timer
+ * mpcore_wdt_ping - reload the timer
*
* Note that the spec says a DIFFERENT value must be written to the reload
* register each time. The "perturb" variable deals with this by adding 1
* to the count every other time the function is called.
*/
-static void mpcore_wdt_keepalive(struct mpcore_wdt *wdt)
+static int mpcore_wdt_ping(struct watchdog_device *wdd)
{
+ struct mpcore_wdt *wdt = watchdog_get_drvdata(wdd);
unsigned long count;
- spin_lock(&wdt_lock);
+ spin_lock(&wdt->lock);
/* Assume prescale is set to 256 */
count = __raw_readl(wdt->base + TWD_WDOG_COUNTER);
count = (0xFFFFFFFFU - count) * (HZ / 5);
@@ -106,24 +103,32 @@ static void mpcore_wdt_keepalive(struct mpcore_wdt *wdt)
/* Reload the counter */
writel(count + wdt->perturb, wdt->base + TWD_WDOG_LOAD);
wdt->perturb = wdt->perturb ? 0 : 1;
- spin_unlock(&wdt_lock);
+ spin_unlock(&wdt->lock);
+
+ return 0;
}
-static void mpcore_wdt_stop(struct mpcore_wdt *wdt)
+static int mpcore_wdt_stop(struct watchdog_device *wdd)
{
- spin_lock(&wdt_lock);
+ struct mpcore_wdt *wdt = watchdog_get_drvdata(wdd);
+
+ spin_lock(&wdt->lock);
writel(0x12345678, wdt->base + TWD_WDOG_DISABLE);
writel(0x87654321, wdt->base + TWD_WDOG_DISABLE);
writel(0x0, wdt->base + TWD_WDOG_CONTROL);
- spin_unlock(&wdt_lock);
+ spin_unlock(&wdt->lock);
+
+ return 0;
}
-static void mpcore_wdt_start(struct mpcore_wdt *wdt)
+static int mpcore_wdt_start(struct watchdog_device *wdd)
{
+ struct mpcore_wdt *wdt = watchdog_get_drvdata(wdd);
+
dev_printk(KERN_INFO, wdt->dev, "enabling watchdog.\n");
/* This loads the count register but does NOT start the count yet */
- mpcore_wdt_keepalive(wdt);
+ mpcore_wdt_ping(wdd);
if (mpcore_noboot) {
/* Enable watchdog - prescale=256, watchdog mode=0, enable=1 */
@@ -132,167 +137,30 @@ static void mpcore_wdt_start(struct mpcore_wdt *wdt)
/* Enable watchdog - prescale=256, watchdog mode=1, enable=1 */
writel(0x0000FF09, wdt->base + TWD_WDOG_CONTROL);
}
-}
-
-static int mpcore_wdt_set_heartbeat(int t)
-{
- if (t < 0x0001 || t > 0xFFFF)
- return -EINVAL;
- mpcore_margin = t;
return 0;
}
-/*
- * /dev/watchdog handling
- */
-static int mpcore_wdt_open(struct inode *inode, struct file *file)
-{
- struct mpcore_wdt *wdt = platform_get_drvdata(mpcore_wdt_pdev);
-
- if (test_and_set_bit(0, &wdt->timer_alive))
- return -EBUSY;
-
- if (nowayout)
- __module_get(THIS_MODULE);
-
- file->private_data = wdt;
-
- /*
- * Activate timer
- */
- mpcore_wdt_start(wdt);
-
- return nonseekable_open(inode, file);
-}
-
-static int mpcore_wdt_release(struct inode *inode, struct file *file)
+static int mpcore_wdt_set_heartbeat(struct watchdog_device *wdd, unsigned int t)
{
- struct mpcore_wdt *wdt = file->private_data;
-
- /*
- * Shut off the timer.
- * Lock it in if it's a module and we set nowayout
- */
- if (wdt->expect_close == 42)
- mpcore_wdt_stop(wdt);
- else {
- dev_printk(KERN_CRIT, wdt->dev,
- "unexpected close, not stopping watchdog!\n");
- mpcore_wdt_keepalive(wdt);
- }
- clear_bit(0, &wdt->timer_alive);
- wdt->expect_close = 0;
+ mpcore_margin = t;
return 0;
}
-static ssize_t mpcore_wdt_write(struct file *file, const char *data,
- size_t len, loff_t *ppos)
-{
- struct mpcore_wdt *wdt = file->private_data;
-
- /*
- * Refresh the timer.
- */
- if (len) {
- if (!nowayout) {
- size_t i;
-
- /* In case it was set long ago */
- wdt->expect_close = 0;
-
- for (i = 0; i != len; i++) {
- char c;
-
- if (get_user(c, data + i))
- return -EFAULT;
- if (c == 'V')
- wdt->expect_close = 42;
- }
- }
- mpcore_wdt_keepalive(wdt);
- }
- return len;
-}
-
-static const struct watchdog_info ident = {
+static const struct watchdog_info mpcore_wdt_info = {
.options = WDIOF_SETTIMEOUT |
WDIOF_KEEPALIVEPING |
WDIOF_MAGICCLOSE,
.identity = "MPcore Watchdog",
};
-static long mpcore_wdt_ioctl(struct file *file, unsigned int cmd,
- unsigned long arg)
-{
- struct mpcore_wdt *wdt = file->private_data;
- int ret;
- union {
- struct watchdog_info ident;
- int i;
- } uarg;
-
- if (_IOC_DIR(cmd) && _IOC_SIZE(cmd) > sizeof(uarg))
- return -ENOTTY;
-
- if (_IOC_DIR(cmd) & _IOC_WRITE) {
- ret = copy_from_user(&uarg, (void __user *)arg, _IOC_SIZE(cmd));
- if (ret)
- return -EFAULT;
- }
-
- switch (cmd) {
- case WDIOC_GETSUPPORT:
- uarg.ident = ident;
- ret = 0;
- break;
-
- case WDIOC_GETSTATUS:
- case WDIOC_GETBOOTSTATUS:
- uarg.i = 0;
- ret = 0;
- break;
-
- case WDIOC_SETOPTIONS:
- ret = -EINVAL;
- if (uarg.i & WDIOS_DISABLECARD) {
- mpcore_wdt_stop(wdt);
- ret = 0;
- }
- if (uarg.i & WDIOS_ENABLECARD) {
- mpcore_wdt_start(wdt);
- ret = 0;
- }
- break;
-
- case WDIOC_KEEPALIVE:
- mpcore_wdt_keepalive(wdt);
- ret = 0;
- break;
-
- case WDIOC_SETTIMEOUT:
- ret = mpcore_wdt_set_heartbeat(uarg.i);
- if (ret)
- break;
-
- mpcore_wdt_keepalive(wdt);
- /* Fall */
- case WDIOC_GETTIMEOUT:
- uarg.i = mpcore_margin;
- ret = 0;
- break;
-
- default:
- return -ENOTTY;
- }
-
- if (ret == 0 && _IOC_DIR(cmd) & _IOC_READ) {
- ret = copy_to_user((void __user *)arg, &uarg, _IOC_SIZE(cmd));
- if (ret)
- ret = -EFAULT;
- }
- return ret;
-}
+static const struct watchdog_ops mpcore_wdt_ops = {
+ .owner = THIS_MODULE,
+ .start = mpcore_wdt_start,
+ .stop = mpcore_wdt_stop,
+ .ping = mpcore_wdt_ping,
+ .set_timeout = mpcore_wdt_set_heartbeat,
+};
/*
* System shutdown handler. Turn off the watchdog if we're
@@ -303,37 +171,15 @@ static void mpcore_wdt_shutdown(struct platform_device *pdev)
struct mpcore_wdt *wdt = platform_get_drvdata(pdev);
if (system_state == SYSTEM_RESTART || system_state == SYSTEM_HALT)
- mpcore_wdt_stop(wdt);
+ mpcore_wdt_stop(&wdt->wdd);
}
-/*
- * Kernel Interfaces
- */
-static const struct file_operations mpcore_wdt_fops = {
- .owner = THIS_MODULE,
- .llseek = no_llseek,
- .write = mpcore_wdt_write,
- .unlocked_ioctl = mpcore_wdt_ioctl,
- .open = mpcore_wdt_open,
- .release = mpcore_wdt_release,
-};
-
-static struct miscdevice mpcore_wdt_miscdev = {
- .minor = WATCHDOG_MINOR,
- .name = "watchdog",
- .fops = &mpcore_wdt_fops,
-};
-
static int __devinit mpcore_wdt_probe(struct platform_device *pdev)
{
struct mpcore_wdt *wdt;
struct resource *res;
int ret;
- /* We only accept one device, and it must have an id of -1 */
- if (pdev->id != -1)
- return -ENODEV;
-
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res)
return -ENODEV;
@@ -359,30 +205,41 @@ static int __devinit mpcore_wdt_probe(struct platform_device *pdev)
if (!wdt->base)
return -ENOMEM;
- mpcore_wdt_miscdev.parent = &pdev->dev;
- ret = misc_register(&mpcore_wdt_miscdev);
- if (ret) {
- dev_printk(KERN_ERR, wdt->dev,
- "cannot register miscdev on minor=%d (err=%d)\n",
- WATCHDOG_MINOR, ret);
- return ret;
- }
+ wdt->wdd.info = &mpcore_wdt_info;
+ wdt->wdd.ops = &mpcore_wdt_ops;
+ wdt->wdd.min_timeout = MIN_TIME;
+ wdt->wdd.max_timeout = MAX_TIME;
+ spin_lock_init(&wdt->lock);
- mpcore_wdt_stop(wdt);
+ watchdog_set_nowayout(&wdt->wdd, nowayout);
platform_set_drvdata(pdev, wdt);
- mpcore_wdt_pdev = pdev;
+ watchdog_set_drvdata(&wdt->wdd, wdt);
+
+ mpcore_wdt_stop(&wdt->wdd);
+
+ ret = watchdog_register_device(&wdt->wdd);
+ if (ret) {
+ dev_err(wdt->dev, "watchdog_register_device() failed: %d\n",
+ ret);
+ goto err_register;
+ }
return 0;
-}
-static int __devexit mpcore_wdt_remove(struct platform_device *pdev)
-{
+err_register:
platform_set_drvdata(pdev, NULL);
+ watchdog_set_drvdata(&wdt->wdd, NULL);
- misc_deregister(&mpcore_wdt_miscdev);
+ return ret;
+}
- mpcore_wdt_pdev = NULL;
+static int __devexit mpcore_wdt_remove(struct platform_device *pdev)
+{
+ struct mpcore_wdt *wdt = platform_get_drvdata(pdev);
+ watchdog_unregister_device(&wdt->wdd);
+ platform_set_drvdata(pdev, NULL);
+ watchdog_set_drvdata(&wdt->wdd, NULL);
return 0;
}
@@ -390,16 +247,18 @@ static int __devexit mpcore_wdt_remove(struct platform_device *pdev)
static int mpcore_wdt_suspend(struct platform_device *pdev, pm_message_t msg)
{
struct mpcore_wdt *wdt = platform_get_drvdata(pdev);
- mpcore_wdt_stop(wdt); /* Turn the WDT off */
+ mpcore_wdt_stop(&wdt->wdd); /* Turn the WDT off */
+
return 0;
}
static int mpcore_wdt_resume(struct platform_device *pdev)
{
struct mpcore_wdt *wdt = platform_get_drvdata(pdev);
- /* re-activate timer */
- if (test_bit(0, &wdt->timer_alive))
- mpcore_wdt_start(wdt);
+
+ if (is_wdd_active(&wdt->wdd))
+ mpcore_wdt_start(&wdt->wdd);
+
return 0;
}
#else
@@ -428,15 +287,16 @@ static char banner[] __initdata = KERN_INFO "MPcore Watchdog Timer: 0.1. "
static int __init mpcore_wdt_init(void)
{
/*
- * Check that the margin value is within it's range;
+ * Check that the mpcore_margin value is within it's range;
* if not reset to the default
*/
- if (mpcore_wdt_set_heartbeat(mpcore_margin)) {
- mpcore_wdt_set_heartbeat(TIMER_MARGIN);
+ if (mpcore_margin < MIN_TIME || mpcore_margin > MAX_TIME) {
+ mpcore_margin = TIMER_MARGIN;
printk(KERN_INFO "mpcore_margin value must be 0 < mpcore_margin < 65536, using %d\n",
- TIMER_MARGIN);
+ TIMER_MARGIN);
}
+ mpcore_wdt_set_heartbeat(NULL, mpcore_margin);
printk(banner, mpcore_noboot, mpcore_margin, nowayout);
return platform_driver_register(&mpcore_wdt_driver);
@@ -453,4 +313,3 @@ module_exit(mpcore_wdt_exit);
MODULE_AUTHOR("ARM Limited");
MODULE_DESCRIPTION("MPcore Watchdog Device Driver");
MODULE_LICENSE("GPL");
-MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
--
1.7.8.110.g4cb5d
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH V2 06/22] watchdog/mpcore_wdt: convert to watchdog core
@ 2012-03-12 4:22 ` Viresh Kumar
0 siblings, 0 replies; 56+ messages in thread
From: Viresh Kumar @ 2012-03-12 4:22 UTC (permalink / raw)
To: linux-arm-kernel
This patch converts existing mpcore watchdog driver to use already in place
common infrastructure present in watchdog core. With this lot of code goes away.
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
drivers/watchdog/Kconfig | 1 +
drivers/watchdog/mpcore_wdt.c | 281 ++++++++++-------------------------------
2 files changed, 71 insertions(+), 211 deletions(-)
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index ee27f57..f66617a 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -208,6 +208,7 @@ config DW_WATCHDOG
config MPCORE_WATCHDOG
tristate "MPcore watchdog"
depends on HAVE_ARM_TWD
+ select WATCHDOG_CORE
help
Watchdog timer embedded into the MPcore system.
diff --git a/drivers/watchdog/mpcore_wdt.c b/drivers/watchdog/mpcore_wdt.c
index 1d2f1a1..953044a 100644
--- a/drivers/watchdog/mpcore_wdt.c
+++ b/drivers/watchdog/mpcore_wdt.c
@@ -22,31 +22,27 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/types.h>
-#include <linux/miscdevice.h>
#include <linux/watchdog.h>
-#include <linux/fs.h>
#include <linux/reboot.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
-#include <linux/uaccess.h>
#include <linux/slab.h>
#include <linux/io.h>
#include <asm/smp_twd.h>
struct mpcore_wdt {
- unsigned long timer_alive;
+ struct watchdog_device wdd;
struct device *dev;
void __iomem *base;
+ spinlock_t lock;
int irq;
unsigned int perturb;
- char expect_close;
};
-static struct platform_device *mpcore_wdt_pdev;
-static DEFINE_SPINLOCK(wdt_lock);
-
+#define MIN_TIME 0x0001
+#define MAX_TIME 0xFFFF
#define TIMER_MARGIN 60
static int mpcore_margin = TIMER_MARGIN;
module_param(mpcore_margin, int, 0);
@@ -87,17 +83,18 @@ static irqreturn_t mpcore_wdt_fire(int irq, void *arg)
}
/*
- * mpcore_wdt_keepalive - reload the timer
+ * mpcore_wdt_ping - reload the timer
*
* Note that the spec says a DIFFERENT value must be written to the reload
* register each time. The "perturb" variable deals with this by adding 1
* to the count every other time the function is called.
*/
-static void mpcore_wdt_keepalive(struct mpcore_wdt *wdt)
+static int mpcore_wdt_ping(struct watchdog_device *wdd)
{
+ struct mpcore_wdt *wdt = watchdog_get_drvdata(wdd);
unsigned long count;
- spin_lock(&wdt_lock);
+ spin_lock(&wdt->lock);
/* Assume prescale is set to 256 */
count = __raw_readl(wdt->base + TWD_WDOG_COUNTER);
count = (0xFFFFFFFFU - count) * (HZ / 5);
@@ -106,24 +103,32 @@ static void mpcore_wdt_keepalive(struct mpcore_wdt *wdt)
/* Reload the counter */
writel(count + wdt->perturb, wdt->base + TWD_WDOG_LOAD);
wdt->perturb = wdt->perturb ? 0 : 1;
- spin_unlock(&wdt_lock);
+ spin_unlock(&wdt->lock);
+
+ return 0;
}
-static void mpcore_wdt_stop(struct mpcore_wdt *wdt)
+static int mpcore_wdt_stop(struct watchdog_device *wdd)
{
- spin_lock(&wdt_lock);
+ struct mpcore_wdt *wdt = watchdog_get_drvdata(wdd);
+
+ spin_lock(&wdt->lock);
writel(0x12345678, wdt->base + TWD_WDOG_DISABLE);
writel(0x87654321, wdt->base + TWD_WDOG_DISABLE);
writel(0x0, wdt->base + TWD_WDOG_CONTROL);
- spin_unlock(&wdt_lock);
+ spin_unlock(&wdt->lock);
+
+ return 0;
}
-static void mpcore_wdt_start(struct mpcore_wdt *wdt)
+static int mpcore_wdt_start(struct watchdog_device *wdd)
{
+ struct mpcore_wdt *wdt = watchdog_get_drvdata(wdd);
+
dev_printk(KERN_INFO, wdt->dev, "enabling watchdog.\n");
/* This loads the count register but does NOT start the count yet */
- mpcore_wdt_keepalive(wdt);
+ mpcore_wdt_ping(wdd);
if (mpcore_noboot) {
/* Enable watchdog - prescale=256, watchdog mode=0, enable=1 */
@@ -132,167 +137,30 @@ static void mpcore_wdt_start(struct mpcore_wdt *wdt)
/* Enable watchdog - prescale=256, watchdog mode=1, enable=1 */
writel(0x0000FF09, wdt->base + TWD_WDOG_CONTROL);
}
-}
-
-static int mpcore_wdt_set_heartbeat(int t)
-{
- if (t < 0x0001 || t > 0xFFFF)
- return -EINVAL;
- mpcore_margin = t;
return 0;
}
-/*
- * /dev/watchdog handling
- */
-static int mpcore_wdt_open(struct inode *inode, struct file *file)
-{
- struct mpcore_wdt *wdt = platform_get_drvdata(mpcore_wdt_pdev);
-
- if (test_and_set_bit(0, &wdt->timer_alive))
- return -EBUSY;
-
- if (nowayout)
- __module_get(THIS_MODULE);
-
- file->private_data = wdt;
-
- /*
- * Activate timer
- */
- mpcore_wdt_start(wdt);
-
- return nonseekable_open(inode, file);
-}
-
-static int mpcore_wdt_release(struct inode *inode, struct file *file)
+static int mpcore_wdt_set_heartbeat(struct watchdog_device *wdd, unsigned int t)
{
- struct mpcore_wdt *wdt = file->private_data;
-
- /*
- * Shut off the timer.
- * Lock it in if it's a module and we set nowayout
- */
- if (wdt->expect_close == 42)
- mpcore_wdt_stop(wdt);
- else {
- dev_printk(KERN_CRIT, wdt->dev,
- "unexpected close, not stopping watchdog!\n");
- mpcore_wdt_keepalive(wdt);
- }
- clear_bit(0, &wdt->timer_alive);
- wdt->expect_close = 0;
+ mpcore_margin = t;
return 0;
}
-static ssize_t mpcore_wdt_write(struct file *file, const char *data,
- size_t len, loff_t *ppos)
-{
- struct mpcore_wdt *wdt = file->private_data;
-
- /*
- * Refresh the timer.
- */
- if (len) {
- if (!nowayout) {
- size_t i;
-
- /* In case it was set long ago */
- wdt->expect_close = 0;
-
- for (i = 0; i != len; i++) {
- char c;
-
- if (get_user(c, data + i))
- return -EFAULT;
- if (c == 'V')
- wdt->expect_close = 42;
- }
- }
- mpcore_wdt_keepalive(wdt);
- }
- return len;
-}
-
-static const struct watchdog_info ident = {
+static const struct watchdog_info mpcore_wdt_info = {
.options = WDIOF_SETTIMEOUT |
WDIOF_KEEPALIVEPING |
WDIOF_MAGICCLOSE,
.identity = "MPcore Watchdog",
};
-static long mpcore_wdt_ioctl(struct file *file, unsigned int cmd,
- unsigned long arg)
-{
- struct mpcore_wdt *wdt = file->private_data;
- int ret;
- union {
- struct watchdog_info ident;
- int i;
- } uarg;
-
- if (_IOC_DIR(cmd) && _IOC_SIZE(cmd) > sizeof(uarg))
- return -ENOTTY;
-
- if (_IOC_DIR(cmd) & _IOC_WRITE) {
- ret = copy_from_user(&uarg, (void __user *)arg, _IOC_SIZE(cmd));
- if (ret)
- return -EFAULT;
- }
-
- switch (cmd) {
- case WDIOC_GETSUPPORT:
- uarg.ident = ident;
- ret = 0;
- break;
-
- case WDIOC_GETSTATUS:
- case WDIOC_GETBOOTSTATUS:
- uarg.i = 0;
- ret = 0;
- break;
-
- case WDIOC_SETOPTIONS:
- ret = -EINVAL;
- if (uarg.i & WDIOS_DISABLECARD) {
- mpcore_wdt_stop(wdt);
- ret = 0;
- }
- if (uarg.i & WDIOS_ENABLECARD) {
- mpcore_wdt_start(wdt);
- ret = 0;
- }
- break;
-
- case WDIOC_KEEPALIVE:
- mpcore_wdt_keepalive(wdt);
- ret = 0;
- break;
-
- case WDIOC_SETTIMEOUT:
- ret = mpcore_wdt_set_heartbeat(uarg.i);
- if (ret)
- break;
-
- mpcore_wdt_keepalive(wdt);
- /* Fall */
- case WDIOC_GETTIMEOUT:
- uarg.i = mpcore_margin;
- ret = 0;
- break;
-
- default:
- return -ENOTTY;
- }
-
- if (ret == 0 && _IOC_DIR(cmd) & _IOC_READ) {
- ret = copy_to_user((void __user *)arg, &uarg, _IOC_SIZE(cmd));
- if (ret)
- ret = -EFAULT;
- }
- return ret;
-}
+static const struct watchdog_ops mpcore_wdt_ops = {
+ .owner = THIS_MODULE,
+ .start = mpcore_wdt_start,
+ .stop = mpcore_wdt_stop,
+ .ping = mpcore_wdt_ping,
+ .set_timeout = mpcore_wdt_set_heartbeat,
+};
/*
* System shutdown handler. Turn off the watchdog if we're
@@ -303,37 +171,15 @@ static void mpcore_wdt_shutdown(struct platform_device *pdev)
struct mpcore_wdt *wdt = platform_get_drvdata(pdev);
if (system_state == SYSTEM_RESTART || system_state == SYSTEM_HALT)
- mpcore_wdt_stop(wdt);
+ mpcore_wdt_stop(&wdt->wdd);
}
-/*
- * Kernel Interfaces
- */
-static const struct file_operations mpcore_wdt_fops = {
- .owner = THIS_MODULE,
- .llseek = no_llseek,
- .write = mpcore_wdt_write,
- .unlocked_ioctl = mpcore_wdt_ioctl,
- .open = mpcore_wdt_open,
- .release = mpcore_wdt_release,
-};
-
-static struct miscdevice mpcore_wdt_miscdev = {
- .minor = WATCHDOG_MINOR,
- .name = "watchdog",
- .fops = &mpcore_wdt_fops,
-};
-
static int __devinit mpcore_wdt_probe(struct platform_device *pdev)
{
struct mpcore_wdt *wdt;
struct resource *res;
int ret;
- /* We only accept one device, and it must have an id of -1 */
- if (pdev->id != -1)
- return -ENODEV;
-
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res)
return -ENODEV;
@@ -359,30 +205,41 @@ static int __devinit mpcore_wdt_probe(struct platform_device *pdev)
if (!wdt->base)
return -ENOMEM;
- mpcore_wdt_miscdev.parent = &pdev->dev;
- ret = misc_register(&mpcore_wdt_miscdev);
- if (ret) {
- dev_printk(KERN_ERR, wdt->dev,
- "cannot register miscdev on minor=%d (err=%d)\n",
- WATCHDOG_MINOR, ret);
- return ret;
- }
+ wdt->wdd.info = &mpcore_wdt_info;
+ wdt->wdd.ops = &mpcore_wdt_ops;
+ wdt->wdd.min_timeout = MIN_TIME;
+ wdt->wdd.max_timeout = MAX_TIME;
+ spin_lock_init(&wdt->lock);
- mpcore_wdt_stop(wdt);
+ watchdog_set_nowayout(&wdt->wdd, nowayout);
platform_set_drvdata(pdev, wdt);
- mpcore_wdt_pdev = pdev;
+ watchdog_set_drvdata(&wdt->wdd, wdt);
+
+ mpcore_wdt_stop(&wdt->wdd);
+
+ ret = watchdog_register_device(&wdt->wdd);
+ if (ret) {
+ dev_err(wdt->dev, "watchdog_register_device() failed: %d\n",
+ ret);
+ goto err_register;
+ }
return 0;
-}
-static int __devexit mpcore_wdt_remove(struct platform_device *pdev)
-{
+err_register:
platform_set_drvdata(pdev, NULL);
+ watchdog_set_drvdata(&wdt->wdd, NULL);
- misc_deregister(&mpcore_wdt_miscdev);
+ return ret;
+}
- mpcore_wdt_pdev = NULL;
+static int __devexit mpcore_wdt_remove(struct platform_device *pdev)
+{
+ struct mpcore_wdt *wdt = platform_get_drvdata(pdev);
+ watchdog_unregister_device(&wdt->wdd);
+ platform_set_drvdata(pdev, NULL);
+ watchdog_set_drvdata(&wdt->wdd, NULL);
return 0;
}
@@ -390,16 +247,18 @@ static int __devexit mpcore_wdt_remove(struct platform_device *pdev)
static int mpcore_wdt_suspend(struct platform_device *pdev, pm_message_t msg)
{
struct mpcore_wdt *wdt = platform_get_drvdata(pdev);
- mpcore_wdt_stop(wdt); /* Turn the WDT off */
+ mpcore_wdt_stop(&wdt->wdd); /* Turn the WDT off */
+
return 0;
}
static int mpcore_wdt_resume(struct platform_device *pdev)
{
struct mpcore_wdt *wdt = platform_get_drvdata(pdev);
- /* re-activate timer */
- if (test_bit(0, &wdt->timer_alive))
- mpcore_wdt_start(wdt);
+
+ if (is_wdd_active(&wdt->wdd))
+ mpcore_wdt_start(&wdt->wdd);
+
return 0;
}
#else
@@ -428,15 +287,16 @@ static char banner[] __initdata = KERN_INFO "MPcore Watchdog Timer: 0.1. "
static int __init mpcore_wdt_init(void)
{
/*
- * Check that the margin value is within it's range;
+ * Check that the mpcore_margin value is within it's range;
* if not reset to the default
*/
- if (mpcore_wdt_set_heartbeat(mpcore_margin)) {
- mpcore_wdt_set_heartbeat(TIMER_MARGIN);
+ if (mpcore_margin < MIN_TIME || mpcore_margin > MAX_TIME) {
+ mpcore_margin = TIMER_MARGIN;
printk(KERN_INFO "mpcore_margin value must be 0 < mpcore_margin < 65536, using %d\n",
- TIMER_MARGIN);
+ TIMER_MARGIN);
}
+ mpcore_wdt_set_heartbeat(NULL, mpcore_margin);
printk(banner, mpcore_noboot, mpcore_margin, nowayout);
return platform_driver_register(&mpcore_wdt_driver);
@@ -453,4 +313,3 @@ module_exit(mpcore_wdt_exit);
MODULE_AUTHOR("ARM Limited");
MODULE_DESCRIPTION("MPcore Watchdog Device Driver");
MODULE_LICENSE("GPL");
-MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
--
1.7.8.110.g4cb5d
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH V2 07/22] watchdog/mpcore_wdt: Fix multiline comments
2012-03-12 4:21 ` Viresh Kumar
@ 2012-03-12 4:22 ` Viresh Kumar
-1 siblings, 0 replies; 56+ messages in thread
From: Viresh Kumar @ 2012-03-12 4:22 UTC (permalink / raw)
To: wim
Cc: linux-watchdog, spear-devel, viresh.linux, linux-arm-kernel,
srinidhi.kasagar, linus.walleij, alan, w.sang, sshtylyov,
Viresh Kumar
In case of few multiline comment a 'tab' is present instead of 'space' after the
'*' in the second column. Replace tab with space here.
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
drivers/watchdog/mpcore_wdt.c | 42 +++++++++++++++++++---------------------
1 files changed, 20 insertions(+), 22 deletions(-)
diff --git a/drivers/watchdog/mpcore_wdt.c b/drivers/watchdog/mpcore_wdt.c
index 953044a..7c9f78c 100644
--- a/drivers/watchdog/mpcore_wdt.c
+++ b/drivers/watchdog/mpcore_wdt.c
@@ -1,23 +1,21 @@
/*
- * Watchdog driver for the mpcore watchdog timer
+ * Watchdog driver for the mpcore watchdog timer
*
- * (c) Copyright 2004 ARM Limited
+ * (c) Copyright 2004 ARM Limited
*
- * Based on the SoftDog driver:
- * (c) Copyright 1996 Alan Cox <alan@lxorguk.ukuu.org.uk>,
- * All Rights Reserved.
+ * Based on the SoftDog driver:
+ * (c) Copyright 1996 Alan Cox <alan@lxorguk.ukuu.org.uk>, All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
*
- * Neither Alan Cox nor CymruNet Ltd. admit liability nor provide
- * warranty for any of this software. This material is provided
- * "AS-IS" and at no charge.
- *
- * (c) Copyright 1995 Alan Cox <alan@lxorguk.ukuu.org.uk>
+ * Neither Alan Cox nor CymruNet Ltd. admit liability nor provide
+ * warranty for any of this software. This material is provided
+ * "AS-IS" and at no charge.
*
+ * (c) Copyright 1995 Alan Cox <alan@lxorguk.ukuu.org.uk>
*/
#include <linux/module.h>
#include <linux/moduleparam.h>
@@ -64,8 +62,8 @@ MODULE_PARM_DESC(mpcore_noboot, "MPcore watchdog action, "
__MODULE_STRING(ONLY_TESTING) ")");
/*
- * This is the interrupt handler. Note that we only use this
- * in testing mode, so don't actually do a reboot here.
+ * This is the interrupt handler. Note that we only use this
+ * in testing mode, so don't actually do a reboot here.
*/
static irqreturn_t mpcore_wdt_fire(int irq, void *arg)
{
@@ -83,11 +81,11 @@ static irqreturn_t mpcore_wdt_fire(int irq, void *arg)
}
/*
- * mpcore_wdt_ping - reload the timer
+ * mpcore_wdt_ping - reload the timer
*
- * Note that the spec says a DIFFERENT value must be written to the reload
- * register each time. The "perturb" variable deals with this by adding 1
- * to the count every other time the function is called.
+ * Note that the spec says a DIFFERENT value must be written to the reload
+ * register each time. The "perturb" variable deals with this by adding 1 to
+ * the count every other time the function is called.
*/
static int mpcore_wdt_ping(struct watchdog_device *wdd)
{
@@ -163,8 +161,8 @@ static const struct watchdog_ops mpcore_wdt_ops = {
};
/*
- * System shutdown handler. Turn off the watchdog if we're
- * restarting or halting the system.
+ * System shutdown handler. Turn off the watchdog if we're restarting or
+ * halting the system.
*/
static void mpcore_wdt_shutdown(struct platform_device *pdev)
{
--
1.7.8.110.g4cb5d
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH V2 07/22] watchdog/mpcore_wdt: Fix multiline comments
@ 2012-03-12 4:22 ` Viresh Kumar
0 siblings, 0 replies; 56+ messages in thread
From: Viresh Kumar @ 2012-03-12 4:22 UTC (permalink / raw)
To: linux-arm-kernel
In case of few multiline comment a 'tab' is present instead of 'space' after the
'*' in the second column. Replace tab with space here.
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
drivers/watchdog/mpcore_wdt.c | 42 +++++++++++++++++++---------------------
1 files changed, 20 insertions(+), 22 deletions(-)
diff --git a/drivers/watchdog/mpcore_wdt.c b/drivers/watchdog/mpcore_wdt.c
index 953044a..7c9f78c 100644
--- a/drivers/watchdog/mpcore_wdt.c
+++ b/drivers/watchdog/mpcore_wdt.c
@@ -1,23 +1,21 @@
/*
- * Watchdog driver for the mpcore watchdog timer
+ * Watchdog driver for the mpcore watchdog timer
*
- * (c) Copyright 2004 ARM Limited
+ * (c) Copyright 2004 ARM Limited
*
- * Based on the SoftDog driver:
- * (c) Copyright 1996 Alan Cox <alan@lxorguk.ukuu.org.uk>,
- * All Rights Reserved.
+ * Based on the SoftDog driver:
+ * (c) Copyright 1996 Alan Cox <alan@lxorguk.ukuu.org.uk>, All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
*
- * Neither Alan Cox nor CymruNet Ltd. admit liability nor provide
- * warranty for any of this software. This material is provided
- * "AS-IS" and at no charge.
- *
- * (c) Copyright 1995 Alan Cox <alan@lxorguk.ukuu.org.uk>
+ * Neither Alan Cox nor CymruNet Ltd. admit liability nor provide
+ * warranty for any of this software. This material is provided
+ * "AS-IS" and at no charge.
*
+ * (c) Copyright 1995 Alan Cox <alan@lxorguk.ukuu.org.uk>
*/
#include <linux/module.h>
#include <linux/moduleparam.h>
@@ -64,8 +62,8 @@ MODULE_PARM_DESC(mpcore_noboot, "MPcore watchdog action, "
__MODULE_STRING(ONLY_TESTING) ")");
/*
- * This is the interrupt handler. Note that we only use this
- * in testing mode, so don't actually do a reboot here.
+ * This is the interrupt handler. Note that we only use this
+ * in testing mode, so don't actually do a reboot here.
*/
static irqreturn_t mpcore_wdt_fire(int irq, void *arg)
{
@@ -83,11 +81,11 @@ static irqreturn_t mpcore_wdt_fire(int irq, void *arg)
}
/*
- * mpcore_wdt_ping - reload the timer
+ * mpcore_wdt_ping - reload the timer
*
- * Note that the spec says a DIFFERENT value must be written to the reload
- * register each time. The "perturb" variable deals with this by adding 1
- * to the count every other time the function is called.
+ * Note that the spec says a DIFFERENT value must be written to the reload
+ * register each time. The "perturb" variable deals with this by adding 1 to
+ * the count every other time the function is called.
*/
static int mpcore_wdt_ping(struct watchdog_device *wdd)
{
@@ -163,8 +161,8 @@ static const struct watchdog_ops mpcore_wdt_ops = {
};
/*
- * System shutdown handler. Turn off the watchdog if we're
- * restarting or halting the system.
+ * System shutdown handler. Turn off the watchdog if we're restarting or
+ * halting the system.
*/
static void mpcore_wdt_shutdown(struct platform_device *pdev)
{
--
1.7.8.110.g4cb5d
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH V2 08/22] watchdog/mpcore_wdt: Arrange #includes in alphabetical order
2012-03-12 4:21 ` Viresh Kumar
@ 2012-03-12 4:22 ` Viresh Kumar
-1 siblings, 0 replies; 56+ messages in thread
From: Viresh Kumar @ 2012-03-12 4:22 UTC (permalink / raw)
To: wim
Cc: linux-watchdog, spear-devel, viresh.linux, linux-arm-kernel,
srinidhi.kasagar, linus.walleij, alan, w.sang, sshtylyov,
Viresh Kumar
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
drivers/watchdog/mpcore_wdt.c | 12 ++++++------
1 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/watchdog/mpcore_wdt.c b/drivers/watchdog/mpcore_wdt.c
index 7c9f78c..1c37109 100644
--- a/drivers/watchdog/mpcore_wdt.c
+++ b/drivers/watchdog/mpcore_wdt.c
@@ -17,16 +17,16 @@
*
* (c) Copyright 1995 Alan Cox <alan@lxorguk.ukuu.org.uk>
*/
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/types.h>
-#include <linux/watchdog.h>
-#include <linux/reboot.h>
#include <linux/init.h>
#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
#include <linux/platform_device.h>
+#include <linux/reboot.h>
#include <linux/slab.h>
-#include <linux/io.h>
+#include <linux/types.h>
+#include <linux/watchdog.h>
#include <asm/smp_twd.h>
--
1.7.8.110.g4cb5d
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH V2 08/22] watchdog/mpcore_wdt: Arrange #includes in alphabetical order
@ 2012-03-12 4:22 ` Viresh Kumar
0 siblings, 0 replies; 56+ messages in thread
From: Viresh Kumar @ 2012-03-12 4:22 UTC (permalink / raw)
To: linux-arm-kernel
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
drivers/watchdog/mpcore_wdt.c | 12 ++++++------
1 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/watchdog/mpcore_wdt.c b/drivers/watchdog/mpcore_wdt.c
index 7c9f78c..1c37109 100644
--- a/drivers/watchdog/mpcore_wdt.c
+++ b/drivers/watchdog/mpcore_wdt.c
@@ -17,16 +17,16 @@
*
* (c) Copyright 1995 Alan Cox <alan@lxorguk.ukuu.org.uk>
*/
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/types.h>
-#include <linux/watchdog.h>
-#include <linux/reboot.h>
#include <linux/init.h>
#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
#include <linux/platform_device.h>
+#include <linux/reboot.h>
#include <linux/slab.h>
-#include <linux/io.h>
+#include <linux/types.h>
+#include <linux/watchdog.h>
#include <asm/smp_twd.h>
--
1.7.8.110.g4cb5d
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH V2 09/22] watchdog/mpcore_wdt: Set default heartbeat in probe instead of init
2012-03-12 4:21 ` Viresh Kumar
@ 2012-03-12 4:22 ` Viresh Kumar
-1 siblings, 0 replies; 56+ messages in thread
From: Viresh Kumar @ 2012-03-12 4:22 UTC (permalink / raw)
To: wim
Cc: linux-watchdog, spear-devel, viresh.linux, linux-arm-kernel,
srinidhi.kasagar, linus.walleij, alan, w.sang, sshtylyov,
Viresh Kumar
Currently mpcore_margin is handled in mpcore_wdt_init routine, which will be
called even if we haven't added any device for watchdog.
This patch moves this code into probe routine, so that it only gets hit once we
add device for this driver.
This also uses dev_info() style print statements instead of printk()
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
drivers/watchdog/mpcore_wdt.c | 31 +++++++++++++++----------------
1 files changed, 15 insertions(+), 16 deletions(-)
diff --git a/drivers/watchdog/mpcore_wdt.c b/drivers/watchdog/mpcore_wdt.c
index 1c37109..19aaad7 100644
--- a/drivers/watchdog/mpcore_wdt.c
+++ b/drivers/watchdog/mpcore_wdt.c
@@ -222,6 +222,21 @@ static int __devinit mpcore_wdt_probe(struct platform_device *pdev)
goto err_register;
}
+ /*
+ * Check that the mpcore_margin value is within it's range; if not reset
+ * to the default
+ */
+ if (mpcore_margin < MIN_TIME || mpcore_margin > MAX_TIME) {
+ mpcore_margin = TIMER_MARGIN;
+ dev_info(wdt->dev, "mpcore_margin value must be 0 < mpcore_margin < 65536, using %d\n",
+ TIMER_MARGIN);
+ }
+
+ mpcore_wdt_set_heartbeat(NULL, mpcore_margin);
+ dev_info(wdt->dev, "MPcore Watchdog Timer: 0.1. mpcore_noboot=%d "
+ "mpcore_margin=%d sec (nowayout= %d)\n", mpcore_noboot,
+ mpcore_margin, nowayout);
+
return 0;
err_register:
@@ -279,24 +294,8 @@ static struct platform_driver mpcore_wdt_driver = {
},
};
-static char banner[] __initdata = KERN_INFO "MPcore Watchdog Timer: 0.1. "
- "mpcore_noboot=%d mpcore_margin=%d sec (nowayout= %d)\n";
-
static int __init mpcore_wdt_init(void)
{
- /*
- * Check that the mpcore_margin value is within it's range;
- * if not reset to the default
- */
- if (mpcore_margin < MIN_TIME || mpcore_margin > MAX_TIME) {
- mpcore_margin = TIMER_MARGIN;
- printk(KERN_INFO "mpcore_margin value must be 0 < mpcore_margin < 65536, using %d\n",
- TIMER_MARGIN);
- }
-
- mpcore_wdt_set_heartbeat(NULL, mpcore_margin);
- printk(banner, mpcore_noboot, mpcore_margin, nowayout);
-
return platform_driver_register(&mpcore_wdt_driver);
}
--
1.7.8.110.g4cb5d
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH V2 09/22] watchdog/mpcore_wdt: Set default heartbeat in probe instead of init
@ 2012-03-12 4:22 ` Viresh Kumar
0 siblings, 0 replies; 56+ messages in thread
From: Viresh Kumar @ 2012-03-12 4:22 UTC (permalink / raw)
To: linux-arm-kernel
Currently mpcore_margin is handled in mpcore_wdt_init routine, which will be
called even if we haven't added any device for watchdog.
This patch moves this code into probe routine, so that it only gets hit once we
add device for this driver.
This also uses dev_info() style print statements instead of printk()
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
drivers/watchdog/mpcore_wdt.c | 31 +++++++++++++++----------------
1 files changed, 15 insertions(+), 16 deletions(-)
diff --git a/drivers/watchdog/mpcore_wdt.c b/drivers/watchdog/mpcore_wdt.c
index 1c37109..19aaad7 100644
--- a/drivers/watchdog/mpcore_wdt.c
+++ b/drivers/watchdog/mpcore_wdt.c
@@ -222,6 +222,21 @@ static int __devinit mpcore_wdt_probe(struct platform_device *pdev)
goto err_register;
}
+ /*
+ * Check that the mpcore_margin value is within it's range; if not reset
+ * to the default
+ */
+ if (mpcore_margin < MIN_TIME || mpcore_margin > MAX_TIME) {
+ mpcore_margin = TIMER_MARGIN;
+ dev_info(wdt->dev, "mpcore_margin value must be 0 < mpcore_margin < 65536, using %d\n",
+ TIMER_MARGIN);
+ }
+
+ mpcore_wdt_set_heartbeat(NULL, mpcore_margin);
+ dev_info(wdt->dev, "MPcore Watchdog Timer: 0.1. mpcore_noboot=%d "
+ "mpcore_margin=%d sec (nowayout= %d)\n", mpcore_noboot,
+ mpcore_margin, nowayout);
+
return 0;
err_register:
@@ -279,24 +294,8 @@ static struct platform_driver mpcore_wdt_driver = {
},
};
-static char banner[] __initdata = KERN_INFO "MPcore Watchdog Timer: 0.1. "
- "mpcore_noboot=%d mpcore_margin=%d sec (nowayout= %d)\n";
-
static int __init mpcore_wdt_init(void)
{
- /*
- * Check that the mpcore_margin value is within it's range;
- * if not reset to the default
- */
- if (mpcore_margin < MIN_TIME || mpcore_margin > MAX_TIME) {
- mpcore_margin = TIMER_MARGIN;
- printk(KERN_INFO "mpcore_margin value must be 0 < mpcore_margin < 65536, using %d\n",
- TIMER_MARGIN);
- }
-
- mpcore_wdt_set_heartbeat(NULL, mpcore_margin);
- printk(banner, mpcore_noboot, mpcore_margin, nowayout);
-
return platform_driver_register(&mpcore_wdt_driver);
}
--
1.7.8.110.g4cb5d
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH V2 10/22] watchdog/mpcore_wdt: Use dev_(crit, err, info) instead of dev_printk
2012-03-12 4:21 ` Viresh Kumar
@ 2012-03-12 4:22 ` Viresh Kumar
-1 siblings, 0 replies; 56+ messages in thread
From: Viresh Kumar @ 2012-03-12 4:22 UTC (permalink / raw)
To: wim
Cc: linux-watchdog, spear-devel, viresh.linux, linux-arm-kernel,
srinidhi.kasagar, linus.walleij, alan, w.sang, sshtylyov,
Viresh Kumar
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
drivers/watchdog/mpcore_wdt.c | 7 +++----
1 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/drivers/watchdog/mpcore_wdt.c b/drivers/watchdog/mpcore_wdt.c
index 19aaad7..c820e4f 100644
--- a/drivers/watchdog/mpcore_wdt.c
+++ b/drivers/watchdog/mpcore_wdt.c
@@ -71,8 +71,7 @@ static irqreturn_t mpcore_wdt_fire(int irq, void *arg)
/* Check it really was our interrupt */
if (readl(wdt->base + TWD_WDOG_INTSTAT)) {
- dev_printk(KERN_CRIT, wdt->dev,
- "Triggered - Reboot ignored.\n");
+ dev_crit(wdt->dev, "Triggered - Reboot ignored.\n");
/* Clear the interrupt on the watchdog */
writel(1, wdt->base + TWD_WDOG_INTSTAT);
return IRQ_HANDLED;
@@ -123,7 +122,7 @@ static int mpcore_wdt_start(struct watchdog_device *wdd)
{
struct mpcore_wdt *wdt = watchdog_get_drvdata(wdd);
- dev_printk(KERN_INFO, wdt->dev, "enabling watchdog.\n");
+ dev_info(wdt->dev, "enabling watchdog.\n");
/* This loads the count register but does NOT start the count yet */
mpcore_wdt_ping(wdd);
@@ -192,7 +191,7 @@ static int __devinit mpcore_wdt_probe(struct platform_device *pdev)
ret = devm_request_irq(wdt->dev, wdt->irq, mpcore_wdt_fire, 0,
"mpcore_wdt", wdt);
if (ret) {
- dev_printk(KERN_ERR, wdt->dev,
+ dev_err(wdt->dev,
"cannot register IRQ%d for watchdog\n",
wdt->irq);
return ret;
--
1.7.8.110.g4cb5d
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH V2 10/22] watchdog/mpcore_wdt: Use dev_(crit, err, info) instead of dev_printk
@ 2012-03-12 4:22 ` Viresh Kumar
0 siblings, 0 replies; 56+ messages in thread
From: Viresh Kumar @ 2012-03-12 4:22 UTC (permalink / raw)
To: linux-arm-kernel
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
drivers/watchdog/mpcore_wdt.c | 7 +++----
1 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/drivers/watchdog/mpcore_wdt.c b/drivers/watchdog/mpcore_wdt.c
index 19aaad7..c820e4f 100644
--- a/drivers/watchdog/mpcore_wdt.c
+++ b/drivers/watchdog/mpcore_wdt.c
@@ -71,8 +71,7 @@ static irqreturn_t mpcore_wdt_fire(int irq, void *arg)
/* Check it really was our interrupt */
if (readl(wdt->base + TWD_WDOG_INTSTAT)) {
- dev_printk(KERN_CRIT, wdt->dev,
- "Triggered - Reboot ignored.\n");
+ dev_crit(wdt->dev, "Triggered - Reboot ignored.\n");
/* Clear the interrupt on the watchdog */
writel(1, wdt->base + TWD_WDOG_INTSTAT);
return IRQ_HANDLED;
@@ -123,7 +122,7 @@ static int mpcore_wdt_start(struct watchdog_device *wdd)
{
struct mpcore_wdt *wdt = watchdog_get_drvdata(wdd);
- dev_printk(KERN_INFO, wdt->dev, "enabling watchdog.\n");
+ dev_info(wdt->dev, "enabling watchdog.\n");
/* This loads the count register but does NOT start the count yet */
mpcore_wdt_ping(wdd);
@@ -192,7 +191,7 @@ static int __devinit mpcore_wdt_probe(struct platform_device *pdev)
ret = devm_request_irq(wdt->dev, wdt->irq, mpcore_wdt_fire, 0,
"mpcore_wdt", wdt);
if (ret) {
- dev_printk(KERN_ERR, wdt->dev,
+ dev_err(wdt->dev,
"cannot register IRQ%d for watchdog\n",
wdt->irq);
return ret;
--
1.7.8.110.g4cb5d
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH V2 11/22] watchdog/mpcore_wdt: convert to use module_platform_driver()
2012-03-12 4:21 ` Viresh Kumar
@ 2012-03-12 4:22 ` Viresh Kumar
-1 siblings, 0 replies; 56+ messages in thread
From: Viresh Kumar @ 2012-03-12 4:22 UTC (permalink / raw)
To: wim
Cc: linux-watchdog, spear-devel, viresh.linux, linux-arm-kernel,
srinidhi.kasagar, linus.walleij, alan, w.sang, sshtylyov,
Viresh Kumar
This patch converts the mpcore_wdt driver to use the module_platform_driver()
macro which makes the code smaller and a bit simpler.
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
drivers/watchdog/mpcore_wdt.c | 13 +------------
1 files changed, 1 insertions(+), 12 deletions(-)
diff --git a/drivers/watchdog/mpcore_wdt.c b/drivers/watchdog/mpcore_wdt.c
index c820e4f..6902580 100644
--- a/drivers/watchdog/mpcore_wdt.c
+++ b/drivers/watchdog/mpcore_wdt.c
@@ -293,18 +293,7 @@ static struct platform_driver mpcore_wdt_driver = {
},
};
-static int __init mpcore_wdt_init(void)
-{
- return platform_driver_register(&mpcore_wdt_driver);
-}
-
-static void __exit mpcore_wdt_exit(void)
-{
- platform_driver_unregister(&mpcore_wdt_driver);
-}
-
-module_init(mpcore_wdt_init);
-module_exit(mpcore_wdt_exit);
+module_platform_driver(mpcore_wdt_driver);
MODULE_AUTHOR("ARM Limited");
MODULE_DESCRIPTION("MPcore Watchdog Device Driver");
--
1.7.8.110.g4cb5d
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH V2 11/22] watchdog/mpcore_wdt: convert to use module_platform_driver()
@ 2012-03-12 4:22 ` Viresh Kumar
0 siblings, 0 replies; 56+ messages in thread
From: Viresh Kumar @ 2012-03-12 4:22 UTC (permalink / raw)
To: linux-arm-kernel
This patch converts the mpcore_wdt driver to use the module_platform_driver()
macro which makes the code smaller and a bit simpler.
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
drivers/watchdog/mpcore_wdt.c | 13 +------------
1 files changed, 1 insertions(+), 12 deletions(-)
diff --git a/drivers/watchdog/mpcore_wdt.c b/drivers/watchdog/mpcore_wdt.c
index c820e4f..6902580 100644
--- a/drivers/watchdog/mpcore_wdt.c
+++ b/drivers/watchdog/mpcore_wdt.c
@@ -293,18 +293,7 @@ static struct platform_driver mpcore_wdt_driver = {
},
};
-static int __init mpcore_wdt_init(void)
-{
- return platform_driver_register(&mpcore_wdt_driver);
-}
-
-static void __exit mpcore_wdt_exit(void)
-{
- platform_driver_unregister(&mpcore_wdt_driver);
-}
-
-module_init(mpcore_wdt_init);
-module_exit(mpcore_wdt_exit);
+module_platform_driver(mpcore_wdt_driver);
MODULE_AUTHOR("ARM Limited");
MODULE_DESCRIPTION("MPcore Watchdog Device Driver");
--
1.7.8.110.g4cb5d
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH V2 12/22] watchdog/mpcore_wdt: Add support for dev_pm_ops interface
2012-03-12 4:21 ` Viresh Kumar
@ 2012-03-12 4:22 ` Viresh Kumar
-1 siblings, 0 replies; 56+ messages in thread
From: Viresh Kumar @ 2012-03-12 4:22 UTC (permalink / raw)
To: wim
Cc: linux-watchdog, spear-devel, viresh.linux, linux-arm-kernel,
srinidhi.kasagar, linus.walleij, alan, w.sang, sshtylyov,
Viresh Kumar
This patch adds dev_pm_ops support for standby/slepp/hibernate.
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
drivers/watchdog/mpcore_wdt.c | 18 +++++++++---------
1 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/drivers/watchdog/mpcore_wdt.c b/drivers/watchdog/mpcore_wdt.c
index 6902580..3f47b7e 100644
--- a/drivers/watchdog/mpcore_wdt.c
+++ b/drivers/watchdog/mpcore_wdt.c
@@ -23,6 +23,7 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/platform_device.h>
+#include <linux/pm.h>
#include <linux/reboot.h>
#include <linux/slab.h>
#include <linux/types.h>
@@ -256,40 +257,39 @@ static int __devexit mpcore_wdt_remove(struct platform_device *pdev)
}
#ifdef CONFIG_PM
-static int mpcore_wdt_suspend(struct platform_device *pdev, pm_message_t msg)
+static int mpcore_wdt_suspend(struct device *dev)
{
- struct mpcore_wdt *wdt = platform_get_drvdata(pdev);
+ struct mpcore_wdt *wdt = dev_get_drvdata(dev);
mpcore_wdt_stop(&wdt->wdd); /* Turn the WDT off */
return 0;
}
-static int mpcore_wdt_resume(struct platform_device *pdev)
+static int mpcore_wdt_resume(struct device *dev)
{
- struct mpcore_wdt *wdt = platform_get_drvdata(pdev);
+ struct mpcore_wdt *wdt = dev_get_drvdata(dev);
if (is_wdd_active(&wdt->wdd))
mpcore_wdt_start(&wdt->wdd);
return 0;
}
-#else
-#define mpcore_wdt_suspend NULL
-#define mpcore_wdt_resume NULL
#endif
+static SIMPLE_DEV_PM_OPS(mpcore_wdt_dev_pm_ops, mpcore_wdt_suspend,
+ mpcore_wdt_resume);
+
/* work with hotplug and coldplug */
MODULE_ALIAS("platform:mpcore_wdt");
static struct platform_driver mpcore_wdt_driver = {
.probe = mpcore_wdt_probe,
.remove = __devexit_p(mpcore_wdt_remove),
- .suspend = mpcore_wdt_suspend,
- .resume = mpcore_wdt_resume,
.shutdown = mpcore_wdt_shutdown,
.driver = {
.owner = THIS_MODULE,
.name = "mpcore_wdt",
+ .pm = &mpcore_wdt_dev_pm_ops,
},
};
--
1.7.8.110.g4cb5d
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH V2 12/22] watchdog/mpcore_wdt: Add support for dev_pm_ops interface
@ 2012-03-12 4:22 ` Viresh Kumar
0 siblings, 0 replies; 56+ messages in thread
From: Viresh Kumar @ 2012-03-12 4:22 UTC (permalink / raw)
To: linux-arm-kernel
This patch adds dev_pm_ops support for standby/slepp/hibernate.
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
drivers/watchdog/mpcore_wdt.c | 18 +++++++++---------
1 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/drivers/watchdog/mpcore_wdt.c b/drivers/watchdog/mpcore_wdt.c
index 6902580..3f47b7e 100644
--- a/drivers/watchdog/mpcore_wdt.c
+++ b/drivers/watchdog/mpcore_wdt.c
@@ -23,6 +23,7 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/platform_device.h>
+#include <linux/pm.h>
#include <linux/reboot.h>
#include <linux/slab.h>
#include <linux/types.h>
@@ -256,40 +257,39 @@ static int __devexit mpcore_wdt_remove(struct platform_device *pdev)
}
#ifdef CONFIG_PM
-static int mpcore_wdt_suspend(struct platform_device *pdev, pm_message_t msg)
+static int mpcore_wdt_suspend(struct device *dev)
{
- struct mpcore_wdt *wdt = platform_get_drvdata(pdev);
+ struct mpcore_wdt *wdt = dev_get_drvdata(dev);
mpcore_wdt_stop(&wdt->wdd); /* Turn the WDT off */
return 0;
}
-static int mpcore_wdt_resume(struct platform_device *pdev)
+static int mpcore_wdt_resume(struct device *dev)
{
- struct mpcore_wdt *wdt = platform_get_drvdata(pdev);
+ struct mpcore_wdt *wdt = dev_get_drvdata(dev);
if (is_wdd_active(&wdt->wdd))
mpcore_wdt_start(&wdt->wdd);
return 0;
}
-#else
-#define mpcore_wdt_suspend NULL
-#define mpcore_wdt_resume NULL
#endif
+static SIMPLE_DEV_PM_OPS(mpcore_wdt_dev_pm_ops, mpcore_wdt_suspend,
+ mpcore_wdt_resume);
+
/* work with hotplug and coldplug */
MODULE_ALIAS("platform:mpcore_wdt");
static struct platform_driver mpcore_wdt_driver = {
.probe = mpcore_wdt_probe,
.remove = __devexit_p(mpcore_wdt_remove),
- .suspend = mpcore_wdt_suspend,
- .resume = mpcore_wdt_resume,
.shutdown = mpcore_wdt_shutdown,
.driver = {
.owner = THIS_MODULE,
.name = "mpcore_wdt",
+ .pm = &mpcore_wdt_dev_pm_ops,
},
};
--
1.7.8.110.g4cb5d
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH V2 13/22] watchdog/mpcore_wdt: disable wdt in suspend only if it is busy
2012-03-12 4:21 ` Viresh Kumar
@ 2012-03-12 4:22 ` Viresh Kumar
-1 siblings, 0 replies; 56+ messages in thread
From: Viresh Kumar @ 2012-03-12 4:22 UTC (permalink / raw)
To: wim
Cc: linux-watchdog, spear-devel, viresh.linux, linux-arm-kernel,
srinidhi.kasagar, linus.walleij, alan, w.sang, sshtylyov,
Viresh Kumar
We don't need to call mpcore_wdt_stop() in suspend, if wdt is not BUSY. So, call
mpcore_wdt_stop() conditionally in suspend.
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
drivers/watchdog/mpcore_wdt.c | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/drivers/watchdog/mpcore_wdt.c b/drivers/watchdog/mpcore_wdt.c
index 3f47b7e..7ded2a0 100644
--- a/drivers/watchdog/mpcore_wdt.c
+++ b/drivers/watchdog/mpcore_wdt.c
@@ -260,7 +260,9 @@ static int __devexit mpcore_wdt_remove(struct platform_device *pdev)
static int mpcore_wdt_suspend(struct device *dev)
{
struct mpcore_wdt *wdt = dev_get_drvdata(dev);
- mpcore_wdt_stop(&wdt->wdd); /* Turn the WDT off */
+
+ if (is_wdd_active(&wdt->wdd))
+ mpcore_wdt_stop(&wdt->wdd); /* Turn the WDT off */
return 0;
}
--
1.7.8.110.g4cb5d
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH V2 13/22] watchdog/mpcore_wdt: disable wdt in suspend only if it is busy
@ 2012-03-12 4:22 ` Viresh Kumar
0 siblings, 0 replies; 56+ messages in thread
From: Viresh Kumar @ 2012-03-12 4:22 UTC (permalink / raw)
To: linux-arm-kernel
We don't need to call mpcore_wdt_stop() in suspend, if wdt is not BUSY. So, call
mpcore_wdt_stop() conditionally in suspend.
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
drivers/watchdog/mpcore_wdt.c | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/drivers/watchdog/mpcore_wdt.c b/drivers/watchdog/mpcore_wdt.c
index 3f47b7e..7ded2a0 100644
--- a/drivers/watchdog/mpcore_wdt.c
+++ b/drivers/watchdog/mpcore_wdt.c
@@ -260,7 +260,9 @@ static int __devexit mpcore_wdt_remove(struct platform_device *pdev)
static int mpcore_wdt_suspend(struct device *dev)
{
struct mpcore_wdt *wdt = dev_get_drvdata(dev);
- mpcore_wdt_stop(&wdt->wdd); /* Turn the WDT off */
+
+ if (is_wdd_active(&wdt->wdd))
+ mpcore_wdt_stop(&wdt->wdd); /* Turn the WDT off */
return 0;
}
--
1.7.8.110.g4cb5d
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH V2 14/22] watchdog/mpcore_wdt: replace (__raw_)readl/writel with lighter *_relaxed variants
2012-03-12 4:21 ` Viresh Kumar
@ 2012-03-12 4:22 ` Viresh Kumar
-1 siblings, 0 replies; 56+ messages in thread
From: Viresh Kumar @ 2012-03-12 4:22 UTC (permalink / raw)
To: wim
Cc: linux-watchdog, spear-devel, viresh.linux, linux-arm-kernel,
srinidhi.kasagar, linus.walleij, alan, w.sang, sshtylyov,
Viresh Kumar
readl/writel versions for ARMV6+ contain memory barrier instruction for
synchronizing DMA buffers. These are not required at least on this module. So
use lighter _relaxed variants.
Also, __raw_* variants don't have take care about endianess, so replace them too
with _relaxed variants.
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
drivers/watchdog/mpcore_wdt.c | 18 +++++++++---------
1 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/drivers/watchdog/mpcore_wdt.c b/drivers/watchdog/mpcore_wdt.c
index 7ded2a0..0d2ea32 100644
--- a/drivers/watchdog/mpcore_wdt.c
+++ b/drivers/watchdog/mpcore_wdt.c
@@ -71,10 +71,10 @@ static irqreturn_t mpcore_wdt_fire(int irq, void *arg)
struct mpcore_wdt *wdt = arg;
/* Check it really was our interrupt */
- if (readl(wdt->base + TWD_WDOG_INTSTAT)) {
+ if (readl_relaxed(wdt->base + TWD_WDOG_INTSTAT)) {
dev_crit(wdt->dev, "Triggered - Reboot ignored.\n");
/* Clear the interrupt on the watchdog */
- writel(1, wdt->base + TWD_WDOG_INTSTAT);
+ writel_relaxed(1, wdt->base + TWD_WDOG_INTSTAT);
return IRQ_HANDLED;
}
return IRQ_NONE;
@@ -94,12 +94,12 @@ static int mpcore_wdt_ping(struct watchdog_device *wdd)
spin_lock(&wdt->lock);
/* Assume prescale is set to 256 */
- count = __raw_readl(wdt->base + TWD_WDOG_COUNTER);
+ count = readl_relaxed(wdt->base + TWD_WDOG_COUNTER);
count = (0xFFFFFFFFU - count) * (HZ / 5);
count = (count / 256) * mpcore_margin;
/* Reload the counter */
- writel(count + wdt->perturb, wdt->base + TWD_WDOG_LOAD);
+ writel_relaxed(count + wdt->perturb, wdt->base + TWD_WDOG_LOAD);
wdt->perturb = wdt->perturb ? 0 : 1;
spin_unlock(&wdt->lock);
@@ -111,9 +111,9 @@ static int mpcore_wdt_stop(struct watchdog_device *wdd)
struct mpcore_wdt *wdt = watchdog_get_drvdata(wdd);
spin_lock(&wdt->lock);
- writel(0x12345678, wdt->base + TWD_WDOG_DISABLE);
- writel(0x87654321, wdt->base + TWD_WDOG_DISABLE);
- writel(0x0, wdt->base + TWD_WDOG_CONTROL);
+ writel_relaxed(0x12345678, wdt->base + TWD_WDOG_DISABLE);
+ writel_relaxed(0x87654321, wdt->base + TWD_WDOG_DISABLE);
+ writel_relaxed(0x0, wdt->base + TWD_WDOG_CONTROL);
spin_unlock(&wdt->lock);
return 0;
@@ -130,10 +130,10 @@ static int mpcore_wdt_start(struct watchdog_device *wdd)
if (mpcore_noboot) {
/* Enable watchdog - prescale=256, watchdog mode=0, enable=1 */
- writel(0x0000FF01, wdt->base + TWD_WDOG_CONTROL);
+ writel_relaxed(0x0000FF01, wdt->base + TWD_WDOG_CONTROL);
} else {
/* Enable watchdog - prescale=256, watchdog mode=1, enable=1 */
- writel(0x0000FF09, wdt->base + TWD_WDOG_CONTROL);
+ writel_relaxed(0x0000FF09, wdt->base + TWD_WDOG_CONTROL);
}
return 0;
--
1.7.8.110.g4cb5d
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH V2 14/22] watchdog/mpcore_wdt: replace (__raw_)readl/writel with lighter *_relaxed variants
@ 2012-03-12 4:22 ` Viresh Kumar
0 siblings, 0 replies; 56+ messages in thread
From: Viresh Kumar @ 2012-03-12 4:22 UTC (permalink / raw)
To: linux-arm-kernel
readl/writel versions for ARMV6+ contain memory barrier instruction for
synchronizing DMA buffers. These are not required at least on this module. So
use lighter _relaxed variants.
Also, __raw_* variants don't have take care about endianess, so replace them too
with _relaxed variants.
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
drivers/watchdog/mpcore_wdt.c | 18 +++++++++---------
1 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/drivers/watchdog/mpcore_wdt.c b/drivers/watchdog/mpcore_wdt.c
index 7ded2a0..0d2ea32 100644
--- a/drivers/watchdog/mpcore_wdt.c
+++ b/drivers/watchdog/mpcore_wdt.c
@@ -71,10 +71,10 @@ static irqreturn_t mpcore_wdt_fire(int irq, void *arg)
struct mpcore_wdt *wdt = arg;
/* Check it really was our interrupt */
- if (readl(wdt->base + TWD_WDOG_INTSTAT)) {
+ if (readl_relaxed(wdt->base + TWD_WDOG_INTSTAT)) {
dev_crit(wdt->dev, "Triggered - Reboot ignored.\n");
/* Clear the interrupt on the watchdog */
- writel(1, wdt->base + TWD_WDOG_INTSTAT);
+ writel_relaxed(1, wdt->base + TWD_WDOG_INTSTAT);
return IRQ_HANDLED;
}
return IRQ_NONE;
@@ -94,12 +94,12 @@ static int mpcore_wdt_ping(struct watchdog_device *wdd)
spin_lock(&wdt->lock);
/* Assume prescale is set to 256 */
- count = __raw_readl(wdt->base + TWD_WDOG_COUNTER);
+ count = readl_relaxed(wdt->base + TWD_WDOG_COUNTER);
count = (0xFFFFFFFFU - count) * (HZ / 5);
count = (count / 256) * mpcore_margin;
/* Reload the counter */
- writel(count + wdt->perturb, wdt->base + TWD_WDOG_LOAD);
+ writel_relaxed(count + wdt->perturb, wdt->base + TWD_WDOG_LOAD);
wdt->perturb = wdt->perturb ? 0 : 1;
spin_unlock(&wdt->lock);
@@ -111,9 +111,9 @@ static int mpcore_wdt_stop(struct watchdog_device *wdd)
struct mpcore_wdt *wdt = watchdog_get_drvdata(wdd);
spin_lock(&wdt->lock);
- writel(0x12345678, wdt->base + TWD_WDOG_DISABLE);
- writel(0x87654321, wdt->base + TWD_WDOG_DISABLE);
- writel(0x0, wdt->base + TWD_WDOG_CONTROL);
+ writel_relaxed(0x12345678, wdt->base + TWD_WDOG_DISABLE);
+ writel_relaxed(0x87654321, wdt->base + TWD_WDOG_DISABLE);
+ writel_relaxed(0x0, wdt->base + TWD_WDOG_CONTROL);
spin_unlock(&wdt->lock);
return 0;
@@ -130,10 +130,10 @@ static int mpcore_wdt_start(struct watchdog_device *wdd)
if (mpcore_noboot) {
/* Enable watchdog - prescale=256, watchdog mode=0, enable=1 */
- writel(0x0000FF01, wdt->base + TWD_WDOG_CONTROL);
+ writel_relaxed(0x0000FF01, wdt->base + TWD_WDOG_CONTROL);
} else {
/* Enable watchdog - prescale=256, watchdog mode=1, enable=1 */
- writel(0x0000FF09, wdt->base + TWD_WDOG_CONTROL);
+ writel_relaxed(0x0000FF09, wdt->base + TWD_WDOG_CONTROL);
}
return 0;
--
1.7.8.110.g4cb5d
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH V2 15/22] watchdog/mpcore_wdt: Add support for WDIOC_GETBOOTSTATUS IOCTL
2012-03-12 4:21 ` Viresh Kumar
@ 2012-03-12 4:22 ` Viresh Kumar
-1 siblings, 0 replies; 56+ messages in thread
From: Viresh Kumar @ 2012-03-12 4:22 UTC (permalink / raw)
To: wim
Cc: linux-watchdog, spear-devel, viresh.linux, linux-arm-kernel,
srinidhi.kasagar, linus.walleij, alan, w.sang, sshtylyov,
Viresh Kumar
mpcore watchdog can give last boot status, whether we got a watchdog reset or
not, via bit 0 of TWD_WDOG_RESETSTAT register. This patch adds support to return
correct status if WDIOC_GETBOOTSTATUS cmd is called with ioctl.
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
arch/arm/include/asm/smp_twd.h | 2 ++
drivers/watchdog/mpcore_wdt.c | 4 ++++
2 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/arch/arm/include/asm/smp_twd.h b/arch/arm/include/asm/smp_twd.h
index ef9ffba9..a13b536 100644
--- a/arch/arm/include/asm/smp_twd.h
+++ b/arch/arm/include/asm/smp_twd.h
@@ -18,6 +18,8 @@
#define TWD_TIMER_CONTROL_PERIODIC (1 << 1)
#define TWD_TIMER_CONTROL_IT_ENABLE (1 << 2)
+#define TWD_WDOG_RESETSTAT_MASK 0x1
+
struct clock_event_device;
extern void __iomem *twd_base;
diff --git a/drivers/watchdog/mpcore_wdt.c b/drivers/watchdog/mpcore_wdt.c
index 0d2ea32..73d50c3 100644
--- a/drivers/watchdog/mpcore_wdt.c
+++ b/drivers/watchdog/mpcore_wdt.c
@@ -148,6 +148,7 @@ static int mpcore_wdt_set_heartbeat(struct watchdog_device *wdd, unsigned int t)
static const struct watchdog_info mpcore_wdt_info = {
.options = WDIOF_SETTIMEOUT |
WDIOF_KEEPALIVEPING |
+ WDIOF_CARDRESET |
WDIOF_MAGICCLOSE,
.identity = "MPcore Watchdog",
};
@@ -213,6 +214,9 @@ static int __devinit mpcore_wdt_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, wdt);
watchdog_set_drvdata(&wdt->wdd, wdt);
+ wdt->wdd.bootstatus = (readl_relaxed(wdt->base + TWD_WDOG_RESETSTAT) &
+ TWD_WDOG_RESETSTAT_MASK) ? WDIOF_CARDRESET : 0;
+
mpcore_wdt_stop(&wdt->wdd);
ret = watchdog_register_device(&wdt->wdd);
--
1.7.8.110.g4cb5d
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH V2 15/22] watchdog/mpcore_wdt: Add support for WDIOC_GETBOOTSTATUS IOCTL
@ 2012-03-12 4:22 ` Viresh Kumar
0 siblings, 0 replies; 56+ messages in thread
From: Viresh Kumar @ 2012-03-12 4:22 UTC (permalink / raw)
To: linux-arm-kernel
mpcore watchdog can give last boot status, whether we got a watchdog reset or
not, via bit 0 of TWD_WDOG_RESETSTAT register. This patch adds support to return
correct status if WDIOC_GETBOOTSTATUS cmd is called with ioctl.
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
arch/arm/include/asm/smp_twd.h | 2 ++
drivers/watchdog/mpcore_wdt.c | 4 ++++
2 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/arch/arm/include/asm/smp_twd.h b/arch/arm/include/asm/smp_twd.h
index ef9ffba9..a13b536 100644
--- a/arch/arm/include/asm/smp_twd.h
+++ b/arch/arm/include/asm/smp_twd.h
@@ -18,6 +18,8 @@
#define TWD_TIMER_CONTROL_PERIODIC (1 << 1)
#define TWD_TIMER_CONTROL_IT_ENABLE (1 << 2)
+#define TWD_WDOG_RESETSTAT_MASK 0x1
+
struct clock_event_device;
extern void __iomem *twd_base;
diff --git a/drivers/watchdog/mpcore_wdt.c b/drivers/watchdog/mpcore_wdt.c
index 0d2ea32..73d50c3 100644
--- a/drivers/watchdog/mpcore_wdt.c
+++ b/drivers/watchdog/mpcore_wdt.c
@@ -148,6 +148,7 @@ static int mpcore_wdt_set_heartbeat(struct watchdog_device *wdd, unsigned int t)
static const struct watchdog_info mpcore_wdt_info = {
.options = WDIOF_SETTIMEOUT |
WDIOF_KEEPALIVEPING |
+ WDIOF_CARDRESET |
WDIOF_MAGICCLOSE,
.identity = "MPcore Watchdog",
};
@@ -213,6 +214,9 @@ static int __devinit mpcore_wdt_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, wdt);
watchdog_set_drvdata(&wdt->wdd, wdt);
+ wdt->wdd.bootstatus = (readl_relaxed(wdt->base + TWD_WDOG_RESETSTAT) &
+ TWD_WDOG_RESETSTAT_MASK) ? WDIOF_CARDRESET : 0;
+
mpcore_wdt_stop(&wdt->wdd);
ret = watchdog_register_device(&wdt->wdd);
--
1.7.8.110.g4cb5d
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH V2 16/22] watchdog/mpcore_wdt: Add clock framework support
2012-03-12 4:21 ` Viresh Kumar
@ 2012-03-12 4:22 ` Viresh Kumar
-1 siblings, 0 replies; 56+ messages in thread
From: Viresh Kumar @ 2012-03-12 4:22 UTC (permalink / raw)
To: wim
Cc: linux-watchdog, spear-devel, viresh.linux, linux-arm-kernel,
srinidhi.kasagar, linus.walleij, alan, w.sang, sshtylyov,
Viresh Kumar
This patch adds in clk framework support for wdt driver. If clk_get fails for
some platform, then we continue without clk_* API's.
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
drivers/watchdog/mpcore_wdt.c | 66 ++++++++++++++++++++++++++++++++++++-----
1 files changed, 58 insertions(+), 8 deletions(-)
diff --git a/drivers/watchdog/mpcore_wdt.c b/drivers/watchdog/mpcore_wdt.c
index 73d50c3..23c324c 100644
--- a/drivers/watchdog/mpcore_wdt.c
+++ b/drivers/watchdog/mpcore_wdt.c
@@ -17,6 +17,8 @@
*
* (c) Copyright 1995 Alan Cox <alan@lxorguk.ukuu.org.uk>
*/
+#include <linux/clk.h>
+#include <linux/err.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
@@ -36,6 +38,7 @@ struct mpcore_wdt {
struct device *dev;
void __iomem *base;
spinlock_t lock;
+ struct clk *clk;
int irq;
unsigned int perturb;
};
@@ -106,15 +109,25 @@ static int mpcore_wdt_ping(struct watchdog_device *wdd)
return 0;
}
-static int mpcore_wdt_stop(struct watchdog_device *wdd)
+static void __mpcore_wdt_stop(struct mpcore_wdt *wdt)
{
- struct mpcore_wdt *wdt = watchdog_get_drvdata(wdd);
-
spin_lock(&wdt->lock);
writel_relaxed(0x12345678, wdt->base + TWD_WDOG_DISABLE);
writel_relaxed(0x87654321, wdt->base + TWD_WDOG_DISABLE);
writel_relaxed(0x0, wdt->base + TWD_WDOG_CONTROL);
spin_unlock(&wdt->lock);
+}
+
+static int mpcore_wdt_stop(struct watchdog_device *wdd)
+{
+ struct mpcore_wdt *wdt = watchdog_get_drvdata(wdd);
+
+ __mpcore_wdt_stop(wdt);
+
+ if (!IS_ERR(wdt->clk)) {
+ clk_disable(wdt->clk);
+ clk_unprepare(wdt->clk);
+ }
return 0;
}
@@ -122,9 +135,25 @@ static int mpcore_wdt_stop(struct watchdog_device *wdd)
static int mpcore_wdt_start(struct watchdog_device *wdd)
{
struct mpcore_wdt *wdt = watchdog_get_drvdata(wdd);
+ int ret;
dev_info(wdt->dev, "enabling watchdog.\n");
+ if (!IS_ERR(wdt->clk)) {
+ ret = clk_prepare(wdt->clk);
+ if (ret) {
+ dev_err(wdt->dev, "clock prepare fail");
+ return ret;
+ }
+
+ ret = clk_enable(wdt->clk);
+ if (ret) {
+ dev_err(wdt->dev, "Clock enable failed\n");
+ clk_unprepare(wdt->clk);
+ return ret;
+ }
+ }
+
/* This loads the count register but does NOT start the count yet */
mpcore_wdt_ping(wdd);
@@ -170,7 +199,7 @@ static void mpcore_wdt_shutdown(struct platform_device *pdev)
struct mpcore_wdt *wdt = platform_get_drvdata(pdev);
if (system_state == SYSTEM_RESTART || system_state == SYSTEM_HALT)
- mpcore_wdt_stop(&wdt->wdd);
+ __mpcore_wdt_stop(wdt);
}
static int __devinit mpcore_wdt_probe(struct platform_device *pdev)
@@ -214,6 +243,24 @@ static int __devinit mpcore_wdt_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, wdt);
watchdog_set_drvdata(&wdt->wdd, wdt);
+ wdt->clk = clk_get(&pdev->dev, NULL);
+ if (IS_ERR(wdt->clk)) {
+ dev_warn(&pdev->dev, "Clock not found\n");
+ } else {
+ ret = clk_prepare(wdt->clk);
+ if (ret) {
+ dev_err(wdt->dev, "clock prepare fail");
+ goto err_put_clk;
+ }
+
+ ret = clk_enable(wdt->clk);
+ if (ret) {
+ dev_err(&pdev->dev, "Clock enable failed\n");
+ clk_unprepare(wdt->clk);
+ goto err_put_clk;
+ }
+ }
+
wdt->wdd.bootstatus = (readl_relaxed(wdt->base + TWD_WDOG_RESETSTAT) &
TWD_WDOG_RESETSTAT_MASK) ? WDIOF_CARDRESET : 0;
@@ -223,7 +270,7 @@ static int __devinit mpcore_wdt_probe(struct platform_device *pdev)
if (ret) {
dev_err(wdt->dev, "watchdog_register_device() failed: %d\n",
ret);
- goto err_register;
+ goto err_put_clk;
}
/*
@@ -243,7 +290,10 @@ static int __devinit mpcore_wdt_probe(struct platform_device *pdev)
return 0;
-err_register:
+err_put_clk:
+ if (!IS_ERR(wdt->clk))
+ clk_put(wdt->clk);
+
platform_set_drvdata(pdev, NULL);
watchdog_set_drvdata(&wdt->wdd, NULL);
@@ -266,7 +316,7 @@ static int mpcore_wdt_suspend(struct device *dev)
struct mpcore_wdt *wdt = dev_get_drvdata(dev);
if (is_wdd_active(&wdt->wdd))
- mpcore_wdt_stop(&wdt->wdd); /* Turn the WDT off */
+ return mpcore_wdt_stop(&wdt->wdd); /* Turn the WDT off */
return 0;
}
@@ -276,7 +326,7 @@ static int mpcore_wdt_resume(struct device *dev)
struct mpcore_wdt *wdt = dev_get_drvdata(dev);
if (is_wdd_active(&wdt->wdd))
- mpcore_wdt_start(&wdt->wdd);
+ return mpcore_wdt_start(&wdt->wdd);
return 0;
}
--
1.7.8.110.g4cb5d
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH V2 16/22] watchdog/mpcore_wdt: Add clock framework support
@ 2012-03-12 4:22 ` Viresh Kumar
0 siblings, 0 replies; 56+ messages in thread
From: Viresh Kumar @ 2012-03-12 4:22 UTC (permalink / raw)
To: linux-arm-kernel
This patch adds in clk framework support for wdt driver. If clk_get fails for
some platform, then we continue without clk_* API's.
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
drivers/watchdog/mpcore_wdt.c | 66 ++++++++++++++++++++++++++++++++++++-----
1 files changed, 58 insertions(+), 8 deletions(-)
diff --git a/drivers/watchdog/mpcore_wdt.c b/drivers/watchdog/mpcore_wdt.c
index 73d50c3..23c324c 100644
--- a/drivers/watchdog/mpcore_wdt.c
+++ b/drivers/watchdog/mpcore_wdt.c
@@ -17,6 +17,8 @@
*
* (c) Copyright 1995 Alan Cox <alan@lxorguk.ukuu.org.uk>
*/
+#include <linux/clk.h>
+#include <linux/err.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
@@ -36,6 +38,7 @@ struct mpcore_wdt {
struct device *dev;
void __iomem *base;
spinlock_t lock;
+ struct clk *clk;
int irq;
unsigned int perturb;
};
@@ -106,15 +109,25 @@ static int mpcore_wdt_ping(struct watchdog_device *wdd)
return 0;
}
-static int mpcore_wdt_stop(struct watchdog_device *wdd)
+static void __mpcore_wdt_stop(struct mpcore_wdt *wdt)
{
- struct mpcore_wdt *wdt = watchdog_get_drvdata(wdd);
-
spin_lock(&wdt->lock);
writel_relaxed(0x12345678, wdt->base + TWD_WDOG_DISABLE);
writel_relaxed(0x87654321, wdt->base + TWD_WDOG_DISABLE);
writel_relaxed(0x0, wdt->base + TWD_WDOG_CONTROL);
spin_unlock(&wdt->lock);
+}
+
+static int mpcore_wdt_stop(struct watchdog_device *wdd)
+{
+ struct mpcore_wdt *wdt = watchdog_get_drvdata(wdd);
+
+ __mpcore_wdt_stop(wdt);
+
+ if (!IS_ERR(wdt->clk)) {
+ clk_disable(wdt->clk);
+ clk_unprepare(wdt->clk);
+ }
return 0;
}
@@ -122,9 +135,25 @@ static int mpcore_wdt_stop(struct watchdog_device *wdd)
static int mpcore_wdt_start(struct watchdog_device *wdd)
{
struct mpcore_wdt *wdt = watchdog_get_drvdata(wdd);
+ int ret;
dev_info(wdt->dev, "enabling watchdog.\n");
+ if (!IS_ERR(wdt->clk)) {
+ ret = clk_prepare(wdt->clk);
+ if (ret) {
+ dev_err(wdt->dev, "clock prepare fail");
+ return ret;
+ }
+
+ ret = clk_enable(wdt->clk);
+ if (ret) {
+ dev_err(wdt->dev, "Clock enable failed\n");
+ clk_unprepare(wdt->clk);
+ return ret;
+ }
+ }
+
/* This loads the count register but does NOT start the count yet */
mpcore_wdt_ping(wdd);
@@ -170,7 +199,7 @@ static void mpcore_wdt_shutdown(struct platform_device *pdev)
struct mpcore_wdt *wdt = platform_get_drvdata(pdev);
if (system_state == SYSTEM_RESTART || system_state == SYSTEM_HALT)
- mpcore_wdt_stop(&wdt->wdd);
+ __mpcore_wdt_stop(wdt);
}
static int __devinit mpcore_wdt_probe(struct platform_device *pdev)
@@ -214,6 +243,24 @@ static int __devinit mpcore_wdt_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, wdt);
watchdog_set_drvdata(&wdt->wdd, wdt);
+ wdt->clk = clk_get(&pdev->dev, NULL);
+ if (IS_ERR(wdt->clk)) {
+ dev_warn(&pdev->dev, "Clock not found\n");
+ } else {
+ ret = clk_prepare(wdt->clk);
+ if (ret) {
+ dev_err(wdt->dev, "clock prepare fail");
+ goto err_put_clk;
+ }
+
+ ret = clk_enable(wdt->clk);
+ if (ret) {
+ dev_err(&pdev->dev, "Clock enable failed\n");
+ clk_unprepare(wdt->clk);
+ goto err_put_clk;
+ }
+ }
+
wdt->wdd.bootstatus = (readl_relaxed(wdt->base + TWD_WDOG_RESETSTAT) &
TWD_WDOG_RESETSTAT_MASK) ? WDIOF_CARDRESET : 0;
@@ -223,7 +270,7 @@ static int __devinit mpcore_wdt_probe(struct platform_device *pdev)
if (ret) {
dev_err(wdt->dev, "watchdog_register_device() failed: %d\n",
ret);
- goto err_register;
+ goto err_put_clk;
}
/*
@@ -243,7 +290,10 @@ static int __devinit mpcore_wdt_probe(struct platform_device *pdev)
return 0;
-err_register:
+err_put_clk:
+ if (!IS_ERR(wdt->clk))
+ clk_put(wdt->clk);
+
platform_set_drvdata(pdev, NULL);
watchdog_set_drvdata(&wdt->wdd, NULL);
@@ -266,7 +316,7 @@ static int mpcore_wdt_suspend(struct device *dev)
struct mpcore_wdt *wdt = dev_get_drvdata(dev);
if (is_wdd_active(&wdt->wdd))
- mpcore_wdt_stop(&wdt->wdd); /* Turn the WDT off */
+ return mpcore_wdt_stop(&wdt->wdd); /* Turn the WDT off */
return 0;
}
@@ -276,7 +326,7 @@ static int mpcore_wdt_resume(struct device *dev)
struct mpcore_wdt *wdt = dev_get_drvdata(dev);
if (is_wdd_active(&wdt->wdd))
- mpcore_wdt_start(&wdt->wdd);
+ return mpcore_wdt_start(&wdt->wdd);
return 0;
}
--
1.7.8.110.g4cb5d
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH V2 17/22] watchdog/mpcore_wdt: use correct clk_rate to program timeout
2012-03-12 4:21 ` Viresh Kumar
@ 2012-03-12 4:22 ` Viresh Kumar
-1 siblings, 0 replies; 56+ messages in thread
From: Viresh Kumar @ 2012-03-12 4:22 UTC (permalink / raw)
To: wim
Cc: linux-watchdog, spear-devel, viresh.linux, linux-arm-kernel,
srinidhi.kasagar, linus.walleij, alan, w.sang, sshtylyov,
Viresh Kumar
Currently, mpcore wdt driver doesn't use exact clk_rate to program timeout in
hardware. This patch provides two ways of doing so:
- either use clk_get_rate() if clk_get passes
- use clk_rate passed via module param
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
arch/arm/include/asm/smp_twd.h | 10 ++++
drivers/watchdog/mpcore_wdt.c | 97 ++++++++++++++++++++++++++++++++-------
2 files changed, 89 insertions(+), 18 deletions(-)
diff --git a/arch/arm/include/asm/smp_twd.h b/arch/arm/include/asm/smp_twd.h
index a13b536..389ca02 100644
--- a/arch/arm/include/asm/smp_twd.h
+++ b/arch/arm/include/asm/smp_twd.h
@@ -13,11 +13,21 @@
#define TWD_WDOG_RESETSTAT 0x30
#define TWD_WDOG_DISABLE 0x34
+#define TWD_WDOG_LOAD_MIN 0x00000000
+#define TWD_WDOG_LOAD_MAX 0xFFFFFFFF
+
#define TWD_TIMER_CONTROL_ENABLE (1 << 0)
#define TWD_TIMER_CONTROL_ONESHOT (0 << 1)
#define TWD_TIMER_CONTROL_PERIODIC (1 << 1)
#define TWD_TIMER_CONTROL_IT_ENABLE (1 << 2)
+#define TWD_WDOG_CONTROL_ENABLE (1 << 0)
+#define TWD_WDOG_CONTROL_IRQ_ENABLE (1 << 2)
+#define TWD_WDOG_CONTROL_WDT_MODE (1 << 3)
+#define TWD_WDOG_CONTROL_WDT_PRESCALE(x) ((x) << 8)
+#define TWD_WDOG_CONTROL_PRESCALE_MIN 0x00
+#define TWD_WDOG_CONTROL_PRESCALE_MAX 0xFF
+
#define TWD_WDOG_RESETSTAT_MASK 0x1
struct clock_event_device;
diff --git a/drivers/watchdog/mpcore_wdt.c b/drivers/watchdog/mpcore_wdt.c
index 23c324c..de46b5d 100644
--- a/drivers/watchdog/mpcore_wdt.c
+++ b/drivers/watchdog/mpcore_wdt.c
@@ -39,7 +39,10 @@ struct mpcore_wdt {
void __iomem *base;
spinlock_t lock;
struct clk *clk;
+ unsigned long clk_rate; /* In Hz */
int irq;
+ unsigned int prescale;
+ unsigned int load_val;
unsigned int perturb;
};
@@ -58,6 +61,11 @@ MODULE_PARM_DESC(nowayout,
"Watchdog cannot be stopped once started (default="
__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
+static int clk_rate;
+module_param(clk_rate, int, 0);
+MODULE_PARM_DESC(clk_rate,
+ "Watchdog clock rate in Hz, required if clk_get() fails");
+
#define ONLY_TESTING 0
static int mpcore_noboot = ONLY_TESTING;
module_param(mpcore_noboot, int, 0);
@@ -93,17 +101,10 @@ static irqreturn_t mpcore_wdt_fire(int irq, void *arg)
static int mpcore_wdt_ping(struct watchdog_device *wdd)
{
struct mpcore_wdt *wdt = watchdog_get_drvdata(wdd);
- unsigned long count;
spin_lock(&wdt->lock);
- /* Assume prescale is set to 256 */
- count = readl_relaxed(wdt->base + TWD_WDOG_COUNTER);
- count = (0xFFFFFFFFU - count) * (HZ / 5);
- count = (count / 256) * mpcore_margin;
-
- /* Reload the counter */
- writel_relaxed(count + wdt->perturb, wdt->base + TWD_WDOG_LOAD);
- wdt->perturb = wdt->perturb ? 0 : 1;
+ writel_relaxed(wdt->load_val + wdt->perturb, wdt->base + TWD_WDOG_LOAD);
+ wdt->perturb = !wdt->perturb;
spin_unlock(&wdt->lock);
return 0;
@@ -135,6 +136,7 @@ static int mpcore_wdt_stop(struct watchdog_device *wdd)
static int mpcore_wdt_start(struct watchdog_device *wdd)
{
struct mpcore_wdt *wdt = watchdog_get_drvdata(wdd);
+ u32 val, mode;
int ret;
dev_info(wdt->dev, "enabling watchdog.\n");
@@ -157,20 +159,70 @@ static int mpcore_wdt_start(struct watchdog_device *wdd)
/* This loads the count register but does NOT start the count yet */
mpcore_wdt_ping(wdd);
- if (mpcore_noboot) {
- /* Enable watchdog - prescale=256, watchdog mode=0, enable=1 */
- writel_relaxed(0x0000FF01, wdt->base + TWD_WDOG_CONTROL);
- } else {
- /* Enable watchdog - prescale=256, watchdog mode=1, enable=1 */
- writel_relaxed(0x0000FF09, wdt->base + TWD_WDOG_CONTROL);
- }
+ if (mpcore_noboot)
+ mode = 0;
+ else
+ mode = TWD_WDOG_CONTROL_WDT_MODE;
+
+ spin_lock(&wdt->lock);
+
+ val = TWD_WDOG_CONTROL_WDT_PRESCALE(wdt->prescale) |
+ TWD_WDOG_CONTROL_ENABLE | mode;
+ writel_relaxed(val, wdt->base + TWD_WDOG_CONTROL);
+
+ spin_unlock(&wdt->lock);
return 0;
}
-static int mpcore_wdt_set_heartbeat(struct watchdog_device *wdd, unsigned int t)
+/* binary search */
+static inline void bsearch(u32 *var, u32 var_start, u32 var_end,
+ const u64 param, const u32 timeout, u32 rate)
+{
+ u64 tmp = 0;
+
+ /* get the lowest var value that can satisfy our requirement */
+ while (var_start < var_end) {
+ tmp = var_start;
+ tmp += var_end;
+ tmp = div_u64(tmp, 2);
+ if (timeout > div_u64((param + 1) * (tmp + 1), rate)) {
+ if (var_start == tmp)
+ break;
+ else
+ var_start = tmp;
+ } else {
+ if (var_end == tmp)
+ break;
+ else
+ var_end = tmp;
+ }
+ }
+ *var = tmp;
+}
+
+static int
+mpcore_wdt_set_heartbeat(struct watchdog_device *wdd, unsigned int timeout)
{
- mpcore_margin = t;
+ struct mpcore_wdt *wdt = watchdog_get_drvdata(wdd);
+ unsigned int psc, rate = wdt->clk_rate;
+ u64 load = 0;
+
+ /* get appropriate value of psc and load */
+ bsearch(&psc, TWD_WDOG_CONTROL_PRESCALE_MIN,
+ TWD_WDOG_CONTROL_PRESCALE_MAX, TWD_WDOG_LOAD_MAX,
+ timeout, rate);
+ bsearch((u32 *)&load, TWD_WDOG_LOAD_MIN, TWD_WDOG_LOAD_MAX, psc,
+ timeout, rate);
+
+ spin_lock(&wdt->lock);
+ wdt->prescale = psc;
+ wdt->load_val = load;
+
+ /* roundup timeout to closest positive integer value */
+ mpcore_margin = div_u64((psc + 1) * (load + 1) + (rate / 2), rate);
+ spin_unlock(&wdt->lock);
+
return 0;
}
@@ -246,7 +298,10 @@ static int __devinit mpcore_wdt_probe(struct platform_device *pdev)
wdt->clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(wdt->clk)) {
dev_warn(&pdev->dev, "Clock not found\n");
+ wdt->clk_rate = clk_rate;
} else {
+ wdt->clk_rate = clk_get_rate(wdt->clk);
+
ret = clk_prepare(wdt->clk);
if (ret) {
dev_err(wdt->dev, "clock prepare fail");
@@ -266,6 +321,12 @@ static int __devinit mpcore_wdt_probe(struct platform_device *pdev)
mpcore_wdt_stop(&wdt->wdd);
+ if (!wdt->clk_rate) {
+ dev_err(&pdev->dev, "Clock rate can't be zero\n");
+ ret = -EINVAL;
+ goto err_put_clk;
+ }
+
ret = watchdog_register_device(&wdt->wdd);
if (ret) {
dev_err(wdt->dev, "watchdog_register_device() failed: %d\n",
--
1.7.8.110.g4cb5d
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH V2 17/22] watchdog/mpcore_wdt: use correct clk_rate to program timeout
@ 2012-03-12 4:22 ` Viresh Kumar
0 siblings, 0 replies; 56+ messages in thread
From: Viresh Kumar @ 2012-03-12 4:22 UTC (permalink / raw)
To: linux-arm-kernel
Currently, mpcore wdt driver doesn't use exact clk_rate to program timeout in
hardware. This patch provides two ways of doing so:
- either use clk_get_rate() if clk_get passes
- use clk_rate passed via module param
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
arch/arm/include/asm/smp_twd.h | 10 ++++
drivers/watchdog/mpcore_wdt.c | 97 ++++++++++++++++++++++++++++++++-------
2 files changed, 89 insertions(+), 18 deletions(-)
diff --git a/arch/arm/include/asm/smp_twd.h b/arch/arm/include/asm/smp_twd.h
index a13b536..389ca02 100644
--- a/arch/arm/include/asm/smp_twd.h
+++ b/arch/arm/include/asm/smp_twd.h
@@ -13,11 +13,21 @@
#define TWD_WDOG_RESETSTAT 0x30
#define TWD_WDOG_DISABLE 0x34
+#define TWD_WDOG_LOAD_MIN 0x00000000
+#define TWD_WDOG_LOAD_MAX 0xFFFFFFFF
+
#define TWD_TIMER_CONTROL_ENABLE (1 << 0)
#define TWD_TIMER_CONTROL_ONESHOT (0 << 1)
#define TWD_TIMER_CONTROL_PERIODIC (1 << 1)
#define TWD_TIMER_CONTROL_IT_ENABLE (1 << 2)
+#define TWD_WDOG_CONTROL_ENABLE (1 << 0)
+#define TWD_WDOG_CONTROL_IRQ_ENABLE (1 << 2)
+#define TWD_WDOG_CONTROL_WDT_MODE (1 << 3)
+#define TWD_WDOG_CONTROL_WDT_PRESCALE(x) ((x) << 8)
+#define TWD_WDOG_CONTROL_PRESCALE_MIN 0x00
+#define TWD_WDOG_CONTROL_PRESCALE_MAX 0xFF
+
#define TWD_WDOG_RESETSTAT_MASK 0x1
struct clock_event_device;
diff --git a/drivers/watchdog/mpcore_wdt.c b/drivers/watchdog/mpcore_wdt.c
index 23c324c..de46b5d 100644
--- a/drivers/watchdog/mpcore_wdt.c
+++ b/drivers/watchdog/mpcore_wdt.c
@@ -39,7 +39,10 @@ struct mpcore_wdt {
void __iomem *base;
spinlock_t lock;
struct clk *clk;
+ unsigned long clk_rate; /* In Hz */
int irq;
+ unsigned int prescale;
+ unsigned int load_val;
unsigned int perturb;
};
@@ -58,6 +61,11 @@ MODULE_PARM_DESC(nowayout,
"Watchdog cannot be stopped once started (default="
__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
+static int clk_rate;
+module_param(clk_rate, int, 0);
+MODULE_PARM_DESC(clk_rate,
+ "Watchdog clock rate in Hz, required if clk_get() fails");
+
#define ONLY_TESTING 0
static int mpcore_noboot = ONLY_TESTING;
module_param(mpcore_noboot, int, 0);
@@ -93,17 +101,10 @@ static irqreturn_t mpcore_wdt_fire(int irq, void *arg)
static int mpcore_wdt_ping(struct watchdog_device *wdd)
{
struct mpcore_wdt *wdt = watchdog_get_drvdata(wdd);
- unsigned long count;
spin_lock(&wdt->lock);
- /* Assume prescale is set to 256 */
- count = readl_relaxed(wdt->base + TWD_WDOG_COUNTER);
- count = (0xFFFFFFFFU - count) * (HZ / 5);
- count = (count / 256) * mpcore_margin;
-
- /* Reload the counter */
- writel_relaxed(count + wdt->perturb, wdt->base + TWD_WDOG_LOAD);
- wdt->perturb = wdt->perturb ? 0 : 1;
+ writel_relaxed(wdt->load_val + wdt->perturb, wdt->base + TWD_WDOG_LOAD);
+ wdt->perturb = !wdt->perturb;
spin_unlock(&wdt->lock);
return 0;
@@ -135,6 +136,7 @@ static int mpcore_wdt_stop(struct watchdog_device *wdd)
static int mpcore_wdt_start(struct watchdog_device *wdd)
{
struct mpcore_wdt *wdt = watchdog_get_drvdata(wdd);
+ u32 val, mode;
int ret;
dev_info(wdt->dev, "enabling watchdog.\n");
@@ -157,20 +159,70 @@ static int mpcore_wdt_start(struct watchdog_device *wdd)
/* This loads the count register but does NOT start the count yet */
mpcore_wdt_ping(wdd);
- if (mpcore_noboot) {
- /* Enable watchdog - prescale=256, watchdog mode=0, enable=1 */
- writel_relaxed(0x0000FF01, wdt->base + TWD_WDOG_CONTROL);
- } else {
- /* Enable watchdog - prescale=256, watchdog mode=1, enable=1 */
- writel_relaxed(0x0000FF09, wdt->base + TWD_WDOG_CONTROL);
- }
+ if (mpcore_noboot)
+ mode = 0;
+ else
+ mode = TWD_WDOG_CONTROL_WDT_MODE;
+
+ spin_lock(&wdt->lock);
+
+ val = TWD_WDOG_CONTROL_WDT_PRESCALE(wdt->prescale) |
+ TWD_WDOG_CONTROL_ENABLE | mode;
+ writel_relaxed(val, wdt->base + TWD_WDOG_CONTROL);
+
+ spin_unlock(&wdt->lock);
return 0;
}
-static int mpcore_wdt_set_heartbeat(struct watchdog_device *wdd, unsigned int t)
+/* binary search */
+static inline void bsearch(u32 *var, u32 var_start, u32 var_end,
+ const u64 param, const u32 timeout, u32 rate)
+{
+ u64 tmp = 0;
+
+ /* get the lowest var value that can satisfy our requirement */
+ while (var_start < var_end) {
+ tmp = var_start;
+ tmp += var_end;
+ tmp = div_u64(tmp, 2);
+ if (timeout > div_u64((param + 1) * (tmp + 1), rate)) {
+ if (var_start == tmp)
+ break;
+ else
+ var_start = tmp;
+ } else {
+ if (var_end == tmp)
+ break;
+ else
+ var_end = tmp;
+ }
+ }
+ *var = tmp;
+}
+
+static int
+mpcore_wdt_set_heartbeat(struct watchdog_device *wdd, unsigned int timeout)
{
- mpcore_margin = t;
+ struct mpcore_wdt *wdt = watchdog_get_drvdata(wdd);
+ unsigned int psc, rate = wdt->clk_rate;
+ u64 load = 0;
+
+ /* get appropriate value of psc and load */
+ bsearch(&psc, TWD_WDOG_CONTROL_PRESCALE_MIN,
+ TWD_WDOG_CONTROL_PRESCALE_MAX, TWD_WDOG_LOAD_MAX,
+ timeout, rate);
+ bsearch((u32 *)&load, TWD_WDOG_LOAD_MIN, TWD_WDOG_LOAD_MAX, psc,
+ timeout, rate);
+
+ spin_lock(&wdt->lock);
+ wdt->prescale = psc;
+ wdt->load_val = load;
+
+ /* roundup timeout to closest positive integer value */
+ mpcore_margin = div_u64((psc + 1) * (load + 1) + (rate / 2), rate);
+ spin_unlock(&wdt->lock);
+
return 0;
}
@@ -246,7 +298,10 @@ static int __devinit mpcore_wdt_probe(struct platform_device *pdev)
wdt->clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(wdt->clk)) {
dev_warn(&pdev->dev, "Clock not found\n");
+ wdt->clk_rate = clk_rate;
} else {
+ wdt->clk_rate = clk_get_rate(wdt->clk);
+
ret = clk_prepare(wdt->clk);
if (ret) {
dev_err(wdt->dev, "clock prepare fail");
@@ -266,6 +321,12 @@ static int __devinit mpcore_wdt_probe(struct platform_device *pdev)
mpcore_wdt_stop(&wdt->wdd);
+ if (!wdt->clk_rate) {
+ dev_err(&pdev->dev, "Clock rate can't be zero\n");
+ ret = -EINVAL;
+ goto err_put_clk;
+ }
+
ret = watchdog_register_device(&wdt->wdd);
if (ret) {
dev_err(wdt->dev, "watchdog_register_device() failed: %d\n",
--
1.7.8.110.g4cb5d
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH V2 18/22] watchdog/sp805: Fix documentation style comment
2012-03-12 4:21 ` Viresh Kumar
@ 2012-03-12 4:22 ` Viresh Kumar
-1 siblings, 0 replies; 56+ messages in thread
From: Viresh Kumar @ 2012-03-12 4:22 UTC (permalink / raw)
To: wim
Cc: linux-watchdog, spear-devel, viresh.linux, linux-arm-kernel,
srinidhi.kasagar, linus.walleij, alan, w.sang, sshtylyov,
Viresh Kumar
@ was missing before variables names, in their description. Also adev is
mentioned as dev in comment. Fix both these issues.
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
drivers/watchdog/sp805_wdt.c | 15 +++++++--------
1 files changed, 7 insertions(+), 8 deletions(-)
diff --git a/drivers/watchdog/sp805_wdt.c b/drivers/watchdog/sp805_wdt.c
index e2d5249..7af1386 100644
--- a/drivers/watchdog/sp805_wdt.c
+++ b/drivers/watchdog/sp805_wdt.c
@@ -56,14 +56,13 @@
/**
* struct sp805_wdt: sp805 wdt device structure
- *
- * lock: spin lock protecting dev structure and io access
- * base: base address of wdt
- * clk: clock structure of wdt
- * dev: amba device structure of wdt
- * status: current status of wdt
- * load_val: load value to be set for current timeout
- * timeout: current programmed timeout
+ * @lock: spin lock protecting dev structure and io access
+ * @base: base address of wdt
+ * @clk: clock structure of wdt
+ * @adev: amba device structure of wdt
+ * @status: current status of wdt
+ * @load_val: load value to be set for current timeout
+ * @timeout: current programmed timeout
*/
struct sp805_wdt {
spinlock_t lock;
--
1.7.8.110.g4cb5d
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH V2 18/22] watchdog/sp805: Fix documentation style comment
@ 2012-03-12 4:22 ` Viresh Kumar
0 siblings, 0 replies; 56+ messages in thread
From: Viresh Kumar @ 2012-03-12 4:22 UTC (permalink / raw)
To: linux-arm-kernel
@ was missing before variables names, in their description. Also adev is
mentioned as dev in comment. Fix both these issues.
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
drivers/watchdog/sp805_wdt.c | 15 +++++++--------
1 files changed, 7 insertions(+), 8 deletions(-)
diff --git a/drivers/watchdog/sp805_wdt.c b/drivers/watchdog/sp805_wdt.c
index e2d5249..7af1386 100644
--- a/drivers/watchdog/sp805_wdt.c
+++ b/drivers/watchdog/sp805_wdt.c
@@ -56,14 +56,13 @@
/**
* struct sp805_wdt: sp805 wdt device structure
- *
- * lock: spin lock protecting dev structure and io access
- * base: base address of wdt
- * clk: clock structure of wdt
- * dev: amba device structure of wdt
- * status: current status of wdt
- * load_val: load value to be set for current timeout
- * timeout: current programmed timeout
+ * @lock: spin lock protecting dev structure and io access
+ * @base: base address of wdt
+ * @clk: clock structure of wdt
+ * @adev: amba device structure of wdt
+ * @status: current status of wdt
+ * @load_val: load value to be set for current timeout
+ * @timeout: current programmed timeout
*/
struct sp805_wdt {
spinlock_t lock;
--
1.7.8.110.g4cb5d
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH V2 19/22] watchdog/sp805: replace readl/writel with lighter _relaxed variants
2012-03-12 4:21 ` Viresh Kumar
@ 2012-03-12 4:22 ` Viresh Kumar
-1 siblings, 0 replies; 56+ messages in thread
From: Viresh Kumar @ 2012-03-12 4:22 UTC (permalink / raw)
To: wim
Cc: linux-watchdog, spear-devel, viresh.linux, linux-arm-kernel,
srinidhi.kasagar, linus.walleij, alan, w.sang, sshtylyov,
Viresh Kumar
readl/writel versions for ARM contain memory barrier instruction for
synchronizing DMA buffers. These are not required at least on this
module. So use lighter _relaxed variants.
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
drivers/watchdog/sp805_wdt.c | 24 ++++++++++++------------
1 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/drivers/watchdog/sp805_wdt.c b/drivers/watchdog/sp805_wdt.c
index 7af1386..1291960 100644
--- a/drivers/watchdog/sp805_wdt.c
+++ b/drivers/watchdog/sp805_wdt.c
@@ -113,10 +113,10 @@ static u32 wdt_timeleft(void)
rate = clk_get_rate(wdt->clk);
spin_lock(&wdt->lock);
- load = readl(wdt->base + WDTVALUE);
+ load = readl_relaxed(wdt->base + WDTVALUE);
/*If the interrupt is inactive then time left is WDTValue + WDTLoad. */
- if (!(readl(wdt->base + WDTRIS) & INT_MASK))
+ if (!(readl_relaxed(wdt->base + WDTRIS) & INT_MASK))
load += wdt->load_val + 1;
spin_unlock(&wdt->lock);
@@ -128,14 +128,14 @@ static void wdt_enable(void)
{
spin_lock(&wdt->lock);
- writel(UNLOCK, wdt->base + WDTLOCK);
- writel(wdt->load_val, wdt->base + WDTLOAD);
- writel(INT_MASK, wdt->base + WDTINTCLR);
- writel(INT_ENABLE | RESET_ENABLE, wdt->base + WDTCONTROL);
- writel(LOCK, wdt->base + WDTLOCK);
+ writel_relaxed(UNLOCK, wdt->base + WDTLOCK);
+ writel_relaxed(wdt->load_val, wdt->base + WDTLOAD);
+ writel_relaxed(INT_MASK, wdt->base + WDTINTCLR);
+ writel_relaxed(INT_ENABLE | RESET_ENABLE, wdt->base + WDTCONTROL);
+ writel_relaxed(LOCK, wdt->base + WDTLOCK);
/* Flush posted writes. */
- readl(wdt->base + WDTLOCK);
+ readl_relaxed(wdt->base + WDTLOCK);
spin_unlock(&wdt->lock);
}
@@ -144,12 +144,12 @@ static void wdt_disable(void)
{
spin_lock(&wdt->lock);
- writel(UNLOCK, wdt->base + WDTLOCK);
- writel(0, wdt->base + WDTCONTROL);
- writel(LOCK, wdt->base + WDTLOCK);
+ writel_relaxed(UNLOCK, wdt->base + WDTLOCK);
+ writel_relaxed(0, wdt->base + WDTCONTROL);
+ writel_relaxed(LOCK, wdt->base + WDTLOCK);
/* Flush posted writes. */
- readl(wdt->base + WDTLOCK);
+ readl_relaxed(wdt->base + WDTLOCK);
spin_unlock(&wdt->lock);
}
--
1.7.8.110.g4cb5d
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH V2 19/22] watchdog/sp805: replace readl/writel with lighter _relaxed variants
@ 2012-03-12 4:22 ` Viresh Kumar
0 siblings, 0 replies; 56+ messages in thread
From: Viresh Kumar @ 2012-03-12 4:22 UTC (permalink / raw)
To: linux-arm-kernel
readl/writel versions for ARM contain memory barrier instruction for
synchronizing DMA buffers. These are not required at least on this
module. So use lighter _relaxed variants.
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
drivers/watchdog/sp805_wdt.c | 24 ++++++++++++------------
1 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/drivers/watchdog/sp805_wdt.c b/drivers/watchdog/sp805_wdt.c
index 7af1386..1291960 100644
--- a/drivers/watchdog/sp805_wdt.c
+++ b/drivers/watchdog/sp805_wdt.c
@@ -113,10 +113,10 @@ static u32 wdt_timeleft(void)
rate = clk_get_rate(wdt->clk);
spin_lock(&wdt->lock);
- load = readl(wdt->base + WDTVALUE);
+ load = readl_relaxed(wdt->base + WDTVALUE);
/*If the interrupt is inactive then time left is WDTValue + WDTLoad. */
- if (!(readl(wdt->base + WDTRIS) & INT_MASK))
+ if (!(readl_relaxed(wdt->base + WDTRIS) & INT_MASK))
load += wdt->load_val + 1;
spin_unlock(&wdt->lock);
@@ -128,14 +128,14 @@ static void wdt_enable(void)
{
spin_lock(&wdt->lock);
- writel(UNLOCK, wdt->base + WDTLOCK);
- writel(wdt->load_val, wdt->base + WDTLOAD);
- writel(INT_MASK, wdt->base + WDTINTCLR);
- writel(INT_ENABLE | RESET_ENABLE, wdt->base + WDTCONTROL);
- writel(LOCK, wdt->base + WDTLOCK);
+ writel_relaxed(UNLOCK, wdt->base + WDTLOCK);
+ writel_relaxed(wdt->load_val, wdt->base + WDTLOAD);
+ writel_relaxed(INT_MASK, wdt->base + WDTINTCLR);
+ writel_relaxed(INT_ENABLE | RESET_ENABLE, wdt->base + WDTCONTROL);
+ writel_relaxed(LOCK, wdt->base + WDTLOCK);
/* Flush posted writes. */
- readl(wdt->base + WDTLOCK);
+ readl_relaxed(wdt->base + WDTLOCK);
spin_unlock(&wdt->lock);
}
@@ -144,12 +144,12 @@ static void wdt_disable(void)
{
spin_lock(&wdt->lock);
- writel(UNLOCK, wdt->base + WDTLOCK);
- writel(0, wdt->base + WDTCONTROL);
- writel(LOCK, wdt->base + WDTLOCK);
+ writel_relaxed(UNLOCK, wdt->base + WDTLOCK);
+ writel_relaxed(0, wdt->base + WDTCONTROL);
+ writel_relaxed(LOCK, wdt->base + WDTLOCK);
/* Flush posted writes. */
- readl(wdt->base + WDTLOCK);
+ readl_relaxed(wdt->base + WDTLOCK);
spin_unlock(&wdt->lock);
}
--
1.7.8.110.g4cb5d
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH V2 20/22] watchdog/sp805: Use devm routines
2012-03-12 4:21 ` Viresh Kumar
@ 2012-03-12 4:22 ` Viresh Kumar
-1 siblings, 0 replies; 56+ messages in thread
From: Viresh Kumar @ 2012-03-12 4:22 UTC (permalink / raw)
To: wim
Cc: linux-watchdog, spear-devel, viresh.linux, linux-arm-kernel,
srinidhi.kasagar, linus.walleij, alan, w.sang, sshtylyov,
Viresh Kumar
sp805 driver currently uses normal kzalloc, ioremap, etc routines. This patch
replaces these routines with devm_kzalloc and devm_request_mem_region etc, so
that we don't need to handle freeing of resources for error cases and module
removal routine.
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
drivers/watchdog/sp805_wdt.c | 35 +++++++++++++----------------------
1 files changed, 13 insertions(+), 22 deletions(-)
diff --git a/drivers/watchdog/sp805_wdt.c b/drivers/watchdog/sp805_wdt.c
index 1291960..859d8b0 100644
--- a/drivers/watchdog/sp805_wdt.c
+++ b/drivers/watchdog/sp805_wdt.c
@@ -285,32 +285,33 @@ sp805_wdt_probe(struct amba_device *adev, const struct amba_id *id)
{
int ret = 0;
- if (!request_mem_region(adev->res.start, resource_size(&adev->res),
- "sp805_wdt")) {
+ if (!devm_request_mem_region(&adev->dev, adev->res.start,
+ resource_size(&adev->res), "sp805_wdt")) {
dev_warn(&adev->dev, "Failed to get memory region resource\n");
ret = -ENOENT;
goto err;
}
- wdt = kzalloc(sizeof(*wdt), GFP_KERNEL);
+ wdt = devm_kzalloc(&adev->dev, sizeof(*wdt), GFP_KERNEL);
if (!wdt) {
dev_warn(&adev->dev, "Kzalloc failed\n");
ret = -ENOMEM;
- goto err_kzalloc;
+ goto err;
+ }
+
+ wdt->base = devm_ioremap(&adev->dev, adev->res.start,
+ resource_size(&adev->res));
+ if (!wdt->base) {
+ ret = -ENOMEM;
+ dev_warn(&adev->dev, "ioremap fail\n");
+ goto err;
}
wdt->clk = clk_get(&adev->dev, NULL);
if (IS_ERR(wdt->clk)) {
dev_warn(&adev->dev, "Clock not found\n");
ret = PTR_ERR(wdt->clk);
- goto err_clk_get;
- }
-
- wdt->base = ioremap(adev->res.start, resource_size(&adev->res));
- if (!wdt->base) {
- ret = -ENOMEM;
- dev_warn(&adev->dev, "ioremap fail\n");
- goto err_ioremap;
+ goto err;
}
wdt->adev = adev;
@@ -327,14 +328,7 @@ sp805_wdt_probe(struct amba_device *adev, const struct amba_id *id)
return 0;
err_misc_register:
- iounmap(wdt->base);
-err_ioremap:
clk_put(wdt->clk);
-err_clk_get:
- kfree(wdt);
- wdt = NULL;
-err_kzalloc:
- release_mem_region(adev->res.start, resource_size(&adev->res));
err:
dev_err(&adev->dev, "Probe Failed!!!\n");
return ret;
@@ -343,10 +337,7 @@ err:
static int __devexit sp805_wdt_remove(struct amba_device *adev)
{
misc_deregister(&sp805_wdt_miscdev);
- iounmap(wdt->base);
clk_put(wdt->clk);
- kfree(wdt);
- release_mem_region(adev->res.start, resource_size(&adev->res));
return 0;
}
--
1.7.8.110.g4cb5d
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH V2 20/22] watchdog/sp805: Use devm routines
@ 2012-03-12 4:22 ` Viresh Kumar
0 siblings, 0 replies; 56+ messages in thread
From: Viresh Kumar @ 2012-03-12 4:22 UTC (permalink / raw)
To: linux-arm-kernel
sp805 driver currently uses normal kzalloc, ioremap, etc routines. This patch
replaces these routines with devm_kzalloc and devm_request_mem_region etc, so
that we don't need to handle freeing of resources for error cases and module
removal routine.
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
drivers/watchdog/sp805_wdt.c | 35 +++++++++++++----------------------
1 files changed, 13 insertions(+), 22 deletions(-)
diff --git a/drivers/watchdog/sp805_wdt.c b/drivers/watchdog/sp805_wdt.c
index 1291960..859d8b0 100644
--- a/drivers/watchdog/sp805_wdt.c
+++ b/drivers/watchdog/sp805_wdt.c
@@ -285,32 +285,33 @@ sp805_wdt_probe(struct amba_device *adev, const struct amba_id *id)
{
int ret = 0;
- if (!request_mem_region(adev->res.start, resource_size(&adev->res),
- "sp805_wdt")) {
+ if (!devm_request_mem_region(&adev->dev, adev->res.start,
+ resource_size(&adev->res), "sp805_wdt")) {
dev_warn(&adev->dev, "Failed to get memory region resource\n");
ret = -ENOENT;
goto err;
}
- wdt = kzalloc(sizeof(*wdt), GFP_KERNEL);
+ wdt = devm_kzalloc(&adev->dev, sizeof(*wdt), GFP_KERNEL);
if (!wdt) {
dev_warn(&adev->dev, "Kzalloc failed\n");
ret = -ENOMEM;
- goto err_kzalloc;
+ goto err;
+ }
+
+ wdt->base = devm_ioremap(&adev->dev, adev->res.start,
+ resource_size(&adev->res));
+ if (!wdt->base) {
+ ret = -ENOMEM;
+ dev_warn(&adev->dev, "ioremap fail\n");
+ goto err;
}
wdt->clk = clk_get(&adev->dev, NULL);
if (IS_ERR(wdt->clk)) {
dev_warn(&adev->dev, "Clock not found\n");
ret = PTR_ERR(wdt->clk);
- goto err_clk_get;
- }
-
- wdt->base = ioremap(adev->res.start, resource_size(&adev->res));
- if (!wdt->base) {
- ret = -ENOMEM;
- dev_warn(&adev->dev, "ioremap fail\n");
- goto err_ioremap;
+ goto err;
}
wdt->adev = adev;
@@ -327,14 +328,7 @@ sp805_wdt_probe(struct amba_device *adev, const struct amba_id *id)
return 0;
err_misc_register:
- iounmap(wdt->base);
-err_ioremap:
clk_put(wdt->clk);
-err_clk_get:
- kfree(wdt);
- wdt = NULL;
-err_kzalloc:
- release_mem_region(adev->res.start, resource_size(&adev->res));
err:
dev_err(&adev->dev, "Probe Failed!!!\n");
return ret;
@@ -343,10 +337,7 @@ err:
static int __devexit sp805_wdt_remove(struct amba_device *adev)
{
misc_deregister(&sp805_wdt_miscdev);
- iounmap(wdt->base);
clk_put(wdt->clk);
- kfree(wdt);
- release_mem_region(adev->res.start, resource_size(&adev->res));
return 0;
}
--
1.7.8.110.g4cb5d
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH V2 21/22] watchdog/sp805: convert to watchdog core
2012-03-12 4:21 ` Viresh Kumar
@ 2012-03-12 4:22 ` Viresh Kumar
-1 siblings, 0 replies; 56+ messages in thread
From: Viresh Kumar @ 2012-03-12 4:22 UTC (permalink / raw)
To: wim
Cc: linux-watchdog, spear-devel, viresh.linux, linux-arm-kernel,
srinidhi.kasagar, linus.walleij, alan, w.sang, sshtylyov,
Viresh Kumar
This patch converts existing sp805 watchdog driver to use already in place
common infrastructure present in watchdog core. With this lot of code goes away.
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
drivers/watchdog/Kconfig | 1 +
drivers/watchdog/sp805_wdt.c | 241 ++++++++++++++---------------------------
2 files changed, 83 insertions(+), 159 deletions(-)
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index f66617a..438c393 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -85,6 +85,7 @@ config WM8350_WATCHDOG
config ARM_SP805_WATCHDOG
tristate "ARM SP805 Watchdog"
depends on ARM_AMBA
+ select WATCHDOG_CORE
help
ARM Primecell SP805 Watchdog timer. This will reboot your system when
the timeout is reached.
diff --git a/drivers/watchdog/sp805_wdt.c b/drivers/watchdog/sp805_wdt.c
index 859d8b0..5c34eda 100644
--- a/drivers/watchdog/sp805_wdt.c
+++ b/drivers/watchdog/sp805_wdt.c
@@ -16,20 +16,17 @@
#include <linux/amba/bus.h>
#include <linux/bitops.h>
#include <linux/clk.h>
-#include <linux/fs.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/kernel.h>
#include <linux/math64.h>
-#include <linux/miscdevice.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/pm.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/types.h>
-#include <linux/uaccess.h>
#include <linux/watchdog.h>
/* default timeout in seconds */
@@ -56,6 +53,7 @@
/**
* struct sp805_wdt: sp805 wdt device structure
+ * @wdd: instance of struct watchdog_device
* @lock: spin lock protecting dev structure and io access
* @base: base address of wdt
* @clk: clock structure of wdt
@@ -65,24 +63,24 @@
* @timeout: current programmed timeout
*/
struct sp805_wdt {
+ struct watchdog_device wdd;
spinlock_t lock;
void __iomem *base;
struct clk *clk;
struct amba_device *adev;
- unsigned long status;
- #define WDT_BUSY 0
- #define WDT_CAN_BE_CLOSED 1
unsigned int load_val;
unsigned int timeout;
};
-/* local variables */
-static struct sp805_wdt *wdt;
static int nowayout = WATCHDOG_NOWAYOUT;
+module_param(nowayout, int, 0);
+MODULE_PARM_DESC(nowayout,
+ "Set to 1 to keep watchdog running after device release");
/* This routine finds load value that will reset system in required timout */
-static void wdt_setload(unsigned int timeout)
+static int wdt_setload(struct watchdog_device *wdd, unsigned int timeout)
{
+ struct sp805_wdt *wdt = watchdog_get_drvdata(wdd);
u64 load, rate;
rate = clk_get_rate(wdt->clk);
@@ -103,11 +101,14 @@ static void wdt_setload(unsigned int timeout)
/* roundup timeout to closest positive integer value */
wdt->timeout = div_u64((load + 1) * 2 + (rate / 2), rate);
spin_unlock(&wdt->lock);
+
+ return 0;
}
/* returns number of seconds left for reset to occur */
-static u32 wdt_timeleft(void)
+static unsigned int wdt_timeleft(struct watchdog_device *wdd)
{
+ struct sp805_wdt *wdt = watchdog_get_drvdata(wdd);
u64 load, rate;
rate = clk_get_rate(wdt->clk);
@@ -123,166 +124,88 @@ static u32 wdt_timeleft(void)
return div_u64(load, rate);
}
-/* enables watchdog timers reset */
-static void wdt_enable(void)
+static int wdt_config(struct watchdog_device *wdd, bool ping)
{
+ struct sp805_wdt *wdt = watchdog_get_drvdata(wdd);
+ int ret;
+
+ if (!ping) {
+ ret = clk_enable(wdt->clk);
+ if (ret) {
+ dev_err(&wdt->adev->dev, "clock enable fail");
+ return ret;
+ }
+ }
+
spin_lock(&wdt->lock);
writel_relaxed(UNLOCK, wdt->base + WDTLOCK);
writel_relaxed(wdt->load_val, wdt->base + WDTLOAD);
- writel_relaxed(INT_MASK, wdt->base + WDTINTCLR);
- writel_relaxed(INT_ENABLE | RESET_ENABLE, wdt->base + WDTCONTROL);
- writel_relaxed(LOCK, wdt->base + WDTLOCK);
-
- /* Flush posted writes. */
- readl_relaxed(wdt->base + WDTLOCK);
- spin_unlock(&wdt->lock);
-}
-/* disables watchdog timers reset */
-static void wdt_disable(void)
-{
- spin_lock(&wdt->lock);
+ if (!ping) {
+ writel_relaxed(INT_MASK, wdt->base + WDTINTCLR);
+ writel_relaxed(INT_ENABLE | RESET_ENABLE, wdt->base +
+ WDTCONTROL);
+ }
- writel_relaxed(UNLOCK, wdt->base + WDTLOCK);
- writel_relaxed(0, wdt->base + WDTCONTROL);
writel_relaxed(LOCK, wdt->base + WDTLOCK);
/* Flush posted writes. */
readl_relaxed(wdt->base + WDTLOCK);
spin_unlock(&wdt->lock);
+
+ return 0;
}
-static ssize_t sp805_wdt_write(struct file *file, const char *data,
- size_t len, loff_t *ppos)
+static int wdt_ping(struct watchdog_device *wdd)
{
- if (len) {
- if (!nowayout) {
- size_t i;
-
- clear_bit(WDT_CAN_BE_CLOSED, &wdt->status);
-
- for (i = 0; i != len; i++) {
- char c;
-
- if (get_user(c, data + i))
- return -EFAULT;
- /* Check for Magic Close character */
- if (c == 'V') {
- set_bit(WDT_CAN_BE_CLOSED,
- &wdt->status);
- break;
- }
- }
- }
- wdt_enable();
- }
- return len;
+ return wdt_config(wdd, true);
}
-static const struct watchdog_info ident = {
- .options = WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
- .identity = MODULE_NAME,
-};
-
-static long sp805_wdt_ioctl(struct file *file, unsigned int cmd,
- unsigned long arg)
+/* enables watchdog timers reset */
+static int wdt_enable(struct watchdog_device *wdd)
{
- int ret = -ENOTTY;
- unsigned int timeout;
-
- switch (cmd) {
- case WDIOC_GETSUPPORT:
- ret = copy_to_user((struct watchdog_info *)arg, &ident,
- sizeof(ident)) ? -EFAULT : 0;
- break;
-
- case WDIOC_GETSTATUS:
- ret = put_user(0, (int *)arg);
- break;
-
- case WDIOC_KEEPALIVE:
- wdt_enable();
- ret = 0;
- break;
-
- case WDIOC_SETTIMEOUT:
- ret = get_user(timeout, (unsigned int *)arg);
- if (ret)
- break;
-
- wdt_setload(timeout);
-
- wdt_enable();
- /* Fall through */
-
- case WDIOC_GETTIMEOUT:
- ret = put_user(wdt->timeout, (unsigned int *)arg);
- break;
- case WDIOC_GETTIMELEFT:
- ret = put_user(wdt_timeleft(), (unsigned int *)arg);
- break;
- }
- return ret;
+ return wdt_config(wdd, false);
}
-static int sp805_wdt_open(struct inode *inode, struct file *file)
+/* disables watchdog timers reset */
+static int wdt_disable(struct watchdog_device *wdd)
{
- int ret = 0;
+ struct sp805_wdt *wdt = watchdog_get_drvdata(wdd);
- if (test_and_set_bit(WDT_BUSY, &wdt->status))
- return -EBUSY;
-
- ret = clk_enable(wdt->clk);
- if (ret) {
- dev_err(&wdt->adev->dev, "clock enable fail");
- goto err;
- }
-
- wdt_enable();
-
- /* can not be closed, once enabled */
- clear_bit(WDT_CAN_BE_CLOSED, &wdt->status);
- return nonseekable_open(inode, file);
+ spin_lock(&wdt->lock);
-err:
- clear_bit(WDT_BUSY, &wdt->status);
- return ret;
-}
+ writel_relaxed(UNLOCK, wdt->base + WDTLOCK);
+ writel_relaxed(0, wdt->base + WDTCONTROL);
+ writel_relaxed(LOCK, wdt->base + WDTLOCK);
-static int sp805_wdt_release(struct inode *inode, struct file *file)
-{
- if (!test_bit(WDT_CAN_BE_CLOSED, &wdt->status)) {
- clear_bit(WDT_BUSY, &wdt->status);
- dev_warn(&wdt->adev->dev, "Device closed unexpectedly\n");
- return 0;
- }
+ /* Flush posted writes. */
+ readl_relaxed(wdt->base + WDTLOCK);
+ spin_unlock(&wdt->lock);
- wdt_disable();
clk_disable(wdt->clk);
- clear_bit(WDT_BUSY, &wdt->status);
return 0;
}
-static const struct file_operations sp805_wdt_fops = {
- .owner = THIS_MODULE,
- .llseek = no_llseek,
- .write = sp805_wdt_write,
- .unlocked_ioctl = sp805_wdt_ioctl,
- .open = sp805_wdt_open,
- .release = sp805_wdt_release,
+static const struct watchdog_info wdt_info = {
+ .options = WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
+ .identity = MODULE_NAME,
};
-static struct miscdevice sp805_wdt_miscdev = {
- .minor = WATCHDOG_MINOR,
- .name = "watchdog",
- .fops = &sp805_wdt_fops,
+static const struct watchdog_ops wdt_ops = {
+ .owner = THIS_MODULE,
+ .start = wdt_enable,
+ .stop = wdt_disable,
+ .ping = wdt_ping,
+ .set_timeout = wdt_setload,
+ .get_timeleft = wdt_timeleft,
};
static int __devinit
sp805_wdt_probe(struct amba_device *adev, const struct amba_id *id)
{
+ struct sp805_wdt *wdt;
int ret = 0;
if (!devm_request_mem_region(&adev->dev, adev->res.start,
@@ -315,19 +238,26 @@ sp805_wdt_probe(struct amba_device *adev, const struct amba_id *id)
}
wdt->adev = adev;
+ wdt->wdd.info = &wdt_info;
+ wdt->wdd.ops = &wdt_ops;
+
spin_lock_init(&wdt->lock);
- wdt_setload(DEFAULT_TIMEOUT);
+ watchdog_set_nowayout(&wdt->wdd, nowayout);
+ wdt_setload(&wdt->wdd, DEFAULT_TIMEOUT);
- ret = misc_register(&sp805_wdt_miscdev);
- if (ret < 0) {
- dev_warn(&adev->dev, "cannot register misc device\n");
- goto err_misc_register;
+ ret = watchdog_register_device(&wdt->wdd);
+ if (ret) {
+ dev_err(&adev->dev, "watchdog_register_device() failed: %d\n",
+ ret);
+ goto err_register;
}
+ amba_set_drvdata(adev, wdt);
+ watchdog_set_drvdata(&wdt->wdd, wdt);
dev_info(&adev->dev, "registration successful\n");
return 0;
-err_misc_register:
+err_register:
clk_put(wdt->clk);
err:
dev_err(&adev->dev, "Probe Failed!!!\n");
@@ -336,7 +266,11 @@ err:
static int __devexit sp805_wdt_remove(struct amba_device *adev)
{
- misc_deregister(&sp805_wdt_miscdev);
+ struct sp805_wdt *wdt = amba_get_drvdata(adev);
+
+ watchdog_unregister_device(&wdt->wdd);
+ amba_set_drvdata(adev, NULL);
+ watchdog_set_drvdata(&wdt->wdd, NULL);
clk_put(wdt->clk);
return 0;
@@ -345,28 +279,22 @@ static int __devexit sp805_wdt_remove(struct amba_device *adev)
#ifdef CONFIG_PM
static int sp805_wdt_suspend(struct device *dev)
{
- if (test_bit(WDT_BUSY, &wdt->status)) {
- wdt_disable();
- clk_disable(wdt->clk);
- }
+ struct sp805_wdt *wdt = dev_get_drvdata(dev);
+
+ if (is_wdd_active(&wdt->wdd))
+ return wdt_disable(&wdt->wdd);
return 0;
}
static int sp805_wdt_resume(struct device *dev)
{
- int ret = 0;
+ struct sp805_wdt *wdt = dev_get_drvdata(dev);
- if (test_bit(WDT_BUSY, &wdt->status)) {
- ret = clk_enable(wdt->clk);
- if (ret) {
- dev_err(dev, "clock enable fail");
- return ret;
- }
- wdt_enable();
- }
+ if (is_wdd_active(&wdt->wdd))
+ return wdt_enable(&wdt->wdd);
- return ret;
+ return 0;
}
#endif /* CONFIG_PM */
@@ -405,11 +333,6 @@ static void __exit sp805_wdt_exit(void)
}
module_exit(sp805_wdt_exit);
-module_param(nowayout, int, 0);
-MODULE_PARM_DESC(nowayout,
- "Set to 1 to keep watchdog running after device release");
-
MODULE_AUTHOR("Viresh Kumar <viresh.kumar@st.com>");
MODULE_DESCRIPTION("ARM SP805 Watchdog Driver");
MODULE_LICENSE("GPL");
-MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
--
1.7.8.110.g4cb5d
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH V2 21/22] watchdog/sp805: convert to watchdog core
@ 2012-03-12 4:22 ` Viresh Kumar
0 siblings, 0 replies; 56+ messages in thread
From: Viresh Kumar @ 2012-03-12 4:22 UTC (permalink / raw)
To: linux-arm-kernel
This patch converts existing sp805 watchdog driver to use already in place
common infrastructure present in watchdog core. With this lot of code goes away.
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
drivers/watchdog/Kconfig | 1 +
drivers/watchdog/sp805_wdt.c | 241 ++++++++++++++---------------------------
2 files changed, 83 insertions(+), 159 deletions(-)
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index f66617a..438c393 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -85,6 +85,7 @@ config WM8350_WATCHDOG
config ARM_SP805_WATCHDOG
tristate "ARM SP805 Watchdog"
depends on ARM_AMBA
+ select WATCHDOG_CORE
help
ARM Primecell SP805 Watchdog timer. This will reboot your system when
the timeout is reached.
diff --git a/drivers/watchdog/sp805_wdt.c b/drivers/watchdog/sp805_wdt.c
index 859d8b0..5c34eda 100644
--- a/drivers/watchdog/sp805_wdt.c
+++ b/drivers/watchdog/sp805_wdt.c
@@ -16,20 +16,17 @@
#include <linux/amba/bus.h>
#include <linux/bitops.h>
#include <linux/clk.h>
-#include <linux/fs.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/kernel.h>
#include <linux/math64.h>
-#include <linux/miscdevice.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/pm.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/types.h>
-#include <linux/uaccess.h>
#include <linux/watchdog.h>
/* default timeout in seconds */
@@ -56,6 +53,7 @@
/**
* struct sp805_wdt: sp805 wdt device structure
+ * @wdd: instance of struct watchdog_device
* @lock: spin lock protecting dev structure and io access
* @base: base address of wdt
* @clk: clock structure of wdt
@@ -65,24 +63,24 @@
* @timeout: current programmed timeout
*/
struct sp805_wdt {
+ struct watchdog_device wdd;
spinlock_t lock;
void __iomem *base;
struct clk *clk;
struct amba_device *adev;
- unsigned long status;
- #define WDT_BUSY 0
- #define WDT_CAN_BE_CLOSED 1
unsigned int load_val;
unsigned int timeout;
};
-/* local variables */
-static struct sp805_wdt *wdt;
static int nowayout = WATCHDOG_NOWAYOUT;
+module_param(nowayout, int, 0);
+MODULE_PARM_DESC(nowayout,
+ "Set to 1 to keep watchdog running after device release");
/* This routine finds load value that will reset system in required timout */
-static void wdt_setload(unsigned int timeout)
+static int wdt_setload(struct watchdog_device *wdd, unsigned int timeout)
{
+ struct sp805_wdt *wdt = watchdog_get_drvdata(wdd);
u64 load, rate;
rate = clk_get_rate(wdt->clk);
@@ -103,11 +101,14 @@ static void wdt_setload(unsigned int timeout)
/* roundup timeout to closest positive integer value */
wdt->timeout = div_u64((load + 1) * 2 + (rate / 2), rate);
spin_unlock(&wdt->lock);
+
+ return 0;
}
/* returns number of seconds left for reset to occur */
-static u32 wdt_timeleft(void)
+static unsigned int wdt_timeleft(struct watchdog_device *wdd)
{
+ struct sp805_wdt *wdt = watchdog_get_drvdata(wdd);
u64 load, rate;
rate = clk_get_rate(wdt->clk);
@@ -123,166 +124,88 @@ static u32 wdt_timeleft(void)
return div_u64(load, rate);
}
-/* enables watchdog timers reset */
-static void wdt_enable(void)
+static int wdt_config(struct watchdog_device *wdd, bool ping)
{
+ struct sp805_wdt *wdt = watchdog_get_drvdata(wdd);
+ int ret;
+
+ if (!ping) {
+ ret = clk_enable(wdt->clk);
+ if (ret) {
+ dev_err(&wdt->adev->dev, "clock enable fail");
+ return ret;
+ }
+ }
+
spin_lock(&wdt->lock);
writel_relaxed(UNLOCK, wdt->base + WDTLOCK);
writel_relaxed(wdt->load_val, wdt->base + WDTLOAD);
- writel_relaxed(INT_MASK, wdt->base + WDTINTCLR);
- writel_relaxed(INT_ENABLE | RESET_ENABLE, wdt->base + WDTCONTROL);
- writel_relaxed(LOCK, wdt->base + WDTLOCK);
-
- /* Flush posted writes. */
- readl_relaxed(wdt->base + WDTLOCK);
- spin_unlock(&wdt->lock);
-}
-/* disables watchdog timers reset */
-static void wdt_disable(void)
-{
- spin_lock(&wdt->lock);
+ if (!ping) {
+ writel_relaxed(INT_MASK, wdt->base + WDTINTCLR);
+ writel_relaxed(INT_ENABLE | RESET_ENABLE, wdt->base +
+ WDTCONTROL);
+ }
- writel_relaxed(UNLOCK, wdt->base + WDTLOCK);
- writel_relaxed(0, wdt->base + WDTCONTROL);
writel_relaxed(LOCK, wdt->base + WDTLOCK);
/* Flush posted writes. */
readl_relaxed(wdt->base + WDTLOCK);
spin_unlock(&wdt->lock);
+
+ return 0;
}
-static ssize_t sp805_wdt_write(struct file *file, const char *data,
- size_t len, loff_t *ppos)
+static int wdt_ping(struct watchdog_device *wdd)
{
- if (len) {
- if (!nowayout) {
- size_t i;
-
- clear_bit(WDT_CAN_BE_CLOSED, &wdt->status);
-
- for (i = 0; i != len; i++) {
- char c;
-
- if (get_user(c, data + i))
- return -EFAULT;
- /* Check for Magic Close character */
- if (c == 'V') {
- set_bit(WDT_CAN_BE_CLOSED,
- &wdt->status);
- break;
- }
- }
- }
- wdt_enable();
- }
- return len;
+ return wdt_config(wdd, true);
}
-static const struct watchdog_info ident = {
- .options = WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
- .identity = MODULE_NAME,
-};
-
-static long sp805_wdt_ioctl(struct file *file, unsigned int cmd,
- unsigned long arg)
+/* enables watchdog timers reset */
+static int wdt_enable(struct watchdog_device *wdd)
{
- int ret = -ENOTTY;
- unsigned int timeout;
-
- switch (cmd) {
- case WDIOC_GETSUPPORT:
- ret = copy_to_user((struct watchdog_info *)arg, &ident,
- sizeof(ident)) ? -EFAULT : 0;
- break;
-
- case WDIOC_GETSTATUS:
- ret = put_user(0, (int *)arg);
- break;
-
- case WDIOC_KEEPALIVE:
- wdt_enable();
- ret = 0;
- break;
-
- case WDIOC_SETTIMEOUT:
- ret = get_user(timeout, (unsigned int *)arg);
- if (ret)
- break;
-
- wdt_setload(timeout);
-
- wdt_enable();
- /* Fall through */
-
- case WDIOC_GETTIMEOUT:
- ret = put_user(wdt->timeout, (unsigned int *)arg);
- break;
- case WDIOC_GETTIMELEFT:
- ret = put_user(wdt_timeleft(), (unsigned int *)arg);
- break;
- }
- return ret;
+ return wdt_config(wdd, false);
}
-static int sp805_wdt_open(struct inode *inode, struct file *file)
+/* disables watchdog timers reset */
+static int wdt_disable(struct watchdog_device *wdd)
{
- int ret = 0;
+ struct sp805_wdt *wdt = watchdog_get_drvdata(wdd);
- if (test_and_set_bit(WDT_BUSY, &wdt->status))
- return -EBUSY;
-
- ret = clk_enable(wdt->clk);
- if (ret) {
- dev_err(&wdt->adev->dev, "clock enable fail");
- goto err;
- }
-
- wdt_enable();
-
- /* can not be closed, once enabled */
- clear_bit(WDT_CAN_BE_CLOSED, &wdt->status);
- return nonseekable_open(inode, file);
+ spin_lock(&wdt->lock);
-err:
- clear_bit(WDT_BUSY, &wdt->status);
- return ret;
-}
+ writel_relaxed(UNLOCK, wdt->base + WDTLOCK);
+ writel_relaxed(0, wdt->base + WDTCONTROL);
+ writel_relaxed(LOCK, wdt->base + WDTLOCK);
-static int sp805_wdt_release(struct inode *inode, struct file *file)
-{
- if (!test_bit(WDT_CAN_BE_CLOSED, &wdt->status)) {
- clear_bit(WDT_BUSY, &wdt->status);
- dev_warn(&wdt->adev->dev, "Device closed unexpectedly\n");
- return 0;
- }
+ /* Flush posted writes. */
+ readl_relaxed(wdt->base + WDTLOCK);
+ spin_unlock(&wdt->lock);
- wdt_disable();
clk_disable(wdt->clk);
- clear_bit(WDT_BUSY, &wdt->status);
return 0;
}
-static const struct file_operations sp805_wdt_fops = {
- .owner = THIS_MODULE,
- .llseek = no_llseek,
- .write = sp805_wdt_write,
- .unlocked_ioctl = sp805_wdt_ioctl,
- .open = sp805_wdt_open,
- .release = sp805_wdt_release,
+static const struct watchdog_info wdt_info = {
+ .options = WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
+ .identity = MODULE_NAME,
};
-static struct miscdevice sp805_wdt_miscdev = {
- .minor = WATCHDOG_MINOR,
- .name = "watchdog",
- .fops = &sp805_wdt_fops,
+static const struct watchdog_ops wdt_ops = {
+ .owner = THIS_MODULE,
+ .start = wdt_enable,
+ .stop = wdt_disable,
+ .ping = wdt_ping,
+ .set_timeout = wdt_setload,
+ .get_timeleft = wdt_timeleft,
};
static int __devinit
sp805_wdt_probe(struct amba_device *adev, const struct amba_id *id)
{
+ struct sp805_wdt *wdt;
int ret = 0;
if (!devm_request_mem_region(&adev->dev, adev->res.start,
@@ -315,19 +238,26 @@ sp805_wdt_probe(struct amba_device *adev, const struct amba_id *id)
}
wdt->adev = adev;
+ wdt->wdd.info = &wdt_info;
+ wdt->wdd.ops = &wdt_ops;
+
spin_lock_init(&wdt->lock);
- wdt_setload(DEFAULT_TIMEOUT);
+ watchdog_set_nowayout(&wdt->wdd, nowayout);
+ wdt_setload(&wdt->wdd, DEFAULT_TIMEOUT);
- ret = misc_register(&sp805_wdt_miscdev);
- if (ret < 0) {
- dev_warn(&adev->dev, "cannot register misc device\n");
- goto err_misc_register;
+ ret = watchdog_register_device(&wdt->wdd);
+ if (ret) {
+ dev_err(&adev->dev, "watchdog_register_device() failed: %d\n",
+ ret);
+ goto err_register;
}
+ amba_set_drvdata(adev, wdt);
+ watchdog_set_drvdata(&wdt->wdd, wdt);
dev_info(&adev->dev, "registration successful\n");
return 0;
-err_misc_register:
+err_register:
clk_put(wdt->clk);
err:
dev_err(&adev->dev, "Probe Failed!!!\n");
@@ -336,7 +266,11 @@ err:
static int __devexit sp805_wdt_remove(struct amba_device *adev)
{
- misc_deregister(&sp805_wdt_miscdev);
+ struct sp805_wdt *wdt = amba_get_drvdata(adev);
+
+ watchdog_unregister_device(&wdt->wdd);
+ amba_set_drvdata(adev, NULL);
+ watchdog_set_drvdata(&wdt->wdd, NULL);
clk_put(wdt->clk);
return 0;
@@ -345,28 +279,22 @@ static int __devexit sp805_wdt_remove(struct amba_device *adev)
#ifdef CONFIG_PM
static int sp805_wdt_suspend(struct device *dev)
{
- if (test_bit(WDT_BUSY, &wdt->status)) {
- wdt_disable();
- clk_disable(wdt->clk);
- }
+ struct sp805_wdt *wdt = dev_get_drvdata(dev);
+
+ if (is_wdd_active(&wdt->wdd))
+ return wdt_disable(&wdt->wdd);
return 0;
}
static int sp805_wdt_resume(struct device *dev)
{
- int ret = 0;
+ struct sp805_wdt *wdt = dev_get_drvdata(dev);
- if (test_bit(WDT_BUSY, &wdt->status)) {
- ret = clk_enable(wdt->clk);
- if (ret) {
- dev_err(dev, "clock enable fail");
- return ret;
- }
- wdt_enable();
- }
+ if (is_wdd_active(&wdt->wdd))
+ return wdt_enable(&wdt->wdd);
- return ret;
+ return 0;
}
#endif /* CONFIG_PM */
@@ -405,11 +333,6 @@ static void __exit sp805_wdt_exit(void)
}
module_exit(sp805_wdt_exit);
-module_param(nowayout, int, 0);
-MODULE_PARM_DESC(nowayout,
- "Set to 1 to keep watchdog running after device release");
-
MODULE_AUTHOR("Viresh Kumar <viresh.kumar@st.com>");
MODULE_DESCRIPTION("ARM SP805 Watchdog Driver");
MODULE_LICENSE("GPL");
-MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
--
1.7.8.110.g4cb5d
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH V2 22/22] watchdog/sp805: Add clk_{un}prepare support
2012-03-12 4:21 ` Viresh Kumar
@ 2012-03-12 4:22 ` Viresh Kumar
-1 siblings, 0 replies; 56+ messages in thread
From: Viresh Kumar @ 2012-03-12 4:22 UTC (permalink / raw)
To: wim
Cc: linux-watchdog, spear-devel, viresh.linux, linux-arm-kernel,
srinidhi.kasagar, linus.walleij, alan, w.sang, sshtylyov,
Viresh Kumar
clk_{un}prepare() routines are required for required on some platforms to run
part of clk enable/disable() routines from contexts that can schedule.
This patch adds support for these routines in sp805 driver.
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
drivers/watchdog/sp805_wdt.c | 8 ++++++++
1 files changed, 8 insertions(+), 0 deletions(-)
diff --git a/drivers/watchdog/sp805_wdt.c b/drivers/watchdog/sp805_wdt.c
index 5c34eda..938b8ab 100644
--- a/drivers/watchdog/sp805_wdt.c
+++ b/drivers/watchdog/sp805_wdt.c
@@ -130,9 +130,16 @@ static int wdt_config(struct watchdog_device *wdd, bool ping)
int ret;
if (!ping) {
+ ret = clk_prepare(wdt->clk);
+ if (ret) {
+ dev_err(&wdt->adev->dev, "clock prepare fail");
+ return ret;
+ }
+
ret = clk_enable(wdt->clk);
if (ret) {
dev_err(&wdt->adev->dev, "clock enable fail");
+ clk_unprepare(wdt->clk);
return ret;
}
}
@@ -184,6 +191,7 @@ static int wdt_disable(struct watchdog_device *wdd)
spin_unlock(&wdt->lock);
clk_disable(wdt->clk);
+ clk_unprepare(wdt->clk);
return 0;
}
--
1.7.8.110.g4cb5d
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH V2 22/22] watchdog/sp805: Add clk_{un}prepare support
@ 2012-03-12 4:22 ` Viresh Kumar
0 siblings, 0 replies; 56+ messages in thread
From: Viresh Kumar @ 2012-03-12 4:22 UTC (permalink / raw)
To: linux-arm-kernel
clk_{un}prepare() routines are required for required on some platforms to run
part of clk enable/disable() routines from contexts that can schedule.
This patch adds support for these routines in sp805 driver.
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
drivers/watchdog/sp805_wdt.c | 8 ++++++++
1 files changed, 8 insertions(+), 0 deletions(-)
diff --git a/drivers/watchdog/sp805_wdt.c b/drivers/watchdog/sp805_wdt.c
index 5c34eda..938b8ab 100644
--- a/drivers/watchdog/sp805_wdt.c
+++ b/drivers/watchdog/sp805_wdt.c
@@ -130,9 +130,16 @@ static int wdt_config(struct watchdog_device *wdd, bool ping)
int ret;
if (!ping) {
+ ret = clk_prepare(wdt->clk);
+ if (ret) {
+ dev_err(&wdt->adev->dev, "clock prepare fail");
+ return ret;
+ }
+
ret = clk_enable(wdt->clk);
if (ret) {
dev_err(&wdt->adev->dev, "clock enable fail");
+ clk_unprepare(wdt->clk);
return ret;
}
}
@@ -184,6 +191,7 @@ static int wdt_disable(struct watchdog_device *wdd)
spin_unlock(&wdt->lock);
clk_disable(wdt->clk);
+ clk_unprepare(wdt->clk);
return 0;
}
--
1.7.8.110.g4cb5d
^ permalink raw reply related [flat|nested] 56+ messages in thread
* Re: [PATCH V2 00/22] watchdog: ARM watchdogs: sp805 & mpcore updates & fixes
2012-03-12 4:21 ` Viresh Kumar
@ 2012-04-10 9:35 ` Viresh Kumar
-1 siblings, 0 replies; 56+ messages in thread
From: Viresh Kumar @ 2012-04-10 9:35 UTC (permalink / raw)
To: wim
Cc: linux-watchdog, spear-devel, viresh.linux, linux-arm-kernel,
Srinidhi KASAGAR, Linus WALLEIJ, alan, w.sang, sshtylyov
On 3/12/2012 9:51 AM, Viresh KUMAR wrote:
> Hello,
>
> This patchset contains fixes and updates for ARM watchdog drivers sp805 and
> mpcore.
>
> Changes since V1:
> - Included patches for sp805 driver.
> - Removed: wdt->clk = NULL from mpcore driver, and use IS_ERR() to check if
> clock is supported or not.
> - Adapted to watchdog core for both the drivers.
> - two patches for watchdog core added
> - add patch to use __raw_readl{writel} instead of readl{writel}
> - taken care of few more review comments.
>
Hi Wim,
Have you applied patches left in this patchset for linux-next?
--
viresh
^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH V2 00/22] watchdog: ARM watchdogs: sp805 & mpcore updates & fixes
@ 2012-04-10 9:35 ` Viresh Kumar
0 siblings, 0 replies; 56+ messages in thread
From: Viresh Kumar @ 2012-04-10 9:35 UTC (permalink / raw)
To: linux-arm-kernel
On 3/12/2012 9:51 AM, Viresh KUMAR wrote:
> Hello,
>
> This patchset contains fixes and updates for ARM watchdog drivers sp805 and
> mpcore.
>
> Changes since V1:
> - Included patches for sp805 driver.
> - Removed: wdt->clk = NULL from mpcore driver, and use IS_ERR() to check if
> clock is supported or not.
> - Adapted to watchdog core for both the drivers.
> - two patches for watchdog core added
> - add patch to use __raw_readl{writel} instead of readl{writel}
> - taken care of few more review comments.
>
Hi Wim,
Have you applied patches left in this patchset for linux-next?
--
viresh
^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH V2 00/22] watchdog: ARM watchdogs: sp805 & mpcore updates & fixes
2012-04-10 9:35 ` Viresh Kumar
@ 2012-04-18 5:08 ` Viresh Kumar
-1 siblings, 0 replies; 56+ messages in thread
From: Viresh Kumar @ 2012-04-18 5:08 UTC (permalink / raw)
To: wim
Cc: linux-watchdog, spear-devel, viresh.linux, linux-arm-kernel,
Srinidhi KASAGAR, Linus WALLEIJ, alan, w.sang, sshtylyov
On 4/10/2012 3:05 PM, Viresh KUMAR wrote:
> On 3/12/2012 9:51 AM, Viresh KUMAR wrote:
>> Hello,
>>
>> This patchset contains fixes and updates for ARM watchdog drivers sp805 and
>> mpcore.
>>
>> Changes since V1:
>> - Included patches for sp805 driver.
>> - Removed: wdt->clk = NULL from mpcore driver, and use IS_ERR() to check if
>> clock is supported or not.
>> - Adapted to watchdog core for both the drivers.
>> - two patches for watchdog core added
>> - add patch to use __raw_readl{writel} instead of readl{writel}
>> - taken care of few more review comments.
>>
>
> Hi Wim,
>
> Have you applied patches left in this patchset for linux-next?
Ping!!
--
viresh
^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH V2 00/22] watchdog: ARM watchdogs: sp805 & mpcore updates & fixes
@ 2012-04-18 5:08 ` Viresh Kumar
0 siblings, 0 replies; 56+ messages in thread
From: Viresh Kumar @ 2012-04-18 5:08 UTC (permalink / raw)
To: linux-arm-kernel
On 4/10/2012 3:05 PM, Viresh KUMAR wrote:
> On 3/12/2012 9:51 AM, Viresh KUMAR wrote:
>> Hello,
>>
>> This patchset contains fixes and updates for ARM watchdog drivers sp805 and
>> mpcore.
>>
>> Changes since V1:
>> - Included patches for sp805 driver.
>> - Removed: wdt->clk = NULL from mpcore driver, and use IS_ERR() to check if
>> clock is supported or not.
>> - Adapted to watchdog core for both the drivers.
>> - two patches for watchdog core added
>> - add patch to use __raw_readl{writel} instead of readl{writel}
>> - taken care of few more review comments.
>>
>
> Hi Wim,
>
> Have you applied patches left in this patchset for linux-next?
Ping!!
--
viresh
^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH V2 17/22] watchdog/mpcore_wdt: use correct clk_rate to program timeout
2012-03-12 4:22 ` Viresh Kumar
@ 2012-04-24 10:42 ` Viresh Kumar
-1 siblings, 0 replies; 56+ messages in thread
From: Viresh Kumar @ 2012-04-24 10:42 UTC (permalink / raw)
To: wim
Cc: Viresh KUMAR, linux-watchdog, spear-devel, viresh.linux,
linux-arm-kernel, Srinidhi KASAGAR, Linus WALLEIJ, alan, w.sang,
sshtylyov
On 3/12/2012 9:52 AM, Viresh KUMAR wrote:
> Currently, mpcore wdt driver doesn't use exact clk_rate to program timeout in
> hardware. This patch provides two ways of doing so:
> - either use clk_get_rate() if clk_get passes
> - use clk_rate passed via module param
>
> Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
Wim,
Will these go in v3.5?
Please squash following with this patch while applying.
diff --git a/drivers/watchdog/mpcore_wdt.c b/drivers/watchdog/mpcore_wdt.c
index 3690af3..e7cadc0 100644
--- a/drivers/watchdog/mpcore_wdt.c
+++ b/drivers/watchdog/mpcore_wdt.c
@@ -370,7 +370,7 @@ static int __devinit mpcore_wdt_probe(struct platform_device *pdev)
TIMER_MARGIN);
}
- mpcore_wdt_set_heartbeat(NULL, mpcore_margin);
+ mpcore_wdt_set_heartbeat(&wdt->wdd, mpcore_margin);
dev_info(wdt->dev, "MPcore Watchdog Timer: 0.1. mpcore_noboot=%d "
"mpcore_margin=%d sec (nowayout= %d)\n", mpcore_noboot,
mpcore_margin, nowayout);
--
viresh
^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCH V2 17/22] watchdog/mpcore_wdt: use correct clk_rate to program timeout
@ 2012-04-24 10:42 ` Viresh Kumar
0 siblings, 0 replies; 56+ messages in thread
From: Viresh Kumar @ 2012-04-24 10:42 UTC (permalink / raw)
To: linux-arm-kernel
On 3/12/2012 9:52 AM, Viresh KUMAR wrote:
> Currently, mpcore wdt driver doesn't use exact clk_rate to program timeout in
> hardware. This patch provides two ways of doing so:
> - either use clk_get_rate() if clk_get passes
> - use clk_rate passed via module param
>
> Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
Wim,
Will these go in v3.5?
Please squash following with this patch while applying.
diff --git a/drivers/watchdog/mpcore_wdt.c b/drivers/watchdog/mpcore_wdt.c
index 3690af3..e7cadc0 100644
--- a/drivers/watchdog/mpcore_wdt.c
+++ b/drivers/watchdog/mpcore_wdt.c
@@ -370,7 +370,7 @@ static int __devinit mpcore_wdt_probe(struct platform_device *pdev)
TIMER_MARGIN);
}
- mpcore_wdt_set_heartbeat(NULL, mpcore_margin);
+ mpcore_wdt_set_heartbeat(&wdt->wdd, mpcore_margin);
dev_info(wdt->dev, "MPcore Watchdog Timer: 0.1. mpcore_noboot=%d "
"mpcore_margin=%d sec (nowayout= %d)\n", mpcore_noboot,
mpcore_margin, nowayout);
--
viresh
^ permalink raw reply related [flat|nested] 56+ messages in thread
* Re: [PATCH V2 17/22] watchdog/mpcore_wdt: use correct clk_rate to program timeout
2012-04-24 10:42 ` Viresh Kumar
(?)
@ 2012-04-24 19:34 ` Wim Van Sebroeck
-1 siblings, 0 replies; 56+ messages in thread
From: Wim Van Sebroeck @ 2012-04-24 19:34 UTC (permalink / raw)
To: Viresh Kumar
Cc: linux-watchdog, spear-devel, viresh.linux, linux-arm-kernel,
Srinidhi KASAGAR, Linus WALLEIJ, alan, w.sang, sshtylyov
Hi Viresh,
> On 3/12/2012 9:52 AM, Viresh KUMAR wrote:
> > Currently, mpcore wdt driver doesn't use exact clk_rate to program timeout in
> > hardware. This patch provides two ways of doing so:
> > - either use clk_get_rate() if clk_get passes
> > - use clk_rate passed via module param
> >
> > Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
>
> Wim,
>
> Will these go in v3.5?
Busy at the moment, but yes this should go in with the following merge window.
Kind regards,
Wim.
^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH V2 00/22] watchdog: ARM watchdogs: sp805 & mpcore updates & fixes
2012-04-18 5:08 ` Viresh Kumar
@ 2012-06-13 9:06 ` viresh kumar
-1 siblings, 0 replies; 56+ messages in thread
From: viresh kumar @ 2012-06-13 9:06 UTC (permalink / raw)
To: wim
Cc: linux-watchdog, spear-devel, linux-arm-kernel, Srinidhi KASAGAR,
Linus WALLEIJ, alan, w.sang, sshtylyov
Hi Wim,
On Wed, Apr 18, 2012 at 6:08 AM, Viresh Kumar <viresh.kumar@st.com> wrote:
> On 4/10/2012 3:05 PM, Viresh KUMAR wrote:
>> On 3/12/2012 9:51 AM, Viresh KUMAR wrote:
>>> Hello,
>>>
>>> This patchset contains fixes and updates for ARM watchdog drivers sp805 and
>>> mpcore.
>>>
>>> Changes since V1:
>>> - Included patches for sp805 driver.
>>> - Removed: wdt->clk = NULL from mpcore driver, and use IS_ERR() to check if
>>> clock is supported or not.
>>> - Adapted to watchdog core for both the drivers.
>>> - two patches for watchdog core added
>>> - add patch to use __raw_readl{writel} instead of readl{writel}
>>> - taken care of few more review comments.
>>>
>>
>> Hi Wim,
>>
>> Have you applied patches left in this patchset for linux-next?
>
> Ping!!
You planned to push them in v-3.5. Isn't it?
--
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] 56+ messages in thread
* [PATCH V2 00/22] watchdog: ARM watchdogs: sp805 & mpcore updates & fixes
@ 2012-06-13 9:06 ` viresh kumar
0 siblings, 0 replies; 56+ messages in thread
From: viresh kumar @ 2012-06-13 9:06 UTC (permalink / raw)
To: linux-arm-kernel
Hi Wim,
On Wed, Apr 18, 2012 at 6:08 AM, Viresh Kumar <viresh.kumar@st.com> wrote:
> On 4/10/2012 3:05 PM, Viresh KUMAR wrote:
>> On 3/12/2012 9:51 AM, Viresh KUMAR wrote:
>>> Hello,
>>>
>>> This patchset contains fixes and updates for ARM watchdog drivers sp805 and
>>> mpcore.
>>>
>>> Changes since V1:
>>> - Included patches for sp805 driver.
>>> - Removed: wdt->clk = NULL from mpcore driver, and use IS_ERR() to check if
>>> ? clock is supported or not.
>>> - Adapted to watchdog core for both the drivers.
>>> - two patches for watchdog core added
>>> - add patch to use __raw_readl{writel} instead of readl{writel}
>>> - taken care of few more review comments.
>>>
>>
>> Hi Wim,
>>
>> Have you applied patches left in this patchset for linux-next?
>
> Ping!!
You planned to push them in v-3.5. Isn't it?
^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH V2 00/22] watchdog: ARM watchdogs: sp805 & mpcore updates & fixes
2012-06-13 9:06 ` viresh kumar
(?)
@ 2012-06-26 19:08 ` Wim Van Sebroeck
-1 siblings, 0 replies; 56+ messages in thread
From: Wim Van Sebroeck @ 2012-06-26 19:08 UTC (permalink / raw)
To: viresh kumar
Cc: linux-watchdog, spear-devel, linux-arm-kernel, Srinidhi KASAGAR,
Linus WALLEIJ, alan, w.sang, sshtylyov
Hi Viresh,
> On Wed, Apr 18, 2012 at 6:08 AM, Viresh Kumar <viresh.kumar@st.com> wrote:
> > On 4/10/2012 3:05 PM, Viresh KUMAR wrote:
> >> On 3/12/2012 9:51 AM, Viresh KUMAR wrote:
> >>> Hello,
> >>>
> >>> This patchset contains fixes and updates for ARM watchdog drivers sp805 and
> >>> mpcore.
> >>>
> >>> Changes since V1:
> >>> - Included patches for sp805 driver.
> >>> - Removed: wdt->clk = NULL from mpcore driver, and use IS_ERR() to check if
> >>> clock is supported or not.
> >>> - Adapted to watchdog core for both the drivers.
> >>> - two patches for watchdog core added
> >>> - add patch to use __raw_readl{writel} instead of readl{writel}
> >>> - taken care of few more review comments.
> >>>
> >>
> >> Hi Wim,
> >>
> >> Have you applied patches left in this patchset for linux-next?
> >
> > Ping!!
>
> You planned to push them in v-3.5. Isn't it?
The sp805_wdt patches are in and are for v3.5. The sp805_wdt driver
however allocates its watchdog device dynamically, so you will need
to add ref and unref functions. (See also commits:
e907df32725204d6d2cb79b872529911c8eadcdf ,
54e2dc9341aca23d5241699e3b74c8dce609fa2d ,
664a0d7862a6b10c709d4b4a3655fe2c59a20064 ).
The mpcore ones are not in. Here I need to reread the discussion
on the interrupt handling and/or the SMP issues. This will be for v3.6
at the earliest. I will add the mpcore patches to linux-next next week.
Kind regards,
Wim.
--
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] 56+ messages in thread
end of thread, other threads:[~2012-06-26 19:08 UTC | newest]
Thread overview: 56+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-03-12 4:21 [PATCH V2 00/22] watchdog: ARM watchdogs: sp805 & mpcore updates & fixes Viresh Kumar
2012-03-12 4:21 ` Viresh Kumar
2012-03-12 4:21 ` [PATCH V2 01/22] watchdog: Add is_wdt_active() routine Viresh Kumar
2012-03-12 4:21 ` Viresh Kumar
2012-03-12 4:21 ` [PATCH V2 02/22] watchdog: Add support for WDIOC_GETTIMELEFT IOCTL in watchdog core Viresh Kumar
2012-03-12 4:21 ` Viresh Kumar
2012-03-12 4:21 ` [PATCH V2 03/22] watchdog/mpcore_wdt: Rename dev to pdev for pointing to struct platform_device Viresh Kumar
2012-03-12 4:21 ` Viresh Kumar
2012-03-12 4:21 ` [PATCH V2 04/22] watchdog/mpcore_wdt: Use devm routines Viresh Kumar
2012-03-12 4:21 ` Viresh Kumar
2012-03-12 4:22 ` [PATCH V2 05/22] watchdog/mpcore_wdt: Allow platform_get_irq() to fail Viresh Kumar
2012-03-12 4:22 ` Viresh Kumar
2012-03-12 4:22 ` [PATCH V2 06/22] watchdog/mpcore_wdt: convert to watchdog core Viresh Kumar
2012-03-12 4:22 ` Viresh Kumar
2012-03-12 4:22 ` [PATCH V2 07/22] watchdog/mpcore_wdt: Fix multiline comments Viresh Kumar
2012-03-12 4:22 ` Viresh Kumar
2012-03-12 4:22 ` [PATCH V2 08/22] watchdog/mpcore_wdt: Arrange #includes in alphabetical order Viresh Kumar
2012-03-12 4:22 ` Viresh Kumar
2012-03-12 4:22 ` [PATCH V2 09/22] watchdog/mpcore_wdt: Set default heartbeat in probe instead of init Viresh Kumar
2012-03-12 4:22 ` Viresh Kumar
2012-03-12 4:22 ` [PATCH V2 10/22] watchdog/mpcore_wdt: Use dev_(crit, err, info) instead of dev_printk Viresh Kumar
2012-03-12 4:22 ` Viresh Kumar
2012-03-12 4:22 ` [PATCH V2 11/22] watchdog/mpcore_wdt: convert to use module_platform_driver() Viresh Kumar
2012-03-12 4:22 ` Viresh Kumar
2012-03-12 4:22 ` [PATCH V2 12/22] watchdog/mpcore_wdt: Add support for dev_pm_ops interface Viresh Kumar
2012-03-12 4:22 ` Viresh Kumar
2012-03-12 4:22 ` [PATCH V2 13/22] watchdog/mpcore_wdt: disable wdt in suspend only if it is busy Viresh Kumar
2012-03-12 4:22 ` Viresh Kumar
2012-03-12 4:22 ` [PATCH V2 14/22] watchdog/mpcore_wdt: replace (__raw_)readl/writel with lighter *_relaxed variants Viresh Kumar
2012-03-12 4:22 ` Viresh Kumar
2012-03-12 4:22 ` [PATCH V2 15/22] watchdog/mpcore_wdt: Add support for WDIOC_GETBOOTSTATUS IOCTL Viresh Kumar
2012-03-12 4:22 ` Viresh Kumar
2012-03-12 4:22 ` [PATCH V2 16/22] watchdog/mpcore_wdt: Add clock framework support Viresh Kumar
2012-03-12 4:22 ` Viresh Kumar
2012-03-12 4:22 ` [PATCH V2 17/22] watchdog/mpcore_wdt: use correct clk_rate to program timeout Viresh Kumar
2012-03-12 4:22 ` Viresh Kumar
2012-04-24 10:42 ` Viresh Kumar
2012-04-24 10:42 ` Viresh Kumar
2012-04-24 19:34 ` Wim Van Sebroeck
2012-03-12 4:22 ` [PATCH V2 18/22] watchdog/sp805: Fix documentation style comment Viresh Kumar
2012-03-12 4:22 ` Viresh Kumar
2012-03-12 4:22 ` [PATCH V2 19/22] watchdog/sp805: replace readl/writel with lighter _relaxed variants Viresh Kumar
2012-03-12 4:22 ` Viresh Kumar
2012-03-12 4:22 ` [PATCH V2 20/22] watchdog/sp805: Use devm routines Viresh Kumar
2012-03-12 4:22 ` Viresh Kumar
2012-03-12 4:22 ` [PATCH V2 21/22] watchdog/sp805: convert to watchdog core Viresh Kumar
2012-03-12 4:22 ` Viresh Kumar
2012-03-12 4:22 ` [PATCH V2 22/22] watchdog/sp805: Add clk_{un}prepare support Viresh Kumar
2012-03-12 4:22 ` Viresh Kumar
2012-04-10 9:35 ` [PATCH V2 00/22] watchdog: ARM watchdogs: sp805 & mpcore updates & fixes Viresh Kumar
2012-04-10 9:35 ` Viresh Kumar
2012-04-18 5:08 ` Viresh Kumar
2012-04-18 5:08 ` Viresh Kumar
2012-06-13 9:06 ` viresh kumar
2012-06-13 9:06 ` viresh kumar
2012-06-26 19:08 ` Wim Van Sebroeck
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.