1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
Implement GPIO interrupt debouncing on ep93xx.
Signed-off-by: Lennert Buytenhek <buytenh@wantstofly.org>
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! */
|