fishonesea

android 驱动,移植,qq群:91386163 推荐《Android深度探索(卷1):HAL与驱动开发》
  博客园  :: 首页  :: 新随笔  :: 管理

另一种linux下的powerpc中断注册的方法

Posted on 2012-02-07 10:39  fishonesea  阅读(405)  评论(0编辑  收藏  举报
下面这种中断的配置方法比较畸形,不过和后面的配合起来,也是成功的。

static int ZwFPGA_irq_init(void)
{
int ret;

irq2 = irq_create_mapping(NULL,FPGA_IRQ2);
printk(KERN_ERR"irq2=0x%08x\n",irq2);
irq3 = irq_create_mapping(NULL,DSP_IRQ3);
printk(KERN_ERR"irq3=0x%08x\n",irq3);
mask_irq(irq3);
mask_irq(irq2);

/* select irq2,set SICRH BIT 18 = 0 */
*(volatile unsigned int *)(immr_base_addr + SICRH_ADDR) &= (~0x00002000);

/* set irq2 edge sensitive */
*(volatile unsigned int *)(immr_base_addr + SECNR_ADDR) |= (0x00002000);

/* Clear SEPNR bit */
*(volatile unsigned int *)(immr_base_addr + SEPNR_ADDR) |= (0x20000000);

/*open the mask bit 2 to close the inttrupt*/
*(volatile unsigned int *)(immr_base_addr + SEMSR_ADDR ) &= (~0x20000000);
//*(volatile unsigned int *)(immr_base_addr + SEMSR_ADDR ) |= 0x20000000;


ret = request_irq(irq2,fpga_irq_handler,SA_INTERRUPT,"fpga_driver",NULL);
//perror(ret);
if(ret < 0){
printk(KERN_ERR"Request irq2 failed.\n");
free_irq(irq2,NULL);
return ret;
}


/* select irq3,set SICRH BIT 19 = 0 */
*(volatile unsigned int *)(immr_base_addr + SICRH_ADDR) &= (~0x00001000);

/* set irq3 edge sensitive */
*(volatile unsigned int *)(immr_base_addr + SECNR_ADDR) |= (0x00001000);

/* Clear SEPNR bit */
*(volatile unsigned int *)(immr_base_addr + SEPNR_ADDR) |= (0x10000000);

/*open the mask bit 3 to close the inttrupt*/
*(volatile unsigned int *)(immr_base_addr + SEMSR_ADDR ) &= (~0x10000000);
//*(volatile unsigned int *)(immr_base_addr + SEMSR_ADDR ) |= (0x10000000);


ret = request_irq(irq3,fpga_irq_handler,SA_INTERRUPT,"dpram_driver",NULL);
//perror(ret);
if(ret < 0){
printk(KERN_ERR"Request irq3 failed.\n");
free_irq(irq3,NULL);
return ret;
}

disable_irq(irq3);
disable_irq(irq2);

unmask_irq(irq3);
unmask_irq(irq2);

return 0;
}

下面是对中断的打开函数
static int fpga_open(struct inode *inode, struct file *filp)
{
/*close MASK bit of irq2 irq3*/
*(volatile unsigned int *)(immr_base_addr + SEMSR_ADDR ) |= (0x30000000);

printk(KERN_ERR"irq2=0x%08x\n",irq2);
enable_irq(irq2);
printk(KERN_ERR"irq3=0x%08x\n",irq3);
enable_irq(irq3);

return 0;
}

卸载函数如下:
static void irq_cleanup(void)
{
mask_irq(irq3);
mask_irq(irq2);
free_irq(irq3,NULL);
free_irq(irq2,NULL);
}

可以看到,这里面很多mask了,disable了,而平常中断基本上都不用的,所以,这些可用不可用,在这里面用了,就要用到底,要照应着。