专栏中心

EEPW首页 > 专栏 > Linux-2.6.21 S3c6400中断剖析之四 (原创)-上海嵌入式索漫科技培训教材

Linux-2.6.21 S3c6400中断剖析之四 (原创)-上海嵌入式索漫科技培训教材

发布人:xiajiashan 时间:2012-10-10 来源:工程师 发布文章

作者:下家山(请尊重原创,转载请注明)  http://www.xiajiashan.com 

 

四:当中断发生时,kernel是怎么找到这个句柄

第二个问题,我们调用register_irq 函数时注册的句柄,当中断发生时,kernel是怎么找到这个句柄,继而执行我们驱动里的函数的???

      4.1 关于s3c_init_irq函数

在asm_do_IRQ执行时,调用了desc_handle_irq(irq, desc);此函数调用了一个回调函数irq_desc->handle_irq,这一回调函数是在s3c_init_irq(位于/arch/arm/plat-s3c24xx/irq-pl192.c中)中设置的,其原型为:

/* --------------------------------------------------

 *  s3c_init_irq

 *

 *  Initialise s3c6400 IRQ system

 * --------------------------------------------------

 */

/*这个函数是在内核启动时被执行的,通过它来初始化irq_desc结构体数组,这样后续的驱动如果要注册中断就填充到这个数组中来*/

void __init s3c_init_irq(void)

{

       int irqno;

       int irqindex = 0;

 

       irqdbf("s3c_init_irq: clearing interrupt status flags\n");

 

       /* first, clear all interrupts pending... */

 

       /* clear external interrupts */

       __raw_writel(0xFFFFFFFF, S3C_EINTPEND);

 

       /* clear all vector interrupts */

       __raw_writel(0x00000000, S3C_VIC0ADDRESS);

       __raw_writel(0x00000000, S3C_VIC1ADDRESS);

 

 

       /* For writing the IRQ number into the VICVECTADDR */

       for (irqno = IRQ_EINT0_3; irqno <= IRQ_LCD_SYSTEM; irqno++) {

              __raw_writel(irqno, S3C_VIC0VECTADDR0 + irqindex);

              irqindex = irqindex + 4;

       }/*初始化第一组(0~31)中断源的向量地址*/

 

       irqindex = 0;

       for (irqno = IRQ_EINT12_19; irqno <= IRQ_ADC; irqno++) {

              __raw_writel(irqno, S3C_VIC1VECTADDR0 + irqindex);

              irqindex = irqindex + 4;

       }/*初始化第二组(32~63)中断源的向量地址*/

 

       /* register the main interrupts */

       irqdbf("s3c6400_init_irq: registering mDirac-III interrupt handlers\n");

       /*下面的for循环设置63个中断源的中断服务例程(中断服务函数或中断句柄),状态,标志,中断服务例程处理时的回调函数*/

       for (irqno = IRQ_EINT0_3; irqno <= IRQ_ADC; irqno++) {

              switch (irqno) {

                     /* deal with the special IRQs in ext (cascaded) */

              case IRQ_EINT0_3:

                     set_irq_chained_handler(IRQ_EINT0_3, s3c_irq_demux_eint0_3);

                     break; /*设置第一组外部中断中断源的中断服务例程(中断服务函数或中断句柄) */

 

 

              case IRQ_EINT4_11:

                     set_irq_chained_handler(IRQ_EINT4_11, s3c_irq_demux_eint4_11);

                     break; /*设置第二组外部中断中断源的中断服务例程(中断服务函数或中断句柄) */

 

              case IRQ_EINT12_19:

                     set_irq_chained_handler(IRQ_EINT12_19, s3c_irq_demux_eint12_19);

                     break; /*设置第三组外部中断中断源的中断服务例程(中断服务函数或中断句柄) */

 

              case IRQ_EINT20_27:

                     set_irq_chained_handler(IRQ_EINT20_27, s3c_irq_demux_eint20_27);

                     break; /*设置第四组外部中断中断源的中断服务例程(中断服务函数或中断句柄) */

 

              default:

                     irqdbf("registering irq %d (s3c irq)\n", irqno);

                     set_irq_chip(irqno, &s3c_irq_level_chip);/* 设置内部中断中断源的irq_desc结构体回调函数*/

                     //set_irq_handler(irqno, do_level_IRQ);

                     set_irq_handler(irqno, handle_level_irq); /*设置内部中断中断源的中断服务例程(中断服务函数或中断句柄) */

                     set_irq_flags(irqno, IRQF_VALID); /*设置内部中断中断源的irq_desc结构体中断标志*/

                     break;

              }

       }

 

       for (irqno = IRQ_EINT0; irqno <= IRQ_EINT27; irqno++) {

              irqdbf("registering irq %d (extended s3c irq)\n", irqno);

              set_irq_chip(irqno, &s3c_irqext_chip); /* 设置外部中断中断源的irq_desc结构体回调函数*/

              //set_irq_handler(irqno, do_level_IRQ);

              set_irq_handler(irqno, handle_level_irq); /*设置外部中断中断源的中断服务例程(中断服务函数或中断句柄) */             

set_irq_flags(irqno, IRQF_VALID); /*设置外部中断中断源的irq_desc结构体中断标志*/

 

       }

 

       irqdbf("s3c6400: registered interrupt handlers\n");

}

