46
46
* @lock: Lock for accessing the IRQ registers and values
47
47
* @intr_mask: Mask for interrupts lines
48
48
* @intr_type: Interrupt type selection
49
+ * @bank_read: Read a bank setting as a single 32-bit value
50
+ * @bank_write: Write a bank setting as a single 32-bit value
51
+ * @imr_line_pos: Bit shift of an IRQ line's IMR value.
52
+ *
53
+ * The DIR, DATA, and ISR registers consist of four 8-bit port values, packed
54
+ * into a single 32-bit register. Use @bank_read (@bank_write) to get (assign)
55
+ * a value from (to) these registers. The IMR register consists of four 16-bit
56
+ * port values, packed into two 32-bit registers. Use @imr_line_pos to get the
57
+ * bit shift of the 2-bit field for a line's IMR settings. Shifts larger than
58
+ * 32 overflow into the second register.
49
59
*
50
60
* Because the interrupt mask register (IMR) combines the function of IRQ type
51
61
* selection and masking, two extra values are stored. @intr_mask is used to
52
- * mask/unmask the interrupts for a GPIO port , and @intr_type is used to store
62
+ * mask/unmask the interrupts for a GPIO line , and @intr_type is used to store
53
63
* the selected interrupt types. The logical AND of these values is written to
54
64
* IMR on changes.
55
65
*/
@@ -59,10 +69,11 @@ struct realtek_gpio_ctrl {
59
69
void __iomem * cpumask_base ;
60
70
struct cpumask cpu_irq_maskable ;
61
71
raw_spinlock_t lock ;
62
- u16 intr_mask [REALTEK_GPIO_PORTS_PER_BANK ];
63
- u16 intr_type [REALTEK_GPIO_PORTS_PER_BANK ];
64
- unsigned int (* port_offset_u8 )(unsigned int port );
65
- unsigned int (* port_offset_u16 )(unsigned int port );
72
+ u8 intr_mask [REALTEK_GPIO_MAX ];
73
+ u8 intr_type [REALTEK_GPIO_MAX ];
74
+ u32 (* bank_read )(void __iomem * reg );
75
+ void (* bank_write )(void __iomem * reg , u32 value );
76
+ unsigned int (* line_imr_pos )(unsigned int line );
66
77
};
67
78
68
79
/* Expand with more flags as devices with other quirks are added */
@@ -101,14 +112,22 @@ static struct realtek_gpio_ctrl *irq_data_to_ctrl(struct irq_data *data)
101
112
* port. The two interrupt mask registers store two bits per GPIO, so use u16
102
113
* values.
103
114
*/
104
- static unsigned int realtek_gpio_port_offset_u8 ( unsigned int port )
115
+ static u32 realtek_gpio_bank_read_swapped ( void __iomem * reg )
105
116
{
106
- return port ;
117
+ return ioread32be ( reg ) ;
107
118
}
108
119
109
- static unsigned int realtek_gpio_port_offset_u16 ( unsigned int port )
120
+ static void realtek_gpio_bank_write_swapped ( void __iomem * reg , u32 value )
110
121
{
111
- return 2 * port ;
122
+ iowrite32be (value , reg );
123
+ }
124
+
125
+ static unsigned int realtek_gpio_line_imr_pos_swapped (unsigned int line )
126
+ {
127
+ unsigned int port_pin = line % 8 ;
128
+ unsigned int port = line / 8 ;
129
+
130
+ return 2 * (8 * (port ^ 1 ) + port_pin );
112
131
}
113
132
114
133
/*
@@ -119,83 +138,79 @@ static unsigned int realtek_gpio_port_offset_u16(unsigned int port)
119
138
* per GPIO, so use u16 values. The first register contains ports 1 and 0, the
120
139
* second ports 3 and 2.
121
140
*/
122
- static unsigned int realtek_gpio_port_offset_u8_rev ( unsigned int port )
141
+ static u32 realtek_gpio_bank_read ( void __iomem * reg )
123
142
{
124
- return 3 - port ;
143
+ return ioread32 ( reg ) ;
125
144
}
126
145
127
- static unsigned int realtek_gpio_port_offset_u16_rev ( unsigned int port )
146
+ static void realtek_gpio_bank_write ( void __iomem * reg , u32 value )
128
147
{
129
- return 2 * ( port ^ 1 );
148
+ iowrite32 ( value , reg );
130
149
}
131
150
132
- static void realtek_gpio_write_imr (struct realtek_gpio_ctrl * ctrl ,
133
- unsigned int port , u16 irq_type , u16 irq_mask )
151
+ static unsigned int realtek_gpio_line_imr_pos (unsigned int line )
134
152
{
135
- iowrite16 (irq_type & irq_mask ,
136
- ctrl -> base + REALTEK_GPIO_REG_IMR + ctrl -> port_offset_u16 (port ));
153
+ return 2 * line ;
137
154
}
138
155
139
- static void realtek_gpio_clear_isr (struct realtek_gpio_ctrl * ctrl ,
140
- unsigned int port , u8 mask )
156
+ static void realtek_gpio_clear_isr (struct realtek_gpio_ctrl * ctrl , u32 mask )
141
157
{
142
- iowrite8 ( mask , ctrl -> base + REALTEK_GPIO_REG_ISR + ctrl -> port_offset_u8 ( port ) );
158
+ ctrl -> bank_write ( ctrl -> base + REALTEK_GPIO_REG_ISR , mask );
143
159
}
144
160
145
- static u8 realtek_gpio_read_isr (struct realtek_gpio_ctrl * ctrl , unsigned int port )
161
+ static u32 realtek_gpio_read_isr (struct realtek_gpio_ctrl * ctrl )
146
162
{
147
- return ioread8 (ctrl -> base + REALTEK_GPIO_REG_ISR + ctrl -> port_offset_u8 ( port ) );
163
+ return ctrl -> bank_read (ctrl -> base + REALTEK_GPIO_REG_ISR );
148
164
}
149
165
150
- /* Set the rising and falling edge mask bits for a GPIO port pin */
151
- static u16 realtek_gpio_imr_bits ( unsigned int pin , u16 value )
166
+ /* Set the rising and falling edge mask bits for a GPIO pin */
167
+ static void realtek_gpio_update_line_imr ( struct realtek_gpio_ctrl * ctrl , unsigned int line )
152
168
{
153
- return (value & REALTEK_GPIO_IMR_LINE_MASK ) << 2 * pin ;
169
+ void __iomem * reg = ctrl -> base + REALTEK_GPIO_REG_IMR ;
170
+ unsigned int line_shift = ctrl -> line_imr_pos (line );
171
+ unsigned int shift = line_shift % 32 ;
172
+ u32 irq_type = ctrl -> intr_type [line ];
173
+ u32 irq_mask = ctrl -> intr_mask [line ];
174
+ u32 reg_val ;
175
+
176
+ reg += 4 * (line_shift / 32 );
177
+ reg_val = ioread32 (reg );
178
+ reg_val &= ~(REALTEK_GPIO_IMR_LINE_MASK << shift );
179
+ reg_val |= (irq_type & irq_mask & REALTEK_GPIO_IMR_LINE_MASK ) << shift ;
180
+ iowrite32 (reg_val , reg );
154
181
}
155
182
156
183
static void realtek_gpio_irq_ack (struct irq_data * data )
157
184
{
158
185
struct realtek_gpio_ctrl * ctrl = irq_data_to_ctrl (data );
159
186
irq_hw_number_t line = irqd_to_hwirq (data );
160
- unsigned int port = line / 8 ;
161
- unsigned int port_pin = line % 8 ;
162
187
163
- realtek_gpio_clear_isr (ctrl , port , BIT (port_pin ));
188
+ realtek_gpio_clear_isr (ctrl , BIT (line ));
164
189
}
165
190
166
191
static void realtek_gpio_irq_unmask (struct irq_data * data )
167
192
{
168
193
struct realtek_gpio_ctrl * ctrl = irq_data_to_ctrl (data );
169
194
unsigned int line = irqd_to_hwirq (data );
170
- unsigned int port = line / 8 ;
171
- unsigned int port_pin = line % 8 ;
172
195
unsigned long flags ;
173
- u16 m ;
174
196
175
197
gpiochip_enable_irq (& ctrl -> gc , line );
176
198
177
199
raw_spin_lock_irqsave (& ctrl -> lock , flags );
178
- m = ctrl -> intr_mask [port ];
179
- m |= realtek_gpio_imr_bits (port_pin , REALTEK_GPIO_IMR_LINE_MASK );
180
- ctrl -> intr_mask [port ] = m ;
181
- realtek_gpio_write_imr (ctrl , port , ctrl -> intr_type [port ], m );
200
+ ctrl -> intr_mask [line ] = REALTEK_GPIO_IMR_LINE_MASK ;
201
+ realtek_gpio_update_line_imr (ctrl , line );
182
202
raw_spin_unlock_irqrestore (& ctrl -> lock , flags );
183
203
}
184
204
185
205
static void realtek_gpio_irq_mask (struct irq_data * data )
186
206
{
187
207
struct realtek_gpio_ctrl * ctrl = irq_data_to_ctrl (data );
188
208
unsigned int line = irqd_to_hwirq (data );
189
- unsigned int port = line / 8 ;
190
- unsigned int port_pin = line % 8 ;
191
209
unsigned long flags ;
192
- u16 m ;
193
210
194
211
raw_spin_lock_irqsave (& ctrl -> lock , flags );
195
- m = ctrl -> intr_mask [port ];
196
- m &= ~realtek_gpio_imr_bits (port_pin , REALTEK_GPIO_IMR_LINE_MASK );
197
- ctrl -> intr_mask [port ] = m ;
198
- realtek_gpio_write_imr (ctrl , port , ctrl -> intr_type [port ], m );
212
+ ctrl -> intr_mask [line ] = 0 ;
213
+ realtek_gpio_update_line_imr (ctrl , line );
199
214
raw_spin_unlock_irqrestore (& ctrl -> lock , flags );
200
215
201
216
gpiochip_disable_irq (& ctrl -> gc , line );
@@ -205,10 +220,8 @@ static int realtek_gpio_irq_set_type(struct irq_data *data, unsigned int flow_ty
205
220
{
206
221
struct realtek_gpio_ctrl * ctrl = irq_data_to_ctrl (data );
207
222
unsigned int line = irqd_to_hwirq (data );
208
- unsigned int port = line / 8 ;
209
- unsigned int port_pin = line % 8 ;
210
223
unsigned long flags ;
211
- u16 type , t ;
224
+ u8 type ;
212
225
213
226
switch (flow_type & IRQ_TYPE_SENSE_MASK ) {
214
227
case IRQ_TYPE_EDGE_FALLING :
@@ -227,11 +240,8 @@ static int realtek_gpio_irq_set_type(struct irq_data *data, unsigned int flow_ty
227
240
irq_set_handler_locked (data , handle_edge_irq );
228
241
229
242
raw_spin_lock_irqsave (& ctrl -> lock , flags );
230
- t = ctrl -> intr_type [port ];
231
- t &= ~realtek_gpio_imr_bits (port_pin , REALTEK_GPIO_IMR_LINE_MASK );
232
- t |= realtek_gpio_imr_bits (port_pin , type );
233
- ctrl -> intr_type [port ] = t ;
234
- realtek_gpio_write_imr (ctrl , port , t , ctrl -> intr_mask [port ]);
243
+ ctrl -> intr_type [line ] = type ;
244
+ realtek_gpio_update_line_imr (ctrl , line );
235
245
raw_spin_unlock_irqrestore (& ctrl -> lock , flags );
236
246
237
247
return 0 ;
@@ -242,57 +252,48 @@ static void realtek_gpio_irq_handler(struct irq_desc *desc)
242
252
struct gpio_chip * gc = irq_desc_get_handler_data (desc );
243
253
struct realtek_gpio_ctrl * ctrl = gpiochip_get_data (gc );
244
254
struct irq_chip * irq_chip = irq_desc_get_chip (desc );
245
- unsigned int lines_done ;
246
- unsigned int port_pin_count ;
247
255
unsigned long status ;
248
256
int offset ;
249
257
250
258
chained_irq_enter (irq_chip , desc );
251
259
252
- for (lines_done = 0 ; lines_done < gc -> ngpio ; lines_done += 8 ) {
253
- status = realtek_gpio_read_isr (ctrl , lines_done / 8 );
254
- port_pin_count = min (gc -> ngpio - lines_done , 8U );
255
- for_each_set_bit (offset , & status , port_pin_count )
256
- generic_handle_domain_irq (gc -> irq .domain , offset + lines_done );
257
- }
260
+ status = realtek_gpio_read_isr (ctrl );
261
+ for_each_set_bit (offset , & status , gc -> ngpio )
262
+ generic_handle_domain_irq (gc -> irq .domain , offset );
258
263
259
264
chained_irq_exit (irq_chip , desc );
260
265
}
261
266
262
- static inline void __iomem * realtek_gpio_irq_cpu_mask (struct realtek_gpio_ctrl * ctrl ,
263
- unsigned int port , int cpu )
267
+ static inline void __iomem * realtek_gpio_irq_cpu_mask (struct realtek_gpio_ctrl * ctrl , int cpu )
264
268
{
265
- return ctrl -> cpumask_base + ctrl -> port_offset_u8 (port ) +
266
- REALTEK_GPIO_PORTS_PER_BANK * cpu ;
269
+ return ctrl -> cpumask_base + REALTEK_GPIO_PORTS_PER_BANK * cpu ;
267
270
}
268
271
269
272
static int realtek_gpio_irq_set_affinity (struct irq_data * data ,
270
273
const struct cpumask * dest , bool force )
271
274
{
272
275
struct realtek_gpio_ctrl * ctrl = irq_data_to_ctrl (data );
273
276
unsigned int line = irqd_to_hwirq (data );
274
- unsigned int port = line / 8 ;
275
- unsigned int port_pin = line % 8 ;
276
277
void __iomem * irq_cpu_mask ;
277
278
unsigned long flags ;
278
279
int cpu ;
279
- u8 v ;
280
+ u32 v ;
280
281
281
282
if (!ctrl -> cpumask_base )
282
283
return - ENXIO ;
283
284
284
285
raw_spin_lock_irqsave (& ctrl -> lock , flags );
285
286
286
287
for_each_cpu (cpu , & ctrl -> cpu_irq_maskable ) {
287
- irq_cpu_mask = realtek_gpio_irq_cpu_mask (ctrl , port , cpu );
288
- v = ioread8 (irq_cpu_mask );
288
+ irq_cpu_mask = realtek_gpio_irq_cpu_mask (ctrl , cpu );
289
+ v = ctrl -> bank_read (irq_cpu_mask );
289
290
290
291
if (cpumask_test_cpu (cpu , dest ))
291
- v |= BIT (port_pin );
292
+ v |= BIT (line );
292
293
else
293
- v &= ~BIT (port_pin );
294
+ v &= ~BIT (line );
294
295
295
- iowrite8 ( v , irq_cpu_mask );
296
+ ctrl -> bank_write ( irq_cpu_mask , v );
296
297
}
297
298
298
299
raw_spin_unlock_irqrestore (& ctrl -> lock , flags );
@@ -305,16 +306,17 @@ static int realtek_gpio_irq_set_affinity(struct irq_data *data,
305
306
static int realtek_gpio_irq_init (struct gpio_chip * gc )
306
307
{
307
308
struct realtek_gpio_ctrl * ctrl = gpiochip_get_data (gc );
308
- unsigned int port ;
309
+ u32 mask_all = GENMASK (gc -> ngpio - 1 , 0 );
310
+ unsigned int line ;
309
311
int cpu ;
310
312
311
- for (port = 0 ; (port * 8 ) < gc -> ngpio ; port ++ ) {
312
- realtek_gpio_write_imr (ctrl , port , 0 , 0 );
313
- realtek_gpio_clear_isr (ctrl , port , GENMASK (7 , 0 ));
313
+ for (line = 0 ; line < gc -> ngpio ; line ++ )
314
+ realtek_gpio_update_line_imr (ctrl , line );
314
315
315
- for_each_cpu (cpu , & ctrl -> cpu_irq_maskable )
316
- iowrite8 (GENMASK (7 , 0 ), realtek_gpio_irq_cpu_mask (ctrl , port , cpu ));
317
- }
316
+ realtek_gpio_clear_isr (ctrl , mask_all );
317
+
318
+ for_each_cpu (cpu , & ctrl -> cpu_irq_maskable )
319
+ ctrl -> bank_write (realtek_gpio_irq_cpu_mask (ctrl , cpu ), mask_all );
318
320
319
321
return 0 ;
320
322
}
@@ -387,12 +389,14 @@ static int realtek_gpio_probe(struct platform_device *pdev)
387
389
388
390
if (dev_flags & GPIO_PORTS_REVERSED ) {
389
391
bgpio_flags = 0 ;
390
- ctrl -> port_offset_u8 = realtek_gpio_port_offset_u8_rev ;
391
- ctrl -> port_offset_u16 = realtek_gpio_port_offset_u16_rev ;
392
+ ctrl -> bank_read = realtek_gpio_bank_read ;
393
+ ctrl -> bank_write = realtek_gpio_bank_write ;
394
+ ctrl -> line_imr_pos = realtek_gpio_line_imr_pos ;
392
395
} else {
393
396
bgpio_flags = BGPIOF_BIG_ENDIAN_BYTE_ORDER ;
394
- ctrl -> port_offset_u8 = realtek_gpio_port_offset_u8 ;
395
- ctrl -> port_offset_u16 = realtek_gpio_port_offset_u16 ;
397
+ ctrl -> bank_read = realtek_gpio_bank_read_swapped ;
398
+ ctrl -> bank_write = realtek_gpio_bank_write_swapped ;
399
+ ctrl -> line_imr_pos = realtek_gpio_line_imr_pos_swapped ;
396
400
}
397
401
398
402
err = bgpio_init (& ctrl -> gc , dev , 4 ,
0 commit comments