姓名:彭东林

E-mail:pengdonglin137@163.com

QQ:405728433

 

平台

板子:TQ2440

内核:Linux-4.9

u-boot: 2015.04

工具链: arm-none-linux-gnueabi-gcc 4.8.3

 

概述

在博文基於tiny4412的Linux內核移植 --- 实例学习中断背后的知识(1)中介绍了最新的Linux下中断的知识,下面我们再结合TQ2440来分析一下。

 

正文

一、基础知识

关于这部分请参考S3C2440的芯片手册或者博文TQ2440中断系统

下面简单介绍:

基于设备树的TQ2440的中断(1)

从图中可以看到,中断主要分为两级,我们可以理解为是两个中断控制器的嵌套或者级联。S3C2440总共支持60个中断源,包含了主中断源和子中断源。

基于设备树的TQ2440的中断(1)

寄存器功能介绍:

1、SRCPND 地址: 0x4A000000 功能:每一位代表一个主中断,置1表示有对应的主中断请求,对应位写入1可以清除中断

2、INTMOD 地址: 0x4A000004 功能:设置对应的主中断为IRQ还是FIQ, 置1表示FIQ

3、INTMSK 地址: 0x4A000008 功能:置1表示对应的主中断被屏蔽(不会影响SRCPND)

4、INTPND 地址: 0x4A000010 功能:表示对应的主中断被request,只可能有一位被置位,写入1可以清除中断

5、INTOFFSET 地址:0x4A000014 功能:存放的是发生中断请求的主中断号

6、SUBSRCPND 地址:0x4A000018 功能:每一位代表一个子中断,置一表示对应子中断请求,对应位写入1清除子中断请求

7、INTSUBMSK 地址:0x4A00001C 功能:置1表示对应的子中断被屏蔽

32个主中断:

基于设备树的TQ2440的中断(1)
图一

15个子中断:

基于设备树的TQ2440的中断(1)
图二
 
基于设备树的TQ2440的中断(1)
图三

外部中断:

EINT0~7对应的GPIO是GPF0~7

EINT8~23对应的GPIO是GPG0~15

二、设备树

1、中断控制器

intc:interrupt-controller@4a000000 {
compatible = "samsung,s3c2410-irq";
reg = <0x4a000000 0x100>;
interrupt-controller;
#interrupt-cells = <4>;
};
2、引用
serial@50000000 {
compatible = "samsung,s3c2440-uart";
reg = <0x50000000 0x4000>;
interrupts = <1 28 0 4>, <1 28 1 4>;
status = "okay";
clock-names = "uart";
clocks = <&clock PCLK_UART0>;
pinctrl-names = "default";
pinctrl-0 = <0x3>;
};
 
i2c:i2c@54000000 {
compatible = "samsung,s3c2410-i2c";
reg = <0x54000000 0x100>;
interrupts = <0 0 27 3>;
#address-cells = <1>;
#size-cells = <0>;
};
上面的serial和i2c设备比较典型,一个引用的是主中断,另一个引用的是子中断。从中断控制器的#interrupt-cells属性知道,要描述一个中断需要四个参数,每一个参数的含义需要由中断控制器的驱动来解释,具体是有中断控制器的irq_domain_ops中的xlate来解释,对于s3c2440就是drivers/irqchip/irq-s3c24xx.c中的s3c24xx_irq_xlate_of。
 1 /* Translate our of irq notation
 2  * format: <ctrl_num ctrl_irq parent_irq type>
 3  */
 4 static int s3c24xx_irq_xlate_of(struct irq_domain *d, struct device_node *n,
 5             const u32 *intspec, unsigned int intsize,
 6             irq_hw_number_t *out_hwirq, unsigned int *out_type)
 7 {
 8     struct s3c_irq_intc *intc;
 9     struct s3c_irq_intc *parent_intc;
10     struct s3c_irq_data *irq_data;
11     struct s3c_irq_data *parent_irq_data;
12     int irqno;
13 
14     if (WARN_ON(intsize < 4))  //如果参数个数不能小于4
15         return -EINVAL;
16         // 从这里知道,第一个参数不能大于2,只能是0和1, 0表示主中断,2表示子中断
17     if (intspec[0] > 2 || !s3c_intc[intspec[0]]) {
18         pr_err("controller number %d invalid\n", intspec[0]);
19         return -EINVAL;
20     }
21         // s3c_intc[0]表示主中断控制器,s3c_intc[1]表示子中断控制器
22     intc = s3c_intc[intspec[0]];
23 
24         // 第三个参数表示的是硬件中断号,从这里知道,主中断的硬件中断是0~31,子中断的硬件中断是32及其以上
25     *out_hwirq = intspec[0] * 32 + intspec[2];
26         // 第四个参数表示的是中断类型,可以查看IRQ_TYPE_SENSE_MASK定义,就知道含义:
27         // 1表示上升沿触发,2表示下降沿触发,3表示双边沿触发,4表示高电平触发,8表示低电平触发,12表示高低电平触发
28     *out_type = intspec[3] & IRQ_TYPE_SENSE_MASK;
29         // 如果是主中断,则intc->parent为NULL, 否则非空
30     parent_intc = intc->parent;
31     if (parent_intc) {  // 子中断
32         irq_data = &intc->irqs[intspec[2]];
33                 // 对于子中断,第二个参数才有意义,表示该子中断所隶属的主中断的硬件中断号
34         irq_data->parent_irq = intspec[1];
35         parent_irq_data = &parent_intc->irqs[irq_data->parent_irq];
36         parent_irq_data->sub_intc = intc;
37                 // sub_bits中记录该主中断下的子中断被被使用的情况
38         parent_irq_data->sub_bits |= (1UL << intspec[2]);
39                 // 将主中断号映射成虚拟中断号
40         /* parent_intc is always s3c_intc[0], so no offset */
41         irqno = irq_create_mapping(parent_intc->domain, intspec[1]);
42         if (irqno < 0) {
43             pr_err("irq: could not map parent interrupt\n");
44             return irqno;
45         }
46                 // 这里设置irqno对应的irq_desc的handle_irq为s3c_irq_demux
47                 // 从函数名称中就可以看出, 这个函数会再次进行检测该主中断的哪个子中断被请求
48         irq_set_chained_handler(irqno, s3c_irq_demux);
49     }
50 
51     return 0;
52 }
View Code

从这里我们知道,interrupts属性中的四个参数中的含义:

相关文章:

  • 2021-09-07
  • 2021-07-21
  • 2021-08-14
  • 2021-12-15
  • 2022-12-23
  • 2021-10-05
  • 2022-01-28
  • 2021-07-03
猜你喜欢
  • 2021-09-13
  • 2021-12-20
  • 2022-01-05
  • 2021-11-07
  • 2021-05-16
  • 2022-12-23
  • 2022-02-22
相关资源
相似解决方案