29
29
#define TQMX86_GPIIC 3 /* GPI Interrupt Configuration Register */
30
30
#define TQMX86_GPIIS 4 /* GPI Interrupt Status Register */
31
31
32
+ #define TQMX86_GPII_NONE 0
32
33
#define TQMX86_GPII_FALLING BIT(0)
33
34
#define TQMX86_GPII_RISING BIT(1)
34
35
#define TQMX86_GPII_MASK (BIT(0) | BIT(1))
35
36
#define TQMX86_GPII_BITS 2
37
+ /* Stored in irq_type with GPII bits */
38
+ #define TQMX86_INT_UNMASKED BIT(2)
36
39
37
40
struct tqmx86_gpio_data {
38
41
struct gpio_chip chip ;
39
42
void __iomem * io_base ;
40
43
int irq ;
44
+ /* Lock must be held for accessing output and irq_type fields */
41
45
raw_spinlock_t spinlock ;
42
46
DECLARE_BITMAP (output , TQMX86_NGPIO );
43
47
u8 irq_type [TQMX86_NGPI ];
@@ -104,21 +108,32 @@ static int tqmx86_gpio_get_direction(struct gpio_chip *chip,
104
108
return GPIO_LINE_DIRECTION_OUT ;
105
109
}
106
110
111
+ static void tqmx86_gpio_irq_config (struct tqmx86_gpio_data * gpio , int offset )
112
+ __must_hold (& gpio - > spinlock )
113
+ {
114
+ u8 type = TQMX86_GPII_NONE , gpiic ;
115
+
116
+ if (gpio -> irq_type [offset ] & TQMX86_INT_UNMASKED )
117
+ type = gpio -> irq_type [offset ] & TQMX86_GPII_MASK ;
118
+
119
+ gpiic = tqmx86_gpio_read (gpio , TQMX86_GPIIC );
120
+ gpiic &= ~(TQMX86_GPII_MASK << (offset * TQMX86_GPII_BITS ));
121
+ gpiic |= type << (offset * TQMX86_GPII_BITS );
122
+ tqmx86_gpio_write (gpio , gpiic , TQMX86_GPIIC );
123
+ }
124
+
107
125
static void tqmx86_gpio_irq_mask (struct irq_data * data )
108
126
{
109
127
unsigned int offset = (data -> hwirq - TQMX86_NGPO );
110
128
struct tqmx86_gpio_data * gpio = gpiochip_get_data (
111
129
irq_data_get_irq_chip_data (data ));
112
130
unsigned long flags ;
113
- u8 gpiic , mask ;
114
-
115
- mask = TQMX86_GPII_MASK << (offset * TQMX86_GPII_BITS );
116
131
117
132
raw_spin_lock_irqsave (& gpio -> spinlock , flags );
118
- gpiic = tqmx86_gpio_read (gpio , TQMX86_GPIIC );
119
- gpiic &= ~mask ;
120
- tqmx86_gpio_write (gpio , gpiic , TQMX86_GPIIC );
133
+ gpio -> irq_type [offset ] &= ~TQMX86_INT_UNMASKED ;
134
+ tqmx86_gpio_irq_config (gpio , offset );
121
135
raw_spin_unlock_irqrestore (& gpio -> spinlock , flags );
136
+
122
137
gpiochip_disable_irq (& gpio -> chip , irqd_to_hwirq (data ));
123
138
}
124
139
@@ -128,16 +143,12 @@ static void tqmx86_gpio_irq_unmask(struct irq_data *data)
128
143
struct tqmx86_gpio_data * gpio = gpiochip_get_data (
129
144
irq_data_get_irq_chip_data (data ));
130
145
unsigned long flags ;
131
- u8 gpiic , mask ;
132
-
133
- mask = TQMX86_GPII_MASK << (offset * TQMX86_GPII_BITS );
134
146
135
147
gpiochip_enable_irq (& gpio -> chip , irqd_to_hwirq (data ));
148
+
136
149
raw_spin_lock_irqsave (& gpio -> spinlock , flags );
137
- gpiic = tqmx86_gpio_read (gpio , TQMX86_GPIIC );
138
- gpiic &= ~mask ;
139
- gpiic |= gpio -> irq_type [offset ] << (offset * TQMX86_GPII_BITS );
140
- tqmx86_gpio_write (gpio , gpiic , TQMX86_GPIIC );
150
+ gpio -> irq_type [offset ] |= TQMX86_INT_UNMASKED ;
151
+ tqmx86_gpio_irq_config (gpio , offset );
141
152
raw_spin_unlock_irqrestore (& gpio -> spinlock , flags );
142
153
}
143
154
@@ -148,7 +159,7 @@ static int tqmx86_gpio_irq_set_type(struct irq_data *data, unsigned int type)
148
159
unsigned int offset = (data -> hwirq - TQMX86_NGPO );
149
160
unsigned int edge_type = type & IRQF_TRIGGER_MASK ;
150
161
unsigned long flags ;
151
- u8 new_type , gpiic ;
162
+ u8 new_type ;
152
163
153
164
switch (edge_type ) {
154
165
case IRQ_TYPE_EDGE_RISING :
@@ -164,13 +175,10 @@ static int tqmx86_gpio_irq_set_type(struct irq_data *data, unsigned int type)
164
175
return - EINVAL ; /* not supported */
165
176
}
166
177
167
- gpio -> irq_type [offset ] = new_type ;
168
-
169
178
raw_spin_lock_irqsave (& gpio -> spinlock , flags );
170
- gpiic = tqmx86_gpio_read (gpio , TQMX86_GPIIC );
171
- gpiic &= ~((TQMX86_GPII_MASK ) << (offset * TQMX86_GPII_BITS ));
172
- gpiic |= new_type << (offset * TQMX86_GPII_BITS );
173
- tqmx86_gpio_write (gpio , gpiic , TQMX86_GPIIC );
179
+ gpio -> irq_type [offset ] &= ~TQMX86_GPII_MASK ;
180
+ gpio -> irq_type [offset ] |= new_type ;
181
+ tqmx86_gpio_irq_config (gpio , offset );
174
182
raw_spin_unlock_irqrestore (& gpio -> spinlock , flags );
175
183
176
184
return 0 ;
0 commit comments