irqchip/loongson-liointc: Save/restore int_edge/int_pol registers during S3/S4
authorHuacai Chen <chenhuacai@loongson.cn>
Wed, 7 Dec 2022 14:06:43 +0000 (22:06 +0800)
committerMarc Zyngier <maz@kernel.org>
Sun, 5 Feb 2023 10:55:19 +0000 (10:55 +0000)
If int_edge/int_pol registers are configured to not be the default values, we
should save/restore them during S3/S4.

Signed-off-by: Yingkun Meng <mengyingkun@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
Signed-off-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20221207140643.1600743-1-chenhuacai@loongson.cn
drivers/irqchip/irq-loongson-liointc.c

index 85b754f7f4e6e94e349491ba15b67cd16bd5ce57..8d00a9ad5b0053b3155538c687dac01a4dda7eac 100644 (file)
@@ -55,6 +55,8 @@ struct liointc_priv {
        struct liointc_handler_data     handler[LIOINTC_NUM_PARENT];
        void __iomem                    *core_isr[LIOINTC_NUM_CORES];
        u8                              map_cache[LIOINTC_CHIP_IRQ];
+       u32                             int_pol;
+       u32                             int_edge;
        bool                            has_lpc_irq_errata;
 };
 
@@ -138,6 +140,14 @@ static int liointc_set_type(struct irq_data *data, unsigned int type)
        return 0;
 }
 
+static void liointc_suspend(struct irq_chip_generic *gc)
+{
+       struct liointc_priv *priv = gc->private;
+
+       priv->int_pol = readl(gc->reg_base + LIOINTC_REG_INTC_POL);
+       priv->int_edge = readl(gc->reg_base + LIOINTC_REG_INTC_EDGE);
+}
+
 static void liointc_resume(struct irq_chip_generic *gc)
 {
        struct liointc_priv *priv = gc->private;
@@ -150,6 +160,8 @@ static void liointc_resume(struct irq_chip_generic *gc)
        /* Restore map cache */
        for (i = 0; i < LIOINTC_CHIP_IRQ; i++)
                writeb(priv->map_cache[i], gc->reg_base + i);
+       writel(priv->int_pol, gc->reg_base + LIOINTC_REG_INTC_POL);
+       writel(priv->int_edge, gc->reg_base + LIOINTC_REG_INTC_EDGE);
        /* Restore mask cache */
        writel(gc->mask_cache, gc->reg_base + LIOINTC_REG_INTC_ENABLE);
        irq_gc_unlock_irqrestore(gc, flags);
@@ -269,6 +281,7 @@ static int liointc_init(phys_addr_t addr, unsigned long size, int revision,
        gc->private = priv;
        gc->reg_base = base;
        gc->domain = domain;
+       gc->suspend = liointc_suspend;
        gc->resume = liointc_resume;
 
        ct = gc->chip_types;