+#ifdef CONFIG_PM
+
+static u32 wakeups[MAX_GPIO_BANKS];
+static u32 backups[MAX_GPIO_BANKS];
+
+static int gpio_irq_set_wake(unsigned pin, unsigned state)
+{
+ unsigned mask = pin_to_mask(pin);
+ unsigned bank = (pin - PIN_BASE) / 32;
+
+ if (unlikely(bank >= MAX_GPIO_BANKS))
+ return -EINVAL;
+
+ if (state)
+ wakeups[bank] |= mask;
+ else
+ wakeups[bank] &= ~mask;
+
+ set_irq_wake(gpio[bank].id, state);
+
+ return 0;
+}
+
+void at91_gpio_suspend(void)
+{
+ int i;
+
+ for (i = 0; i < gpio_banks; i++) {
+ u32 pio = gpio[i].offset;
+
+ backups[i] = at91_sys_read(pio + PIO_IMR);
+ at91_sys_write(pio + PIO_IDR, backups[i]);
+ at91_sys_write(pio + PIO_IER, wakeups[i]);
+
+ if (!wakeups[i])
+ clk_disable(gpio[i].clock);
+ else {
+#ifdef CONFIG_PM_DEBUG
+ printk(KERN_DEBUG "GPIO-%c may wake for %08x\n", 'A'+i, wakeups[i]);
+#endif
+ }
+ }
+}
+
+void at91_gpio_resume(void)
+{
+ int i;
+
+ for (i = 0; i < gpio_banks; i++) {
+ u32 pio = gpio[i].offset;
+
+ if (!wakeups[i])
+ clk_enable(gpio[i].clock);
+
+ at91_sys_write(pio + PIO_IDR, wakeups[i]);
+ at91_sys_write(pio + PIO_IER, backups[i]);
+ }
+}
+
+#else
+#define gpio_irq_set_wake NULL
+#endif
+