linux看门狗设备,Linux设备驱动之watchdog设备驱动

2.5 platform_driver 结构体

struct platform driver

{

int (*probe)(struct platform device *);//探测

int (*remove)(struct platform device *);//移除

void (*shutdown)(struct platform device *);//关闭

int (*suspend)(struct platform device *, pm message t state);// 挂起

int (*resume)(struct platform device *);//恢复

struct device driver driver;

};

2.6 S3C2410 看门狗的platform_driver 结构体

static struct platform driver s3c2410wdt driver =

{

.probe      = s3c2410wdt probe,//S3C2410看门狗探测

.remove     = s3c2410wdt remove,// S3C2410看门狗移除

.shutdown   = s3c2410wdt shutdown,//S3C2410看门狗关闭

.suspend    = s3c2410wdt suspend,//S3C2410看门狗挂起

.resume     = s3c2410wdt resume, //S3C2410看门狗恢复

.driver     = {

.owner  = THIS MODULE,

.name   = "s3c2410-wdt",//设备名

},

};

2.7 S3C2410 看门狗所用资源

static struct resource s3c wdt resource[] =

{

[0] =

{

.start = S3C24XX PA WATCHDOG,     //看门狗I/O 内存开始位置

.end = S3C24XX PA WATCHDOG + S3C24XX SZ WATCHDOG - 1,

//看门狗I/O 内存结束位置

.flags = IORESOURCE MEM,  //I/O 内存资源

} ,

[1] =

{

.start = IRQ WDT, //看门狗开始IRQ 号

.end = IRQ WDT, //看门狗结束IRQ 号

.flags = IORESOURCE IRQ,  //IRQ 资源

}

};

2.8 S3C2410 看门狗驱动的miscdevice 结构体

static struct miscdevice s3c2410wdt miscdev =

{

.minor      = WATCHDOG MINOR,//次设备号

.name       = "watchdog",

.fops       = &s3c2410wdt fops,//文件操作结构体

};

2.9 S3C2410 看门狗驱动的文件操作结构体

static struct file operations s3c2410wdt fops =

{

.owner      = THIS MODULE,

.llseek     = no llseek,    //seek

.write      = s3c2410wdt write,     //写函数

.ioctl      = s3c2410wdt ioctl, //ioctl 函数

.open       = s3c2410wdt open,  //打开函数

.release    = s3c2410wdt release,//释放函数

};

3 加载和卸载函数

驱动模块的加载和卸载函数分别 用 platform_driver_register() 和 platform_driver_ unregister()注册和注销platform_driver

3.1 S3C2410 看门狗驱动

static int     __init watchdog__init (void)

{

printk (banner);

return   platform driver register(&s3c2410wdt driver);//       注 册platform driver

}

static void     exit watchdog exit (void)

{

platform driver unregister (&s3c2410wdt driver);//          注  销 platform driver

}

4 探测和移除函数

4.1 探测函数

static int s3c2410wdt probe (struct platform device *pdev)

{

struct resource *res;

int started = 0;

int ret;

int size;

DBG ("%s: probe=%p\n", _ _FUNCTION_ _, pdev);

/* 获得看门狗的内存区域 */

res = platform get resource (pdev, IORESOURCE MEM, 0);

if (res == NULL)

{

printk(KERN INFO PFX "failed to get memory region resouce\n");

return  - ENOENT;

}

size = (res->end - res->start) + 1;

//申请I/O 内存

wdt mem = request mem region (res->start, size, pdev->name);

if (wdt mem == NULL)

{

printk(KERN INFO PFX "failed to get memory region\n");

return  - ENOENT;

}

wdt base = ioremap (res->start, size); //设备内存->虚拟地址

if (wdt base == 0)

{

printk(KERN INFO PFX "failed to ioremap () region\n");

return  - EINVAL;

}

DBG ("probe: mapped wdt base=%p\n", wdt base);

/* 获得看门狗的中断 */

res = platform get resource (pdev, IORESOURCE IRQ, 0);

if (res == NULL)

{

printk(KERN INFO PFX "failed to get irq resource\n");

return  - ENOENT;

}

//申请中断

ret = request irq (res->start, s3c2410wdt irq, 0, pdev->name,

pdev);

if (ret != 0)

{

printk(KERN INFO PFX "failed to install irq (%d)\n", ret);

return ret;

}

wdt clock = clk get (&pdev->dev, "watchdog"); //获得看门狗时钟源

if (wdt clock == NULL)

{

printk(KERN INFO PFX "failed to find watchdog clock source\n");

return  - ENOENT;

}

clk enable (wdt clock);

/* 看看是否能设置定时器的超时时间为期望的值,如果不能,使用缺省值 */

if (s3c2410wdt set heartbeat (tmr margin))

{

started = s3c2410wdt set heartbeat (

CONFIG S3C2410 WATCHDOG DEFAULT TIME);

if (started == 0)

{

printk (KERN INFO PFX "tmr margin value out of range, default

%d

used\n",CONFIG S3C2410 WATCHDOG DEFAULT TIME);

}

else

{

printk (KERN INFO PFX

"default timer value is out of range, cannot start\n");

}

}

//注册miscdevice

ret = misc register(&s3c2410wdt miscdev);

if (ret)

{

printk(KERN ERR PFX "cannot registermiscdev on minor=%d (%d)\n",

WATCHDOG MINOR, ret);

return ret;

}

if (tmr atboot && started == 0)

{

printk(KERN INFO PFX "Starting Watchdog Timer\n");

s3c2410wdt start ();

}

return 0;

}

4.2 探测函数

static int s3c2410wdt remove (struct platform device *dev)

{

if (wdt mem != NULL)

{

release resource (wdt mem); //释放资源

kfree (wdt mem);//释放内存

wdt mem = NULL;

}

//释放中断

if (wdt irq != NULL)

{

free irq (wdt irq->start, dev);

wdt irq = NULL;

}

//禁止时钟源

if (wdt clock != NULL)

{

clk disable (wdt clock);

clk put (wdt clock);

wdt clock = NULL;

}

misc deregister(&s3c2410wdt miscdev);//注销miscdevice

return 0;

}

5 挂起和恢复函数

5.1 挂起函数

static   int  s3c2410wdt suspend (struct    platform device   *dev,

pm message t state)

{

/* 保存看门狗状态,停止它 */

wtcon save = readl (wdt base + S3C2410 WTCON);

wtdat save = readl (wdt base + S3C2410 WTDAT);

s3c2410wdt stop ();

return 0;

}

5.2 恢复函数

static int s3c2410wdt resume (struct platform device *dev)

{

/* 恢复看门狗状态 */

writel (wtdat save, wdt base + S3C2410 WTDAT);

writel (wtdat save, wdt base + S3C2410 WTCNT);

writel (wtcon save, wdt base + S3C2410 WTCON);

printk (KERN INFO PFX "watchdog %sabled\n", (wtcon save

&S3C2410 WTCON ENABLE)? "en" : "dis");

return 0;

}

6 打开和释放函数

6.1 打开函数

static int s3c2410wdt open (struct inode *inode, struct file *file)

{

if (down trylock (&open lock))  //获得打开锁

return  - EBUSY;

if (nowayout)

{

module get (THIS MODULE);

}

else

{

allow close = CLOSE STATE ALLOW;

}

/* 启动看门狗 */

s3c2410wdt start ();

return nonseekable open (inode, file);

}

6.2 释放函数

static int s3c2410wdt release (struct inode *inode,struct file *file)

{

/* 停止看门狗 */

if (allow close == CLOSE STATE ALLOW)

{

s3c2410wdt stop ();

}

else

{

printk (KERN CRIT  PFX  "Unexpected  close,  not  stopping

watchdog!\n");

s3c2410wdt keepalive ();

}

allow close = CLOSE STATE NOT;

up (&open lock);  //释放打开锁

return 0;

}

7 启停watchdog函数和写函数

7.1 启停看门狗函数

/*停止看门狗*/

staticints3c2410wdtstop(void)

{

unsignedlongwtcon;

wtcon=readl(wdtbase+S3C2410WTCON);

//停止看门狗,禁止复位

wtcon&=~(S3C2410WTCONENABLE|S3C2410WTCONRSTEN);

writel(wtcon,wdtbase+S3C2410WTCON);

return0;

}

/*开启看门狗*/

staticints3c2410wdtstart(void)

{

unsignedlongwtcon;

s3c2410wdtstop();

wtcon=readl(wdtbase+S3C2410WTCON);

//使能看门狗,128分频

wtcon|=S3C2410WTCONENABLE|S3C2410WTCONDIV128;

if(softnoboot)

{

wtcon|=S3C2410WTCONINTEN;//使能中断

wtcon&=~S3C2410WTCONRSTEN;//禁止复位

}

else

{

wtcon&=~S3C2410WTCONINTEN;//禁止中断

wtcon|=S3C2410WTCONRSTEN;//使能复位

}

DBG("%s:wdtcount=0x%08x,wtcon=%08lx\n",FUNCTION,

wdtcount,wtcon);

writel(wdtcount,wdtbase+S3C2410WTDAT);

writel(wdtcount,wdtbase+S3C2410WTCNT);

writel(wtcon,wdtbase+S3C2410WTCON);

return0;

}

7.2 写函数

static ssize t s3c2410wdt write (struct file *file, const char      user *data,

size t len, loff t *ppos)

{

/* 刷新看门狗 */

if (len)

{

if (!nowayout)

{

size t i;

allow close = CLOSE STATE NOT;

for (i = 0; i != len; i++)

{

char c;

if (get user(c, data + i))//用户空间->内核空间

return  - EFAULT;

if (c == 'V ')  //如果写入了'V ' ,允许关闭

allow close = CLOSE STATE ALLOW;

}

}

s3c2410wdt keepalive ();

}

return len;

}

22/2<12

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值