9
9
*/
10
10
11
11
#include <linux/gpio.h>
12
+ #include <linux/irq.h>
13
+ #include <linux/interrupt.h>
14
+ #include <linux/irqdomain.h>
12
15
#include <linux/export.h>
13
16
#include <linux/ssb/ssb.h>
14
17
15
18
#include "ssb_private.h"
16
19
20
+
21
+ /**************************************************
22
+ * Shared
23
+ **************************************************/
24
+
17
25
static struct ssb_bus * ssb_gpio_get_bus (struct gpio_chip * chip )
18
26
{
19
27
return container_of (chip , struct ssb_bus , gpio );
20
28
}
21
29
30
+ #if IS_ENABLED (CONFIG_SSB_EMBEDDED )
31
+ static int ssb_gpio_to_irq (struct gpio_chip * chip , unsigned gpio )
32
+ {
33
+ struct ssb_bus * bus = ssb_gpio_get_bus (chip );
34
+
35
+ if (bus -> bustype == SSB_BUSTYPE_SSB )
36
+ return irq_find_mapping (bus -> irq_domain , gpio );
37
+ else
38
+ return - EINVAL ;
39
+ }
40
+ #endif
41
+
42
+ /**************************************************
43
+ * ChipCommon
44
+ **************************************************/
45
+
22
46
static int ssb_gpio_chipco_get_value (struct gpio_chip * chip , unsigned gpio )
23
47
{
24
48
struct ssb_bus * bus = ssb_gpio_get_bus (chip );
@@ -74,19 +98,129 @@ static void ssb_gpio_chipco_free(struct gpio_chip *chip, unsigned gpio)
74
98
ssb_chipco_gpio_pullup (& bus -> chipco , 1 << gpio , 0 );
75
99
}
76
100
77
- static int ssb_gpio_chipco_to_irq (struct gpio_chip * chip , unsigned gpio )
101
+ #if IS_ENABLED (CONFIG_SSB_EMBEDDED )
102
+ static void ssb_gpio_irq_chipco_mask (struct irq_data * d )
78
103
{
79
- struct ssb_bus * bus = ssb_gpio_get_bus (chip );
104
+ struct ssb_bus * bus = irq_data_get_irq_chip_data (d );
105
+ int gpio = irqd_to_hwirq (d );
80
106
81
- if (bus -> bustype == SSB_BUSTYPE_SSB )
82
- return ssb_mips_irq (bus -> chipco .dev ) + 2 ;
83
- else
84
- return - EINVAL ;
107
+ ssb_chipco_gpio_intmask (& bus -> chipco , BIT (gpio ), 0 );
108
+ }
109
+
110
+ static void ssb_gpio_irq_chipco_unmask (struct irq_data * d )
111
+ {
112
+ struct ssb_bus * bus = irq_data_get_irq_chip_data (d );
113
+ int gpio = irqd_to_hwirq (d );
114
+ u32 val = ssb_chipco_gpio_in (& bus -> chipco , BIT (gpio ));
115
+
116
+ ssb_chipco_gpio_polarity (& bus -> chipco , BIT (gpio ), val );
117
+ ssb_chipco_gpio_intmask (& bus -> chipco , BIT (gpio ), BIT (gpio ));
118
+ }
119
+
120
+ static struct irq_chip ssb_gpio_irq_chipco_chip = {
121
+ .name = "SSB-GPIO-CC" ,
122
+ .irq_mask = ssb_gpio_irq_chipco_mask ,
123
+ .irq_unmask = ssb_gpio_irq_chipco_unmask ,
124
+ };
125
+
126
+ static irqreturn_t ssb_gpio_irq_chipco_handler (int irq , void * dev_id )
127
+ {
128
+ struct ssb_bus * bus = dev_id ;
129
+ struct ssb_chipcommon * chipco = & bus -> chipco ;
130
+ u32 val = chipco_read32 (chipco , SSB_CHIPCO_GPIOIN );
131
+ u32 mask = chipco_read32 (chipco , SSB_CHIPCO_GPIOIRQ );
132
+ u32 pol = chipco_read32 (chipco , SSB_CHIPCO_GPIOPOL );
133
+ unsigned long irqs = (val ^ pol ) & mask ;
134
+ int gpio ;
135
+
136
+ if (!irqs )
137
+ return IRQ_NONE ;
138
+
139
+ for_each_set_bit (gpio , & irqs , bus -> gpio .ngpio )
140
+ generic_handle_irq (ssb_gpio_to_irq (& bus -> gpio , gpio ));
141
+ ssb_chipco_gpio_polarity (chipco , irqs , val & irqs );
142
+
143
+ return IRQ_HANDLED ;
144
+ }
145
+
146
+ static int ssb_gpio_irq_chipco_domain_init (struct ssb_bus * bus )
147
+ {
148
+ struct ssb_chipcommon * chipco = & bus -> chipco ;
149
+ struct gpio_chip * chip = & bus -> gpio ;
150
+ int gpio , hwirq , err ;
151
+
152
+ if (bus -> bustype != SSB_BUSTYPE_SSB )
153
+ return 0 ;
154
+
155
+ bus -> irq_domain = irq_domain_add_linear (NULL , chip -> ngpio ,
156
+ & irq_domain_simple_ops , chipco );
157
+ if (!bus -> irq_domain ) {
158
+ err = - ENODEV ;
159
+ goto err_irq_domain ;
160
+ }
161
+ for (gpio = 0 ; gpio < chip -> ngpio ; gpio ++ ) {
162
+ int irq = irq_create_mapping (bus -> irq_domain , gpio );
163
+
164
+ irq_set_chip_data (irq , bus );
165
+ irq_set_chip_and_handler (irq , & ssb_gpio_irq_chipco_chip ,
166
+ handle_simple_irq );
167
+ }
168
+
169
+ hwirq = ssb_mips_irq (bus -> chipco .dev ) + 2 ;
170
+ err = request_irq (hwirq , ssb_gpio_irq_chipco_handler , IRQF_SHARED ,
171
+ "gpio" , bus );
172
+ if (err )
173
+ goto err_req_irq ;
174
+
175
+ ssb_chipco_gpio_intmask (& bus -> chipco , ~0 , 0 );
176
+ chipco_set32 (chipco , SSB_CHIPCO_IRQMASK , SSB_CHIPCO_IRQ_GPIO );
177
+
178
+ return 0 ;
179
+
180
+ err_req_irq :
181
+ for (gpio = 0 ; gpio < chip -> ngpio ; gpio ++ ) {
182
+ int irq = irq_find_mapping (bus -> irq_domain , gpio );
183
+
184
+ irq_dispose_mapping (irq );
185
+ }
186
+ irq_domain_remove (bus -> irq_domain );
187
+ err_irq_domain :
188
+ return err ;
189
+ }
190
+
191
+ static void ssb_gpio_irq_chipco_domain_exit (struct ssb_bus * bus )
192
+ {
193
+ struct ssb_chipcommon * chipco = & bus -> chipco ;
194
+ struct gpio_chip * chip = & bus -> gpio ;
195
+ int gpio ;
196
+
197
+ if (bus -> bustype != SSB_BUSTYPE_SSB )
198
+ return ;
199
+
200
+ chipco_mask32 (chipco , SSB_CHIPCO_IRQMASK , ~SSB_CHIPCO_IRQ_GPIO );
201
+ free_irq (ssb_mips_irq (bus -> chipco .dev ) + 2 , chipco );
202
+ for (gpio = 0 ; gpio < chip -> ngpio ; gpio ++ ) {
203
+ int irq = irq_find_mapping (bus -> irq_domain , gpio );
204
+
205
+ irq_dispose_mapping (irq );
206
+ }
207
+ irq_domain_remove (bus -> irq_domain );
208
+ }
209
+ #else
210
+ static int ssb_gpio_irq_chipco_domain_init (struct ssb_bus * bus )
211
+ {
212
+ return 0 ;
85
213
}
86
214
215
+ static void ssb_gpio_irq_chipco_domain_exit (struct ssb_bus * bus )
216
+ {
217
+ }
218
+ #endif
219
+
87
220
static int ssb_gpio_chipco_init (struct ssb_bus * bus )
88
221
{
89
222
struct gpio_chip * chip = & bus -> gpio ;
223
+ int err ;
90
224
91
225
chip -> label = "ssb_chipco_gpio" ;
92
226
chip -> owner = THIS_MODULE ;
@@ -96,7 +230,9 @@ static int ssb_gpio_chipco_init(struct ssb_bus *bus)
96
230
chip -> set = ssb_gpio_chipco_set_value ;
97
231
chip -> direction_input = ssb_gpio_chipco_direction_input ;
98
232
chip -> direction_output = ssb_gpio_chipco_direction_output ;
99
- chip -> to_irq = ssb_gpio_chipco_to_irq ;
233
+ #if IS_ENABLED (CONFIG_SSB_EMBEDDED )
234
+ chip -> to_irq = ssb_gpio_to_irq ;
235
+ #endif
100
236
chip -> ngpio = 16 ;
101
237
/* There is just one SoC in one device and its GPIO addresses should be
102
238
* deterministic to address them more easily. The other buses could get
@@ -106,9 +242,23 @@ static int ssb_gpio_chipco_init(struct ssb_bus *bus)
106
242
else
107
243
chip -> base = -1 ;
108
244
109
- return gpiochip_add (chip );
245
+ err = ssb_gpio_irq_chipco_domain_init (bus );
246
+ if (err )
247
+ return err ;
248
+
249
+ err = gpiochip_add (chip );
250
+ if (err ) {
251
+ ssb_gpio_irq_chipco_domain_exit (bus );
252
+ return err ;
253
+ }
254
+
255
+ return 0 ;
110
256
}
111
257
258
+ /**************************************************
259
+ * EXTIF
260
+ **************************************************/
261
+
112
262
#ifdef CONFIG_SSB_DRIVER_EXTIF
113
263
114
264
static int ssb_gpio_extif_get_value (struct gpio_chip * chip , unsigned gpio )
@@ -145,27 +295,137 @@ static int ssb_gpio_extif_direction_output(struct gpio_chip *chip,
145
295
return 0 ;
146
296
}
147
297
148
- static int ssb_gpio_extif_to_irq (struct gpio_chip * chip , unsigned gpio )
298
+ #if IS_ENABLED (CONFIG_SSB_EMBEDDED )
299
+ static void ssb_gpio_irq_extif_mask (struct irq_data * d )
149
300
{
150
- struct ssb_bus * bus = ssb_gpio_get_bus (chip );
301
+ struct ssb_bus * bus = irq_data_get_irq_chip_data (d );
302
+ int gpio = irqd_to_hwirq (d );
151
303
152
- if (bus -> bustype == SSB_BUSTYPE_SSB )
153
- return ssb_mips_irq (bus -> extif .dev ) + 2 ;
154
- else
155
- return - EINVAL ;
304
+ ssb_extif_gpio_intmask (& bus -> extif , BIT (gpio ), 0 );
305
+ }
306
+
307
+ static void ssb_gpio_irq_extif_unmask (struct irq_data * d )
308
+ {
309
+ struct ssb_bus * bus = irq_data_get_irq_chip_data (d );
310
+ int gpio = irqd_to_hwirq (d );
311
+ u32 val = ssb_extif_gpio_in (& bus -> extif , BIT (gpio ));
312
+
313
+ ssb_extif_gpio_polarity (& bus -> extif , BIT (gpio ), val );
314
+ ssb_extif_gpio_intmask (& bus -> extif , BIT (gpio ), BIT (gpio ));
315
+ }
316
+
317
+ static struct irq_chip ssb_gpio_irq_extif_chip = {
318
+ .name = "SSB-GPIO-EXTIF" ,
319
+ .irq_mask = ssb_gpio_irq_extif_mask ,
320
+ .irq_unmask = ssb_gpio_irq_extif_unmask ,
321
+ };
322
+
323
+ static irqreturn_t ssb_gpio_irq_extif_handler (int irq , void * dev_id )
324
+ {
325
+ struct ssb_bus * bus = dev_id ;
326
+ struct ssb_extif * extif = & bus -> extif ;
327
+ u32 val = ssb_read32 (extif -> dev , SSB_EXTIF_GPIO_IN );
328
+ u32 mask = ssb_read32 (extif -> dev , SSB_EXTIF_GPIO_INTMASK );
329
+ u32 pol = ssb_read32 (extif -> dev , SSB_EXTIF_GPIO_INTPOL );
330
+ unsigned long irqs = (val ^ pol ) & mask ;
331
+ int gpio ;
332
+
333
+ if (!irqs )
334
+ return IRQ_NONE ;
335
+
336
+ for_each_set_bit (gpio , & irqs , bus -> gpio .ngpio )
337
+ generic_handle_irq (ssb_gpio_to_irq (& bus -> gpio , gpio ));
338
+ ssb_extif_gpio_polarity (extif , irqs , val & irqs );
339
+
340
+ return IRQ_HANDLED ;
341
+ }
342
+
343
+ static int ssb_gpio_irq_extif_domain_init (struct ssb_bus * bus )
344
+ {
345
+ struct ssb_extif * extif = & bus -> extif ;
346
+ struct gpio_chip * chip = & bus -> gpio ;
347
+ int gpio , hwirq , err ;
348
+
349
+ if (bus -> bustype != SSB_BUSTYPE_SSB )
350
+ return 0 ;
351
+
352
+ bus -> irq_domain = irq_domain_add_linear (NULL , chip -> ngpio ,
353
+ & irq_domain_simple_ops , extif );
354
+ if (!bus -> irq_domain ) {
355
+ err = - ENODEV ;
356
+ goto err_irq_domain ;
357
+ }
358
+ for (gpio = 0 ; gpio < chip -> ngpio ; gpio ++ ) {
359
+ int irq = irq_create_mapping (bus -> irq_domain , gpio );
360
+
361
+ irq_set_chip_data (irq , bus );
362
+ irq_set_chip_and_handler (irq , & ssb_gpio_irq_extif_chip ,
363
+ handle_simple_irq );
364
+ }
365
+
366
+ hwirq = ssb_mips_irq (bus -> extif .dev ) + 2 ;
367
+ err = request_irq (hwirq , ssb_gpio_irq_extif_handler , IRQF_SHARED ,
368
+ "gpio" , bus );
369
+ if (err )
370
+ goto err_req_irq ;
371
+
372
+ ssb_extif_gpio_intmask (& bus -> extif , ~0 , 0 );
373
+
374
+ return 0 ;
375
+
376
+ err_req_irq :
377
+ for (gpio = 0 ; gpio < chip -> ngpio ; gpio ++ ) {
378
+ int irq = irq_find_mapping (bus -> irq_domain , gpio );
379
+
380
+ irq_dispose_mapping (irq );
381
+ }
382
+ irq_domain_remove (bus -> irq_domain );
383
+ err_irq_domain :
384
+ return err ;
385
+ }
386
+
387
+ static void ssb_gpio_irq_extif_domain_exit (struct ssb_bus * bus )
388
+ {
389
+ struct ssb_extif * extif = & bus -> extif ;
390
+ struct gpio_chip * chip = & bus -> gpio ;
391
+ int gpio ;
392
+
393
+ if (bus -> bustype != SSB_BUSTYPE_SSB )
394
+ return ;
395
+
396
+ free_irq (ssb_mips_irq (bus -> extif .dev ) + 2 , extif );
397
+ for (gpio = 0 ; gpio < chip -> ngpio ; gpio ++ ) {
398
+ int irq = irq_find_mapping (bus -> irq_domain , gpio );
399
+
400
+ irq_dispose_mapping (irq );
401
+ }
402
+ irq_domain_remove (bus -> irq_domain );
156
403
}
404
+ #else
405
+ static int ssb_gpio_irq_extif_domain_init (struct ssb_bus * bus )
406
+ {
407
+ return 0 ;
408
+ }
409
+
410
+ static void ssb_gpio_irq_extif_domain_exit (struct ssb_bus * bus )
411
+ {
412
+ }
413
+ #endif
157
414
158
415
static int ssb_gpio_extif_init (struct ssb_bus * bus )
159
416
{
160
417
struct gpio_chip * chip = & bus -> gpio ;
418
+ int err ;
161
419
162
420
chip -> label = "ssb_extif_gpio" ;
163
421
chip -> owner = THIS_MODULE ;
164
422
chip -> get = ssb_gpio_extif_get_value ;
165
423
chip -> set = ssb_gpio_extif_set_value ;
166
424
chip -> direction_input = ssb_gpio_extif_direction_input ;
167
425
chip -> direction_output = ssb_gpio_extif_direction_output ;
168
- chip -> to_irq = ssb_gpio_extif_to_irq ;
426
+ #if IS_ENABLED (CONFIG_SSB_EMBEDDED )
427
+ chip -> to_irq = ssb_gpio_to_irq ;
428
+ #endif
169
429
chip -> ngpio = 5 ;
170
430
/* There is just one SoC in one device and its GPIO addresses should be
171
431
* deterministic to address them more easily. The other buses could get
@@ -175,7 +435,17 @@ static int ssb_gpio_extif_init(struct ssb_bus *bus)
175
435
else
176
436
chip -> base = -1 ;
177
437
178
- return gpiochip_add (chip );
438
+ err = ssb_gpio_irq_extif_domain_init (bus );
439
+ if (err )
440
+ return err ;
441
+
442
+ err = gpiochip_add (chip );
443
+ if (err ) {
444
+ ssb_gpio_irq_extif_domain_exit (bus );
445
+ return err ;
446
+ }
447
+
448
+ return 0 ;
179
449
}
180
450
181
451
#else
@@ -185,6 +455,10 @@ static int ssb_gpio_extif_init(struct ssb_bus *bus)
185
455
}
186
456
#endif
187
457
458
+ /**************************************************
459
+ * Init
460
+ **************************************************/
461
+
188
462
int ssb_gpio_init (struct ssb_bus * bus )
189
463
{
190
464
if (ssb_chipco_available (& bus -> chipco ))
0 commit comments