打印

使用PXA3xx内部watchdog碰到的问题

[复制链接]
1608|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
chenbo35|  楼主 | 2008-11-18 15:55 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
请教一下,我在linux下编写watchdog的驱动程序,使用linux内核中的sa1100-wdt.c做了修改,可是不管是修改
static int margin __initdata = 60 还是
#define OSCR_FREQ        CLOCK_TICK_RATE的值在不喂狗的情况下watchdog总是在60秒后reset 究竟是什么原因呢?以下是我的程序:
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <linux/init.h>

#ifdef CONFIG_ARCH_PXA
#include <asm/arch/pxa-regs.h>
#endif

#include <asm/hardware.h>
#include <asm/bitops.h>
#include <asm/uaccess.h>
//#include <asm/sa-1100.h>

#define OSCR_FREQ        3250000//CLOCK_TICK_RATE

#define WDIOC_SETTIMEOUT    1
#define WDIOC_GETTIMEOUT   2
#define WDIOC_KEEPALIVE        3
//static unsigned long pxa3xxwdt_users;
unsigned long pre_margin;

//static int boot_status;

/*
 *    Allow only one person to hold it open
 */
static int pxa3xx_watchdog_open(struct inode *inode, struct file *file)
{
//    nonseekable_open(inode, file);
    /*if (test_and_set_bit(1,&pxa3xxwdt_users))
        return -EBUSY;*/
    /* Activate SA1100 Watchdog timer */
    OSMR3 = OSCR + pre_margin;
    OSSR = OSSR_M3;
    OWER = OWER_WME;
    OIER |= OIER_E3;
    printk(KERN_EMERG "device is open ");
    return 0;
}

/*
 * The watchdog cannot be disabled.
 *
 * Previous comments suggested that turning off the interrupt by
 * clearing OIER[E3] would prevent the watchdog timing out but this
 * does not appear to be true (at least on the PXA255).
 */
static int pxa3xx_watchdog_release(struct inode *inode, struct file *file)
{
    printk(KERN_CRIT "WATCHDOG: Device closed - timer will not stop ");
    OWER = ~OWER_WME;
    //clear_bit(1, &pxa3xxwdt_users);
    return 0;
}

/*static struct watchdog_info ident = {
    .options    = WDIOF_CARDRESET | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
    .identity    = "SA1100/PXA255 Watchdog",
};
*/
static int pxa3xx_watchdog_ioctl(struct inode *inode, struct file *file,
    unsigned int cmd, unsigned long arg)
{
    int ret = -ENOTTY;
    int time;
//    void __user *argp = (void __user *)arg;
//    int __user *p = argp;
    switch (cmd) {
/*    case WDIOC_GETSUPPORT:
        ret = copy_to_user(&arg, &ident,sizeof(ident)) ? -EFAULT : 0;
        break;*/
    case WDIOC_SETTIMEOUT:
        ret = get_user(time, &arg);
        if (ret)
            break;
        if (time <= 0 || time > 255) {
            ret = -EINVAL;
            break;
        }
        pre_margin = OSCR_FREQ*time;
        OSMR3 = OSCR + pre_margin;
        printk(KERN_EMERG "pre_margin=%d ",pre_margin);
        /*fall through*/
    case WDIOC_GETTIMEOUT:
        ret = put_user(pre_margin / OSCR_FREQ, &arg);
        break;
    case WDIOC_KEEPALIVE:
        OSMR3 = OSCR + pre_margin;
        ret = 0;
        break;
    }
    return ret;
}

static const struct file_operations pxa3xx_watchdog_fops =
{
    .owner        = THIS_MODULE,
    .llseek        = no_llseek,
    .ioctl        = pxa3xx_watchdog_ioctl,
    .open            = pxa3xx_watchdog_open,
    .release        = pxa3xx_watchdog_release,
};

static struct miscdevice pxa3xx_watchdog_miscdev =
{
    .minor    = WATCHDOG_MINOR,
    .name        = "watchdog",
    .fops        = &pxa3xx_watchdog_fops,
};

int margin    =    10; //__initdata = 60;        /* (secs) Default is 1 minute */

static int __init pxa3xx_watchdog_init(void)
{
    int ret;
    pre_margin=OSCR_FREQ * margin;
    ret = misc_register(&pxa3xx_watchdog_miscdev);
    if (ret == 0)
        printk(KERN_EMERG "initial succeed! ");
    return 0;
}

static void __exit pxa3xx_watchdog_exit(void)
{
    misc_deregister(&pxa3xx_watchdog_miscdev);
}

module_init(pxa3xx_watchdog_init);
module_exit(pxa3xx_watchdog_exit);

觉得有点奇怪,请指教一下,谢谢

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

3

主题

3

帖子

0

粉丝