summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/irqchip/irq-gic.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index bc846e7fec44..abf2ffaed392 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -73,9 +73,11 @@ struct gic_chip_data {
73 union gic_base cpu_base; 73 union gic_base cpu_base;
74#ifdef CONFIG_CPU_PM 74#ifdef CONFIG_CPU_PM
75 u32 saved_spi_enable[DIV_ROUND_UP(1020, 32)]; 75 u32 saved_spi_enable[DIV_ROUND_UP(1020, 32)];
76 u32 saved_spi_active[DIV_ROUND_UP(1020, 32)];
76 u32 saved_spi_conf[DIV_ROUND_UP(1020, 16)]; 77 u32 saved_spi_conf[DIV_ROUND_UP(1020, 16)];
77 u32 saved_spi_target[DIV_ROUND_UP(1020, 4)]; 78 u32 saved_spi_target[DIV_ROUND_UP(1020, 4)];
78 u32 __percpu *saved_ppi_enable; 79 u32 __percpu *saved_ppi_enable;
80 u32 __percpu *saved_ppi_active;
79 u32 __percpu *saved_ppi_conf; 81 u32 __percpu *saved_ppi_conf;
80#endif 82#endif
81 struct irq_domain *domain; 83 struct irq_domain *domain;
@@ -566,6 +568,10 @@ static void gic_dist_save(unsigned int gic_nr)
566 for (i = 0; i < DIV_ROUND_UP(gic_irqs, 32); i++) 568 for (i = 0; i < DIV_ROUND_UP(gic_irqs, 32); i++)
567 gic_data[gic_nr].saved_spi_enable[i] = 569 gic_data[gic_nr].saved_spi_enable[i] =
568 readl_relaxed(dist_base + GIC_DIST_ENABLE_SET + i * 4); 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/*
@@ -611,6 +617,13 @@ static void gic_dist_restore(unsigned int gic_nr)
611 dist_base + GIC_DIST_ENABLE_SET + i * 4); 617 dist_base + GIC_DIST_ENABLE_SET + i * 4);
612 } 618 }
613 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 }
626
614 writel_relaxed(GICD_ENABLE, dist_base + GIC_DIST_CTRL); 627 writel_relaxed(GICD_ENABLE, dist_base + GIC_DIST_CTRL);
615} 628}
616 629
@@ -634,6 +647,10 @@ static void gic_cpu_save(unsigned int gic_nr)
634 for (i = 0; i < DIV_ROUND_UP(32, 32); i++) 647 for (i = 0; i < DIV_ROUND_UP(32, 32); i++)
635 ptr[i] = readl_relaxed(dist_base + GIC_DIST_ENABLE_SET + i * 4); 648 ptr[i] = readl_relaxed(dist_base + GIC_DIST_ENABLE_SET + i * 4);
636 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
637 ptr = raw_cpu_ptr(gic_data[gic_nr].saved_ppi_conf); 654 ptr = raw_cpu_ptr(gic_data[gic_nr].saved_ppi_conf);
638 for (i = 0; i < DIV_ROUND_UP(32, 16); i++) 655 for (i = 0; i < DIV_ROUND_UP(32, 16); i++)
639 ptr[i] = readl_relaxed(dist_base + GIC_DIST_CONFIG + i * 4); 656 ptr[i] = readl_relaxed(dist_base + GIC_DIST_CONFIG + i * 4);
@@ -663,6 +680,13 @@ static void gic_cpu_restore(unsigned int gic_nr)
663 writel_relaxed(ptr[i], dist_base + GIC_DIST_ENABLE_SET + i * 4); 680 writel_relaxed(ptr[i], dist_base + GIC_DIST_ENABLE_SET + i * 4);
664 } 681 }
665 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 }
689
666 ptr = raw_cpu_ptr(gic_data[gic_nr].saved_ppi_conf); 690 ptr = raw_cpu_ptr(gic_data[gic_nr].saved_ppi_conf);
667 for (i = 0; i < DIV_ROUND_UP(32, 16); i++) 691 for (i = 0; i < DIV_ROUND_UP(32, 16); i++)
668 writel_relaxed(ptr[i], dist_base + GIC_DIST_CONFIG + i * 4); 692 writel_relaxed(ptr[i], dist_base + GIC_DIST_CONFIG + i * 4);
@@ -716,6 +740,10 @@ static void __init gic_pm_init(struct gic_chip_data *gic)
716 sizeof(u32)); 740 sizeof(u32));
717 BUG_ON(!gic->saved_ppi_enable); 741 BUG_ON(!gic->saved_ppi_enable);
718 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
719 gic->saved_ppi_conf = __alloc_percpu(DIV_ROUND_UP(32, 16) * 4, 747 gic->saved_ppi_conf = __alloc_percpu(DIV_ROUND_UP(32, 16) * 4,
720 sizeof(u32)); 748 sizeof(u32));
721 BUG_ON(!gic->saved_ppi_conf); 749 BUG_ON(!gic->saved_ppi_conf);