博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
慢慢欣赏linux 中断学习之外部中断 arm实现
阅读量:4070 次
发布时间:2019-05-25

本文共 6913 字,大约阅读时间需要 23 分钟。

void __init init_IRQ(void){	if (IS_ENABLED(CONFIG_OF) && !machine_desc->init_irq)		irqchip_init();	else		machine_desc->init_irq();		==>{			DT_MACHINE_START(CNS3XXX_DT, "Cavium Networks CNS3xxx")				.dt_compat	= cns3xxx_dt_compat,				.map_io		= cns3xxx_map_io,				.init_irq	= cns3xxx_init_irq,				=>/* used by entry-macro.S */				void __init cns3xxx_init_irq(void)				{					gic_init(0, 29, IOMEM(CNS3XXX_TC11MP_GIC_DIST_BASE_VIRT),						 IOMEM(CNS3XXX_TC11MP_GIC_CPU_BASE_VIRT));					=>void __init gic_init(unsigned int gic_nr, int irq_start,								 void __iomem *dist_base, void __iomem *cpu_base)					{						struct gic_chip_data *gic = &gic_data[gic_nr];						gic->raw_dist_base = dist_base;						gic->raw_cpu_base = cpu_base;						__gic_init_bases(gic, irq_start, NULL);						=>int __init __gic_init_bases(struct gic_chip_data *gic,										   int irq_start,										   struct fwnode_handle *handle)						{							if (gic == &gic_data[0]) {								/*								 * Initialize the CPU interface map to all CPUs.								 * It will be refined as each CPU probes its ID.								 * This is only necessary for the primary GIC.								 */								for (i = 0; i < NR_GIC_CPU_IF; i++)									gic_cpu_map[i] = 0xff;								set_smp_cross_call(gic_raise_softirq);								cpuhp_setup_state_nocalls(CPUHP_AP_IRQ_GIC_STARTING,											  "irqchip/arm/gic:starting",											  gic_starting_cpu, NULL);								set_handle_irq(gic_handle_irq);							}							if (static_key_true(&supports_deactivate) && gic == &gic_data[0]) {								name = kasprintf(GFP_KERNEL, "GICv2");								gic_init_chip(gic, NULL, name, true);							} else {								name = kasprintf(GFP_KERNEL, "GIC-%d", (int)(gic-&gic_data[0]));								gic_init_chip(gic, NULL, name, false);							}							ret = gic_init_bases(gic, irq_start, handle);							=>int gic_init_bases(struct gic_chip_data *gic, int irq_start,										  struct fwnode_handle *handle)							{								irq_hw_number_t hwirq_base;								int gic_irqs, irq_base, ret;								if (IS_ENABLED(CONFIG_GIC_NON_BANKED) && gic->percpu_offset) {									/* Frankein-GIC without banked registers... */									unsigned int cpu;									gic->dist_base.percpu_base = alloc_percpu(void __iomem *);									gic->cpu_base.percpu_base = alloc_percpu(void __iomem *);									for_each_possible_cpu(cpu) {										u32 mpidr = cpu_logical_map(cpu);										u32 core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0);										unsigned long offset = gic->percpu_offset * core_id;										*per_cpu_ptr(gic->dist_base.percpu_base, cpu) =											gic->raw_dist_base + offset;										*per_cpu_ptr(gic->cpu_base.percpu_base, cpu) =											gic->raw_cpu_base + offset;									}									gic_set_base_accessor(gic, gic_get_percpu_base);								} else {									/* Normal, sane GIC... */									WARN(gic->percpu_offset,										 "GIC_NON_BANKED not enabled, ignoring %08x offset!",										 gic->percpu_offset);									gic->dist_base.common_base = gic->raw_dist_base;									gic->cpu_base.common_base = gic->raw_cpu_base;									gic_set_base_accessor(gic, gic_get_common_base);								}								/*								 * Find out how many interrupts are supported.								 * The GIC only supports up to 1020 interrupt sources.								 */								gic_irqs = readl_relaxed(gic_data_dist_base(gic) + GIC_DIST_CTR) & 0x1f;								gic_irqs = (gic_irqs + 1) * 32;								if (gic_irqs > 1020)									gic_irqs = 1020;								gic->gic_irqs = gic_irqs;								if (handle) {		/* DT/ACPI */									gic->domain = irq_domain_create_linear(handle, gic_irqs,														   &gic_irq_domain_hierarchy_ops,														   gic);								} else {		/* Legacy support */									/*									 * For primary GICs, skip over SGIs.									 * For secondary GICs, skip over PPIs, too.									 */									if (gic == &gic_data[0] && (irq_start & 31) > 0) {										hwirq_base = 16;										if (irq_start != -1)											irq_start = (irq_start & ~31) + 16;									} else {										hwirq_base = 32;									}									gic_irqs -= hwirq_base; /* calculate # of irqs to allocate */									irq_base = irq_alloc_descs(irq_start, 16, gic_irqs,												   numa_node_id());									if (irq_base < 0) {										WARN(1, "Cannot allocate irq_descs @ IRQ%d, assuming pre-allocated\n",											 irq_start);										irq_base = irq_start;									}									gic->domain = irq_domain_add_legacy(NULL, gic_irqs, irq_base,												hwirq_base, &gic_irq_domain_ops, gic);									=>struct irq_domain *irq_domain_add_legacy(struct device_node *of_node,														 unsigned int size,														 unsigned int first_irq,														 irq_hw_number_t first_hwirq,														 const struct irq_domain_ops *ops,														 void *host_data)									{										struct irq_domain *domain;										domain = __irq_domain_add(of_node_to_fwnode(of_node), first_hwirq + size,													  first_hwirq + size, 0, ops, host_data);										if (domain)											irq_domain_associate_many(domain, first_irq, first_hwirq, size);											=>void irq_domain_associate_many(struct irq_domain *domain, unsigned int irq_base,															   irq_hw_number_t hwirq_base, int count)											{												struct device_node *of_node;												int i;												of_node = irq_domain_get_of_node(domain);												for (i = 0; i < count; i++) {													irq_domain_associate(domain, irq_base + i, hwirq_base + i);													=>int irq_domain_associate(struct irq_domain *domain, unsigned int virq,																 irq_hw_number_t hwirq)													{														struct irq_data *irq_data = irq_get_irq_data(virq);														int ret;														irq_data->hwirq = hwirq;														irq_data->domain = domain;														if (domain->ops->map) {															ret = domain->ops->map(domain, virq, hwirq);															/* If not already assigned, give the domain the chip's name */															if (!domain->name && irq_data->chip)																domain->name = irq_data->chip->name;														}														domain->mapcount++;														irq_domain_set_mapping(domain, hwirq, irq_data);														=>void irq_domain_set_mapping(struct irq_domain *domain,																		   irq_hw_number_t hwirq,																		   struct irq_data *irq_data)														{															if (hwirq < domain->revmap_size) {																domain->linear_revmap[hwirq] = irq_data->irq;															} else {																mutex_lock(&domain->revmap_tree_mutex);																radix_tree_insert(&domain->revmap_tree, hwirq, irq_data);																mutex_unlock(&domain->revmap_tree_mutex);															}														}														irq_clear_status_flags(virq, IRQ_NOREQUEST);														return 0;													}												}											}										return domain;									}								}								gic_dist_init(gic);								ret = gic_cpu_init(gic);								ret = gic_pm_init(gic);								return 0;								return ret;							}							return ret;						}					}				}			MACHINE_END		}]

 

转载地址:http://sdlji.baihongyu.com/

你可能感兴趣的文章
my pdfs
查看>>
framework Schedule Quartz
查看>>
IBM WebSphere Commerce Analyzer
查看>>
Unix + OS IBM Aix System Director
查看>>
Unix + OS IBM Aix FTP / wu-ftp / proftp
查看>>
framework apache commons
查看>>
my read work
查看>>
blancerServer IBM WebSphere Edge Server 6.1
查看>>
db db2 base / instance database tablespace container
查看>>
my read _job
查看>>
hd disk / disk raid / disk io / iops / iostat / iowait / iotop / iometer
查看>>
project ASP.NET
查看>>
db db2_monitorTool IBM Rational Performace Tester
查看>>
OS + Unix Aix telnet
查看>>
IBM Lotus
查看>>
Linux +Win LAMPP Tools XAMPP 1.7.3 / 5.6.3
查看>>
my read_university
查看>>
network manager
查看>>
searchServer IBM OminiFind / WebSphere Commerce SOLR
查看>>
OS + Linux Disk disk lvm / disk partition / disk mount / disk io
查看>>