INIT/MAIN.C:
1 void Start_kernel (void)2{3 ... 4 early_irq_init (); 5 Init_irq (); 6 ...... 7 }
The Early_irq_init () function has two implementations, one based on Radix tree, one defining a static array, and if you want to use radix tree to implement it, you need to turn on the SPARSE_IRQ configuration option, because I don't understand the data structure, Therefore, the following static array implementation version is parsed.
/kernel/irq/irqdesc.c
1 structIrq_desc Irq_desc[nr_irqs] __CACHELINE_ALIGNED_IN_SMP = {2[0... nr_irqs-1] = {3. HANDLE_IRQ =Handle_bad_irq,4. depth =1,5.Lock= __raw_spin_lock_unlocked (irq_desc->Lock),6 }7 };8 9 int__init Early_irq_init (void)Ten { One intCount, I, node =First_online_node; A structIRQ_DESC *desc; - - init_irq_default_affinity (); the -PRINTK (Kern_info"nr_irqs:%d\n", Nr_irqs); - -desc =Irq_desc; +Count =array_size (IRQ_DESC); - + for(i =0; I < count; i++) { ADesc[i].kstat_irqs = alloc_percpu (unsignedint); atAlloc_masks (&Desc[i], Gfp_kernel, node); -Raw_spin_lock_init (&desc[i].Lock); -Lockdep_set_class (&desc[i].Lock, &irq_desc_lock_class); -Desc_set_defaults (i, &Desc[i], node); - } - returnarch_early_irq_init (); in}
The first time you see this initialized array all members are in the same content way that you can learn to accumulate under.
Nr_irqs is defined under Arch/arm/mach-s5pv210/include/mach/irqs.h:
1 #define Nr_irqs (irq_eint) + S5p_gpioint_count + 1)
The core of the above function is to call Desc_set_defaults () to initialize the above interrupt descriptor array, KERNEL/IRQ/IRQDESC.C:
1 Static voidDesc_set_defaults (unsignedintIrqstructIrq_desc *desc,intnode)2 {3 intCPU;4 5DESC->IRQ_DATA.IRQ =IRQ;6Desc->irq_data.chip = &no_irq_chip;7Desc->irq_data.chip_data =NULL;8Desc->irq_data.handler_data =NULL;9Desc->irq_data.msi_desc =NULL;TenIrq_settings_clr_and_set (DESC, ~0, _irq_default_init_flags); OneIrqd_set (&desc->Irq_data, irqd_irq_disabled); ADESC->HANDLE_IRQ =Handle_bad_irq; -Desc->depth =1; -Desc->irq_count =0; thedesc->irqs_unhandled =0; -Desc->name =NULL; - for_each_possible_cpu (CPU) -*per_cpu_ptr (Desc->kstat_irqs, CPU) =0; + Desc_smp_init (DESC, node); -}
The Arch_early_irq_init () function that was called when it was last returned did not do anything.
Then look at INIT_IRQ ():
1 void __init Init_irq (void)2{3 machine_desc-> INIT_IRQ (); 4 }
MACHINE_DESC is a global variable, defined in the board file, because we are using s5pv210, and the demo board number is selected smdkv210, so this global variable is in ARCH/ARM/MACH-S5PV210/MACH-S5PV210.C:
1Machine_start (SMDKV210,"SMDKV210")2 /*Maintainer:kukjin Kim <[email protected]>*/3. Boot_params = S5p_pa_sdram +0x100,4. INIT_IRQ =S5pv210_init_irq,5. Map_io =Smdkv210_map_io,6. Init_machine =Smdkv210_machine_init,7. Timer = &S5p_timer,8Machine_end
ARCH/ARM/MACH-S5PV210/MACH-S5PV210.C also has the following function definitions:
1 void__init S5PV210_INIT_IRQ (void)2 {3U32 vic[4];/*s5pv210 supports 4 VIC*/4 5 /*All the VICs is fully populated.*/6vic[0] = ~0;7vic[1] = ~0;8vic[2] = ~0;9vic[3] = ~0;Ten One S5P_INIT_IRQ (VIC, Array_size (Vic)); A}
Arch/arm/plat-s5p/irq.c
1 void__init S5P_INIT_IRQ (U32 *Vic, u32 Num_vic)2 {3 #ifdef Config_arm_vic4 intIRQ;5 6 /*Initialize the VICs*/7 for(IRQ =0; IRQ < Num_vic; irq++)8Vic_init (Va_vic (IRQ), Vic_base (IRQ), VIC[IRQ],0);9 #endifTen OneS3C_INIT_VIC_TIMER_IRQ (5, IRQ_TIMER0); A - S3c_init_uart_irqs (Uart_irqs, Array_size (Uart_irqs)); -}
The above functions are to operate the VIC-related registers, this part of the operation is not very clear, do not go down to continue tracking.
S5PV210-based IRQ module code tracing and analysis in LInux-3.0.8