From: "Bob Zhang" <zhanglinbao@gmail.com>
To: <linux-kernel@vger.kernel.org>
Subject: About watch dog timer limit of CPU (Xscale ->IXP425) How can I set more long time ?
Date: Mon, 4 Dec 2006 13:41:24 +0800 [thread overview]
Message-ID: <02ab01c71766$dcb2b1f0$270515ac@9BobZhang1> (raw)
[-- Attachment #1: Type: text/plain, Size: 1682 bytes --]
Hello all ,
My embeded board hardware configuration is like this :
# cat /proc/cpuinfo
Processor : XScale-IXP425/IXC1100 rev 1 (v5b)
BogoMIPS : 266.24
Features : swp half thumb fastmult edsp
Hardware : Intel IXDP425 Development Platform
Revision : 0000
Serial : 0000000000000000
Through reading datasheet of ixp4xx ,I know it has own watchdog functions ,
please see attchment :15 Timer
I find a driver by goole ,
see attachment .
Watchdog timer counter is 32 bit register , its max value is 2<<32 -1
#define TIMER_FREQ 66000000 /* 66 MHZ timer */
#define TIMER_KEY 0x482e
#define TIMER_MARGIN 60 /* (secs) Default is 1 minute */
//I want to modify it ,I find its max value is 65
static int ixp425_margin = TIMER_MARGIN; /* in seconds */
static int ixp425wdt_users;
//static int pre_margin; //IXP425 CPU 's watch dog timer is 32 bit ,
//so I define it to be unsigned int --bob
static unsigned int pre_margin;
pre_margin = TIMER_FREQ * TIMER_MARGIN
*IXP425_OSWT = pre_margin;
if I need one minutes ,
*IXP425_OSWT = 66000000 * 60 = 396000000 ,not overflow
if I need two minutes ,
*IXP425_OSWT = 66000000 * 120 = 792000000 ( which has been > 2<<32-1 , overflow
So I compute the max time I can set :
T_max = 2<<32-1 / 66000000 = 65 seconds 。
--------------------
My question:
if need more seconds ( for example , 5 minutes ) ,what should I do ?
I have a method based on datasheet (ixp4xx) ,but I don't know if it will successed when system crash
How can I do to break the limit of hardware ?
Thanks ahead !
--
Best Regards
bob
[-- Attachment #2: ixp425_wdt.c --]
[-- Type: application/octet-stream, Size: 7150 bytes --]
/*
* Watchdog driver for the IXP2400/IXP2800 based platforms
*
* (c) Copyright 2000 Intel Coporation
* Based on SoftDog driver by Alan Cox <alan@redhat.com>
*
* 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 Oleg Drokin nor iXcelerator.com admit liability nor provide
* warranty for any of this software. This material is provided
* "AS-IS" and at no charge.
*
* Harold Yang <harold.yang@intel.com>
* Stanley Wang <stanley.wang@intel.com>
*
*/
#include <linux/module.h>
#include <linux/config.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/miscdevice.h>
#include <linux/watchdog.h>
#include <linux/reboot.h>
#include <linux/smp_lock.h>
#include <linux/init.h>
#include <asm/uaccess.h>
#include <asm/hardware.h>
#include <asm/bitops.h>
#include <asm/arch/ixp425.h>
#define MY_NAME "IXP425 Watchdog Timer"
/* you must define it ,otherwise ,the timer will stop after write() ,read() */
//#define CONFIG_WATCHDOG_NOWAYOUT
/* you can comment it ,if you don't debug */
#define CONFIG_IXP425_WTDEBUG
#ifdef CONFIG_IXP425_WTDEBUG
#define dbg(format, arg...) \
do { \
printk("<0>" "%s: " format, \
MY_NAME , ## arg); \
} while (0)
#else
#define dbg(format, arg...)
#endif
#define TIMER_FREQ 66000000 /* 66 MHZ timer */
#define TIMER_KEY 0x482e
#define TIMER_MARGIN 66 /* (secs) Default is 1 minute */
static int ixp425_margin = TIMER_MARGIN; /* in seconds */
static int ixp425wdt_users;
//static int pre_margin; //IXP425 CPU 's watch dog timer is 32 bit , so I define it to be unsigned int --bob
static unsigned int pre_margin;
/*
* Allow only one person to hold it open
*/
static int ixp425dog_open(struct inode *inode, struct file *file)
{
if(test_and_set_bit(1,&ixp425wdt_users))
return -EBUSY;
MOD_INC_USE_COUNT;
dbg("\n\nin open () function , *IXP425_OSWT = %u\n",*IXP425_OSWT);
dbg("ixp425_margin=%d\n",ixp425_margin);
/* Activate IXP425 Watchdog timer */
pre_margin=TIMER_FREQ * ixp425_margin;
*IXP425_OSWK = TIMER_KEY; /* Unlock the watch dog timer */
*IXP425_OSWT = pre_margin;
dbg("in open function pre_margin = %u\n",pre_margin);
*IXP425_OSWE = 0x5; //bit 0:reset ; bit 1:interupt; bit 2:counter down enable
*IXP425_OSWK = 0; /* Lock the watch dog timer */
return 0;
}
static int ixp425dog_release(struct inode *inode, struct file *file)
{
/*
* Shut off the timer.
* Lock it in if it's a module and we defined ...NOWAYOUT
*/
*IXP425_OSWK = TIMER_KEY; /* Unlock the watch dog timer */
*IXP425_OSWT = pre_margin;
#ifndef CONFIG_WATCHDOG_NOWAYOUT
*IXP425_OSWE = 0x0;
#endif
*IXP425_OSWK = 0; /* Lock the watch dog timer */
ixp425wdt_users = 0;
MOD_DEC_USE_COUNT;
return 0;
}
static ssize_t ixp425dog_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)
return -ESPIPE;
/* Refresh OSMR3 timer. */
if(len) {
dbg("has into write function len !=0 , *IXP425_OSWT = %u\n",*IXP425_OSWT);
dbg("just IXP425_OSWT will set to be %u \n",pre_margin);
*IXP425_OSWK = TIMER_KEY; /* Unlock the watch dog timer */
*IXP425_OSWT = pre_margin;
*IXP425_OSWK = 0; /* Lock the watch dog timer */
return 1;
}
return 0;
}
/* it is only used to test the IXP425_OSWT register's value
--BOB */
static ssize_t ixp425dog_read(struct file *file, char *data, size_t len, loff_t *ppos)
{
/* read OSMR3 timer. */
int current_timer = 0;
char buffer[10] = {'\0'};
dbg("has into read() function , *IXP425_OSWT = %u\n",*IXP425_OSWT);
//*IXP425_OSWK = TIMER_KEY; /* Unlock the watch dog timer */
current_timer = *IXP425_OSWT ;
//*IXP425_OSWK = 0; /* Lock the watch dog timer */
//-->
snprintf(buffer,sizeof(buffer)-1,"%d",current_timer);
copy_to_user(data,buffer,strlen(buffer));
}
static int ixp425dog_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
int new_margin;
int options = 0;
static struct watchdog_info ident = {
identity: "IXP425 Watchdog Timer",
options: WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_CARDRESET,
};
switch(cmd){
default:
return -ENOIOCTLCMD;
case WDIOC_GETSUPPORT:
return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident));
case WDIOC_GETSTATUS:
return put_user(0,(int *)arg);
case WDIOC_GETBOOTSTATUS:
return put_user((*IXP425_OSST & 0x00000010) ? WDIOF_CARDRESET : 0, (int *)arg);
case WDIOC_GETTEMP:
return -ENOIOCTLCMD;
case WDIOC_SETOPTIONS:
if (get_user(options, (int *)arg))
return -EFAULT;
switch(options) {
case WDIOS_DISABLECARD:
*IXP425_OSWK = TIMER_KEY; /* Unlock the watch dog timer */
*IXP425_OSWE = 0x0;
*IXP425_OSWK = 0; /* Lock the watch dog timer */
return 0;
case WDIOS_ENABLECARD:
*IXP425_OSWK = TIMER_KEY; /* Unlock the watch dog timer */
*IXP425_OSWE = 0x5;
*IXP425_OSWK = 0; /* Lock the watch dog timer */
return 0;
default:
return -ENOIOCTLCMD;
}
case WDIOC_SETTIMEOUT:
if (get_user(new_margin, (int *)arg))
return -EFAULT;
if (new_margin < 1)
return -EINVAL;
ixp425_margin = new_margin;
pre_margin=TIMER_FREQ * ixp425_margin;
*IXP425_OSWK = TIMER_KEY; /* Unlock the watch dog timer */
*IXP425_OSWT = pre_margin;
*IXP425_OSWK = 0; /* Lock the watch dog timer */
return 0;
case WDIOC_GETTIMEOUT:
put_user(ixp425_margin, (int *)arg);
return 0;
case WDIOC_KEEPALIVE:
*IXP425_OSWK = TIMER_KEY; /* Unlock the watch dog timer */
*IXP425_OSWT = pre_margin;
*IXP425_OSWK = 0; /* Lock the watch dog timer */
return 0;
}
}
static struct file_operations ixp425dog_fops=
{
owner: THIS_MODULE,
read: ixp425dog_read,
write: ixp425dog_write,
ioctl: ixp425dog_ioctl,
open: ixp425dog_open,
release: ixp425dog_release,
};
static struct miscdevice ixp425dog_miscdev=
{
WATCHDOG_MINOR,
"IXP425 watchdog",
&ixp425dog_fops
};
static int __init ixp425dog_init(void)
{
int ret;
dbg("WATCHDOG_MINOR = %d\n",WATCHDOG_MINOR);
ret = misc_register(&ixp425dog_miscdev);
dbg("ret of misc_register() = %d\n",ret);
if (ret)
return ret;
dbg("timer margin %d sec\n", ixp425_margin);
return 0;
}
static void __exit ixp425dog_exit(void)
{
misc_deregister(&ixp425dog_miscdev);
}
module_init(ixp425dog_init);
module_exit(ixp425dog_exit);
MODULE_AUTHOR("Stanely Wang");
MODULE_LICENSE("GPL");
MODULE_PARM(ixp425_margin,"i");
MODULE_PARM_DESC(ixp425_margin,"IXP425 Watchdog Timer's expiring time.");
MODULE_DESCRIPTION("IXP425 Watchdog Timer driver.");
MODULE_SUPPORTED_DEVICE("IXCDP1100 dev board.");
next reply other threads:[~2006-12-04 5:42 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-12-04 5:41 Bob Zhang [this message]
2006-12-04 9:18 zhang bob
2006-12-05 3:32 Bob Zhang
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='02ab01c71766$dcb2b1f0$270515ac@9BobZhang1' \
--to=zhanglinbao@gmail.com \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®