diff options
-rw-r--r-- | drivers/irqchip/irq-gic.c | 28 |
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); |