Chinaunix首页 | 论坛 | 博客
  • 博客访问: 149264
  • 博文数量: 52
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 316
  • 用 户 组: 普通用户
  • 注册时间: 2015-05-19 22:20
文章分类
文章存档

2016年(43)

2015年(9)

我的朋友

分类: 其他平台

2016-05-19 13:25:18

#include
#include
#include
#include
#include
#include
#include
#include
#include


#if 0
#define MAGIC 'x'
#define WDT_RESET _IO(MAGIC, 0) //产正一个数字
#define WDT_INTERRUPT _IO(MAGIC, 1)
#define WDT_START _IO(MAGIC, 2)
#define WDT_STOP _IO(MAGIC, 3)
#endif


static struct resource s3c_wdt_xb_resource[] = {
     [0] = {
.start = 0x53000000,
.end = 0x530000ff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_S3C2440_WDT,
.end = IRQ_S3C2440_WDT,
.flags = IORESOURCE_IRQ,
   }
 };
static void s3c_device_wdt_release(struct device * dev)
{
}




static struct platform_device s3c_device_wdt_dev = {
    .name         = "watchdog",
    .id       = -1,
    .num_resources    = ARRAY_SIZE(s3c_wdt_xb_resource),
    .resource     = s3c_wdt_xb_resource,
    .dev = { 
    .release = s3c_device_wdt_release, 
},
};








//Prescaler value 


//t_watchdog = 1/[ PCLK / (Prescaler value + 1) / Division_factor ] = 3906.25
#define WDT_1S 3906.25
struct _wdt_t {
unsigned long irqno;
unsigned long phys, virt;
unsigned long wtcon, wtdat, wtcnt;
unsigned long reg;
void (*init_reset)(struct _wdt_t *);
void (*init_interrupt)(struct _wdt_t *);
void (*start)(struct _wdt_t *);
void (*stop)(struct _wdt_t *);
void (*feed)(struct _wdt_t*);
};
struct _wdt_t my_wdt;
static void  s3c_wdt_init_reset(struct _wdt_t *wdt)
{
printk("*******%s %d\n",__FUNCTION__,__LINE__);
iowrite32((int)(WDT_1S * 10),wdt->wtdat);
iowrite32((int)(WDT_1S * 10), wdt->wtcnt);


iowrite32(0x6339, wdt->wtcon);
}
static void s3c_wdt_init_interrupt(struct _wdt_t *wdt)
{
iowrite32((int)(WDT_1S), wdt->wtdat);
iowrite32((int)(WDT_1S), wdt->wtcnt);
iowrite32(0x6338, wdt->wtcon);
}
static void s3c_wdt_start(struct _wdt_t *wdt)
{
wdt->reg = ioread32(wdt->wtcon);
wdt->reg |= (1 << 2);
iowrite32(wdt->reg, wdt->wtcon);
}
static void s3c_wdt_stop(struct _wdt_t *wdt)
{
wdt->reg = ioread32(wdt->wtcon);
wdt->reg &= (1 << 2);
iowrite32(wdt->reg, wdt->wtcon);
}
static void s3c_wdt_feed(struct _wd_t *wdt)
{
iowrite32((int)(WDT_1S * 10), wdt->wtcnt);


}
irqreturn_t wdt_irq_handler(int irqno, void *dev_id)
{
printk("wang wang wang ...\n");
return IRQ_HANDLED;
}
int init_wdt_device(struct _wdt_t *wdt)
{
int ret = 0;
//ioremap
wdt->virt = (unsigned long)ioremap(wdt->phys, 0x0c);
wdt->wtcon = wdt->virt + 0x0;
wdt->wtdat = wdt->virt + 0x4;
wdt->wtcnt = wdt->virt + 0x8;
//irq
ret = request_irq(wdt->irqno, wdt_irq_handler, IRQF_TRIGGER_NONE,"s3c2440_wdt-irq", NULL);
if(ret)
{
printk("request wdt-irq failed!\n");
goto err;
}
//function
wdt->init_reset = s3c_wdt_init_reset;
wdt->init_interrupt = s3c_wdt_init_interrupt;
wdt->start = s3c_wdt_start;
wdt->stop = s3c_wdt_stop;
wdt->feed = s3c_wdt_feed;
return ret;
err:
iounmap((void *)wdt->virt);
return ret;
}
void destroy_wdt_device(struct _wdt_t *wdt)
{
free_irq(IRQ_S3C2440_WDT, NULL);
iounmap((void *)wdt->virt);
}
int s3c_wdt_ioctl (struct inode *node, struct file *filp,unsigned int cmd, unsigned long args)
{
switch(cmd)
{
case 0:
my_wdt.init_reset(&my_wdt);
break;
case 1:
my_wdt.init_interrupt(&my_wdt);
break;
case 2:
my_wdt.start(&my_wdt);
break;
case 3:
my_wdt.stop(&my_wdt);
break;
case 4:
my_wdt.feed(&my_wdt);
break;
default:
printk("no suppy\n");
return -EINVAL;
}
return 0;
}


static struct file_operations wdt_ops = {
.ioctl = s3c_wdt_ioctl,
};


static struct miscdevice wdt_misc = {
.name = "watchdog",
.fops = &wdt_ops,
};


static int s3c_wdt_probe(struct platform_device *pdev)
{
printk("[%s]\n", __FUNCTION__);
my_wdt.phys = pdev->resource[0].start;
my_wdt.irqno = pdev->resource[1].start;
init_wdt_device(&my_wdt);
misc_register(&wdt_misc);
}


static int s3c_wdt_remove(struct platform_device *pdev)
{
printk("[%s]\n", __FUNCTION__);
my_wdt.stop(&my_wdt);
misc_deregister(&wdt_misc);
destroy_wdt_device(&my_wdt);
return 0;
}
static struct platform_driver wdt_pdrv = {
.probe = s3c_wdt_probe,
.remove = s3c_wdt_remove,
.driver = {
.name = "watchdog", },
};
static int __init wdt_init(void)
{
platform_driver_register(&wdt_pdrv);  //平台驱动注册
platform_device_register(&s3c_device_wdt_dev);//平台资源注册
printk("hello wdt!\n");
return 0;
}
static void __exit wdt_exit(void)
{
platform_driver_unregister(&wdt_pdrv);
platform_device_unregister(&s3c_device_wdt_dev);
printk("bye wdt!\n");
}
module_init(wdt_init);
module_exit(wdt_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("xiao bai");
MODULE_VERSION("v0.1");

//应用测试程序
#include
#include
#include
#include
#include
#include


#include "ioctl_wdt.h"


int main(int argc, char *argv[])
{
int fd;


fd = open("/dev/watchdog", O_RDWR);
if(fd < 0)
perror("open");


printf("./app [func]\n");
printf("func : reset interrupt start stop\n");
printf("[%s]\n", argv[1]);


if(!strncasecmp("reset", argv[1], 5))
ioctl(fd,0);
if(!strncasecmp("interrupt", argv[1], 9))
ioctl(fd, 1);
if(!strncasecmp("start", argv[1], 5))
ioctl(fd,2);
if(!strncasecmp("stop", argv[1], 4))
ioctl(fd,3);
if(!strncasecmp("feed", argv[1], 4))
ioctl(fd,3);


return 0;
}



阅读(1022) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~