irqchip/loongson-htvec: Add suspend/resume support
authorHuacai Chen <chenhuacai@loongson.cn>
Thu, 20 Oct 2022 07:35:24 +0000 (15:35 +0800)
committerMarc Zyngier <maz@kernel.org>
Sat, 26 Nov 2022 13:09:25 +0000 (13:09 +0000)
Add suspend/resume support for HTVEC irqchip, which is needed for
upcoming suspend/hibernation.

Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
Signed-off-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20221020073527.541845-2-chenhuacai@loongson.cn
drivers/irqchip/irq-loongson-htvec.c

index 8b06082616cb57b6197bbbb1f5651f8e76dd7a44..fc8bf1f5d41b2238f4444363043d31136a49d768 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
 #include <linux/of_platform.h>
+#include <linux/syscore_ops.h>
 
 /* Registers */
 #define HTVEC_EN_OFF           0x20
@@ -29,6 +30,7 @@ struct htvec {
        void __iomem            *base;
        struct irq_domain       *htvec_domain;
        raw_spinlock_t          htvec_lock;
+       u32                     saved_vec_en[HTVEC_MAX_PARENT_IRQ];
 };
 
 static struct htvec *htvec_priv;
@@ -156,6 +158,29 @@ static void htvec_reset(struct htvec *priv)
        }
 }
 
+static int htvec_suspend(void)
+{
+       int i;
+
+       for (i = 0; i < htvec_priv->num_parents; i++)
+               htvec_priv->saved_vec_en[i] = readl(htvec_priv->base + HTVEC_EN_OFF + 4 * i);
+
+       return 0;
+}
+
+static void htvec_resume(void)
+{
+       int i;
+
+       for (i = 0; i < htvec_priv->num_parents; i++)
+               writel(htvec_priv->saved_vec_en[i], htvec_priv->base + HTVEC_EN_OFF + 4 * i);
+}
+
+static struct syscore_ops htvec_syscore_ops = {
+       .suspend = htvec_suspend,
+       .resume = htvec_resume,
+};
+
 static int htvec_init(phys_addr_t addr, unsigned long size,
                int num_parents, int parent_irq[], struct fwnode_handle *domain_handle)
 {
@@ -188,6 +213,8 @@ static int htvec_init(phys_addr_t addr, unsigned long size,
 
        htvec_priv = priv;
 
+       register_syscore_ops(&htvec_syscore_ops);
+
        return 0;
 
 iounmap_base: