6868 */
6969
7070#define AIC_INFO 0x0004
71- #define AIC_INFO_NR_HW GENMASK(15, 0)
71+ #define AIC_INFO_NR_IRQ GENMASK(15, 0)
7272
7373#define AIC_CONFIG 0x0010
7474
7777#define AIC_EVENT_TYPE GENMASK(31, 16)
7878#define AIC_EVENT_NUM GENMASK(15, 0)
7979
80- #define AIC_EVENT_TYPE_HW 1
80+ #define AIC_EVENT_TYPE_FIQ 0 /* Software use */
81+ #define AIC_EVENT_TYPE_IRQ 1
8182#define AIC_EVENT_TYPE_IPI 4
8283#define AIC_EVENT_IPI_OTHER 1
8384#define AIC_EVENT_IPI_SELF 2
160161#define MPIDR_CPU (x ) MPIDR_AFFINITY_LEVEL(x, 0)
161162#define MPIDR_CLUSTER (x ) MPIDR_AFFINITY_LEVEL(x, 1)
162163
164+ #define AIC_IRQ_HWIRQ (x ) (FIELD_PREP(AIC_EVENT_TYPE, AIC_EVENT_TYPE_IRQ) | \
165+ FIELD_PREP(AIC_EVENT_NUM, x))
166+ #define AIC_FIQ_HWIRQ (x ) (FIELD_PREP(AIC_EVENT_TYPE, AIC_EVENT_TYPE_FIQ) | \
167+ FIELD_PREP(AIC_EVENT_NUM, x))
168+ #define AIC_HWIRQ_IRQ (x ) FIELD_GET(AIC_EVENT_NUM, x)
163169#define AIC_NR_FIQ 4
164170#define AIC_NR_SWIPI 32
165171
@@ -213,7 +219,7 @@ struct aic_irq_chip {
213219 void __iomem * base ;
214220 struct irq_domain * hw_domain ;
215221 struct irq_domain * ipi_domain ;
216- int nr_hw ;
222+ int nr_irq ;
217223
218224 struct aic_info info ;
219225};
@@ -243,18 +249,22 @@ static void aic_ic_write(struct aic_irq_chip *ic, u32 reg, u32 val)
243249
244250static void aic_irq_mask (struct irq_data * d )
245251{
252+ irq_hw_number_t hwirq = irqd_to_hwirq (d );
246253 struct aic_irq_chip * ic = irq_data_get_irq_chip_data (d );
247254
248- aic_ic_write (ic , AIC_MASK_SET + MASK_REG (irqd_to_hwirq (d )),
249- MASK_BIT (irqd_to_hwirq (d )));
255+ u32 irq = AIC_HWIRQ_IRQ (hwirq );
256+
257+ aic_ic_write (ic , AIC_MASK_SET + MASK_REG (irq ), MASK_BIT (irq ));
250258}
251259
252260static void aic_irq_unmask (struct irq_data * d )
253261{
262+ irq_hw_number_t hwirq = irqd_to_hwirq (d );
254263 struct aic_irq_chip * ic = irq_data_get_irq_chip_data (d );
255264
256- aic_ic_write (ic , AIC_MASK_CLR + MASK_REG (d -> hwirq ),
257- MASK_BIT (irqd_to_hwirq (d )));
265+ u32 irq = AIC_HWIRQ_IRQ (hwirq );
266+
267+ aic_ic_write (ic , AIC_MASK_CLR + MASK_REG (irq ), MASK_BIT (irq ));
258268}
259269
260270static void aic_irq_eoi (struct irq_data * d )
@@ -281,8 +291,8 @@ static void __exception_irq_entry aic_handle_irq(struct pt_regs *regs)
281291 type = FIELD_GET (AIC_EVENT_TYPE , event );
282292 irq = FIELD_GET (AIC_EVENT_NUM , event );
283293
284- if (type == AIC_EVENT_TYPE_HW )
285- generic_handle_domain_irq (aic_irqc -> hw_domain , irq );
294+ if (type == AIC_EVENT_TYPE_IRQ )
295+ generic_handle_domain_irq (aic_irqc -> hw_domain , event );
286296 else if (type == AIC_EVENT_TYPE_IPI && irq == 1 )
287297 aic_handle_ipi (regs );
288298 else if (event != 0 )
@@ -314,7 +324,7 @@ static int aic_irq_set_affinity(struct irq_data *d,
314324 else
315325 cpu = cpumask_any_and (mask_val , cpu_online_mask );
316326
317- aic_ic_write (ic , AIC_TARGET_CPU + hwirq * 4 , BIT (cpu ));
327+ aic_ic_write (ic , AIC_TARGET_CPU + AIC_HWIRQ_IRQ ( hwirq ) * 4 , BIT (cpu ));
318328 irq_data_update_effective_affinity (d , cpumask_of (cpu ));
319329
320330 return IRQ_SET_MASK_OK ;
@@ -344,9 +354,7 @@ static struct irq_chip aic_chip = {
344354
345355static unsigned long aic_fiq_get_idx (struct irq_data * d )
346356{
347- struct aic_irq_chip * ic = irq_data_get_irq_chip_data (d );
348-
349- return irqd_to_hwirq (d ) - ic -> nr_hw ;
357+ return AIC_HWIRQ_IRQ (irqd_to_hwirq (d ));
350358}
351359
352360static void aic_fiq_set_mask (struct irq_data * d )
@@ -434,24 +442,24 @@ static void __exception_irq_entry aic_handle_fiq(struct pt_regs *regs)
434442
435443 if (TIMER_FIRING (read_sysreg (cntp_ctl_el0 )))
436444 generic_handle_domain_irq (aic_irqc -> hw_domain ,
437- aic_irqc -> nr_hw + AIC_TMR_EL0_PHYS );
445+ AIC_FIQ_HWIRQ ( AIC_TMR_EL0_PHYS ) );
438446
439447 if (TIMER_FIRING (read_sysreg (cntv_ctl_el0 )))
440448 generic_handle_domain_irq (aic_irqc -> hw_domain ,
441- aic_irqc -> nr_hw + AIC_TMR_EL0_VIRT );
449+ AIC_FIQ_HWIRQ ( AIC_TMR_EL0_VIRT ) );
442450
443451 if (is_kernel_in_hyp_mode ()) {
444452 uint64_t enabled = read_sysreg_s (SYS_IMP_APL_VM_TMR_FIQ_ENA_EL2 );
445453
446454 if ((enabled & VM_TMR_FIQ_ENABLE_P ) &&
447455 TIMER_FIRING (read_sysreg_s (SYS_CNTP_CTL_EL02 )))
448456 generic_handle_domain_irq (aic_irqc -> hw_domain ,
449- aic_irqc -> nr_hw + AIC_TMR_EL02_PHYS );
457+ AIC_FIQ_HWIRQ ( AIC_TMR_EL02_PHYS ) );
450458
451459 if ((enabled & VM_TMR_FIQ_ENABLE_V ) &&
452460 TIMER_FIRING (read_sysreg_s (SYS_CNTV_CTL_EL02 )))
453461 generic_handle_domain_irq (aic_irqc -> hw_domain ,
454- aic_irqc -> nr_hw + AIC_TMR_EL02_VIRT );
462+ AIC_FIQ_HWIRQ ( AIC_TMR_EL02_VIRT ) );
455463 }
456464
457465 if ((read_sysreg_s (SYS_IMP_APL_PMCR0_EL1 ) & (PMCR0_IMODE | PMCR0_IACT )) ==
@@ -496,9 +504,9 @@ static struct irq_chip fiq_chip = {
496504static int aic_irq_domain_map (struct irq_domain * id , unsigned int irq ,
497505 irq_hw_number_t hw )
498506{
499- struct aic_irq_chip * ic = id -> host_data ;
507+ u32 type = FIELD_GET ( AIC_EVENT_TYPE , hw ) ;
500508
501- if (hw < ic -> nr_hw ) {
509+ if (type == AIC_EVENT_TYPE_IRQ ) {
502510 irq_domain_set_info (id , irq , hw , & aic_chip , id -> host_data ,
503511 handle_fasteoi_irq , NULL , NULL );
504512 irqd_set_single_target (irq_desc_get_irq_data (irq_to_desc (irq )));
@@ -523,14 +531,14 @@ static int aic_irq_domain_translate(struct irq_domain *id,
523531
524532 switch (fwspec -> param [0 ]) {
525533 case AIC_IRQ :
526- if (fwspec -> param [1 ] >= ic -> nr_hw )
534+ if (fwspec -> param [1 ] >= ic -> nr_irq )
527535 return - EINVAL ;
528- * hwirq = fwspec -> param [1 ];
536+ * hwirq = AIC_IRQ_HWIRQ ( fwspec -> param [1 ]) ;
529537 break ;
530538 case AIC_FIQ :
531539 if (fwspec -> param [1 ] >= AIC_NR_FIQ )
532540 return - EINVAL ;
533- * hwirq = ic -> nr_hw + fwspec -> param [1 ];
541+ * hwirq = AIC_FIQ_HWIRQ ( fwspec -> param [1 ]) ;
534542
535543 /*
536544 * In EL1 the non-redirected registers are the guest's,
@@ -539,10 +547,10 @@ static int aic_irq_domain_translate(struct irq_domain *id,
539547 if (!is_kernel_in_hyp_mode ()) {
540548 switch (fwspec -> param [1 ]) {
541549 case AIC_TMR_GUEST_PHYS :
542- * hwirq = ic -> nr_hw + AIC_TMR_EL0_PHYS ;
550+ * hwirq = AIC_FIQ_HWIRQ ( AIC_TMR_EL0_PHYS ) ;
543551 break ;
544552 case AIC_TMR_GUEST_VIRT :
545- * hwirq = ic -> nr_hw + AIC_TMR_EL0_VIRT ;
553+ * hwirq = AIC_FIQ_HWIRQ ( AIC_TMR_EL0_VIRT ) ;
546554 break ;
547555 case AIC_TMR_HV_PHYS :
548556 case AIC_TMR_HV_VIRT :
@@ -900,16 +908,15 @@ static int __init aic_of_ic_init(struct device_node *node, struct device_node *p
900908 aic_irqc = irqc ;
901909
902910 info = aic_ic_read (irqc , AIC_INFO );
903- irqc -> nr_hw = FIELD_GET (AIC_INFO_NR_HW , info );
911+ irqc -> nr_irq = FIELD_GET (AIC_INFO_NR_IRQ , info );
904912
905913 if (irqc -> info .fast_ipi )
906914 static_branch_enable (& use_fast_ipi );
907915 else
908916 static_branch_disable (& use_fast_ipi );
909917
910- irqc -> hw_domain = irq_domain_create_linear (of_node_to_fwnode (node ),
911- irqc -> nr_hw + AIC_NR_FIQ ,
912- & aic_irq_domain_ops , irqc );
918+ irqc -> hw_domain = irq_domain_create_tree (of_node_to_fwnode (node ),
919+ & aic_irq_domain_ops , irqc );
913920 if (WARN_ON (!irqc -> hw_domain )) {
914921 iounmap (irqc -> base );
915922 kfree (irqc );
@@ -928,11 +935,11 @@ static int __init aic_of_ic_init(struct device_node *node, struct device_node *p
928935 set_handle_irq (aic_handle_irq );
929936 set_handle_fiq (aic_handle_fiq );
930937
931- for (i = 0 ; i < BITS_TO_U32 (irqc -> nr_hw ); i ++ )
938+ for (i = 0 ; i < BITS_TO_U32 (irqc -> nr_irq ); i ++ )
932939 aic_ic_write (irqc , AIC_MASK_SET + i * 4 , U32_MAX );
933- for (i = 0 ; i < BITS_TO_U32 (irqc -> nr_hw ); i ++ )
940+ for (i = 0 ; i < BITS_TO_U32 (irqc -> nr_irq ); i ++ )
934941 aic_ic_write (irqc , AIC_SW_CLR + i * 4 , U32_MAX );
935- for (i = 0 ; i < irqc -> nr_hw ; i ++ )
942+ for (i = 0 ; i < irqc -> nr_irq ; i ++ )
936943 aic_ic_write (irqc , AIC_TARGET_CPU + i * 4 , 1 );
937944
938945 if (!is_kernel_in_hyp_mode ())
@@ -948,7 +955,7 @@ static int __init aic_of_ic_init(struct device_node *node, struct device_node *p
948955 vgic_set_kvm_info (& vgic_info );
949956
950957 pr_info ("Initialized with %d IRQs, %d FIQs, %d vIPIs\n" ,
951- irqc -> nr_hw , AIC_NR_FIQ , AIC_NR_SWIPI );
958+ irqc -> nr_irq , AIC_NR_FIQ , AIC_NR_SWIPI );
952959
953960 return 0 ;
954961}
0 commit comments