Implement GPIO interrupt debouncing on ep93xx. Signed-off-by: Lennert Buytenhek Index: linux-2.6.22/arch/arm/mach-ep93xx/core.c =================================================================== --- linux-2.6.22.orig/arch/arm/mach-ep93xx/core.c +++ linux-2.6.22/arch/arm/mach-ep93xx/core.c @@ -154,6 +154,7 @@ struct sys_timer ep93xx_timer = { *************************************************************************/ static unsigned char gpio_int_unmasked[3]; static unsigned char gpio_int_enabled[3]; +static unsigned char gpio_int_debounce[3]; static unsigned char gpio_int_type1[3]; static unsigned char gpio_int_type2[3]; @@ -161,16 +162,19 @@ static void update_gpio_int_params(int a { if (abf == 0) { __raw_writeb(0, EP93XX_GPIO_A_INT_ENABLE); + __raw_writeb(gpio_int_debounce[0], EP93XX_GPIO_A_INT_DEBOUNCE); __raw_writeb(gpio_int_type2[0], EP93XX_GPIO_A_INT_TYPE2); __raw_writeb(gpio_int_type1[0], EP93XX_GPIO_A_INT_TYPE1); __raw_writeb(gpio_int_unmasked[0] & gpio_int_enabled[0], EP93XX_GPIO_A_INT_ENABLE); } else if (abf == 1) { __raw_writeb(0, EP93XX_GPIO_B_INT_ENABLE); + __raw_writeb(gpio_int_debounce[1], EP93XX_GPIO_B_INT_DEBOUNCE); __raw_writeb(gpio_int_type2[1], EP93XX_GPIO_B_INT_TYPE2); __raw_writeb(gpio_int_type1[1], EP93XX_GPIO_B_INT_TYPE1); __raw_writeb(gpio_int_unmasked[1] & gpio_int_enabled[1], EP93XX_GPIO_B_INT_ENABLE); } else if (abf == 2) { __raw_writeb(0, EP93XX_GPIO_F_INT_ENABLE); + __raw_writeb(gpio_int_debounce[2], EP93XX_GPIO_F_INT_DEBOUNCE); __raw_writeb(gpio_int_type2[2], EP93XX_GPIO_F_INT_TYPE2); __raw_writeb(gpio_int_type1[2], EP93XX_GPIO_F_INT_TYPE1); __raw_writeb(gpio_int_unmasked[2] & gpio_int_enabled[2], EP93XX_GPIO_F_INT_ENABLE); @@ -361,6 +365,13 @@ static int ep93xx_gpio_irq_type(unsigned } else { gpio_int_enabled[port] &= ~(1 << line); } + + if (type & IRQ_TYPE_DEBOUNCE) { + gpio_int_debounce[port] |= 1 << line; + } else { + gpio_int_debounce[port] &= ~(1 << line); + } + update_gpio_int_params(port); return 0; Index: linux-2.6.22/include/asm-arm/arch-ep93xx/ep93xx-regs.h =================================================================== --- linux-2.6.22.orig/include/asm-arm/arch-ep93xx/ep93xx-regs.h +++ linux-2.6.22/include/asm-arm/arch-ep93xx/ep93xx-regs.h @@ -78,16 +78,19 @@ #define EP93XX_GPIO_F_INT_ACK EP93XX_GPIO_REG(0x54) #define EP93XX_GPIO_F_INT_ENABLE EP93XX_GPIO_REG(0x58) #define EP93XX_GPIO_F_INT_STATUS EP93XX_GPIO_REG(0x5c) +#define EP93XX_GPIO_F_INT_DEBOUNCE EP93XX_GPIO_REG(0x64) #define EP93XX_GPIO_A_INT_TYPE1 EP93XX_GPIO_REG(0x90) #define EP93XX_GPIO_A_INT_TYPE2 EP93XX_GPIO_REG(0x94) #define EP93XX_GPIO_A_INT_ACK EP93XX_GPIO_REG(0x98) #define EP93XX_GPIO_A_INT_ENABLE EP93XX_GPIO_REG(0x9c) #define EP93XX_GPIO_A_INT_STATUS EP93XX_GPIO_REG(0xa0) +#define EP93XX_GPIO_A_INT_DEBOUNCE EP93XX_GPIO_REG(0xa8) #define EP93XX_GPIO_B_INT_TYPE1 EP93XX_GPIO_REG(0xac) #define EP93XX_GPIO_B_INT_TYPE2 EP93XX_GPIO_REG(0xb0) #define EP93XX_GPIO_B_INT_ACK EP93XX_GPIO_REG(0xb4) #define EP93XX_GPIO_B_INT_ENABLE EP93XX_GPIO_REG(0xb8) #define EP93XX_GPIO_B_INT_STATUS EP93XX_GPIO_REG(0xbc) +#define EP93XX_GPIO_B_INT_DEBOUNCE EP93XX_GPIO_REG(0xc4) #define EP93XX_AAC_BASE (EP93XX_APB_VIRT_BASE + 0x00080000) Index: linux-2.6.22/include/linux/irq.h =================================================================== --- linux-2.6.22.orig/include/linux/irq.h +++ linux-2.6.22/include/linux/irq.h @@ -44,6 +44,7 @@ typedef void fastcall (*irq_flow_handler #define IRQ_TYPE_LEVEL_LOW 0x00000008 /* Level low type */ #define IRQ_TYPE_SENSE_MASK 0x0000000f /* Mask of the above */ #define IRQ_TYPE_PROBE 0x00000010 /* Probing in progress */ +#define IRQ_TYPE_DEBOUNCE 0x00000020 /* Enable HW debounce */ /* Internal flags */ #define IRQ_INPROGRESS 0x00000100 /* IRQ handler active - do not enter! */