慢慢欣赏linux 中断学习之外部中断 arm glcv3控制器初始化

int __init gic_of_init(struct device_node *node, struct device_node *parent)
{
	gic_init_bases(dist_base, rdist_regs, nr_redist_regions, redist_stride, &node->fwnode);
	=>int __init gic_init_bases(void __iomem *dist_base,
				 struct redist_region *rdist_regs,
				 u32 nr_redist_regions,
				 u64 redist_stride,
				 struct fwnode_handle *handle)
	{
		gic_data.fwnode = handle;
		gic_data.dist_base = dist_base;
		gic_data.redist_regions = rdist_regs;
		gic_data.nr_redist_regions = nr_redist_regions;
		gic_data.redist_stride = redist_stride;
		==>static struct gic_chip_data gic_data __read_mostly;
		
		/* 下面是读硬件, 获取支持中断的个数 */
		/*
		 * Find out how many interrupts are supported.
		 * The GIC only supports up to 1020 interrupt sources (SGI+PPI+SPI)
		 */
		typer = readl_relaxed(gic_data.dist_base + GICD_TYPER);
		gic_data.rdists.id_bits = GICD_TYPER_ID_BITS(typer);
		gic_irqs = GICD_TYPER_IRQS(typer);
		if (gic_irqs > 1020)
			gic_irqs = 1020;
		gic_data.irq_nr = gic_irqs;
		
		/* 创建中断控制器对应的域 */
		gic_data.domain = irq_domain_create_tree(handle, &gic_irq_domain_ops, &gic_data);
		==>static const struct irq_domain_ops gic_irq_domain_ops = {
			.translate = gic_irq_domain_translate,
			.alloc = gic_irq_domain_alloc,
			.free = gic_irq_domain_free,
			.select = gic_irq_domain_select,
		};
		=>struct irq_domain *irq_domain_create_tree(struct fwnode_handle *fwnode,
					 const struct irq_domain_ops *ops,
					 void *host_data)
		{
			return __irq_domain_add(fwnode, 0, ~0, 0, ops, host_data);
			=>struct irq_domain *__irq_domain_add(struct fwnode_handle *fwnode, int size,
				    irq_hw_number_t hwirq_max, int direct_max,
				    const struct irq_domain_ops *ops,
				    void *host_data)
			{
				struct device_node *of_node = to_of_node(fwnode);
				struct irqchip_fwid *fwid;
				struct irq_domain *domain;

				static atomic_t unknown_domains;

				domain = kzalloc_node(sizeof(*domain) + (sizeof(unsigned int) * size), GFP_KERNEL, of_node_to_nid(of_node));
				
				if (fwnode && is_fwnode_irqchip(fwnode)) {
					fwid = container_of(fwnode, struct irqchip_fwid, fwnode);

					switch (fwid->type) {
						case IRQCHIP_FWNODE_NAMED:
						case IRQCHIP_FWNODE_NAMED_ID:
							domain->name = kstrdup(fwid->name, GFP_KERNEL);
							if (!domain->name) {
								kfree(domain);
								return NULL;
							}
							domain->flags |= IRQ_DOMAIN_NAME_ALLOCATED;
							break;
						default:
							domain->fwnode = fwnode;
							domain->name = fwid->name;
							break;
					}
				} else if (of_node) {
					char *name;

					/*
					 * DT paths contain '/', which debugfs is legitimately
					 * unhappy about. Replace them with ':', which does
					 * the trick and is not as offensive as '\'...
					 */
					name = kstrdup(of_node_full_name(of_node), GFP_KERNEL);
					if (!name) {
						kfree(domain);
						return NULL;
					}

					strreplace(name, '/', ':');

					domain->name = name;
					domain->fwnode = fwnode;
					domain->flags |= IRQ_DOMAIN_NAME_ALLOCATED;
				}
				
				of_node_get(of_node);

				/* Fill structure */
				INIT_RADIX_TREE(&domain->revmap_tree, GFP_KERNEL);
				mutex_init(&domain->revmap_tree_mutex);
				domain->ops = ops;
				domain->host_data = host_data;
				domain->hwirq_max = hwirq_max;
				domain->revmap_size = size;
				domain->revmap_direct_max_irq = direct_max;
				irq_domain_check_hierarchy(domain);

				mutex_lock(&irq_domain_mutex);
				debugfs_add_domain_dir(domain);
				list_add(&domain->link, &irq_domain_list);
				mutex_unlock(&irq_domain_mutex);

				pr_debug("Added domain %s\n", domain->name);
				return domain;
			}
		}
		
		set_handle_irq(gic_handle_irq);
		void __init set_handle_irq(void (*handle_irq)(struct pt_regs *))
		{
			if (handle_arch_irq)
				return;

			handle_arch_irq = handle_irq;
		}
	}
}

中断子系统    ---博客不错
https://blog.csdn.net/yhb1047818384/category_9762456.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值