13
13
#include <linux/of.h>
14
14
#include <linux/of_address.h>
15
15
#include <linux/of_device.h>
16
+ #include <linux/soc/qcom/irq.h>
16
17
#include <linux/spinlock.h>
17
- #include <linux/platform_device.h>
18
18
#include <linux/slab.h>
19
19
#include <linux/types.h>
20
20
21
21
#define PDC_MAX_IRQS 168
22
+ #define PDC_MAX_GPIO_IRQS 256
22
23
23
24
#define CLEAR_INTR (reg , intr ) (reg & ~(1 << intr))
24
25
#define ENABLE_INTR (reg , intr ) (reg | (1 << intr))
25
26
26
27
#define IRQ_ENABLE_BANK 0x10
27
28
#define IRQ_i_CFG 0x110
28
29
30
+ #define PDC_NO_PARENT_IRQ ~0UL
31
+
29
32
struct pdc_pin_region {
30
33
u32 pin_base ;
31
34
u32 parent_base ;
@@ -65,23 +68,35 @@ static void pdc_enable_intr(struct irq_data *d, bool on)
65
68
66
69
static void qcom_pdc_gic_disable (struct irq_data * d )
67
70
{
71
+ if (d -> hwirq == GPIO_NO_WAKE_IRQ )
72
+ return ;
73
+
68
74
pdc_enable_intr (d , false);
69
75
irq_chip_disable_parent (d );
70
76
}
71
77
72
78
static void qcom_pdc_gic_enable (struct irq_data * d )
73
79
{
80
+ if (d -> hwirq == GPIO_NO_WAKE_IRQ )
81
+ return ;
82
+
74
83
pdc_enable_intr (d , true);
75
84
irq_chip_enable_parent (d );
76
85
}
77
86
78
87
static void qcom_pdc_gic_mask (struct irq_data * d )
79
88
{
89
+ if (d -> hwirq == GPIO_NO_WAKE_IRQ )
90
+ return ;
91
+
80
92
irq_chip_mask_parent (d );
81
93
}
82
94
83
95
static void qcom_pdc_gic_unmask (struct irq_data * d )
84
96
{
97
+ if (d -> hwirq == GPIO_NO_WAKE_IRQ )
98
+ return ;
99
+
85
100
irq_chip_unmask_parent (d );
86
101
}
87
102
@@ -124,6 +139,9 @@ static int qcom_pdc_gic_set_type(struct irq_data *d, unsigned int type)
124
139
int pin_out = d -> hwirq ;
125
140
enum pdc_irq_config_bits pdc_type ;
126
141
142
+ if (pin_out == GPIO_NO_WAKE_IRQ )
143
+ return 0 ;
144
+
127
145
switch (type ) {
128
146
case IRQ_TYPE_EDGE_RISING :
129
147
pdc_type = PDC_EDGE_RISING ;
@@ -181,8 +199,7 @@ static irq_hw_number_t get_parent_hwirq(int pin)
181
199
return (region -> parent_base + pin - region -> pin_base );
182
200
}
183
201
184
- WARN_ON (1 );
185
- return ~0UL ;
202
+ return PDC_NO_PARENT_IRQ ;
186
203
}
187
204
188
205
static int qcom_pdc_translate (struct irq_domain * d , struct irq_fwspec * fwspec ,
@@ -211,17 +228,17 @@ static int qcom_pdc_alloc(struct irq_domain *domain, unsigned int virq,
211
228
212
229
ret = qcom_pdc_translate (domain , fwspec , & hwirq , & type );
213
230
if (ret )
214
- return - EINVAL ;
215
-
216
- parent_hwirq = get_parent_hwirq (hwirq );
217
- if (parent_hwirq == ~0UL )
218
- return - EINVAL ;
231
+ return ret ;
219
232
220
233
ret = irq_domain_set_hwirq_and_chip (domain , virq , hwirq ,
221
234
& qcom_pdc_gic_chip , NULL );
222
235
if (ret )
223
236
return ret ;
224
237
238
+ parent_hwirq = get_parent_hwirq (hwirq );
239
+ if (parent_hwirq == PDC_NO_PARENT_IRQ )
240
+ return 0 ;
241
+
225
242
if (type & IRQ_TYPE_EDGE_BOTH )
226
243
type = IRQ_TYPE_EDGE_RISING ;
227
244
@@ -244,6 +261,60 @@ static const struct irq_domain_ops qcom_pdc_ops = {
244
261
.free = irq_domain_free_irqs_common ,
245
262
};
246
263
264
+ static int qcom_pdc_gpio_alloc (struct irq_domain * domain , unsigned int virq ,
265
+ unsigned int nr_irqs , void * data )
266
+ {
267
+ struct irq_fwspec * fwspec = data ;
268
+ struct irq_fwspec parent_fwspec ;
269
+ irq_hw_number_t hwirq , parent_hwirq ;
270
+ unsigned int type ;
271
+ int ret ;
272
+
273
+ ret = qcom_pdc_translate (domain , fwspec , & hwirq , & type );
274
+ if (ret )
275
+ return ret ;
276
+
277
+ ret = irq_domain_set_hwirq_and_chip (domain , virq , hwirq ,
278
+ & qcom_pdc_gic_chip , NULL );
279
+ if (ret )
280
+ return ret ;
281
+
282
+ if (hwirq == GPIO_NO_WAKE_IRQ )
283
+ return 0 ;
284
+
285
+ parent_hwirq = get_parent_hwirq (hwirq );
286
+ if (parent_hwirq == PDC_NO_PARENT_IRQ )
287
+ return 0 ;
288
+
289
+ if (type & IRQ_TYPE_EDGE_BOTH )
290
+ type = IRQ_TYPE_EDGE_RISING ;
291
+
292
+ if (type & IRQ_TYPE_LEVEL_MASK )
293
+ type = IRQ_TYPE_LEVEL_HIGH ;
294
+
295
+ parent_fwspec .fwnode = domain -> parent -> fwnode ;
296
+ parent_fwspec .param_count = 3 ;
297
+ parent_fwspec .param [0 ] = 0 ;
298
+ parent_fwspec .param [1 ] = parent_hwirq ;
299
+ parent_fwspec .param [2 ] = type ;
300
+
301
+ return irq_domain_alloc_irqs_parent (domain , virq , nr_irqs ,
302
+ & parent_fwspec );
303
+ }
304
+
305
+ static int qcom_pdc_gpio_domain_select (struct irq_domain * d ,
306
+ struct irq_fwspec * fwspec ,
307
+ enum irq_domain_bus_token bus_token )
308
+ {
309
+ return bus_token == DOMAIN_BUS_WAKEUP ;
310
+ }
311
+
312
+ static const struct irq_domain_ops qcom_pdc_gpio_ops = {
313
+ .select = qcom_pdc_gpio_domain_select ,
314
+ .alloc = qcom_pdc_gpio_alloc ,
315
+ .free = irq_domain_free_irqs_common ,
316
+ };
317
+
247
318
static int pdc_setup_pin_mapping (struct device_node * np )
248
319
{
249
320
int ret , n ;
@@ -282,7 +353,7 @@ static int pdc_setup_pin_mapping(struct device_node *np)
282
353
283
354
static int qcom_pdc_init (struct device_node * node , struct device_node * parent )
284
355
{
285
- struct irq_domain * parent_domain , * pdc_domain ;
356
+ struct irq_domain * parent_domain , * pdc_domain , * pdc_gpio_domain ;
286
357
int ret ;
287
358
288
359
pdc_base = of_iomap (node , 0 );
@@ -313,8 +384,23 @@ static int qcom_pdc_init(struct device_node *node, struct device_node *parent)
313
384
goto fail ;
314
385
}
315
386
387
+ pdc_gpio_domain = irq_domain_create_hierarchy (parent_domain ,
388
+ IRQ_DOMAIN_FLAG_QCOM_PDC_WAKEUP ,
389
+ PDC_MAX_GPIO_IRQS ,
390
+ of_fwnode_handle (node ),
391
+ & qcom_pdc_gpio_ops , NULL );
392
+ if (!pdc_gpio_domain ) {
393
+ pr_err ("%pOF: PDC domain add failed for GPIO domain\n" , node );
394
+ ret = - ENOMEM ;
395
+ goto remove ;
396
+ }
397
+
398
+ irq_domain_update_bus_token (pdc_gpio_domain , DOMAIN_BUS_WAKEUP );
399
+
316
400
return 0 ;
317
401
402
+ remove :
403
+ irq_domain_remove (pdc_domain );
318
404
fail :
319
405
kfree (pdc_region );
320
406
iounmap (pdc_base );
0 commit comments