]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/avr32/mach-at32ap/intc.c
avr32: Power Management support ("standby" and "mem" modes)
[linux-2.6-omap-h63xx.git] / arch / avr32 / mach-at32ap / intc.c
index 644a3fb8c164de068316f489288532445159cd6a..994c4545e2b7ecac3bc50b95db9e871aebf7d8e4 100644 (file)
@@ -22,6 +22,10 @@ struct intc {
        void __iomem            *regs;
        struct irq_chip         chip;
        struct sys_device       sysdev;
+#ifdef CONFIG_PM
+       unsigned long           suspend_ipr;
+       unsigned long           saved_ipr[64];
+#endif
 };
 
 extern struct platform_device at32_intc0_device;
@@ -138,8 +142,56 @@ fail:
        panic("Interrupt controller initialization failed!\n");
 }
 
+#ifdef CONFIG_PM
+void intc_set_suspend_handler(unsigned long offset)
+{
+       intc0.suspend_ipr = offset;
+}
+
+static int intc_suspend(struct sys_device *sdev, pm_message_t state)
+{
+       struct intc *intc = container_of(sdev, struct intc, sysdev);
+       int i;
+
+       if (unlikely(!irqs_disabled())) {
+               pr_err("intc_suspend: called with interrupts enabled\n");
+               return -EINVAL;
+       }
+
+       if (unlikely(!intc->suspend_ipr)) {
+               pr_err("intc_suspend: suspend_ipr not initialized\n");
+               return -EINVAL;
+       }
+
+       for (i = 0; i < 64; i++) {
+               intc->saved_ipr[i] = intc_readl(intc, INTPR0 + 4 * i);
+               intc_writel(intc, INTPR0 + 4 * i, intc->suspend_ipr);
+       }
+
+       return 0;
+}
+
+static int intc_resume(struct sys_device *sdev)
+{
+       struct intc *intc = container_of(sdev, struct intc, sysdev);
+       int i;
+
+       WARN_ON(!irqs_disabled());
+
+       for (i = 0; i < 64; i++)
+               intc_writel(intc, INTPR0 + 4 * i, intc->saved_ipr[i]);
+
+       return 0;
+}
+#else
+#define intc_suspend   NULL
+#define intc_resume    NULL
+#endif
+
 static struct sysdev_class intc_class = {
-       .name   = "intc",
+       .name           = "intc",
+       .suspend        = intc_suspend,
+       .resume         = intc_resume,
 };
 
 static int __init intc_init_sysdev(void)