watchdog: ARM watchdogs: sp805 & mpcore updates & fixes
Subsystems (3)
v2 cover watchdog: ARM watchdogs: sp805 & mpcore updates & fixes
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(-)
Signature · 1 line
1.7.8.110.g4cb5d
PATCH v2 1/22 watchdog: Add is_wdt_active() routine
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.
--- drivers/watchdog/via_wdt.c | 2 +- drivers/watchdog/watchdog_dev.c | 6 +++--- include/linux/watchdog.h | 5 +++++ 3 files changed, 9 insertions(+), 4 deletions(-)
drivers/watchdog/via_wdt.c +1 -1
@@ -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
drivers/watchdog/watchdog_dev.c +3 -3
@@ -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;
include/linux/watchdog.h +5 -0
@@ -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)
Signature · 1 line
1.7.8.110.g4cb5d
PATCH v2 2/22 watchdog: Add support for WDIOC_GETTIMELEFT IOCTL in watchdog core
In reply to Viresh KumarThis 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.
--- .../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(-)
Documentation/watchdog/convert_drivers_to_kernel_api.txt +4 -0
@@ -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
Documentation/watchdog/watchdog-kernel-api.txt +2 -0
@@ -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
drivers/watchdog/watchdog_dev.c +5 -0
@@ -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 ; }
include/linux/watchdog.h +2 -0
@@ -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 ); };
Signature · 1 line
1.7.8.110.g4cb5d
PATCH v2 3/22 watchdog/mpcore_wdt: Rename dev to pdev for pointing to struct platform_device
In reply to Viresh KumarPointer 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.
--- drivers/watchdog/mpcore_wdt.c | 40 ++++++++++++++++++++-------------------- 1 files changed, 20 insertions(+), 20 deletions(-)
drivers/watchdog/mpcore_wdt.c +20 -20
@@ -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);
Signature · 1 line
1.7.8.110.g4cb5d
PATCH v2 4/22 watchdog/mpcore_wdt: Use devm routines
In reply to Viresh Kumarmpcore_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.
--- drivers/watchdog/mpcore_wdt.c | 58 +++++++++++++--------------------------- 1 files changed, 19 insertions(+), 39 deletions(-)
drivers/watchdog/mpcore_wdt.c +19 -39
@@ -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 ; }
Signature · 1 line
1.7.8.110.g4cb5d
PATCH v2 5/22 watchdog/mpcore_wdt: Allow platform_get_irq() to fail
In reply to Viresh Kumarirq 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.
--- drivers/watchdog/mpcore_wdt.c | 18 +++++++++--------- 1 files changed, 9 insertions(+), 9 deletions(-)
drivers/watchdog/mpcore_wdt.c +9 -9
@@ -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));
Signature · 1 line
1.7.8.110.g4cb5d
PATCH v2 6/22 watchdog/mpcore_wdt: convert to watchdog core
In reply to Viresh KumarThis patch converts existing mpcore watchdog driver to use already in place common infrastructure present in watchdog core. With this lot of code goes away.
--- drivers/watchdog/Kconfig | 1 + drivers/watchdog/mpcore_wdt.c | 281 ++++++++++------------------------------- 2 files changed, 71 insertions(+), 211 deletions(-)
drivers/watchdog/Kconfig +1 -0
@@ -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.
drivers/watchdog/mpcore_wdt.c +70 -211
411 lines not on this page · raw message
Signature · 1 line
1.7.8.110.g4cb5d
PATCH v2 7/22 watchdog/mpcore_wdt: Fix multiline comments
In reply to Viresh KumarIn case of few multiline comment a 'tab' is present instead of 'space' after the '*' in the second column. Replace tab with space here.
--- drivers/watchdog/mpcore_wdt.c | 42 +++++++++++++++++++--------------------- 1 files changed, 20 insertions(+), 22 deletions(-)
drivers/watchdog/mpcore_wdt.c +20 -22
@@ -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 <[email protected]>, -* All Rights Reserved. +* Based on the SoftDog driver: +* (c) Copyright 1996 Alan Cox <[email protected]>, 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 <[email protected]> +* 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 <[email protected]> */ #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) {
Signature · 1 line
1.7.8.110.g4cb5d
PATCH v2 8/22 watchdog/mpcore_wdt: Arrange #includes in alphabetical order
In reply to Viresh Kumar--- drivers/watchdog/mpcore_wdt.c | 12 ++++++------ 1 files changed, 6 insertions(+), 6 deletions(-)
drivers/watchdog/mpcore_wdt.c +6 -6
@@ -17,16 +17,16 @@* * (c) Copyright 1995 Alan Cox <[email protected]> */ -#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>
Signature · 1 line
1.7.8.110.g4cb5d
PATCH v2 9/22 watchdog/mpcore_wdt: Set default heartbeat in probe instead of init
In reply to Viresh KumarCurrently 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()
--- drivers/watchdog/mpcore_wdt.c | 31 +++++++++++++++---------------- 1 files changed, 15 insertions(+), 16 deletions(-)
drivers/watchdog/mpcore_wdt.c +15 -16
@@ -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); }
Signature · 1 line
1.7.8.110.g4cb5d
PATCH v2 10/22 watchdog/mpcore_wdt: Use dev_(crit, err, info) instead of dev_printk
In reply to Viresh Kumar--- drivers/watchdog/mpcore_wdt.c | 7 +++---- 1 files changed, 3 insertions(+), 4 deletions(-)
drivers/watchdog/mpcore_wdt.c +3 -4
@@ -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;
Signature · 1 line
1.7.8.110.g4cb5d
PATCH v2 11/22 watchdog/mpcore_wdt: convert to use module_platform_driver()
In reply to Viresh KumarThis patch converts the mpcore_wdt driver to use the module_platform_driver() macro which makes the code smaller and a bit simpler.
--- drivers/watchdog/mpcore_wdt.c | 13 +------------ 1 files changed, 1 insertions(+), 12 deletions(-)
drivers/watchdog/mpcore_wdt.c +1 -12
@@ -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" );
Signature · 1 line
1.7.8.110.g4cb5d
PATCH v2 12/22 watchdog/mpcore_wdt: Add support for dev_pm_ops interface
In reply to Viresh KumarThis patch adds dev_pm_ops support for standby/slepp/hibernate.
--- drivers/watchdog/mpcore_wdt.c | 18 +++++++++--------- 1 files changed, 9 insertions(+), 9 deletions(-)
drivers/watchdog/mpcore_wdt.c +9 -9
@@ -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, }, };
Signature · 1 line
1.7.8.110.g4cb5d
PATCH v2 13/22 watchdog/mpcore_wdt: disable wdt in suspend only if it is busy
In reply to Viresh KumarWe don't need to call mpcore_wdt_stop() in suspend, if wdt is not BUSY. So, call mpcore_wdt_stop() conditionally in suspend.
--- drivers/watchdog/mpcore_wdt.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-)
drivers/watchdog/mpcore_wdt.c +3 -1
@@ -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 ; }
Signature · 1 line
1.7.8.110.g4cb5d
PATCH v2 14/22 watchdog/mpcore_wdt: replace (__raw_)readl/writel with lighter *_relaxed variants
In reply to Viresh Kumarreadl/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.
--- drivers/watchdog/mpcore_wdt.c | 18 +++++++++--------- 1 files changed, 9 insertions(+), 9 deletions(-)
drivers/watchdog/mpcore_wdt.c +9 -9
@@ -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 ;
Signature · 1 line
1.7.8.110.g4cb5d
PATCH v2 15/22 watchdog/mpcore_wdt: Add support for WDIOC_GETBOOTSTATUS IOCTL
In reply to Viresh Kumarmpcore 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.
--- arch/arm/include/asm/smp_twd.h | 2 ++ drivers/watchdog/mpcore_wdt.c | 4 ++++ 2 files changed, 6 insertions(+), 0 deletions(-)
arch/arm/include/asm/smp_twd.h +2 -0
@@ -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;
drivers/watchdog/mpcore_wdt.c +4 -0
@@ -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);
Signature · 1 line
1.7.8.110.g4cb5d
PATCH v2 16/22 watchdog/mpcore_wdt: Add clock framework support
In reply to Viresh KumarThis patch adds in clk framework support for wdt driver. If clk_get fails for some platform, then we continue without clk_* API's.
--- drivers/watchdog/mpcore_wdt.c | 66 ++++++++++++++++++++++++++++++++++++----- 1 files changed, 58 insertions(+), 8 deletions(-)
drivers/watchdog/mpcore_wdt.c +58 -8
@@ -17,6 +17,8 @@* * (c) Copyright 1995 Alan Cox <[email protected]> */ +#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 ; }
Signature · 1 line
1.7.8.110.g4cb5d
PATCH v2 17/22 watchdog/mpcore_wdt: use correct clk_rate to program timeout
In reply to Viresh KumarCurrently, 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
--- arch/arm/include/asm/smp_twd.h | 10 ++++ drivers/watchdog/mpcore_wdt.c | 97 ++++++++++++++++++++++++++++++++------- 2 files changed, 89 insertions(+), 18 deletions(-)
arch/arm/include/asm/smp_twd.h +10 -0
@@ -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 0x1struct clock_event_device ;
drivers/watchdog/mpcore_wdt.c +79 -18
148 lines not on this page · raw message
Signature · 1 line
1.7.8.110.g4cb5d
PATCH v2 17/22 watchdog/mpcore_wdt: use correct clk_rate to program timeout
Quoted 6 lines · Viresh KUMAR
Currently, mpcore wdt driver doesn't use exact
clk_rateto program timeout in hardware. This patch provides two ways of doing so:
- either useclk_get_rate()ifclk_getpasses
- useclk_ratepassed via module paramSigned-off-by Viresh Kumar <[email protected]>
Wim,
Will these go in v3.5?
Please squash following with this patch while applying.
drivers/watchdog/mpcore_wdt.c +1 -1
@@ -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);
Signature · 1 line
viresh
Re: [PATCH V2 17/22] watchdog/mpcore_wdt: use correct clk_rate to program timeout
Hi Viresh,
Quoted 11 lines · Viresh KUMAR
Quoted 6 lines
Currently, mpcore wdt driver doesn't use exact
clk_rateto program timeout in hardware. This patch provides two ways of doing so:
- either useclk_get_rate()ifclk_getpasses
- useclk_ratepassed via module paramSigned-off-by Viresh Kumar <[email protected]>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.
PATCH v2 18/22 watchdog/sp805: Fix documentation style comment
In reply to Viresh Kumar@ was missing before variables names, in their description. Also adev is mentioned as dev in comment. Fix both these issues.
--- drivers/watchdog/sp805_wdt.c | 15 +++++++-------- 1 files changed, 7 insertions(+), 8 deletions(-)
drivers/watchdog/sp805_wdt.c +7 -8
@@ -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;
Signature · 1 line
1.7.8.110.g4cb5d
PATCH v2 19/22 watchdog/sp805: replace readl/writel with lighter _relaxed variants
In reply to Viresh Kumarreadl/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.
--- drivers/watchdog/sp805_wdt.c | 24 ++++++++++++------------ 1 files changed, 12 insertions(+), 12 deletions(-)
drivers/watchdog/sp805_wdt.c +12 -12
@@ -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); }
Signature · 1 line
1.7.8.110.g4cb5d
PATCH v2 20/22 watchdog/sp805: Use devm routines
In reply to Viresh Kumarsp805 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.
--- drivers/watchdog/sp805_wdt.c | 35 +++++++++++++---------------------- 1 files changed, 13 insertions(+), 22 deletions(-)
drivers/watchdog/sp805_wdt.c +13 -22
@@ -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 ; }
Signature · 1 line
1.7.8.110.g4cb5d
PATCH v2 21/22 watchdog/sp805: convert to watchdog core
In reply to Viresh KumarThis patch converts existing sp805 watchdog driver to use already in place common infrastructure present in watchdog core. With this lot of code goes away.
--- drivers/watchdog/Kconfig | 1 + drivers/watchdog/sp805_wdt.c | 241 ++++++++++++++--------------------------- 2 files changed, 83 insertions(+), 159 deletions(-)
drivers/watchdog/Kconfig +1 -0
@@ -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.
drivers/watchdog/sp805_wdt.c +82 -159
374 lines not on this page · raw message
Signature · 1 line
1.7.8.110.g4cb5d
PATCH v2 22/22 watchdog/sp805: Add clk_{un}prepare support
In reply to Viresh Kumarclk_{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.
--- drivers/watchdog/sp805_wdt.c | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-)
drivers/watchdog/sp805_wdt.c +8 -0
@@ -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 ; }
Signature · 1 line
1.7.8.110.g4cb5d
v2 cover watchdog: ARM watchdogs: sp805 & mpcore updates & fixes
In reply to Viresh KumarQuoted 5 lines · Viresh KUMAR
Hello,
This patchset contains fixes and updates for ARM watchdog drivers sp805 and mpcore.
Quoted 9 lines
Changes since V1:
- Included patches for sp805 driver.
- Removed:wdt->clk= NULL from mpcore driver, and useIS_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
v2 cover watchdog: ARM watchdogs: sp805 & mpcore updates & fixes
Quoted 16 lines · Viresh KUMAR
Quoted 5 lines · Viresh KUMAR
Hello,
This patchset contains fixes and updates for ARM watchdog drivers sp805 and mpcore.
Quoted 9 lines
Changes since V1:
- Included patches for sp805 driver.
- Removed:wdt->clk= NULL from mpcore driver, and useIS_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.
Quoted 3 lines
Hi Wim,
Have you applied patches left in this patchset for linux-next?
Ping!!
Signature · 1 line
viresh
v2 cover watchdog: ARM watchdogs: sp805 & mpcore updates & fixes
Hi Wim,
Quoted 17 lines · Viresh Kumar
Quoted 16 lines · Viresh KUMAR
Quoted 14 lines · 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 useIS_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.
Quoted 5 lines
Quoted 3 lines
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?
Hi Viresh,
Quoted 18 lines · Viresh Kumar
Quoted 17 lines · Viresh KUMAR
Quoted 16 lines · Viresh KUMAR
Quoted 14 lines
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 useIS_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.
Quoted 7 lines
Quoted 5 lines
Quoted 3 lines
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 [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html