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 ", _ _FUNCTION_ _, pdev);
/* 获得看门狗的内存区域 */
res = platform get resource (pdev, IORESOURCE MEM, 0);
if (res == NULL)
{
printk(KERN INFO PFX "failed to get memory region resouce ");
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 ");
return  - ENOENT;
}
wdt base = ioremap (res->start, size); //设备内存->虚拟地址
if (wdt base == 0)
{
printk(KERN INFO PFX "failed to ioremap () region ");
return  - EINVAL;
}
DBG ("probe: mapped wdt base=%p ", wdt base);
/* 获得看门狗的中断 */
res = platform get resource (pdev, IORESOURCE IRQ, 0);
if (res == NULL)
{
printk(KERN INFO PFX "failed to get irq resource ");
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) ", ret);
return ret;
}
wdt clock = clk get (&pdev->dev, "watchdog"); //获得看门狗时钟源
if (wdt clock == NULL)
{
printk(KERN INFO PFX "failed to find watchdog clock source ");
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 ",CONFIG S3C2410 WATCHDOG DEFAULT TIME);
}
else
{
printk (KERN INFO PFX
"default timer value is out of range, cannot start ");
}
}
//注册miscdevice
ret = misc register(&s3c2410wdt miscdev);
if (ret)
{
printk(KERN ERR PFX "cannot registermiscdev on minor=%d (%d) ",
WATCHDOG MINOR, ret);
return ret;
}
if (tmr atboot && started == 0)
{
printk(KERN INFO PFX "Starting Watchdog Timer ");
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 ", (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! ");
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 ",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;
}