6464#include <dt-bindings/interrupt-controller/apple-aic.h>
6565
6666/*
67- * AIC registers (MMIO)
67+ * AIC v1 registers (MMIO)
6868 */
6969
7070#define AIC_INFO 0x0004
9494#define AIC_IPI_SELF BIT(31)
9595
9696#define AIC_TARGET_CPU 0x3000
97- #define AIC_SW_SET 0x4000
98- #define AIC_SW_CLR 0x4080
99- #define AIC_MASK_SET 0x4100
100- #define AIC_MASK_CLR 0x4180
10197
10298#define AIC_CPU_IPI_SET (cpu ) (0x5008 + ((cpu) << 7))
10399#define AIC_CPU_IPI_CLR (cpu ) (0x500c + ((cpu) << 7))
104100#define AIC_CPU_IPI_MASK_SET (cpu ) (0x5024 + ((cpu) << 7))
105101#define AIC_CPU_IPI_MASK_CLR (cpu ) (0x5028 + ((cpu) << 7))
106102
103+ #define AIC_MAX_IRQ 0x400
104+
107105#define MASK_REG (x ) (4 * ((x) >> 5))
108106#define MASK_BIT (x ) BIT((x) & GENMASK(4, 0))
109107
@@ -189,17 +187,31 @@ DEFINE_STATIC_KEY_TRUE(use_fast_ipi);
189187struct aic_info {
190188 int version ;
191189
190+ /* Register offsets */
191+ u32 event ;
192+ u32 target_cpu ;
193+ u32 sw_set ;
194+ u32 sw_clr ;
195+ u32 mask_set ;
196+ u32 mask_clr ;
197+
192198 /* Features */
193199 bool fast_ipi ;
194200};
195201
196202static const struct aic_info aic1_info = {
197203 .version = 1 ,
204+
205+ .event = AIC_EVENT ,
206+ .target_cpu = AIC_TARGET_CPU ,
198207};
199208
200209static const struct aic_info aic1_fipi_info = {
201210 .version = 1 ,
202211
212+ .event = AIC_EVENT ,
213+ .target_cpu = AIC_TARGET_CPU ,
214+
203215 .fast_ipi = true,
204216};
205217
@@ -219,7 +231,9 @@ struct aic_irq_chip {
219231 void __iomem * base ;
220232 struct irq_domain * hw_domain ;
221233 struct irq_domain * ipi_domain ;
234+
222235 int nr_irq ;
236+ int max_irq ;
223237
224238 struct aic_info info ;
225239};
@@ -254,7 +268,7 @@ static void aic_irq_mask(struct irq_data *d)
254268
255269 u32 irq = AIC_HWIRQ_IRQ (hwirq );
256270
257- aic_ic_write (ic , AIC_MASK_SET + MASK_REG (irq ), MASK_BIT (irq ));
271+ aic_ic_write (ic , ic -> info . mask_set + MASK_REG (irq ), MASK_BIT (irq ));
258272}
259273
260274static void aic_irq_unmask (struct irq_data * d )
@@ -264,7 +278,7 @@ static void aic_irq_unmask(struct irq_data *d)
264278
265279 u32 irq = AIC_HWIRQ_IRQ (hwirq );
266280
267- aic_ic_write (ic , AIC_MASK_CLR + MASK_REG (irq ), MASK_BIT (irq ));
281+ aic_ic_write (ic , ic -> info . mask_clr + MASK_REG (irq ), MASK_BIT (irq ));
268282}
269283
270284static void aic_irq_eoi (struct irq_data * d )
@@ -287,7 +301,7 @@ static void __exception_irq_entry aic_handle_irq(struct pt_regs *regs)
287301 * We cannot use a relaxed read here, as reads from DMA buffers
288302 * need to be ordered after the IRQ fires.
289303 */
290- event = readl (ic -> base + AIC_EVENT );
304+ event = readl (ic -> base + ic -> info . event );
291305 type = FIELD_GET (AIC_EVENT_TYPE , event );
292306 irq = FIELD_GET (AIC_EVENT_NUM , event );
293307
@@ -319,12 +333,14 @@ static int aic_irq_set_affinity(struct irq_data *d,
319333 struct aic_irq_chip * ic = irq_data_get_irq_chip_data (d );
320334 int cpu ;
321335
336+ BUG_ON (!ic -> info .target_cpu );
337+
322338 if (force )
323339 cpu = cpumask_first (mask_val );
324340 else
325341 cpu = cpumask_any_and (mask_val , cpu_online_mask );
326342
327- aic_ic_write (ic , AIC_TARGET_CPU + AIC_HWIRQ_IRQ (hwirq ) * 4 , BIT (cpu ));
343+ aic_ic_write (ic , ic -> info . target_cpu + AIC_HWIRQ_IRQ (hwirq ) * 4 , BIT (cpu ));
328344 irq_data_update_effective_affinity (d , cpumask_of (cpu ));
329345
330346 return IRQ_SET_MASK_OK ;
@@ -884,8 +900,8 @@ static struct gic_kvm_info vgic_info __initdata = {
884900static int __init aic_of_ic_init (struct device_node * node , struct device_node * parent )
885901{
886902 int i ;
903+ u32 off ;
887904 void __iomem * regs ;
888- u32 info ;
889905 struct aic_irq_chip * irqc ;
890906 const struct of_device_id * match ;
891907
@@ -907,8 +923,30 @@ static int __init aic_of_ic_init(struct device_node *node, struct device_node *p
907923
908924 aic_irqc = irqc ;
909925
910- info = aic_ic_read (irqc , AIC_INFO );
911- irqc -> nr_irq = FIELD_GET (AIC_INFO_NR_IRQ , info );
926+ switch (irqc -> info .version ) {
927+ case 1 : {
928+ u32 info ;
929+
930+ info = aic_ic_read (irqc , AIC_INFO );
931+ irqc -> nr_irq = FIELD_GET (AIC_INFO_NR_IRQ , info );
932+ irqc -> max_irq = AIC_MAX_IRQ ;
933+
934+ off = irqc -> info .target_cpu ;
935+ off += sizeof (u32 ) * irqc -> max_irq ; /* TARGET_CPU */
936+
937+ break ;
938+ }
939+ }
940+
941+ irqc -> info .sw_set = off ;
942+ off += sizeof (u32 ) * (irqc -> max_irq >> 5 ); /* SW_SET */
943+ irqc -> info .sw_clr = off ;
944+ off += sizeof (u32 ) * (irqc -> max_irq >> 5 ); /* SW_CLR */
945+ irqc -> info .mask_set = off ;
946+ off += sizeof (u32 ) * (irqc -> max_irq >> 5 ); /* MASK_SET */
947+ irqc -> info .mask_clr = off ;
948+ off += sizeof (u32 ) * (irqc -> max_irq >> 5 ); /* MASK_CLR */
949+ off += sizeof (u32 ) * (irqc -> max_irq >> 5 ); /* HW_STATE */
912950
913951 if (irqc -> info .fast_ipi )
914952 static_branch_enable (& use_fast_ipi );
@@ -936,11 +974,11 @@ static int __init aic_of_ic_init(struct device_node *node, struct device_node *p
936974 set_handle_fiq (aic_handle_fiq );
937975
938976 for (i = 0 ; i < BITS_TO_U32 (irqc -> nr_irq ); i ++ )
939- aic_ic_write (irqc , AIC_MASK_SET + i * 4 , U32_MAX );
977+ aic_ic_write (irqc , irqc -> info . mask_set + i * 4 , U32_MAX );
940978 for (i = 0 ; i < BITS_TO_U32 (irqc -> nr_irq ); i ++ )
941- aic_ic_write (irqc , AIC_SW_CLR + i * 4 , U32_MAX );
979+ aic_ic_write (irqc , irqc -> info . sw_clr + i * 4 , U32_MAX );
942980 for (i = 0 ; i < irqc -> nr_irq ; i ++ )
943- aic_ic_write (irqc , AIC_TARGET_CPU + i * 4 , 1 );
981+ aic_ic_write (irqc , irqc -> info . target_cpu + i * 4 , 1 );
944982
945983 if (!is_kernel_in_hyp_mode ())
946984 pr_info ("Kernel running in EL1, mapping interrupts" );
@@ -954,8 +992,8 @@ static int __init aic_of_ic_init(struct device_node *node, struct device_node *p
954992
955993 vgic_set_kvm_info (& vgic_info );
956994
957- pr_info ("Initialized with %d IRQs, %d FIQs, %d vIPIs\n " ,
958- irqc -> nr_irq , AIC_NR_FIQ , AIC_NR_SWIPI );
995+ pr_info ("Initialized with %d/%d IRQs, %d FIQs, %d vIPIs" ,
996+ irqc -> nr_irq , irqc -> max_irq , AIC_NR_FIQ , AIC_NR_SWIPI );
959997
960998 return 0 ;
961999}
0 commit comments