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 @@
*/
#undef ONLY_TESTING
#define TIMER_MARGIN 60 /* (secs) Default is 1 minute */
#define FCLK (50*1000*1000) /* 50MHz */
static int soft_margin = TIMER_MARGIN; /* in seconds */
static int timer_alive;
static unsigned int soft_margin = 60; /* in seconds */
static unsigned int reload;
static unsigned long timer_alive;
#ifdef ONLY_TESTING
/*
* If the timer expires..
*/
static void watchdog_fire(int irq, void *dev_id, struct pt_regs *regs)
{
printk(KERN_CRIT "Watchdog: Would Reboot.\n");
......@@ -57,53 +53,68 @@ static void watchdog_fire(int irq, void *dev_id, struct pt_regs *regs)
}
#endif
static void watchdog_ping(void)
{
/*
/*
* Refresh the timer.
*/
*CSR_TIMER4_LOAD = soft_margin * (FCLK / 256);
static void watchdog_ping(void)
{
*CSR_TIMER4_LOAD = reload;
}
/*
* Allow only one person to hold it open
*/
static int watchdog_open(struct inode *inode, struct file *file)
{
if(timer_alive)
int ret;
if (*CSR_SA110_CNTL & (1 << 13))
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;
watchdog_ping();
*CSR_TIMER4_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_AUTORELOAD
| TIMER_CNTL_DIV256;
#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
/*
* Setting this bit is irreversible; once enabled, there is
* no way to disable the watchdog.
*/
*CSR_SA110_CNTL |= 1 << 13;
MOD_INC_USE_COUNT;
ret = 0;
#endif
timer_alive = 1;
return 0;
return ret;
}
/*
* 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)
{
#ifdef ONLY_TESTING
free_irq(IRQ_TIMER4, NULL);
timer_alive = 0;
#else
/*
* It's irreversible!
*/
clear_bit(1, &timer_alive);
#endif
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 */
if (ppos != &file->f_pos)
......@@ -112,54 +123,64 @@ static ssize_t watchdog_write(struct file *file, const char *data, size_t len, l
/*
* Refresh the timer.
*/
if(len)
{
if (len)
watchdog_ping();
return 1;
}
return 0;
return len;
}
static int watchdog_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
static struct watchdog_info ident = {
.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;
static struct watchdog_info ident=
{
WDIOF_SETTIMEOUT,
0,
"Footbridge Watchdog"
};
switch(cmd)
{
default:
return -ENOTTY;
unsigned int new_margin;
int ret = -ENOIOCTLCMD;
switch(cmd) {
case WDIOC_GETSUPPORT:
if(copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident)))
return -EFAULT;
return 0;
ret = 0;
if (copy_to_user((void *)arg, &ident, sizeof(ident)))
ret = -EFAULT;
break;
case WDIOC_GETSTATUS:
case WDIOC_GETBOOTSTATUS:
return put_user(0,(int *)arg);
ret = put_user(0,(int *)arg);
break;
case WDIOC_KEEPALIVE:
watchdog_ping();
return 0;
ret = 0;
break;
case WDIOC_SETTIMEOUT:
if (get_user(new_margin, (int *)arg))
return -EFAULT;
ret = get_user(new_margin, (int *)arg);
if (ret)
break;
/* Arbitrary, can't find the card's limits */
if ((new_marg < 0) || (new_margin > 60))
return -EINVAL;
if (new_margin < 0 || new_margin > 60) {
ret = -EINVAL;
break;
}
soft_margin = new_margin;
reload = soft_margin * (mem_fclk_21285 / 256);
watchdog_ping();
/* Fall */
case WDIOC_GETTIMEOUT:
return put_user(soft_margin, (int *)arg);
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,
.write = watchdog_write,
.ioctl = watchdog_ioctl,
......@@ -167,11 +188,10 @@ static struct file_operations watchdog_fops=
.release = watchdog_release,
};
static struct miscdevice watchdog_miscdev=
{
WATCHDOG_MINOR,
"watchdog",
&watchdog_fops
static struct miscdevice watchdog_miscdev = {
.minor = WATCHDOG_MINOR,
.name = "watchdog",
.fops = &watchdog_fops
};
static int __init footbridge_watchdog_init(void)
......@@ -182,11 +202,12 @@ static int __init footbridge_watchdog_init(void)
return -ENODEV;
retval = misc_register(&watchdog_miscdev);
if(retval < 0)
if (retval < 0)
return retval;
printk("Footbridge Watchdog Timer: 0.01, timer margin: %d sec\n",
soft_margin);
if (machine_is_cats())
printk("Warning: Watchdog reset may not work on this machine.\n");
return 0;
......@@ -198,7 +219,7 @@ static void __exit footbridge_watchdog_exit(void)
}
MODULE_AUTHOR("Phil Blundell <pb@nexus.co.uk>");
MODULE_DESCRIPTION("21285 watchdog driver");
MODULE_DESCRIPTION("Footbridge watchdog driver");
MODULE_LICENSE("GPL");
MODULE_PARM(soft_margin,"i");
......
......@@ -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 */
int kick_wdog(void)
static int kick_wdog(void)
{
/*
* Refresh the timer.
......@@ -220,17 +220,16 @@ static ssize_t wdt977_write(struct file *file, const char *buf, size_t count, lo
if (ppos != &file->f_pos)
return -ESPIPE;
if(count)
{
if (count) {
if (!nowayout) {
size_t i;
/* In case it was set long ago */
expect_close = 0;
for (i = 0; i != len; i++) {
for (i = 0; i != count; i++) {
char c;
if (get_user(c, data + i))
if (get_user(c, buf + i))
return -EFAULT;
if (c == 'V')
expect_close = 1;
......@@ -238,9 +237,8 @@ static ssize_t wdt977_write(struct file *file, const char *buf, size_t count, lo
}
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
* 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,
unsigned int cmd, unsigned long arg)
{
static struct watchdog_info ident = {
identity : "Winbond 83977"
};
int temp;
int temp;
switch(cmd)
{
......@@ -337,9 +337,9 @@ static struct file_operations wdt977_fops=
static struct miscdevice wdt977_miscdev=
{
WATCHDOG_MINOR,
"watchdog",
&wdt977_fops
.minor = WATCHDOG_MINOR,
.name = "watchdog",
.fops = &wdt977_fops
};
static int __init nwwatchdog_init(void)
......@@ -360,4 +360,5 @@ static void __exit nwwatchdog_exit(void)
module_init(nwwatchdog_init);
module_exit(nwwatchdog_exit);
MODULE_DESCRIPTION("W83977AF Watchdog driver");
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