@@ -73,9 +73,11 @@ struct gic_chip_data {
73
73
union gic_base cpu_base ;
74
74
#ifdef CONFIG_CPU_PM
75
75
u32 saved_spi_enable [DIV_ROUND_UP (1020 , 32 )];
76
+ u32 saved_spi_active [DIV_ROUND_UP (1020 , 32 )];
76
77
u32 saved_spi_conf [DIV_ROUND_UP (1020 , 16 )];
77
78
u32 saved_spi_target [DIV_ROUND_UP (1020 , 4 )];
78
79
u32 __percpu * saved_ppi_enable ;
80
+ u32 __percpu * saved_ppi_active ;
79
81
u32 __percpu * saved_ppi_conf ;
80
82
#endif
81
83
struct irq_domain * domain ;
@@ -566,6 +568,10 @@ static void gic_dist_save(unsigned int gic_nr)
566
568
for (i = 0 ; i < DIV_ROUND_UP (gic_irqs , 32 ); i ++ )
567
569
gic_data [gic_nr ].saved_spi_enable [i ] =
568
570
readl_relaxed (dist_base + GIC_DIST_ENABLE_SET + i * 4 );
571
+
572
+ for (i = 0 ; i < DIV_ROUND_UP (gic_irqs , 32 ); i ++ )
573
+ gic_data [gic_nr ].saved_spi_active [i ] =
574
+ readl_relaxed (dist_base + GIC_DIST_ACTIVE_SET + i * 4 );
569
575
}
570
576
571
577
/*
@@ -604,9 +610,19 @@ static void gic_dist_restore(unsigned int gic_nr)
604
610
writel_relaxed (gic_data [gic_nr ].saved_spi_target [i ],
605
611
dist_base + GIC_DIST_TARGET + i * 4 );
606
612
607
- for (i = 0 ; i < DIV_ROUND_UP (gic_irqs , 32 ); i ++ )
613
+ for (i = 0 ; i < DIV_ROUND_UP (gic_irqs , 32 ); i ++ ) {
614
+ writel_relaxed (GICD_INT_EN_CLR_X32 ,
615
+ dist_base + GIC_DIST_ENABLE_CLEAR + i * 4 );
608
616
writel_relaxed (gic_data [gic_nr ].saved_spi_enable [i ],
609
617
dist_base + GIC_DIST_ENABLE_SET + i * 4 );
618
+ }
619
+
620
+ for (i = 0 ; i < DIV_ROUND_UP (gic_irqs , 32 ); i ++ ) {
621
+ writel_relaxed (GICD_INT_EN_CLR_X32 ,
622
+ dist_base + GIC_DIST_ACTIVE_CLEAR + i * 4 );
623
+ writel_relaxed (gic_data [gic_nr ].saved_spi_active [i ],
624
+ dist_base + GIC_DIST_ACTIVE_SET + i * 4 );
625
+ }
610
626
611
627
writel_relaxed (GICD_ENABLE , dist_base + GIC_DIST_CTRL );
612
628
}
@@ -631,6 +647,10 @@ static void gic_cpu_save(unsigned int gic_nr)
631
647
for (i = 0 ; i < DIV_ROUND_UP (32 , 32 ); i ++ )
632
648
ptr [i ] = readl_relaxed (dist_base + GIC_DIST_ENABLE_SET + i * 4 );
633
649
650
+ ptr = raw_cpu_ptr (gic_data [gic_nr ].saved_ppi_active );
651
+ for (i = 0 ; i < DIV_ROUND_UP (32 , 32 ); i ++ )
652
+ ptr [i ] = readl_relaxed (dist_base + GIC_DIST_ACTIVE_SET + i * 4 );
653
+
634
654
ptr = raw_cpu_ptr (gic_data [gic_nr ].saved_ppi_conf );
635
655
for (i = 0 ; i < DIV_ROUND_UP (32 , 16 ); i ++ )
636
656
ptr [i ] = readl_relaxed (dist_base + GIC_DIST_CONFIG + i * 4 );
@@ -654,8 +674,18 @@ static void gic_cpu_restore(unsigned int gic_nr)
654
674
return ;
655
675
656
676
ptr = raw_cpu_ptr (gic_data [gic_nr ].saved_ppi_enable );
657
- for (i = 0 ; i < DIV_ROUND_UP (32 , 32 ); i ++ )
677
+ for (i = 0 ; i < DIV_ROUND_UP (32 , 32 ); i ++ ) {
678
+ writel_relaxed (GICD_INT_EN_CLR_X32 ,
679
+ dist_base + GIC_DIST_ENABLE_CLEAR + i * 4 );
658
680
writel_relaxed (ptr [i ], dist_base + GIC_DIST_ENABLE_SET + i * 4 );
681
+ }
682
+
683
+ ptr = raw_cpu_ptr (gic_data [gic_nr ].saved_ppi_active );
684
+ for (i = 0 ; i < DIV_ROUND_UP (32 , 32 ); i ++ ) {
685
+ writel_relaxed (GICD_INT_EN_CLR_X32 ,
686
+ dist_base + GIC_DIST_ACTIVE_CLEAR + i * 4 );
687
+ writel_relaxed (ptr [i ], dist_base + GIC_DIST_ACTIVE_SET + i * 4 );
688
+ }
659
689
660
690
ptr = raw_cpu_ptr (gic_data [gic_nr ].saved_ppi_conf );
661
691
for (i = 0 ; i < DIV_ROUND_UP (32 , 16 ); i ++ )
@@ -710,6 +740,10 @@ static void __init gic_pm_init(struct gic_chip_data *gic)
710
740
sizeof (u32 ));
711
741
BUG_ON (!gic -> saved_ppi_enable );
712
742
743
+ gic -> saved_ppi_active = __alloc_percpu (DIV_ROUND_UP (32 , 32 ) * 4 ,
744
+ sizeof (u32 ));
745
+ BUG_ON (!gic -> saved_ppi_active );
746
+
713
747
gic -> saved_ppi_conf = __alloc_percpu (DIV_ROUND_UP (32 , 16 ) * 4 ,
714
748
sizeof (u32 ));
715
749
BUG_ON (!gic -> saved_ppi_conf );
0 commit comments