【原创】Linux中断子系统(一)-中断控制器及驱动分析 (3)

还是上一下具体的数据结构代码吧,关键注释如下:

struct irq_chip { struct device *parent_device; //指向父设备 const char *name; // /proc/interrupts中显示的名字 unsigned int (*irq_startup)(struct irq_data *data); //启动中断,如果设置成NULL,则默认为enable void (*irq_shutdown)(struct irq_data *data); //关闭中断,如果设置成NULL,则默认为disable void (*irq_enable)(struct irq_data *data); //中断使能,如果设置成NULL,则默认为chip->unmask void (*irq_disable)(struct irq_data *data); //中断禁止 void (*irq_ack)(struct irq_data *data); //开始新的中断 void (*irq_mask)(struct irq_data *data); //中断源屏蔽 void (*irq_mask_ack)(struct irq_data *data); //应答并屏蔽中断 void (*irq_unmask)(struct irq_data *data); //解除中断屏蔽 void (*irq_eoi)(struct irq_data *data); //中断处理结束后调用 int (*irq_set_affinity)(struct irq_data *data, const struct cpumask *dest, bool force); //在SMP中设置CPU亲和力 int (*irq_retrigger)(struct irq_data *data); //重新发送中断到CPU int (*irq_set_type)(struct irq_data *data, unsigned int flow_type); //设置中断触发类型 int (*irq_set_wake)(struct irq_data *data, unsigned int on); //使能/禁止电源管理中的唤醒功能 void (*irq_bus_lock)(struct irq_data *data); //慢速芯片总线上的锁 void (*irq_bus_sync_unlock)(struct irq_data *data); //同步释放慢速总线芯片的锁 void (*irq_cpu_online)(struct irq_data *data); void (*irq_cpu_offline)(struct irq_data *data); void (*irq_suspend)(struct irq_data *data); void (*irq_resume)(struct irq_data *data); void (*irq_pm_shutdown)(struct irq_data *data); void (*irq_calc_mask)(struct irq_data *data); void (*irq_print_chip)(struct irq_data *data, struct seq_file *p); int (*irq_request_resources)(struct irq_data *data); void (*irq_release_resources)(struct irq_data *data); void (*irq_compose_msi_msg)(struct irq_data *data, struct msi_msg *msg); void (*irq_write_msi_msg)(struct irq_data *data, struct msi_msg *msg); int (*irq_get_irqchip_state)(struct irq_data *data, enum irqchip_irq_state which, bool *state); int (*irq_set_irqchip_state)(struct irq_data *data, enum irqchip_irq_state which, bool state); int (*irq_set_vcpu_affinity)(struct irq_data *data, void *vcpu_info); void (*ipi_send_single)(struct irq_data *data, unsigned int cpu); void (*ipi_send_mask)(struct irq_data *data, const struct cpumask *dest); unsigned long flags; }; struct irq_domain { struct list_head link; //用于添加到全局链表irq_domain_list中 const char *name; //IRQ domain的名字 const struct irq_domain_ops *ops; //IRQ domain映射操作函数集 void *host_data; //在GIC驱动中,指向了irq_gic_data unsigned int flags; unsigned int mapcount; //映射中断的个数 /* Optional data */ struct fwnode_handle *fwnode; enum irq_domain_bus_token bus_token; struct irq_domain_chip_generic *gc; #ifdef CONFIG_IRQ_DOMAIN_HIERARCHY struct irq_domain *parent; //支持级联的话,指向父设备 #endif #ifdef CONFIG_GENERIC_IRQ_DEBUGFS struct dentry *debugfs_file; #endif /* reverse map data. The linear map gets appended to the irq_domain */ irq_hw_number_t hwirq_max; //IRQ domain支持中断数量的最大值 unsigned int revmap_direct_max_irq; unsigned int revmap_size; //线性映射的大小 struct radix_tree_root revmap_tree; //Radix Tree映射的根节点 unsigned int linear_revmap[]; //线性映射用到的查找表 }; struct irq_domain_ops { int (*match)(struct irq_domain *d, struct device_node *node, enum irq_domain_bus_token bus_token); // 用于中断控制器设备与IRQ domain的匹配 int (*select)(struct irq_domain *d, struct irq_fwspec *fwspec, enum irq_domain_bus_token bus_token); int (*map)(struct irq_domain *d, unsigned int virq, irq_hw_number_t hw); //用于硬件中断号与Linux中断号的映射 void (*unmap)(struct irq_domain *d, unsigned int virq); int (*xlate)(struct irq_domain *d, struct device_node *node, const u32 *intspec, unsigned int intsize, unsigned long *out_hwirq, unsigned int *out_type); //通过device_node,解析硬件中断号和触发方式 #ifdef CONFIG_IRQ_DOMAIN_HIERARCHY /* extended V2 interfaces to support hierarchy irq_domains */ int (*alloc)(struct irq_domain *d, unsigned int virq, unsigned int nr_irqs, void *arg); void (*free)(struct irq_domain *d, unsigned int virq, unsigned int nr_irqs); void (*activate)(struct irq_domain *d, struct irq_data *irq_data); void (*deactivate)(struct irq_domain *d, struct irq_data *irq_data); int (*translate)(struct irq_domain *d, struct irq_fwspec *fwspec, unsigned long *out_hwirq, unsigned int *out_type); #endif }; 3.3.1 IRQ domain

IRQ domain用于将硬件的中断号,转换成Linux系统中的中断号(virtual irq, virq),来张图:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wppxjf.html