开发学习记录之看门狗驱动

#include <linux/init.h>
#include <linux/module.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/io.h>

MODULE_LICENSE("GPL");

struct up_wtd{
 unsigned long virt_wtd,virt_led;
 unsigned long *gpmcon,*gpmdat,*wtcon,*wtcnt,*wtdat,*wtclrint;
 char *name;
 unsigned int flag;
 void (*wtd_init)(struct up_wtd *this); 
 void (*wtd_exit)(struct up_wtd *this);
 void (*wtd_on)(struct up_wtd *this);
 void (*wtd_off)(struct up_wtd *this);
 void (*wtd_clr)(struct up_wtd *this);
 void (*led_on)(struct up_wtd *this);
 void (*led_off)(struct up_wtd *this);
 irqreturn_t (*do_irq)(int irq,struct up_wtd *this);
};

void my_wtd_init(struct up_wtd *this);
void my_wtd_exit(struct up_wtd *this);
void my_wtd_on(struct up_wtd *this);
void my_wtd_off(struct up_wtd *this);
void my_wtd_clr(struct up_wtd *this);
void my_led_on(struct up_wtd *this);
void my_led_off(struct up_wtd *this);
irqreturn_t my_do_irq(int irq,struct up_wtd *this);

struct up_wtd wtd;
int up_init(void)
{
 wtd.wtd_init = my_wtd_init;
 wtd.wtd_exit = my_wtd_exit; 
 
 wtd.wtd_init(&wtd);
 return 0;
}
void up_exit(void)
{
 wtd.wtd_exit(&wtd); 
}
module_init(up_init);
module_exit(up_exit);
void my_wtd_init(struct up_wtd *this)
{
 this->virt_wtd = ioremap(0x7e004000,SZ_4K); 
 this->virt_led = ioremap(0x7f008000,SZ_4K);
 this->gpmcon = this->virt_led + 0x820;
 this->gpmdat = this->virt_led + 0x824;
 this->wtcon = this->virt_wtd + 0x00;
 this->wtdat = this->virt_wtd + 0x04;
 this->wtcnt = this->virt_wtd + 0x08;
 this->wtclrint = this->virt_wtd + 0x0c;
 
 this->name = "s3c6410-wdt";
 this->flag = 1;
 this->wtd_on = my_wtd_on;
 this->wtd_off = my_wtd_off;
 this->wtd_clr = my_wtd_clr;
 this->led_on = my_led_on;
 this->led_off = my_led_off;
 this->do_irq = my_do_irq;
 int ret = request_irq(IRQ_WDT,this->do_irq,IRQF_SHARED,this->name,this);
 if(ret < 0){
  printk("wdt request error\n");
  return 1;
 }
 this->wtd_on(this);
}
void my_wtd_exit(struct up_wtd *this)
{
 free_irq(IRQ_WDT,this);
 this->led_off(this);
 this->wtd_off(this);
 iounmap(this->virt_wtd);
 iounmap(this->virt_led);
}
void my_wtd_on(struct up_wtd *this)
{
 *this->wtcon = (1 << 2) | (3 << 3) | (1 << 5) | (15 << 8);
 *this->wtdat = 0x8000;
 *this->wtcnt = 0x8000;
}
void my_wtd_off(struct up_wtd *this)
{
 *this->wtcon = 0;
}
void my_wtd_clr(struct up_wtd *this)
{
 *this->wtclrint = 0;
}
void my_led_on(struct up_wtd *this)
{
 *this->gpmcon &= ~0xf;
 *this->gpmcon |= 1;
 *this->gpmdat &= ~1;
}
void my_led_off(struct up_wtd *this)
{
 *this->gpmcon &= ~0xf;
 *this->gpmcon |= 1;
 *this->gpmdat |= 1;
}
irqreturn_t my_do_irq(int irq,struct up_wtd *this)
{
 if(irq == IRQ_WDT){
  this->wtd_clr(this);
  if(this->flag)
  { 
   printk("led_on\n");
   this->led_on(this);
  }
  else
  {
   printk("led_off\n");
   this->led_off(this);
  }
  this->flag ^= 1;
 }
 return IRQ_HANDLED;
}

坑爹了。。。。这些都是模型,可以套用别的驱动,有机会可以讨论

你可能感兴趣的:(linux,嵌入式,驱动,看门狗)