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
@@ -624,7 +640,7 @@ static int aic_irq_domain_map(struct irq_domain *id, unsigned int irq,
624640 u32 type = FIELD_GET (AIC_EVENT_TYPE , hw );
625641 struct irq_chip * chip = & aic_chip ;
626642
627- if (ic -> info .version == 2 )
643+ if (ic -> info .version == 2 || ic -> info . version == 3 )
628644 chip = & aic2_chip ;
629645
630646 if (type == AIC_EVENT_TYPE_IRQ ) {
@@ -931,6 +947,7 @@ static void build_fiq_affinity(struct aic_irq_chip *ic, struct device_node *aff)
931947
932948static int __init aic_of_ic_init (struct device_node * node , struct device_node * parent )
933949{
950+ int ret ;
934951 int i , die ;
935952 u32 off , start_off ;
936953 void __iomem * regs ;
@@ -974,11 +991,24 @@ static int __init aic_of_ic_init(struct device_node *node, struct device_node *p
974991
975992 break ;
976993 }
994+ case 3 :
995+ /* read offsets from device tree for aic version 3 */
996+ /* extint-baseaddress? */
997+ ret = of_property_read_u32 (node , "config-offset" , & irqc -> info .irq_cfg );
998+ if (ret < 0 )
999+ return ret ;
1000+ ret = of_property_read_u32 (node , "cap0-offset" , & irqc -> info .cap0_off );
1001+ if (ret < 0 )
1002+ return ret ;
1003+ ret = of_property_read_u32 (node , "maxnumirq-offset" , & irqc -> info .maxnumirq_off );
1004+ if (ret < 0 )
1005+ return ret ;
1006+ fallthrough ;
9771007 case 2 : {
9781008 u32 info1 , info3 ;
9791009
980- info1 = aic_ic_read (irqc , AIC2_INFO1 );
981- info3 = aic_ic_read (irqc , AIC2_INFO3 );
1010+ info1 = aic_ic_read (irqc , irqc -> info . cap0_off );
1011+ info3 = aic_ic_read (irqc , irqc -> info . maxnumirq_off );
9821012
9831013 irqc -> nr_irq = FIELD_GET (AIC2_INFO1_NR_IRQ , info1 );
9841014 irqc -> max_irq = FIELD_GET (AIC2_INFO3_MAX_IRQ , info3 );
@@ -1048,7 +1078,7 @@ static int __init aic_of_ic_init(struct device_node *node, struct device_node *p
10481078 off += irqc -> info .die_stride ;
10491079 }
10501080
1051- if (irqc -> info .version == 2 ) {
1081+ if (irqc -> info .version == 2 || irqc -> info . version == 3 ) {
10521082 u32 config = aic_ic_read (irqc , AIC2_CONFIG );
10531083
10541084 config |= AIC2_CONFIG_ENABLE ;
@@ -1099,3 +1129,4 @@ static int __init aic_of_ic_init(struct device_node *node, struct device_node *p
10991129
11001130IRQCHIP_DECLARE (apple_aic , "apple,aic" , aic_of_ic_init );
11011131IRQCHIP_DECLARE (apple_aic2 , "apple,aic2" , aic_of_ic_init );
1132+ IRQCHIP_DECLARE (apple_aic3 , "apple,aic3" , aic_of_ic_init );
0 commit comments