Root/
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 |
Branches:
ben-wpan
ben-wpan-stefan
javiroman/ks7010
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9