18
18
#include <linux/pm_runtime.h>
19
19
#include <linux/reset.h>
20
20
#include <linux/spinlock.h>
21
+ #include <linux/syscore_ops.h>
21
22
22
23
#define IRQC_IRQ_START 1
23
24
#define IRQC_IRQ_COUNT 8
28
29
#define ISCR 0x10
29
30
#define IITSR 0x14
30
31
#define TSCR 0x20
31
- #define TITSR0 0x24
32
- #define TITSR1 0x28
32
+ #define TITSR (n ) (0x24 + (n) * 4)
33
33
#define TITSR0_MAX_INT 16
34
34
#define TITSEL_WIDTH 0x2
35
35
#define TSSR (n ) (0x30 + ((n) * 4))
53
53
#define IITSR_IITSEL_EDGE_BOTH 3
54
54
#define IITSR_IITSEL_MASK (n ) IITSR_IITSEL((n), 3)
55
55
56
- #define TINT_EXTRACT_HWIRQ (x ) FIELD_GET(GENMASK(15, 0), (x))
57
- #define TINT_EXTRACT_GPIOINT (x ) FIELD_GET(GENMASK(31, 16), (x))
56
+ #define TINT_EXTRACT_HWIRQ (x ) FIELD_GET(GENMASK(15, 0), (x))
57
+ #define TINT_EXTRACT_GPIOINT (x ) FIELD_GET(GENMASK(31, 16), (x))
58
58
59
- struct rzg2l_irqc_priv {
60
- void __iomem * base ;
61
- struct irq_fwspec fwspec [IRQC_NUM_IRQ ];
62
- raw_spinlock_t lock ;
59
+ /**
60
+ * struct rzg2l_irqc_reg_cache - registers cache (necessary for suspend/resume)
61
+ * @iitsr: IITSR register
62
+ * @titsr: TITSR registers
63
+ */
64
+ struct rzg2l_irqc_reg_cache {
65
+ u32 iitsr ;
66
+ u32 titsr [2 ];
63
67
};
64
68
69
+ /**
70
+ * struct rzg2l_irqc_priv - IRQ controller private data structure
71
+ * @base: Controller's base address
72
+ * @fwspec: IRQ firmware specific data
73
+ * @lock: Lock to serialize access to hardware registers
74
+ * @cache: Registers cache for suspend/resume
75
+ */
76
+ static struct rzg2l_irqc_priv {
77
+ void __iomem * base ;
78
+ struct irq_fwspec fwspec [IRQC_NUM_IRQ ];
79
+ raw_spinlock_t lock ;
80
+ struct rzg2l_irqc_reg_cache cache ;
81
+ } * rzg2l_irqc_data ;
82
+
65
83
static struct rzg2l_irqc_priv * irq_data_to_priv (struct irq_data * data )
66
84
{
67
85
return data -> domain -> host_data ;
@@ -72,11 +90,17 @@ static void rzg2l_irq_eoi(struct irq_data *d)
72
90
unsigned int hw_irq = irqd_to_hwirq (d ) - IRQC_IRQ_START ;
73
91
struct rzg2l_irqc_priv * priv = irq_data_to_priv (d );
74
92
u32 bit = BIT (hw_irq );
75
- u32 reg ;
93
+ u32 iitsr , iscr ;
76
94
77
- reg = readl_relaxed (priv -> base + ISCR );
78
- if (reg & bit )
79
- writel_relaxed (reg & ~bit , priv -> base + ISCR );
95
+ iscr = readl_relaxed (priv -> base + ISCR );
96
+ iitsr = readl_relaxed (priv -> base + IITSR );
97
+
98
+ /*
99
+ * ISCR can only be cleared if the type is falling-edge, rising-edge or
100
+ * falling/rising-edge.
101
+ */
102
+ if ((iscr & bit ) && (iitsr & IITSR_IITSEL_MASK (hw_irq )))
103
+ writel_relaxed (iscr & ~bit , priv -> base + ISCR );
80
104
}
81
105
82
106
static void rzg2l_tint_eoi (struct irq_data * d )
@@ -188,8 +212,7 @@ static int rzg2l_tint_set_edge(struct irq_data *d, unsigned int type)
188
212
struct rzg2l_irqc_priv * priv = irq_data_to_priv (d );
189
213
unsigned int hwirq = irqd_to_hwirq (d );
190
214
u32 titseln = hwirq - IRQC_TINT_START ;
191
- u32 offset ;
192
- u8 sense ;
215
+ u8 index , sense ;
193
216
u32 reg ;
194
217
195
218
switch (type & IRQ_TYPE_SENSE_MASK ) {
@@ -205,17 +228,17 @@ static int rzg2l_tint_set_edge(struct irq_data *d, unsigned int type)
205
228
return - EINVAL ;
206
229
}
207
230
208
- offset = TITSR0 ;
231
+ index = 0 ;
209
232
if (titseln >= TITSR0_MAX_INT ) {
210
233
titseln -= TITSR0_MAX_INT ;
211
- offset = TITSR1 ;
234
+ index = 1 ;
212
235
}
213
236
214
237
raw_spin_lock (& priv -> lock );
215
- reg = readl_relaxed (priv -> base + offset );
238
+ reg = readl_relaxed (priv -> base + TITSR ( index ) );
216
239
reg &= ~(IRQ_MASK << (titseln * TITSEL_WIDTH ));
217
240
reg |= sense << (titseln * TITSEL_WIDTH );
218
- writel_relaxed (reg , priv -> base + offset );
241
+ writel_relaxed (reg , priv -> base + TITSR ( index ) );
219
242
raw_spin_unlock (& priv -> lock );
220
243
221
244
return 0 ;
@@ -236,6 +259,38 @@ static int rzg2l_irqc_set_type(struct irq_data *d, unsigned int type)
236
259
return irq_chip_set_type_parent (d , IRQ_TYPE_LEVEL_HIGH );
237
260
}
238
261
262
+ static int rzg2l_irqc_irq_suspend (void )
263
+ {
264
+ struct rzg2l_irqc_reg_cache * cache = & rzg2l_irqc_data -> cache ;
265
+ void __iomem * base = rzg2l_irqc_data -> base ;
266
+
267
+ cache -> iitsr = readl_relaxed (base + IITSR );
268
+ for (u8 i = 0 ; i < 2 ; i ++ )
269
+ cache -> titsr [i ] = readl_relaxed (base + TITSR (i ));
270
+
271
+ return 0 ;
272
+ }
273
+
274
+ static void rzg2l_irqc_irq_resume (void )
275
+ {
276
+ struct rzg2l_irqc_reg_cache * cache = & rzg2l_irqc_data -> cache ;
277
+ void __iomem * base = rzg2l_irqc_data -> base ;
278
+
279
+ /*
280
+ * Restore only interrupt type. TSSRx will be restored at the
281
+ * request of pin controller to avoid spurious interrupts due
282
+ * to invalid PIN states.
283
+ */
284
+ for (u8 i = 0 ; i < 2 ; i ++ )
285
+ writel_relaxed (cache -> titsr [i ], base + TITSR (i ));
286
+ writel_relaxed (cache -> iitsr , base + IITSR );
287
+ }
288
+
289
+ static struct syscore_ops rzg2l_irqc_syscore_ops = {
290
+ .suspend = rzg2l_irqc_irq_suspend ,
291
+ .resume = rzg2l_irqc_irq_resume ,
292
+ };
293
+
239
294
static const struct irq_chip irqc_chip = {
240
295
.name = "rzg2l-irqc" ,
241
296
.irq_eoi = rzg2l_irqc_eoi ,
@@ -321,7 +376,6 @@ static int rzg2l_irqc_init(struct device_node *node, struct device_node *parent)
321
376
struct irq_domain * irq_domain , * parent_domain ;
322
377
struct platform_device * pdev ;
323
378
struct reset_control * resetn ;
324
- struct rzg2l_irqc_priv * priv ;
325
379
int ret ;
326
380
327
381
pdev = of_find_device_by_node (node );
@@ -334,15 +388,15 @@ static int rzg2l_irqc_init(struct device_node *node, struct device_node *parent)
334
388
return - ENODEV ;
335
389
}
336
390
337
- priv = devm_kzalloc (& pdev -> dev , sizeof (* priv ), GFP_KERNEL );
338
- if (!priv )
391
+ rzg2l_irqc_data = devm_kzalloc (& pdev -> dev , sizeof (* rzg2l_irqc_data ), GFP_KERNEL );
392
+ if (!rzg2l_irqc_data )
339
393
return - ENOMEM ;
340
394
341
- priv -> base = devm_of_iomap (& pdev -> dev , pdev -> dev .of_node , 0 , NULL );
342
- if (IS_ERR (priv -> base ))
343
- return PTR_ERR (priv -> base );
395
+ rzg2l_irqc_data -> base = devm_of_iomap (& pdev -> dev , pdev -> dev .of_node , 0 , NULL );
396
+ if (IS_ERR (rzg2l_irqc_data -> base ))
397
+ return PTR_ERR (rzg2l_irqc_data -> base );
344
398
345
- ret = rzg2l_irqc_parse_interrupts (priv , node );
399
+ ret = rzg2l_irqc_parse_interrupts (rzg2l_irqc_data , node );
346
400
if (ret ) {
347
401
dev_err (& pdev -> dev , "cannot parse interrupts: %d\n" , ret );
348
402
return ret ;
@@ -365,17 +419,19 @@ static int rzg2l_irqc_init(struct device_node *node, struct device_node *parent)
365
419
goto pm_disable ;
366
420
}
367
421
368
- raw_spin_lock_init (& priv -> lock );
422
+ raw_spin_lock_init (& rzg2l_irqc_data -> lock );
369
423
370
424
irq_domain = irq_domain_add_hierarchy (parent_domain , 0 , IRQC_NUM_IRQ ,
371
425
node , & rzg2l_irqc_domain_ops ,
372
- priv );
426
+ rzg2l_irqc_data );
373
427
if (!irq_domain ) {
374
428
dev_err (& pdev -> dev , "failed to add irq domain\n" );
375
429
ret = - ENOMEM ;
376
430
goto pm_put ;
377
431
}
378
432
433
+ register_syscore_ops (& rzg2l_irqc_syscore_ops );
434
+
379
435
return 0 ;
380
436
381
437
pm_put :
0 commit comments