Commit adae0c4e authored by Russell King's avatar Russell King

[ARM] Update wdt285 and wdt977 watchdog drivers

General updates to these two watchdog drivers, including:
- converting initialisers to C99 syntax
- correcting module descriptions
- ensuring private symbols are declared static
- ensuring correct options are reported in the watchdog_info structure
- ensuring we use the right clock value for calculating timeouts
- ensuring failure cleanup paths are properly implemented
- don't use MOD_{INC,DEC}_USE_COUNT
parent 974a9d19
...@@ -37,18 +37,14 @@ ...@@ -37,18 +37,14 @@
*/ */
#undef ONLY_TESTING #undef ONLY_TESTING
#define TIMER_MARGIN 60 /* (secs) Default is 1 minute */ static unsigned int soft_margin = 60; /* in seconds */
static unsigned int reload;
#define FCLK (50*1000*1000) /* 50MHz */ static unsigned long timer_alive;
static int soft_margin = TIMER_MARGIN; /* in seconds */
static int timer_alive;
#ifdef ONLY_TESTING #ifdef ONLY_TESTING
/* /*
* If the timer expires.. * If the timer expires..
*/ */
static void watchdog_fire(int irq, void *dev_id, struct pt_regs *regs) static void watchdog_fire(int irq, void *dev_id, struct pt_regs *regs)
{ {
printk(KERN_CRIT "Watchdog: Would Reboot.\n"); printk(KERN_CRIT "Watchdog: Would Reboot.\n");
...@@ -57,109 +53,134 @@ static void watchdog_fire(int irq, void *dev_id, struct pt_regs *regs) ...@@ -57,109 +53,134 @@ static void watchdog_fire(int irq, void *dev_id, struct pt_regs *regs)
} }
#endif #endif
/*
* Refresh the timer.
*/
static void watchdog_ping(void) static void watchdog_ping(void)
{ {
/* *CSR_TIMER4_LOAD = reload;
* Refresh the timer.
*/
*CSR_TIMER4_LOAD = soft_margin * (FCLK / 256);
} }
/* /*
* Allow only one person to hold it open * Allow only one person to hold it open
*/ */
static int watchdog_open(struct inode *inode, struct file *file) static int watchdog_open(struct inode *inode, struct file *file)
{ {
if(timer_alive) int ret;
if (*CSR_SA110_CNTL & (1 << 13))
return -EBUSY; return -EBUSY;
/*
* Ahead watchdog factor ten, Mr Sulu if (test_and_set_bit(1, &timer_alive))
*/ return -EBUSY;
reload = soft_margin * (mem_fclk_21285 / 256);
*CSR_TIMER4_CLR = 0; *CSR_TIMER4_CLR = 0;
watchdog_ping(); watchdog_ping();
*CSR_TIMER4_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_AUTORELOAD *CSR_TIMER4_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_AUTORELOAD
| TIMER_CNTL_DIV256; | TIMER_CNTL_DIV256;
#ifdef ONLY_TESTING #ifdef ONLY_TESTING
request_irq(IRQ_TIMER4, watchdog_fire, 0, "watchdog", NULL); ret = request_irq(IRQ_TIMER4, watchdog_fire, 0, "watchdog", NULL);
if (ret) {
*CSR_TIMER4_CNTL = 0;
clear_bit(1, &timer_alive);
}
#else #else
/*
* Setting this bit is irreversible; once enabled, there is
* no way to disable the watchdog.
*/
*CSR_SA110_CNTL |= 1 << 13; *CSR_SA110_CNTL |= 1 << 13;
MOD_INC_USE_COUNT;
ret = 0;
#endif #endif
timer_alive = 1; return ret;
return 0;
} }
/*
* Shut off the timer.
* Note: if we really have enabled the watchdog, there
* is no way to turn off.
*/
static int watchdog_release(struct inode *inode, struct file *file) static int watchdog_release(struct inode *inode, struct file *file)
{ {
#ifdef ONLY_TESTING #ifdef ONLY_TESTING
free_irq(IRQ_TIMER4, NULL); free_irq(IRQ_TIMER4, NULL);
timer_alive = 0; clear_bit(1, &timer_alive);
#else
/*
* It's irreversible!
*/
#endif #endif
return 0; return 0;
} }
static ssize_t watchdog_write(struct file *file, const char *data, size_t len, loff_t *ppos) static ssize_t
watchdog_write(struct file *file, const char *data, size_t len, loff_t *ppos)
{ {
/* Can't seek (pwrite) on this device */ /* Can't seek (pwrite) on this device */
if (ppos != &file->f_pos) if (ppos != &file->f_pos)
return -ESPIPE; return -ESPIPE;
/* /*
* Refresh the timer. * Refresh the timer.
*/ */
if(len) if (len)
{
watchdog_ping(); watchdog_ping();
return 1;
} return len;
return 0;
} }
static int watchdog_ioctl(struct inode *inode, struct file *file, static struct watchdog_info ident = {
unsigned int cmd, unsigned long arg) .options = WDIOF_SETTIMEOUT,
.identity = "Footbridge Watchdog"
};
static int
watchdog_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg)
{ {
int i, new_margin; unsigned int new_margin;
static struct watchdog_info ident= int ret = -ENOIOCTLCMD;
{
WDIOF_SETTIMEOUT, switch(cmd) {
0, case WDIOC_GETSUPPORT:
"Footbridge Watchdog" ret = 0;
}; if (copy_to_user((void *)arg, &ident, sizeof(ident)))
switch(cmd) ret = -EFAULT;
{ break;
default:
return -ENOTTY; case WDIOC_GETSTATUS:
case WDIOC_GETSUPPORT: case WDIOC_GETBOOTSTATUS:
if(copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident))) ret = put_user(0,(int *)arg);
return -EFAULT; break;
return 0;
case WDIOC_GETSTATUS: case WDIOC_KEEPALIVE:
case WDIOC_GETBOOTSTATUS: watchdog_ping();
return put_user(0,(int *)arg); ret = 0;
case WDIOC_KEEPALIVE: break;
watchdog_ping();
return 0; case WDIOC_SETTIMEOUT:
case WDIOC_SETTIMEOUT: ret = get_user(new_margin, (int *)arg);
if (get_user(new_margin, (int *)arg)) if (ret)
return -EFAULT; break;
/* Arbitrary, can't find the card's limits */
if ((new_marg < 0) || (new_margin > 60)) /* Arbitrary, can't find the card's limits */
return -EINVAL; if (new_margin < 0 || new_margin > 60) {
soft_margin = new_margin; ret = -EINVAL;
watchdog_ping(); break;
/* Fall */ }
case WDIOC_GETTIMEOUT:
return put_user(soft_margin, (int *)arg); soft_margin = new_margin;
reload = soft_margin * (mem_fclk_21285 / 256);
watchdog_ping();
/* Fall */
case WDIOC_GETTIMEOUT:
ret = put_user(soft_margin, (int *)arg);
break;
} }
return ret;
} }
static struct file_operations watchdog_fops= static struct file_operations watchdog_fops = {
{
.owner = THIS_MODULE, .owner = THIS_MODULE,
.write = watchdog_write, .write = watchdog_write,
.ioctl = watchdog_ioctl, .ioctl = watchdog_ioctl,
...@@ -167,11 +188,10 @@ static struct file_operations watchdog_fops= ...@@ -167,11 +188,10 @@ static struct file_operations watchdog_fops=
.release = watchdog_release, .release = watchdog_release,
}; };
static struct miscdevice watchdog_miscdev= static struct miscdevice watchdog_miscdev = {
{ .minor = WATCHDOG_MINOR,
WATCHDOG_MINOR, .name = "watchdog",
"watchdog", .fops = &watchdog_fops
&watchdog_fops
}; };
static int __init footbridge_watchdog_init(void) static int __init footbridge_watchdog_init(void)
...@@ -182,11 +202,12 @@ static int __init footbridge_watchdog_init(void) ...@@ -182,11 +202,12 @@ static int __init footbridge_watchdog_init(void)
return -ENODEV; return -ENODEV;
retval = misc_register(&watchdog_miscdev); retval = misc_register(&watchdog_miscdev);
if(retval < 0) if (retval < 0)
return retval; return retval;
printk("Footbridge Watchdog Timer: 0.01, timer margin: %d sec\n", printk("Footbridge Watchdog Timer: 0.01, timer margin: %d sec\n",
soft_margin); soft_margin);
if (machine_is_cats()) if (machine_is_cats())
printk("Warning: Watchdog reset may not work on this machine.\n"); printk("Warning: Watchdog reset may not work on this machine.\n");
return 0; return 0;
...@@ -198,7 +219,7 @@ static void __exit footbridge_watchdog_exit(void) ...@@ -198,7 +219,7 @@ static void __exit footbridge_watchdog_exit(void)
} }
MODULE_AUTHOR("Phil Blundell <pb@nexus.co.uk>"); MODULE_AUTHOR("Phil Blundell <pb@nexus.co.uk>");
MODULE_DESCRIPTION("21285 watchdog driver"); MODULE_DESCRIPTION("Footbridge watchdog driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_PARM(soft_margin,"i"); MODULE_PARM(soft_margin,"i");
......
...@@ -58,7 +58,7 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CON ...@@ -58,7 +58,7 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CON
/* This is kicking the watchdog by simply re-writing the timeout to reg. 0xF2 */ /* This is kicking the watchdog by simply re-writing the timeout to reg. 0xF2 */
int kick_wdog(void) static int kick_wdog(void)
{ {
/* /*
* Refresh the timer. * Refresh the timer.
...@@ -216,21 +216,20 @@ static int wdt977_release(struct inode *inode, struct file *file) ...@@ -216,21 +216,20 @@ static int wdt977_release(struct inode *inode, struct file *file)
static ssize_t wdt977_write(struct file *file, const char *buf, size_t count, loff_t *ppos) static ssize_t wdt977_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
{ {
/* Can't seek (pwrite) on this device */ /* Can't seek (pwrite) on this device */
if (ppos != &file->f_pos) if (ppos != &file->f_pos)
return -ESPIPE; return -ESPIPE;
if(count) if (count) {
{
if (!nowayout) { if (!nowayout) {
size_t i; size_t i;
/* In case it was set long ago */ /* In case it was set long ago */
expect_close = 0; expect_close = 0;
for (i = 0; i != len; i++) { for (i = 0; i != count; i++) {
char c; char c;
if (get_user(c, data + i)) if (get_user(c, buf + i))
return -EFAULT; return -EFAULT;
if (c == 'V') if (c == 'V')
expect_close = 1; expect_close = 1;
...@@ -238,9 +237,8 @@ static ssize_t wdt977_write(struct file *file, const char *buf, size_t count, lo ...@@ -238,9 +237,8 @@ static ssize_t wdt977_write(struct file *file, const char *buf, size_t count, lo
} }
kick_wdog(); kick_wdog();
return 1;
} }
return 0; return count;
} }
/* /*
...@@ -254,14 +252,16 @@ static ssize_t wdt977_write(struct file *file, const char *buf, size_t count, lo ...@@ -254,14 +252,16 @@ static ssize_t wdt977_write(struct file *file, const char *buf, size_t count, lo
* according to their available features. * according to their available features.
*/ */
static struct watchdog_info ident = {
.options = WDIOF_SETTIMEOUT,
.identity = "Winbond 83977"
};
static int wdt977_ioctl(struct inode *inode, struct file *file, static int wdt977_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg) unsigned int cmd, unsigned long arg)
{ {
static struct watchdog_info ident = {
identity : "Winbond 83977"
};
int temp; int temp;
switch(cmd) switch(cmd)
{ {
...@@ -337,9 +337,9 @@ static struct file_operations wdt977_fops= ...@@ -337,9 +337,9 @@ static struct file_operations wdt977_fops=
static struct miscdevice wdt977_miscdev= static struct miscdevice wdt977_miscdev=
{ {
WATCHDOG_MINOR, .minor = WATCHDOG_MINOR,
"watchdog", .name = "watchdog",
&wdt977_fops .fops = &wdt977_fops
}; };
static int __init nwwatchdog_init(void) static int __init nwwatchdog_init(void)
...@@ -360,4 +360,5 @@ static void __exit nwwatchdog_exit(void) ...@@ -360,4 +360,5 @@ static void __exit nwwatchdog_exit(void)
module_init(nwwatchdog_init); module_init(nwwatchdog_init);
module_exit(nwwatchdog_exit); module_exit(nwwatchdog_exit);
MODULE_DESCRIPTION("W83977AF Watchdog driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment