at91sam9_wdt.c (6ad390a25a9d1d8606b9b826878f0a30639dc2b3) | at91sam9_wdt.c (c1c30a29df7e47310caa979dc48f715ae478de5f) |
---|---|
1/* 2 * Watchdog driver for Atmel AT91SAM9x processors. 3 * 4 * Copyright (C) 2008 Renaud CERRATO r.cerrato@til-technologies.fr 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * as published by the Free Software Foundation; either version --- 21 unchanged lines hidden (view full) --- 30#include <linux/timer.h> 31#include <linux/bitops.h> 32#include <linux/uaccess.h> 33 34#include "at91sam9_wdt.h" 35 36#define DRV_NAME "AT91SAM9 Watchdog" 37 | 1/* 2 * Watchdog driver for Atmel AT91SAM9x processors. 3 * 4 * Copyright (C) 2008 Renaud CERRATO r.cerrato@til-technologies.fr 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * as published by the Free Software Foundation; either version --- 21 unchanged lines hidden (view full) --- 30#include <linux/timer.h> 31#include <linux/bitops.h> 32#include <linux/uaccess.h> 33 34#include "at91sam9_wdt.h" 35 36#define DRV_NAME "AT91SAM9 Watchdog" 37 |
38#define wdt_read(field) \ 39 __raw_readl(at91wdt_private.base + field) 40#define wdt_write(field, val) \ 41 __raw_writel((val), at91wdt_private.base + field) 42 |
|
38/* AT91SAM9 watchdog runs a 12bit counter @ 256Hz, 39 * use this to convert a watchdog 40 * value from/to milliseconds. 41 */ 42#define ms_to_ticks(t) (((t << 8) / 1000) - 1) 43#define ticks_to_ms(t) (((t + 1) * 1000) >> 8) 44 45/* Hardware timeout in seconds */ --- 12 unchanged lines hidden (view full) --- 58static int nowayout = WATCHDOG_NOWAYOUT; 59module_param(nowayout, int, 0); 60MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started " 61 "(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 62 63static void at91_ping(unsigned long data); 64 65static struct { | 43/* AT91SAM9 watchdog runs a 12bit counter @ 256Hz, 44 * use this to convert a watchdog 45 * value from/to milliseconds. 46 */ 47#define ms_to_ticks(t) (((t << 8) / 1000) - 1) 48#define ticks_to_ms(t) (((t + 1) * 1000) >> 8) 49 50/* Hardware timeout in seconds */ --- 12 unchanged lines hidden (view full) --- 63static int nowayout = WATCHDOG_NOWAYOUT; 64module_param(nowayout, int, 0); 65MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started " 66 "(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 67 68static void at91_ping(unsigned long data); 69 70static struct { |
71 void __iomem *base; |
|
66 unsigned long next_heartbeat; /* the next_heartbeat for the timer */ 67 unsigned long open; 68 char expect_close; 69 struct timer_list timer; /* The timer that pings the watchdog */ 70} at91wdt_private; 71 72/* ......................................................................... */ 73 74 75/* 76 * Reload the watchdog timer. (ie, pat the watchdog) 77 */ 78static inline void at91_wdt_reset(void) 79{ | 72 unsigned long next_heartbeat; /* the next_heartbeat for the timer */ 73 unsigned long open; 74 char expect_close; 75 struct timer_list timer; /* The timer that pings the watchdog */ 76} at91wdt_private; 77 78/* ......................................................................... */ 79 80 81/* 82 * Reload the watchdog timer. (ie, pat the watchdog) 83 */ 84static inline void at91_wdt_reset(void) 85{ |
80 at91_sys_write(AT91_WDT_CR, AT91_WDT_KEY | AT91_WDT_WDRSTT); | 86 wdt_write(AT91_WDT_CR, AT91_WDT_KEY | AT91_WDT_WDRSTT); |
81} 82 83/* 84 * Timer tick 85 */ 86static void at91_ping(unsigned long data) 87{ 88 if (time_before(jiffies, at91wdt_private.next_heartbeat) || --- 38 unchanged lines hidden (view full) --- 127 * Counter is 12 bit. 128 */ 129static int at91_wdt_settimeout(unsigned int timeout) 130{ 131 unsigned int reg; 132 unsigned int mr; 133 134 /* Check if disabled */ | 87} 88 89/* 90 * Timer tick 91 */ 92static void at91_ping(unsigned long data) 93{ 94 if (time_before(jiffies, at91wdt_private.next_heartbeat) || --- 38 unchanged lines hidden (view full) --- 133 * Counter is 12 bit. 134 */ 135static int at91_wdt_settimeout(unsigned int timeout) 136{ 137 unsigned int reg; 138 unsigned int mr; 139 140 /* Check if disabled */ |
135 mr = at91_sys_read(AT91_WDT_MR); | 141 mr = wdt_read(AT91_WDT_MR); |
136 if (mr & AT91_WDT_WDDIS) { 137 printk(KERN_ERR DRV_NAME": sorry, watchdog is disabled\n"); 138 return -EIO; 139 } 140 141 /* 142 * All counting occurs at SLOW_CLOCK / 128 = 256 Hz 143 * 144 * Since WDV is a 12-bit counter, the maximum period is 145 * 4096 / 256 = 16 seconds. 146 */ 147 reg = AT91_WDT_WDRSTEN /* causes watchdog reset */ 148 /* | AT91_WDT_WDRPROC causes processor reset only */ 149 | AT91_WDT_WDDBGHLT /* disabled in debug mode */ 150 | AT91_WDT_WDD /* restart at any time */ 151 | (timeout & AT91_WDT_WDV); /* timer value */ | 142 if (mr & AT91_WDT_WDDIS) { 143 printk(KERN_ERR DRV_NAME": sorry, watchdog is disabled\n"); 144 return -EIO; 145 } 146 147 /* 148 * All counting occurs at SLOW_CLOCK / 128 = 256 Hz 149 * 150 * Since WDV is a 12-bit counter, the maximum period is 151 * 4096 / 256 = 16 seconds. 152 */ 153 reg = AT91_WDT_WDRSTEN /* causes watchdog reset */ 154 /* | AT91_WDT_WDRPROC causes processor reset only */ 155 | AT91_WDT_WDDBGHLT /* disabled in debug mode */ 156 | AT91_WDT_WDD /* restart at any time */ 157 | (timeout & AT91_WDT_WDV); /* timer value */ |
152 at91_sys_write(AT91_WDT_MR, reg); | 158 wdt_write(AT91_WDT_MR, reg); |
153 154 return 0; 155} 156 157static const struct watchdog_info at91_wdt_info = { 158 .identity = DRV_NAME, 159 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | 160 WDIOF_MAGICCLOSE, --- 82 unchanged lines hidden (view full) --- 243static struct miscdevice at91wdt_miscdev = { 244 .minor = WATCHDOG_MINOR, 245 .name = "watchdog", 246 .fops = &at91wdt_fops, 247}; 248 249static int __init at91wdt_probe(struct platform_device *pdev) 250{ | 159 160 return 0; 161} 162 163static const struct watchdog_info at91_wdt_info = { 164 .identity = DRV_NAME, 165 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | 166 WDIOF_MAGICCLOSE, --- 82 unchanged lines hidden (view full) --- 249static struct miscdevice at91wdt_miscdev = { 250 .minor = WATCHDOG_MINOR, 251 .name = "watchdog", 252 .fops = &at91wdt_fops, 253}; 254 255static int __init at91wdt_probe(struct platform_device *pdev) 256{ |
257 struct resource *r; |
|
251 int res; 252 253 if (at91wdt_miscdev.parent) 254 return -EBUSY; 255 at91wdt_miscdev.parent = &pdev->dev; 256 | 258 int res; 259 260 if (at91wdt_miscdev.parent) 261 return -EBUSY; 262 at91wdt_miscdev.parent = &pdev->dev; 263 |
264 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 265 if (!r) 266 return -ENODEV; 267 at91wdt_private.base = ioremap(r->start, resource_size(r)); 268 if (!at91wdt_private.base) { 269 dev_err(&pdev->dev, "failed to map registers, aborting.\n"); 270 return -ENOMEM; 271 } 272 |
|
257 /* Set watchdog */ 258 res = at91_wdt_settimeout(ms_to_ticks(WDT_HW_TIMEOUT * 1000)); 259 if (res) 260 return res; 261 262 res = misc_register(&at91wdt_miscdev); 263 if (res) 264 return res; --- 47 unchanged lines hidden --- | 273 /* Set watchdog */ 274 res = at91_wdt_settimeout(ms_to_ticks(WDT_HW_TIMEOUT * 1000)); 275 if (res) 276 return res; 277 278 res = misc_register(&at91wdt_miscdev); 279 if (res) 280 return res; --- 47 unchanged lines hidden --- |