5454#include <linux/irqdomain.h>
5555#include <linux/jump_label.h>
5656#include <linux/limits.h>
57+ #include <linux/of.h>
5758#include <linux/of_address.h>
5859#include <linux/slab.h>
5960#include <asm/apple_m1_pmu.h>
@@ -251,6 +252,9 @@ struct aic_info {
251252 u32 mask_set ;
252253 u32 mask_clr ;
253254
255+ u32 cap0_off ;
256+ u32 maxnumirq_off ;
257+
254258 u32 die_stride ;
255259
256260 /* Features */
@@ -288,6 +292,14 @@ static const struct aic_info aic2_info __initconst = {
288292 .version = 2 ,
289293
290294 .irq_cfg = AIC2_IRQ_CFG ,
295+ .cap0_off = AIC2_INFO1 ,
296+ .maxnumirq_off = AIC2_INFO3 ,
297+
298+ .fast_ipi = true,
299+ };
300+
301+ static const struct aic_info aic3_info __initconst = {
302+ .version = 3 ,
291303
292304 .fast_ipi = true,
293305 .local_fast_ipi = true,
@@ -310,6 +322,10 @@ static const struct of_device_id aic_info_match[] = {
310322 .compatible = "apple,aic2" ,
311323 .data = & aic2_info ,
312324 },
325+ {
326+ .compatible = "apple,aic3" ,
327+ .data = & aic3_info ,
328+ },
313329 {}
314330};
315331
@@ -623,7 +639,7 @@ static int aic_irq_domain_map(struct irq_domain *id, unsigned int irq,
623639 u32 type = FIELD_GET (AIC_EVENT_TYPE , hw );
624640 struct irq_chip * chip = & aic_chip ;
625641
626- if (ic -> info .version == 2 )
642+ if (ic -> info .version == 2 || ic -> info . version == 3 )
627643 chip = & aic2_chip ;
628644
629645 if (type == AIC_EVENT_TYPE_IRQ ) {
@@ -930,6 +946,7 @@ static void build_fiq_affinity(struct aic_irq_chip *ic, struct device_node *aff)
930946
931947static int __init aic_of_ic_init (struct device_node * node , struct device_node * parent )
932948{
949+ int ret ;
933950 int i , die ;
934951 u32 off , start_off ;
935952 void __iomem * regs ;
@@ -973,11 +990,24 @@ static int __init aic_of_ic_init(struct device_node *node, struct device_node *p
973990
974991 break ;
975992 }
993+ case 3 :
994+ /* read offsets from device tree for aic version 3 */
995+ /* extint-baseaddress? */
996+ ret = of_property_read_u32 (node , "config-offset" , & irqc -> info .irq_cfg );
997+ if (ret < 0 )
998+ return ret ;
999+ ret = of_property_read_u32 (node , "cap0-offset" , & irqc -> info .cap0_off );
1000+ if (ret < 0 )
1001+ return ret ;
1002+ ret = of_property_read_u32 (node , "maxnumirq-offset" , & irqc -> info .maxnumirq_off );
1003+ if (ret < 0 )
1004+ return ret ;
1005+ fallthrough ;
9761006 case 2 : {
9771007 u32 info1 , info3 ;
9781008
979- info1 = aic_ic_read (irqc , AIC2_INFO1 );
980- info3 = aic_ic_read (irqc , AIC2_INFO3 );
1009+ info1 = aic_ic_read (irqc , irqc -> info . cap0_off );
1010+ info3 = aic_ic_read (irqc , irqc -> info . maxnumirq_off );
9811011
9821012 irqc -> nr_irq = FIELD_GET (AIC2_INFO1_NR_IRQ , info1 );
9831013 irqc -> max_irq = FIELD_GET (AIC2_INFO3_MAX_IRQ , info3 );
@@ -1047,7 +1077,7 @@ static int __init aic_of_ic_init(struct device_node *node, struct device_node *p
10471077 off += irqc -> info .die_stride ;
10481078 }
10491079
1050- if (irqc -> info .version == 2 ) {
1080+ if (irqc -> info .version == 2 || irqc -> info . version == 3 ) {
10511081 u32 config = aic_ic_read (irqc , AIC2_CONFIG );
10521082
10531083 config |= AIC2_CONFIG_ENABLE ;
@@ -1098,3 +1128,4 @@ static int __init aic_of_ic_init(struct device_node *node, struct device_node *p
10981128
10991129IRQCHIP_DECLARE (apple_aic , "apple,aic" , aic_of_ic_init );
11001130IRQCHIP_DECLARE (apple_aic2 , "apple,aic2" , aic_of_ic_init );
1131+ IRQCHIP_DECLARE (apple_aic3 , "apple,aic3" , aic_of_ic_init );
0 commit comments