GIC400驱动分析
中断控制器irq_domain_ops如下:
static const struct irq_domain_ops gic_irq_domain_hierarchy_ops = {
.translate = gic_irq_domain_translate,
.alloc = gic_irq_domain_alloc,
.free = irq_domain_free_irqs_top,
};
其中函数指针translate主要使将设备树的硬件中断号转为为主板上中中断号,中断类型,如上升沿触发,下降沿触发,高低电平触发等,还有就是SPI类型的中断,还是PPI中断
int gic_irq_domain_translate(struct irq_domain *d,
struct irq_fwspec *fwspec,
unsigned long *hwirq,
unsigned int *type)
{
if (is_of_node(fwspec->fwnode)) {
if (fwspec->param_count < 3)
return -EINVAL;
/* Get the interrupt number and add 16 to skip over SGIs */
*hwirq = fwspec->param[1] + 16;
/*
* For SPIs, we need to add 16 more to get the GIC irq
* ID number
*/
if (!fwspec->param[0])
*hwirq += 16;
*type = fwspec->param[2] & IRQ_TYPE_SENSE_MASK;
return 0;
设备树获取中断
of_irq_get
解码设备树中中断号,并返回linux IRQ中断号
int of_irq_get(struct device_node *dev, int index)
{
struct of_phandle_args oirq;
of_irq_parse_one(dev, index, &oirq); //返回硬件中断号信息
return irq_create_of_mapping(&oirq);
}
irq_create_of_mapping
unsigned int irq_create_of_mapping(struct of_phandle_args *irq_data)
{
struct irq_fwspec fwspec;
of_phandle_args_to_fwspec(irq_data, &fwspec);
return irq_create_fwspec_mapping(&fwspec);
}
显然of_phandle_args_to_fwspec是将上一个结构irq_data转化为irq_fwspec结构