@@ -51,6 +51,8 @@ struct hlwd_gpio {
51
51
struct irq_chip irqc ;
52
52
void __iomem * regs ;
53
53
int irq ;
54
+ u32 edge_emulation ;
55
+ u32 rising_edge , falling_edge ;
54
56
};
55
57
56
58
static void hlwd_gpio_irqhandler (struct irq_desc * desc )
@@ -61,10 +63,36 @@ static void hlwd_gpio_irqhandler(struct irq_desc *desc)
61
63
unsigned long flags ;
62
64
unsigned long pending ;
63
65
int hwirq ;
66
+ u32 emulated_pending ;
64
67
65
68
spin_lock_irqsave (& hlwd -> gpioc .bgpio_lock , flags );
66
69
pending = ioread32be (hlwd -> regs + HW_GPIOB_INTFLAG );
67
70
pending &= ioread32be (hlwd -> regs + HW_GPIOB_INTMASK );
71
+
72
+ /* Treat interrupts due to edge trigger emulation separately */
73
+ emulated_pending = hlwd -> edge_emulation & pending ;
74
+ pending &= ~emulated_pending ;
75
+ if (emulated_pending ) {
76
+ u32 level , rising , falling ;
77
+
78
+ level = ioread32be (hlwd -> regs + HW_GPIOB_INTLVL );
79
+ rising = level & emulated_pending ;
80
+ falling = ~level & emulated_pending ;
81
+
82
+ /* Invert the levels */
83
+ iowrite32be (level ^ emulated_pending ,
84
+ hlwd -> regs + HW_GPIOB_INTLVL );
85
+
86
+ /* Ack all emulated-edge interrupts */
87
+ iowrite32be (emulated_pending , hlwd -> regs + HW_GPIOB_INTFLAG );
88
+
89
+ /* Signal interrupts only on the correct edge */
90
+ rising &= hlwd -> rising_edge ;
91
+ falling &= hlwd -> falling_edge ;
92
+
93
+ /* Mark emulated interrupts as pending */
94
+ pending |= rising | falling ;
95
+ }
68
96
spin_unlock_irqrestore (& hlwd -> gpioc .bgpio_lock , flags );
69
97
70
98
chained_irq_enter (chip , desc );
@@ -120,6 +148,27 @@ static void hlwd_gpio_irq_enable(struct irq_data *data)
120
148
hlwd_gpio_irq_unmask (data );
121
149
}
122
150
151
+ static void hlwd_gpio_irq_setup_emulation (struct hlwd_gpio * hlwd , int hwirq ,
152
+ unsigned int flow_type )
153
+ {
154
+ u32 level , state ;
155
+
156
+ /* Set the trigger level to the inactive level */
157
+ level = ioread32be (hlwd -> regs + HW_GPIOB_INTLVL );
158
+ state = ioread32be (hlwd -> regs + HW_GPIOB_IN ) & BIT (hwirq );
159
+ level &= ~BIT (hwirq );
160
+ level |= state ^ BIT (hwirq );
161
+ iowrite32be (level , hlwd -> regs + HW_GPIOB_INTLVL );
162
+
163
+ hlwd -> edge_emulation |= BIT (hwirq );
164
+ hlwd -> rising_edge &= ~BIT (hwirq );
165
+ hlwd -> falling_edge &= ~BIT (hwirq );
166
+ if (flow_type & IRQ_TYPE_EDGE_RISING )
167
+ hlwd -> rising_edge |= BIT (hwirq );
168
+ if (flow_type & IRQ_TYPE_EDGE_FALLING )
169
+ hlwd -> falling_edge |= BIT (hwirq );
170
+ }
171
+
123
172
static int hlwd_gpio_irq_set_type (struct irq_data * data , unsigned int flow_type )
124
173
{
125
174
struct hlwd_gpio * hlwd =
@@ -129,6 +178,8 @@ static int hlwd_gpio_irq_set_type(struct irq_data *data, unsigned int flow_type)
129
178
130
179
spin_lock_irqsave (& hlwd -> gpioc .bgpio_lock , flags );
131
180
181
+ hlwd -> edge_emulation &= ~BIT (data -> hwirq );
182
+
132
183
switch (flow_type ) {
133
184
case IRQ_TYPE_LEVEL_HIGH :
134
185
level = ioread32be (hlwd -> regs + HW_GPIOB_INTLVL );
@@ -140,6 +191,11 @@ static int hlwd_gpio_irq_set_type(struct irq_data *data, unsigned int flow_type)
140
191
level &= ~BIT (data -> hwirq );
141
192
iowrite32be (level , hlwd -> regs + HW_GPIOB_INTLVL );
142
193
break ;
194
+ case IRQ_TYPE_EDGE_RISING :
195
+ case IRQ_TYPE_EDGE_FALLING :
196
+ case IRQ_TYPE_EDGE_BOTH :
197
+ hlwd_gpio_irq_setup_emulation (hlwd , data -> hwirq , flow_type );
198
+ break ;
143
199
default :
144
200
spin_unlock_irqrestore (& hlwd -> gpioc .bgpio_lock , flags );
145
201
return - EINVAL ;
0 commit comments