(f)这段代码主要是向系统中注册一个irq domain的数据结构。为何需要struct irq_domain这样一个数据结构呢?从linux kernel的角度来看,任何外部的设备的中断都是一个异步事件,kernel都需要识别这个事件。在内核中,用IRQ number来标识某一个设备的某个interrupt request。有了IRQ number就可以定位到该中断的描述符(struct irq_desc)。但是,对于中断控制器而言,它不并知道IRQ number,它只是知道HW interrupt number(中断控制器会为其支持的interrupt source进行编码,这个编码被称为Hardware interrupt number )。不同的软件模块用不同的ID来识别interrupt source,这样就需要映射了。如何将Hardware interrupt number 映射到IRQ number呢?这需要一个translation object,内核定义为struct irq_domain。
每个interrupt controller都会形成一个irq domain,负责解析其下游的interrut source。如果interrupt controller有级联的情况,那么一个非root interrupt controller的中断控制器也是其parent irq domain的一个普通的interrupt source。struct irq_domain定义如下:
struct irq_domain {
……
const struct irq_domain_ops *ops;
void *host_data;
……
};
这个数据结构是属于linux kernel通用中断子系统的一部分,我们这里只是描述相关的数据成员。host_data成员是底层interrupt controller的私有数据,linux kernel通用中断子系统不应该修改它。对于GIC而言,host_data成员指向一个struct gic_chip_data的数据结构,定义如下:
struct gic_chip_data {
union gic_base dist_base;------------------GIC Distributor的基地址空间
union gic_base cpu_base;------------------GIC CPU interface的基地址空间
#ifdef CONFIG_CPU_PM--------------------GIC 电源管理相关的成员
u32 saved_spi_enable[DIV_ROUND_UP(1020, 32)];
u32 saved_spi_conf[DIV_ROUND_UP(1020, 16)];
u32 saved_spi_target[DIV_ROUND_UP(1020, 4)];
u32 __percpu *saved_ppi_enable;
u32 __percpu *saved_ppi_conf;
#endif
struct irq_domain *domain;-----------------该GIC对应的irq domain数据结构
unsigned int gic_irqs;-------------------GIC支持的IRQ的数目
#ifdef CONFIG_GIC_NON_BANKED
void __iomem *(*get_base)(union gic_base *);
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/shumachanpin/article-76887-10.html
哪怕一次也好
放屁