diff options
| author | Thomas Reitmayr <treitmayr@devbase.at> | 2009-02-24 17:59:22 -0500 |
|---|---|---|
| committer | Wim Van Sebroeck <wim@iguana.be> | 2009-03-25 05:02:50 -0400 |
| commit | 9e058d4f57751daa008b764735f97fdfccfeab6c (patch) | |
| tree | d9e194a94ab6b1dd30400570c8796ab017185cdc | |
| parent | f296b14355a2d0cb170a85236ec391bb0a3fdb3a (diff) | |
[WATCHDOG] orion5x_wdt: fix compile issue by providing tclk as platform data
The orion5x-wdt driver is now registered as a platform device and
receives the tclk value as platform data. This fixes a compile issue
cause by a previously removed define "ORION5X_TCLK".
Signed-off-by: Thomas Reitmayr <treitmayr@devbase.at>
Acked-by: Nicolas Pitre <nico@marvell.com>
Signed-off-by: Kristof Provost <kristof@sigsegv.be>
Cc: Lennert Buytenhek <buytenh@wantstofly.org>
Cc: Wim Van Sebroeck <wim@iguana.be>
Cc: Russell King <rmk@arm.linux.org.uk>
Cc: Martin Michlmayr <tbm@cyrius.com>
Cc: Sylver Bruneau <sylver.bruneau@googlemail.com>
Cc: Kunihiko IMAI <bak@d2.dion.ne.jp>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
| -rw-r--r-- | arch/arm/mach-orion5x/common.c | 29 | ||||
| -rw-r--r-- | arch/arm/plat-orion/include/plat/orion5x_wdt.h | 18 | ||||
| -rw-r--r-- | drivers/watchdog/orion5x_wdt.c | 76 |
3 files changed, 109 insertions, 14 deletions
diff --git a/arch/arm/mach-orion5x/common.c b/arch/arm/mach-orion5x/common.c index 8a0e49d84256..1a1df24f419e 100644 --- a/arch/arm/mach-orion5x/common.c +++ b/arch/arm/mach-orion5x/common.c | |||
| @@ -31,6 +31,7 @@ | |||
| 31 | #include <plat/ehci-orion.h> | 31 | #include <plat/ehci-orion.h> |
| 32 | #include <plat/mv_xor.h> | 32 | #include <plat/mv_xor.h> |
| 33 | #include <plat/orion_nand.h> | 33 | #include <plat/orion_nand.h> |
| 34 | #include <plat/orion5x_wdt.h> | ||
| 34 | #include <plat/time.h> | 35 | #include <plat/time.h> |
| 35 | #include "common.h" | 36 | #include "common.h" |
| 36 | 37 | ||
| @@ -533,6 +534,29 @@ void __init orion5x_xor_init(void) | |||
| 533 | 534 | ||
| 534 | 535 | ||
| 535 | /***************************************************************************** | 536 | /***************************************************************************** |
| 537 | * Watchdog | ||
| 538 | ****************************************************************************/ | ||
| 539 | static struct orion5x_wdt_platform_data orion5x_wdt_data = { | ||
| 540 | .tclk = 0, | ||
| 541 | }; | ||
| 542 | |||
| 543 | static struct platform_device orion5x_wdt_device = { | ||
| 544 | .name = "orion5x_wdt", | ||
| 545 | .id = -1, | ||
| 546 | .dev = { | ||
| 547 | .platform_data = &orion5x_wdt_data, | ||
| 548 | }, | ||
| 549 | .num_resources = 0, | ||
| 550 | }; | ||
| 551 | |||
| 552 | void __init orion5x_wdt_init(void) | ||
| 553 | { | ||
| 554 | orion5x_wdt_data.tclk = orion5x_tclk; | ||
| 555 | platform_device_register(&orion5x_wdt_device); | ||
| 556 | } | ||
| 557 | |||
| 558 | |||
| 559 | /***************************************************************************** | ||
| 536 | * Time handling | 560 | * Time handling |
| 537 | ****************************************************************************/ | 561 | ****************************************************************************/ |
| 538 | int orion5x_tclk; | 562 | int orion5x_tclk; |
| @@ -631,6 +655,11 @@ void __init orion5x_init(void) | |||
| 631 | printk(KERN_INFO "Orion: Applying 5281 D0 WFI workaround.\n"); | 655 | printk(KERN_INFO "Orion: Applying 5281 D0 WFI workaround.\n"); |
| 632 | disable_hlt(); | 656 | disable_hlt(); |
| 633 | } | 657 | } |
| 658 | |||
| 659 | /* | ||
| 660 | * Register watchdog driver | ||
| 661 | */ | ||
| 662 | orion5x_wdt_init(); | ||
| 634 | } | 663 | } |
| 635 | 664 | ||
| 636 | /* | 665 | /* |
diff --git a/arch/arm/plat-orion/include/plat/orion5x_wdt.h b/arch/arm/plat-orion/include/plat/orion5x_wdt.h new file mode 100644 index 000000000000..3c9cf6a305ef --- /dev/null +++ b/arch/arm/plat-orion/include/plat/orion5x_wdt.h | |||
| @@ -0,0 +1,18 @@ | |||
| 1 | /* | ||
| 2 | * arch/arm/plat-orion/include/plat/orion5x_wdt.h | ||
| 3 | * | ||
| 4 | * This file is licensed under the terms of the GNU General Public | ||
| 5 | * License version 2. This program is licensed "as is" without any | ||
| 6 | * warranty of any kind, whether express or implied. | ||
| 7 | */ | ||
| 8 | |||
| 9 | #ifndef __PLAT_ORION5X_WDT_H | ||
| 10 | #define __PLAT_ORION5X_WDT_H | ||
| 11 | |||
| 12 | struct orion5x_wdt_platform_data { | ||
| 13 | u32 tclk; /* no <linux/clk.h> support yet */ | ||
| 14 | }; | ||
| 15 | |||
| 16 | |||
| 17 | #endif | ||
| 18 | |||
diff --git a/drivers/watchdog/orion5x_wdt.c b/drivers/watchdog/orion5x_wdt.c index b64ae1a17832..e81441f103dd 100644 --- a/drivers/watchdog/orion5x_wdt.c +++ b/drivers/watchdog/orion5x_wdt.c | |||
| @@ -16,11 +16,13 @@ | |||
| 16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
| 17 | #include <linux/fs.h> | 17 | #include <linux/fs.h> |
| 18 | #include <linux/miscdevice.h> | 18 | #include <linux/miscdevice.h> |
| 19 | #include <linux/platform_device.h> | ||
| 19 | #include <linux/watchdog.h> | 20 | #include <linux/watchdog.h> |
| 20 | #include <linux/init.h> | 21 | #include <linux/init.h> |
| 21 | #include <linux/uaccess.h> | 22 | #include <linux/uaccess.h> |
| 22 | #include <linux/io.h> | 23 | #include <linux/io.h> |
| 23 | #include <linux/spinlock.h> | 24 | #include <linux/spinlock.h> |
| 25 | #include <plat/orion5x_wdt.h> | ||
| 24 | 26 | ||
| 25 | /* | 27 | /* |
| 26 | * Watchdog timer block registers. | 28 | * Watchdog timer block registers. |
| @@ -29,13 +31,14 @@ | |||
| 29 | #define WDT_EN 0x0010 | 31 | #define WDT_EN 0x0010 |
| 30 | #define WDT_VAL (TIMER_VIRT_BASE + 0x0024) | 32 | #define WDT_VAL (TIMER_VIRT_BASE + 0x0024) |
| 31 | 33 | ||
| 32 | #define ORION5X_TCLK 166666667 | 34 | #define WDT_MAX_CYCLE_COUNT 0xffffffff |
| 33 | #define WDT_MAX_DURATION (0xffffffff / ORION5X_TCLK) | ||
| 34 | #define WDT_IN_USE 0 | 35 | #define WDT_IN_USE 0 |
| 35 | #define WDT_OK_TO_CLOSE 1 | 36 | #define WDT_OK_TO_CLOSE 1 |
| 36 | 37 | ||
| 37 | static int nowayout = WATCHDOG_NOWAYOUT; | 38 | static int nowayout = WATCHDOG_NOWAYOUT; |
| 38 | static int heartbeat = WDT_MAX_DURATION; /* (seconds) */ | 39 | static int heartbeat = -1; /* module parameter (seconds) */ |
| 40 | static unsigned int wdt_max_duration; /* (seconds) */ | ||
| 41 | static unsigned int wdt_tclk; | ||
| 39 | static unsigned long wdt_status; | 42 | static unsigned long wdt_status; |
| 40 | static spinlock_t wdt_lock; | 43 | static spinlock_t wdt_lock; |
| 41 | 44 | ||
| @@ -46,7 +49,7 @@ static void wdt_enable(void) | |||
| 46 | spin_lock(&wdt_lock); | 49 | spin_lock(&wdt_lock); |
| 47 | 50 | ||
| 48 | /* Set watchdog duration */ | 51 | /* Set watchdog duration */ |
| 49 | writel(ORION5X_TCLK * heartbeat, WDT_VAL); | 52 | writel(wdt_tclk * heartbeat, WDT_VAL); |
| 50 | 53 | ||
| 51 | /* Clear watchdog timer interrupt */ | 54 | /* Clear watchdog timer interrupt */ |
| 52 | reg = readl(BRIDGE_CAUSE); | 55 | reg = readl(BRIDGE_CAUSE); |
| @@ -88,7 +91,7 @@ static void wdt_disable(void) | |||
| 88 | static int orion5x_wdt_get_timeleft(int *time_left) | 91 | static int orion5x_wdt_get_timeleft(int *time_left) |
| 89 | { | 92 | { |
| 90 | spin_lock(&wdt_lock); | 93 | spin_lock(&wdt_lock); |
| 91 | *time_left = readl(WDT_VAL) / ORION5X_TCLK; | 94 | *time_left = readl(WDT_VAL) / wdt_tclk; |
| 92 | spin_unlock(&wdt_lock); | 95 | spin_unlock(&wdt_lock); |
| 93 | return 0; | 96 | return 0; |
| 94 | } | 97 | } |
| @@ -158,7 +161,7 @@ static long orion5x_wdt_ioctl(struct file *file, unsigned int cmd, | |||
| 158 | if (ret) | 161 | if (ret) |
| 159 | break; | 162 | break; |
| 160 | 163 | ||
| 161 | if (time <= 0 || time > WDT_MAX_DURATION) { | 164 | if (time <= 0 || time > wdt_max_duration) { |
| 162 | ret = -EINVAL; | 165 | ret = -EINVAL; |
| 163 | break; | 166 | break; |
| 164 | } | 167 | } |
| @@ -210,23 +213,69 @@ static struct miscdevice orion5x_wdt_miscdev = { | |||
| 210 | .fops = &orion5x_wdt_fops, | 213 | .fops = &orion5x_wdt_fops, |
| 211 | }; | 214 | }; |
| 212 | 215 | ||
| 213 | static int __init orion5x_wdt_init(void) | 216 | static int __devinit orion5x_wdt_probe(struct platform_device *pdev) |
| 214 | { | 217 | { |
| 218 | struct orion5x_wdt_platform_data *pdata = pdev->dev.platform_data; | ||
| 215 | int ret; | 219 | int ret; |
| 216 | 220 | ||
| 217 | spin_lock_init(&wdt_lock); | 221 | if (pdata) { |
| 222 | wdt_tclk = pdata->tclk; | ||
| 223 | } else { | ||
| 224 | printk(KERN_ERR "Orion5x Watchdog misses platform data\n"); | ||
| 225 | return -ENODEV; | ||
| 226 | } | ||
| 227 | |||
| 228 | if (orion5x_wdt_miscdev.parent) | ||
| 229 | return -EBUSY; | ||
| 230 | orion5x_wdt_miscdev.parent = &pdev->dev; | ||
| 231 | |||
| 232 | wdt_max_duration = WDT_MAX_CYCLE_COUNT / wdt_tclk; | ||
| 233 | if (heartbeat <= 0 || heartbeat > wdt_max_duration) | ||
| 234 | heartbeat = wdt_max_duration; | ||
| 218 | 235 | ||
| 219 | ret = misc_register(&orion5x_wdt_miscdev); | 236 | ret = misc_register(&orion5x_wdt_miscdev); |
| 220 | if (ret == 0) | 237 | if (ret) |
| 221 | printk("Orion5x Watchdog Timer: heartbeat %d sec\n", | 238 | return ret; |
| 222 | heartbeat); | 239 | |
| 240 | printk(KERN_INFO "Orion5x Watchdog Timer: Initial timeout %d sec%s\n", | ||
| 241 | heartbeat, nowayout ? ", nowayout" : ""); | ||
| 242 | return 0; | ||
| 243 | } | ||
| 244 | |||
| 245 | static int __devexit orion5x_wdt_remove(struct platform_device *pdev) | ||
| 246 | { | ||
| 247 | int ret; | ||
| 248 | |||
| 249 | if (test_bit(WDT_IN_USE, &wdt_status)) { | ||
| 250 | wdt_disable(); | ||
| 251 | clear_bit(WDT_IN_USE, &wdt_status); | ||
| 252 | } | ||
| 253 | |||
| 254 | ret = misc_deregister(&orion5x_wdt_miscdev); | ||
| 255 | if (!ret) | ||
| 256 | orion5x_wdt_miscdev.parent = NULL; | ||
| 223 | 257 | ||
| 224 | return ret; | 258 | return ret; |
| 225 | } | 259 | } |
| 226 | 260 | ||
| 261 | static struct platform_driver orion5x_wdt_driver = { | ||
| 262 | .probe = orion5x_wdt_probe, | ||
| 263 | .remove = __devexit_p(orion5x_wdt_remove), | ||
| 264 | .driver = { | ||
| 265 | .owner = THIS_MODULE, | ||
| 266 | .name = "orion5x_wdt", | ||
| 267 | }, | ||
| 268 | }; | ||
| 269 | |||
| 270 | static int __init orion5x_wdt_init(void) | ||
| 271 | { | ||
| 272 | spin_lock_init(&wdt_lock); | ||
| 273 | return platform_driver_register(&orion5x_wdt_driver); | ||
| 274 | } | ||
| 275 | |||
| 227 | static void __exit orion5x_wdt_exit(void) | 276 | static void __exit orion5x_wdt_exit(void) |
| 228 | { | 277 | { |
| 229 | misc_deregister(&orion5x_wdt_miscdev); | 278 | platform_driver_unregister(&orion5x_wdt_driver); |
| 230 | } | 279 | } |
| 231 | 280 | ||
| 232 | module_init(orion5x_wdt_init); | 281 | module_init(orion5x_wdt_init); |
| @@ -236,8 +285,7 @@ MODULE_AUTHOR("Sylver Bruneau <sylver.bruneau@googlemail.com>"); | |||
| 236 | MODULE_DESCRIPTION("Orion5x Processor Watchdog"); | 285 | MODULE_DESCRIPTION("Orion5x Processor Watchdog"); |
| 237 | 286 | ||
| 238 | module_param(heartbeat, int, 0); | 287 | module_param(heartbeat, int, 0); |
| 239 | MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds (default is " | 288 | MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds"); |
| 240 | __MODULE_STRING(WDT_MAX_DURATION) ")"); | ||
| 241 | 289 | ||
| 242 | module_param(nowayout, int, 0); | 290 | module_param(nowayout, int, 0); |
| 243 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started"); | 291 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started"); |
