diff options
Diffstat (limited to 'kernel/irq/internals.h')
-rw-r--r-- | kernel/irq/internals.h | 130 |
1 files changed, 122 insertions, 8 deletions
diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h index c63f3bc88f0b..8eb01e379ccc 100644 --- a/kernel/irq/internals.h +++ b/kernel/irq/internals.h | |||
@@ -1,9 +1,12 @@ | |||
1 | /* | 1 | /* |
2 | * IRQ subsystem internal functions and variables: | 2 | * IRQ subsystem internal functions and variables: |
3 | */ | 3 | */ |
4 | #include <linux/irqdesc.h> | ||
4 | 5 | ||
5 | extern int noirqdebug; | 6 | extern int noirqdebug; |
6 | 7 | ||
8 | #define irq_data_to_desc(data) container_of(data, struct irq_desc, irq_data) | ||
9 | |||
7 | /* Set default functions for irq_chip structures: */ | 10 | /* Set default functions for irq_chip structures: */ |
8 | extern void irq_chip_set_defaults(struct irq_chip *chip); | 11 | extern void irq_chip_set_defaults(struct irq_chip *chip); |
9 | 12 | ||
@@ -20,16 +23,21 @@ extern void init_kstat_irqs(struct irq_desc *desc, int node, int nr); | |||
20 | extern void clear_kstat_irqs(struct irq_desc *desc); | 23 | extern void clear_kstat_irqs(struct irq_desc *desc); |
21 | extern raw_spinlock_t sparse_irq_lock; | 24 | extern raw_spinlock_t sparse_irq_lock; |
22 | 25 | ||
26 | /* Resending of interrupts :*/ | ||
27 | void check_irq_resend(struct irq_desc *desc, unsigned int irq); | ||
28 | |||
23 | #ifdef CONFIG_SPARSE_IRQ | 29 | #ifdef CONFIG_SPARSE_IRQ |
24 | void replace_irq_desc(unsigned int irq, struct irq_desc *desc); | 30 | void replace_irq_desc(unsigned int irq, struct irq_desc *desc); |
25 | #endif | 31 | #endif |
26 | 32 | ||
27 | #ifdef CONFIG_PROC_FS | 33 | #ifdef CONFIG_PROC_FS |
28 | extern void register_irq_proc(unsigned int irq, struct irq_desc *desc); | 34 | extern void register_irq_proc(unsigned int irq, struct irq_desc *desc); |
35 | extern void unregister_irq_proc(unsigned int irq, struct irq_desc *desc); | ||
29 | extern void register_handler_proc(unsigned int irq, struct irqaction *action); | 36 | extern void register_handler_proc(unsigned int irq, struct irqaction *action); |
30 | extern void unregister_handler_proc(unsigned int irq, struct irqaction *action); | 37 | extern void unregister_handler_proc(unsigned int irq, struct irqaction *action); |
31 | #else | 38 | #else |
32 | static inline void register_irq_proc(unsigned int irq, struct irq_desc *desc) { } | 39 | static inline void register_irq_proc(unsigned int irq, struct irq_desc *desc) { } |
40 | static inline void unregister_irq_proc(unsigned int irq, struct irq_desc *desc) { } | ||
33 | static inline void register_handler_proc(unsigned int irq, | 41 | static inline void register_handler_proc(unsigned int irq, |
34 | struct irqaction *action) { } | 42 | struct irqaction *action) { } |
35 | static inline void unregister_handler_proc(unsigned int irq, | 43 | static inline void unregister_handler_proc(unsigned int irq, |
@@ -40,17 +48,27 @@ extern int irq_select_affinity_usr(unsigned int irq); | |||
40 | 48 | ||
41 | extern void irq_set_thread_affinity(struct irq_desc *desc); | 49 | extern void irq_set_thread_affinity(struct irq_desc *desc); |
42 | 50 | ||
51 | #ifndef CONFIG_GENERIC_HARDIRQS_NO_DEPRECATED | ||
52 | static inline void irq_end(unsigned int irq, struct irq_desc *desc) | ||
53 | { | ||
54 | if (desc->irq_data.chip && desc->irq_data.chip->end) | ||
55 | desc->irq_data.chip->end(irq); | ||
56 | } | ||
57 | #else | ||
58 | static inline void irq_end(unsigned int irq, struct irq_desc *desc) { } | ||
59 | #endif | ||
60 | |||
43 | /* Inline functions for support of irq chips on slow busses */ | 61 | /* Inline functions for support of irq chips on slow busses */ |
44 | static inline void chip_bus_lock(unsigned int irq, struct irq_desc *desc) | 62 | static inline void chip_bus_lock(struct irq_desc *desc) |
45 | { | 63 | { |
46 | if (unlikely(desc->chip->bus_lock)) | 64 | if (unlikely(desc->irq_data.chip->irq_bus_lock)) |
47 | desc->chip->bus_lock(irq); | 65 | desc->irq_data.chip->irq_bus_lock(&desc->irq_data); |
48 | } | 66 | } |
49 | 67 | ||
50 | static inline void chip_bus_sync_unlock(unsigned int irq, struct irq_desc *desc) | 68 | static inline void chip_bus_sync_unlock(struct irq_desc *desc) |
51 | { | 69 | { |
52 | if (unlikely(desc->chip->bus_sync_unlock)) | 70 | if (unlikely(desc->irq_data.chip->irq_bus_sync_unlock)) |
53 | desc->chip->bus_sync_unlock(irq); | 71 | desc->irq_data.chip->irq_bus_sync_unlock(&desc->irq_data); |
54 | } | 72 | } |
55 | 73 | ||
56 | /* | 74 | /* |
@@ -67,8 +85,8 @@ static inline void print_irq_desc(unsigned int irq, struct irq_desc *desc) | |||
67 | irq, desc, desc->depth, desc->irq_count, desc->irqs_unhandled); | 85 | irq, desc, desc->depth, desc->irq_count, desc->irqs_unhandled); |
68 | printk("->handle_irq(): %p, ", desc->handle_irq); | 86 | printk("->handle_irq(): %p, ", desc->handle_irq); |
69 | print_symbol("%s\n", (unsigned long)desc->handle_irq); | 87 | print_symbol("%s\n", (unsigned long)desc->handle_irq); |
70 | printk("->chip(): %p, ", desc->chip); | 88 | printk("->irq_data.chip(): %p, ", desc->irq_data.chip); |
71 | print_symbol("%s\n", (unsigned long)desc->chip); | 89 | print_symbol("%s\n", (unsigned long)desc->irq_data.chip); |
72 | printk("->action(): %p\n", desc->action); | 90 | printk("->action(): %p\n", desc->action); |
73 | if (desc->action) { | 91 | if (desc->action) { |
74 | printk("->action->handler(): %p, ", desc->action->handler); | 92 | printk("->action->handler(): %p, ", desc->action->handler); |
@@ -93,3 +111,99 @@ static inline void print_irq_desc(unsigned int irq, struct irq_desc *desc) | |||
93 | 111 | ||
94 | #undef P | 112 | #undef P |
95 | 113 | ||
114 | /* Stuff below will be cleaned up after the sparse allocator is done */ | ||
115 | |||
116 | #ifdef CONFIG_SMP | ||
117 | /** | ||
118 | * alloc_desc_masks - allocate cpumasks for irq_desc | ||
119 | * @desc: pointer to irq_desc struct | ||
120 | * @node: node which will be handling the cpumasks | ||
121 | * @boot: true if need bootmem | ||
122 | * | ||
123 | * Allocates affinity and pending_mask cpumask if required. | ||
124 | * Returns true if successful (or not required). | ||
125 | */ | ||
126 | static inline bool alloc_desc_masks(struct irq_desc *desc, int node, | ||
127 | bool boot) | ||
128 | { | ||
129 | gfp_t gfp = GFP_ATOMIC; | ||
130 | |||
131 | if (boot) | ||
132 | gfp = GFP_NOWAIT; | ||
133 | |||
134 | #ifdef CONFIG_CPUMASK_OFFSTACK | ||
135 | if (!alloc_cpumask_var_node(&desc->irq_data.affinity, gfp, node)) | ||
136 | return false; | ||
137 | |||
138 | #ifdef CONFIG_GENERIC_PENDING_IRQ | ||
139 | if (!alloc_cpumask_var_node(&desc->pending_mask, gfp, node)) { | ||
140 | free_cpumask_var(desc->irq_data.affinity); | ||
141 | return false; | ||
142 | } | ||
143 | #endif | ||
144 | #endif | ||
145 | return true; | ||
146 | } | ||
147 | |||
148 | static inline void init_desc_masks(struct irq_desc *desc) | ||
149 | { | ||
150 | cpumask_setall(desc->irq_data.affinity); | ||
151 | #ifdef CONFIG_GENERIC_PENDING_IRQ | ||
152 | cpumask_clear(desc->pending_mask); | ||
153 | #endif | ||
154 | } | ||
155 | |||
156 | /** | ||
157 | * init_copy_desc_masks - copy cpumasks for irq_desc | ||
158 | * @old_desc: pointer to old irq_desc struct | ||
159 | * @new_desc: pointer to new irq_desc struct | ||
160 | * | ||
161 | * Insures affinity and pending_masks are copied to new irq_desc. | ||
162 | * If !CONFIG_CPUMASKS_OFFSTACK the cpumasks are embedded in the | ||
163 | * irq_desc struct so the copy is redundant. | ||
164 | */ | ||
165 | |||
166 | static inline void init_copy_desc_masks(struct irq_desc *old_desc, | ||
167 | struct irq_desc *new_desc) | ||
168 | { | ||
169 | #ifdef CONFIG_CPUMASK_OFFSTACK | ||
170 | cpumask_copy(new_desc->irq_data.affinity, old_desc->irq_data.affinity); | ||
171 | |||
172 | #ifdef CONFIG_GENERIC_PENDING_IRQ | ||
173 | cpumask_copy(new_desc->pending_mask, old_desc->pending_mask); | ||
174 | #endif | ||
175 | #endif | ||
176 | } | ||
177 | |||
178 | static inline void free_desc_masks(struct irq_desc *old_desc, | ||
179 | struct irq_desc *new_desc) | ||
180 | { | ||
181 | free_cpumask_var(old_desc->irq_data.affinity); | ||
182 | |||
183 | #ifdef CONFIG_GENERIC_PENDING_IRQ | ||
184 | free_cpumask_var(old_desc->pending_mask); | ||
185 | #endif | ||
186 | } | ||
187 | |||
188 | #else /* !CONFIG_SMP */ | ||
189 | |||
190 | static inline bool alloc_desc_masks(struct irq_desc *desc, int node, | ||
191 | bool boot) | ||
192 | { | ||
193 | return true; | ||
194 | } | ||
195 | |||
196 | static inline void init_desc_masks(struct irq_desc *desc) | ||
197 | { | ||
198 | } | ||
199 | |||
200 | static inline void init_copy_desc_masks(struct irq_desc *old_desc, | ||
201 | struct irq_desc *new_desc) | ||
202 | { | ||
203 | } | ||
204 | |||
205 | static inline void free_desc_masks(struct irq_desc *old_desc, | ||
206 | struct irq_desc *new_desc) | ||
207 | { | ||
208 | } | ||
209 | #endif /* CONFIG_SMP */ | ||