Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/kernel/irq/generic-chip.c
10818 views
1
/*
2
* Library implementing the most common irq chip callback functions
3
*
4
* Copyright (C) 2011, Thomas Gleixner
5
*/
6
#include <linux/io.h>
7
#include <linux/irq.h>
8
#include <linux/slab.h>
9
#include <linux/interrupt.h>
10
#include <linux/kernel_stat.h>
11
#include <linux/syscore_ops.h>
12
13
#include "internals.h"
14
15
static LIST_HEAD(gc_list);
16
static DEFINE_RAW_SPINLOCK(gc_lock);
17
18
static inline struct irq_chip_regs *cur_regs(struct irq_data *d)
19
{
20
return &container_of(d->chip, struct irq_chip_type, chip)->regs;
21
}
22
23
/**
24
* irq_gc_noop - NOOP function
25
* @d: irq_data
26
*/
27
void irq_gc_noop(struct irq_data *d)
28
{
29
}
30
31
/**
32
* irq_gc_mask_disable_reg - Mask chip via disable register
33
* @d: irq_data
34
*
35
* Chip has separate enable/disable registers instead of a single mask
36
* register.
37
*/
38
void irq_gc_mask_disable_reg(struct irq_data *d)
39
{
40
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
41
u32 mask = 1 << (d->irq - gc->irq_base);
42
43
irq_gc_lock(gc);
44
irq_reg_writel(mask, gc->reg_base + cur_regs(d)->disable);
45
gc->mask_cache &= ~mask;
46
irq_gc_unlock(gc);
47
}
48
49
/**
50
* irq_gc_mask_set_mask_bit - Mask chip via setting bit in mask register
51
* @d: irq_data
52
*
53
* Chip has a single mask register. Values of this register are cached
54
* and protected by gc->lock
55
*/
56
void irq_gc_mask_set_bit(struct irq_data *d)
57
{
58
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
59
u32 mask = 1 << (d->irq - gc->irq_base);
60
61
irq_gc_lock(gc);
62
gc->mask_cache |= mask;
63
irq_reg_writel(gc->mask_cache, gc->reg_base + cur_regs(d)->mask);
64
irq_gc_unlock(gc);
65
}
66
67
/**
68
* irq_gc_mask_set_mask_bit - Mask chip via clearing bit in mask register
69
* @d: irq_data
70
*
71
* Chip has a single mask register. Values of this register are cached
72
* and protected by gc->lock
73
*/
74
void irq_gc_mask_clr_bit(struct irq_data *d)
75
{
76
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
77
u32 mask = 1 << (d->irq - gc->irq_base);
78
79
irq_gc_lock(gc);
80
gc->mask_cache &= ~mask;
81
irq_reg_writel(gc->mask_cache, gc->reg_base + cur_regs(d)->mask);
82
irq_gc_unlock(gc);
83
}
84
85
/**
86
* irq_gc_unmask_enable_reg - Unmask chip via enable register
87
* @d: irq_data
88
*
89
* Chip has separate enable/disable registers instead of a single mask
90
* register.
91
*/
92
void irq_gc_unmask_enable_reg(struct irq_data *d)
93
{
94
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
95
u32 mask = 1 << (d->irq - gc->irq_base);
96
97
irq_gc_lock(gc);
98
irq_reg_writel(mask, gc->reg_base + cur_regs(d)->enable);
99
gc->mask_cache |= mask;
100
irq_gc_unlock(gc);
101
}
102
103
/**
104
* irq_gc_ack_set_bit - Ack pending interrupt via setting bit
105
* @d: irq_data
106
*/
107
void irq_gc_ack_set_bit(struct irq_data *d)
108
{
109
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
110
u32 mask = 1 << (d->irq - gc->irq_base);
111
112
irq_gc_lock(gc);
113
irq_reg_writel(mask, gc->reg_base + cur_regs(d)->ack);
114
irq_gc_unlock(gc);
115
}
116
117
/**
118
* irq_gc_ack_clr_bit - Ack pending interrupt via clearing bit
119
* @d: irq_data
120
*/
121
void irq_gc_ack_clr_bit(struct irq_data *d)
122
{
123
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
124
u32 mask = ~(1 << (d->irq - gc->irq_base));
125
126
irq_gc_lock(gc);
127
irq_reg_writel(mask, gc->reg_base + cur_regs(d)->ack);
128
irq_gc_unlock(gc);
129
}
130
131
/**
132
* irq_gc_mask_disable_reg_and_ack- Mask and ack pending interrupt
133
* @d: irq_data
134
*/
135
void irq_gc_mask_disable_reg_and_ack(struct irq_data *d)
136
{
137
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
138
u32 mask = 1 << (d->irq - gc->irq_base);
139
140
irq_gc_lock(gc);
141
irq_reg_writel(mask, gc->reg_base + cur_regs(d)->mask);
142
irq_reg_writel(mask, gc->reg_base + cur_regs(d)->ack);
143
irq_gc_unlock(gc);
144
}
145
146
/**
147
* irq_gc_eoi - EOI interrupt
148
* @d: irq_data
149
*/
150
void irq_gc_eoi(struct irq_data *d)
151
{
152
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
153
u32 mask = 1 << (d->irq - gc->irq_base);
154
155
irq_gc_lock(gc);
156
irq_reg_writel(mask, gc->reg_base + cur_regs(d)->eoi);
157
irq_gc_unlock(gc);
158
}
159
160
/**
161
* irq_gc_set_wake - Set/clr wake bit for an interrupt
162
* @d: irq_data
163
*
164
* For chips where the wake from suspend functionality is not
165
* configured in a separate register and the wakeup active state is
166
* just stored in a bitmask.
167
*/
168
int irq_gc_set_wake(struct irq_data *d, unsigned int on)
169
{
170
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
171
u32 mask = 1 << (d->irq - gc->irq_base);
172
173
if (!(mask & gc->wake_enabled))
174
return -EINVAL;
175
176
irq_gc_lock(gc);
177
if (on)
178
gc->wake_active |= mask;
179
else
180
gc->wake_active &= ~mask;
181
irq_gc_unlock(gc);
182
return 0;
183
}
184
185
/**
186
* irq_alloc_generic_chip - Allocate a generic chip and initialize it
187
* @name: Name of the irq chip
188
* @num_ct: Number of irq_chip_type instances associated with this
189
* @irq_base: Interrupt base nr for this chip
190
* @reg_base: Register base address (virtual)
191
* @handler: Default flow handler associated with this chip
192
*
193
* Returns an initialized irq_chip_generic structure. The chip defaults
194
* to the primary (index 0) irq_chip_type and @handler
195
*/
196
struct irq_chip_generic *
197
irq_alloc_generic_chip(const char *name, int num_ct, unsigned int irq_base,
198
void __iomem *reg_base, irq_flow_handler_t handler)
199
{
200
struct irq_chip_generic *gc;
201
unsigned long sz = sizeof(*gc) + num_ct * sizeof(struct irq_chip_type);
202
203
gc = kzalloc(sz, GFP_KERNEL);
204
if (gc) {
205
raw_spin_lock_init(&gc->lock);
206
gc->num_ct = num_ct;
207
gc->irq_base = irq_base;
208
gc->reg_base = reg_base;
209
gc->chip_types->chip.name = name;
210
gc->chip_types->handler = handler;
211
}
212
return gc;
213
}
214
215
/*
216
* Separate lockdep class for interrupt chip which can nest irq_desc
217
* lock.
218
*/
219
static struct lock_class_key irq_nested_lock_class;
220
221
/**
222
* irq_setup_generic_chip - Setup a range of interrupts with a generic chip
223
* @gc: Generic irq chip holding all data
224
* @msk: Bitmask holding the irqs to initialize relative to gc->irq_base
225
* @flags: Flags for initialization
226
* @clr: IRQ_* bits to clear
227
* @set: IRQ_* bits to set
228
*
229
* Set up max. 32 interrupts starting from gc->irq_base. Note, this
230
* initializes all interrupts to the primary irq_chip_type and its
231
* associated handler.
232
*/
233
void irq_setup_generic_chip(struct irq_chip_generic *gc, u32 msk,
234
enum irq_gc_flags flags, unsigned int clr,
235
unsigned int set)
236
{
237
struct irq_chip_type *ct = gc->chip_types;
238
unsigned int i;
239
240
raw_spin_lock(&gc_lock);
241
list_add_tail(&gc->list, &gc_list);
242
raw_spin_unlock(&gc_lock);
243
244
/* Init mask cache ? */
245
if (flags & IRQ_GC_INIT_MASK_CACHE)
246
gc->mask_cache = irq_reg_readl(gc->reg_base + ct->regs.mask);
247
248
for (i = gc->irq_base; msk; msk >>= 1, i++) {
249
if (!msk & 0x01)
250
continue;
251
252
if (flags & IRQ_GC_INIT_NESTED_LOCK)
253
irq_set_lockdep_class(i, &irq_nested_lock_class);
254
255
irq_set_chip_and_handler(i, &ct->chip, ct->handler);
256
irq_set_chip_data(i, gc);
257
irq_modify_status(i, clr, set);
258
}
259
gc->irq_cnt = i - gc->irq_base;
260
}
261
262
/**
263
* irq_setup_alt_chip - Switch to alternative chip
264
* @d: irq_data for this interrupt
265
* @type Flow type to be initialized
266
*
267
* Only to be called from chip->irq_set_type() callbacks.
268
*/
269
int irq_setup_alt_chip(struct irq_data *d, unsigned int type)
270
{
271
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
272
struct irq_chip_type *ct = gc->chip_types;
273
unsigned int i;
274
275
for (i = 0; i < gc->num_ct; i++, ct++) {
276
if (ct->type & type) {
277
d->chip = &ct->chip;
278
irq_data_to_desc(d)->handle_irq = ct->handler;
279
return 0;
280
}
281
}
282
return -EINVAL;
283
}
284
285
/**
286
* irq_remove_generic_chip - Remove a chip
287
* @gc: Generic irq chip holding all data
288
* @msk: Bitmask holding the irqs to initialize relative to gc->irq_base
289
* @clr: IRQ_* bits to clear
290
* @set: IRQ_* bits to set
291
*
292
* Remove up to 32 interrupts starting from gc->irq_base.
293
*/
294
void irq_remove_generic_chip(struct irq_chip_generic *gc, u32 msk,
295
unsigned int clr, unsigned int set)
296
{
297
unsigned int i = gc->irq_base;
298
299
raw_spin_lock(&gc_lock);
300
list_del(&gc->list);
301
raw_spin_unlock(&gc_lock);
302
303
for (; msk; msk >>= 1, i++) {
304
if (!msk & 0x01)
305
continue;
306
307
/* Remove handler first. That will mask the irq line */
308
irq_set_handler(i, NULL);
309
irq_set_chip(i, &no_irq_chip);
310
irq_set_chip_data(i, NULL);
311
irq_modify_status(i, clr, set);
312
}
313
}
314
315
#ifdef CONFIG_PM
316
static int irq_gc_suspend(void)
317
{
318
struct irq_chip_generic *gc;
319
320
list_for_each_entry(gc, &gc_list, list) {
321
struct irq_chip_type *ct = gc->chip_types;
322
323
if (ct->chip.irq_suspend)
324
ct->chip.irq_suspend(irq_get_irq_data(gc->irq_base));
325
}
326
return 0;
327
}
328
329
static void irq_gc_resume(void)
330
{
331
struct irq_chip_generic *gc;
332
333
list_for_each_entry(gc, &gc_list, list) {
334
struct irq_chip_type *ct = gc->chip_types;
335
336
if (ct->chip.irq_resume)
337
ct->chip.irq_resume(irq_get_irq_data(gc->irq_base));
338
}
339
}
340
#else
341
#define irq_gc_suspend NULL
342
#define irq_gc_resume NULL
343
#endif
344
345
static void irq_gc_shutdown(void)
346
{
347
struct irq_chip_generic *gc;
348
349
list_for_each_entry(gc, &gc_list, list) {
350
struct irq_chip_type *ct = gc->chip_types;
351
352
if (ct->chip.irq_pm_shutdown)
353
ct->chip.irq_pm_shutdown(irq_get_irq_data(gc->irq_base));
354
}
355
}
356
357
static struct syscore_ops irq_gc_syscore_ops = {
358
.suspend = irq_gc_suspend,
359
.resume = irq_gc_resume,
360
.shutdown = irq_gc_shutdown,
361
};
362
363
static int __init irq_gc_init_ops(void)
364
{
365
register_syscore_ops(&irq_gc_syscore_ops);
366
return 0;
367
}
368
device_initcall(irq_gc_init_ops);
369
370