下面对

              set_irq_chip();//见kernel/irq/chip.c

              set_irq_handler();//见include/linux/irq.h->见kernel/irq/chip.c

              set_irq_flags();//见arch/arm/kernel/irq.c

这三个函数分别展开

4.1.1 关于 set_irq_chip()函数

/**

 *    set_irq_chip - set the irq chip for an irq

 *    @irq:      irq number

 *    @chip:    pointer to irq chip description structure

 */

int set_irq_chip(unsigned int irq, struct irq_chip *chip)

{

       struct irq_desc *desc;

       unsigned long flags;

 

       if (irq >= NR_IRQS) {

              printk(KERN_ERR "Trying to install chip for IRQ%d\n", irq);

              WARN_ON(1);

              return -EINVAL;

       }

 

       if (!chip)

              chip = &no_irq_chip;

 

       desc = irq_desc + irq;

       spin_lock_irqsave(&desc->lock, flags);

       irq_chip_set_defaults(chip);/*会调用到irq_chip_set_defaults函数*/

       desc->chip = chip;

       spin_unlock_irqrestore(&desc->lock, flags);

 

       return 0;

}

4.1.2 关于 irq_chip_set_defaults函数

 

下面是irq_chip_set_defaults函数的原型(见当前页)

/*

 * Fixup enable/disable function pointers

 */

void irq_chip_set_defaults(struct irq_chip *chip)

{

       if (!chip->enable)

              chip->enable = default_enable;/* 见当前页*/

       if (!chip->disable)

              chip->disable = default_disable; /* 见当前页*/

       if (!chip->startup)

              chip->startup = default_startup; /* 见当前页*/

       if (!chip->shutdown)

              chip->shutdown = chip->disable; /* 见当前页*/

       if (!chip->name)

              chip->name = chip->typename;

       if (!chip->end)

              chip->end = dummy_irq_chip.end;

}

2009-2-13   下家山     写于上海.漕河泾

                                   有什么问题可以给我邮件ximenpiaoxue4016@sina.com或加我群198204885

专栏文章内容及配图由作者撰写发布,仅供工程师学习之用,如有侵权或者其他违规问题,请联系本站处理。 联系我们

关键词:

相关推荐

英特尔发布2025年第四季度及全年财报

高速电路设计与仿真 上

视频 2009-10-27

WindowsCE系统开发及bootloader移植 下

视频 2009-10-27

WindowsCE系统开发及bootloader移植 上

视频 2009-10-27

这种“二维”晶体管工艺能否改变逻辑和功率器件的生产?

什么是Accellera系统计划?

EDA/PCB 2026-01-23

人工智能促进科研职业发展,但抑制科学发现

2026AI发展大预测:通过情境智能实现人工智能代理的规模化扩展

台积电惊艳财报背后:唯有笃信客户对人工智能未来的乐观

老牌供应商的整合、赋能通信运营商自建BSS/OSS以及代理式AI是2026年的主题

WindowsCE系统开发及bootloader移植 中

视频 2009-10-27

用eFuse缓解汽车短路危险

高速电路设计与仿真 下

视频 2009-10-27

为机器造“皮肤”,她是北航鲍容容!

2026-01-23

2026并购大猜想:国家级并购基金能否引发半导体并购潮?

更多 培训课堂
更多 焦点
更多 视频

技术专区