#include <asm/io.h>
#include <asm/hardware.h>
+#include <asm/arch/at91_pio.h>
#include <asm/arch/gpio.h>
#include "generic.h"
static int gpio_irq_set_wake(unsigned pin, unsigned state)
{
unsigned mask = pin_to_mask(pin);
+ unsigned bank = (pin - PIN_BASE) / 32;
- pin -= PIN_BASE;
- pin /= 32;
-
- if (unlikely(pin >= MAX_GPIO_BANKS))
+ if (unlikely(bank >= MAX_GPIO_BANKS))
return -EINVAL;
if (state)
- wakeups[pin] |= mask;
+ wakeups[bank] |= mask;
else
- wakeups[pin] &= ~mask;
+ wakeups[bank] &= ~mask;
+
+ set_irq_wake(gpio[bank].id, state);
return 0;
}
for (i = 0; i < gpio_banks; i++) {
u32 pio = gpio[i].offset;
- /*
- * Note: drivers should have disabled GPIO interrupts that
- * aren't supposed to be wakeup sources.
- * But that is not much good on ARM..... disable_irq() does
- * not update the hardware immediately, so the hardware mask
- * (IMR) has the wrong value (not current, too much is
- * permitted).
- *
- * Our workaround is to disable all non-wakeup IRQs ...
- * which is exactly what correct drivers asked for in the
- * first place!
- */
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]) {
- disable_irq_wake(gpio[i].id);
- at91_sys_write(AT91_PMC_PCDR, 1 << gpio[i].id);
- } else {
- enable_irq_wake(gpio[i].id);
+ if (!wakeups[i])
+ clk_disable(gpio[i].clock);
+ else {
#ifdef CONFIG_PM_DEBUG
- printk(KERN_DEBUG "GPIO-%c may wake for %08x\n", "ABCD"[i], wakeups[i]);
+ printk(KERN_DEBUG "GPIO-%c may wake for %08x\n", 'A'+i, wakeups[i]);
#endif
}
}
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]);
- at91_sys_write(AT91_PMC_PCER, 1 << gpio[i].id);
}
}
.set_wake = gpio_irq_set_wake,
};
-static void gpio_irq_handler(unsigned irq, struct irqdesc *desc, struct pt_regs *regs)
+static void gpio_irq_handler(unsigned irq, struct irq_desc *desc)
{
unsigned pin;
- struct irqdesc *gpio;
+ struct irq_desc *gpio;
void __iomem *pio;
u32 isr;
gpio_irq_mask(pin);
}
else
- desc_handle_irq(pin, gpio, regs);
+ desc_handle_irq(pin, gpio);
}
pin++;
gpio++;
__raw_writel(~0, controller + PIO_IDR);
set_irq_data(id, (void *) pin);
- set_irq_chipdata(id, controller);
+ set_irq_chip_data(id, controller);
for (i = 0; i < 32; i++, pin++) {
/*
* shorter, and the AIC handles interupts sanely.
*/
set_irq_chip(pin, &gpio_irqchip);
- set_irq_handler(pin, do_simple_IRQ);
+ set_irq_handler(pin, handle_simple_irq);
set_irq_flags(pin, IRQF_VALID);
}