diff options
author | Yinghai Lu <yhlu.kernel@gmail.com> | 2008-08-19 23:50:18 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-10-16 10:52:51 -0400 |
commit | 67fb283e148e9bd761f73691d3173b6eab9ba8db (patch) | |
tree | 88ba8337dc5bc90e5f95d84d981f750bb7173dd2 /kernel/irq | |
parent | cb5bc83225a86ca53bbb889ed8439e4fd6cf44ac (diff) |
irq: separate sparse_irqs from sparse_irqs_free
so later don't need compare with -1U
Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/irq')
-rw-r--r-- | kernel/irq/handle.c | 115 |
1 files changed, 61 insertions, 54 deletions
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c index d44e3515eae1..6d174390f3a0 100644 --- a/kernel/irq/handle.c +++ b/kernel/irq/handle.c | |||
@@ -112,6 +112,11 @@ static void init_kstat_irqs(struct irq_desc *desc, int nr_desc, int nr) | |||
112 | } | 112 | } |
113 | } | 113 | } |
114 | 114 | ||
115 | #ifdef CONFIG_HAVE_SPARSE_IRQ | ||
116 | static struct irq_desc *sparse_irqs_free; | ||
117 | struct irq_desc *sparse_irqs; | ||
118 | #endif | ||
119 | |||
115 | static void __init init_work(void *data) | 120 | static void __init init_work(void *data) |
116 | { | 121 | { |
117 | struct dyn_array *da = data; | 122 | struct dyn_array *da = data; |
@@ -127,13 +132,16 @@ static void __init init_work(void *data) | |||
127 | #endif | 132 | #endif |
128 | } | 133 | } |
129 | 134 | ||
135 | /* init kstat_irqs, nr_cpu_ids is ready already */ | ||
136 | init_kstat_irqs(desc, *da->nr, nr_cpu_ids); | ||
137 | |||
130 | #ifdef CONFIG_HAVE_SPARSE_IRQ | 138 | #ifdef CONFIG_HAVE_SPARSE_IRQ |
131 | for (i = 1; i < *da->nr; i++) | 139 | for (i = 1; i < *da->nr; i++) |
132 | desc[i-1].next = &desc[i]; | 140 | desc[i-1].next = &desc[i]; |
133 | #endif | ||
134 | 141 | ||
135 | /* init kstat_irqs, nr_cpu_ids is ready already */ | 142 | sparse_irqs_free = sparse_irqs; |
136 | init_kstat_irqs(desc, *da->nr, nr_cpu_ids); | 143 | sparse_irqs = NULL; |
144 | #endif | ||
137 | } | 145 | } |
138 | 146 | ||
139 | #ifdef CONFIG_HAVE_SPARSE_IRQ | 147 | #ifdef CONFIG_HAVE_SPARSE_IRQ |
@@ -148,23 +156,17 @@ static int __init parse_nr_irq_desc(char *arg) | |||
148 | 156 | ||
149 | early_param("nr_irq_desc", parse_nr_irq_desc); | 157 | early_param("nr_irq_desc", parse_nr_irq_desc); |
150 | 158 | ||
151 | struct irq_desc *sparse_irqs; | ||
152 | DEFINE_DYN_ARRAY(sparse_irqs, sizeof(struct irq_desc), nr_irq_desc, PAGE_SIZE, init_work); | 159 | DEFINE_DYN_ARRAY(sparse_irqs, sizeof(struct irq_desc), nr_irq_desc, PAGE_SIZE, init_work); |
153 | 160 | ||
154 | struct irq_desc *irq_to_desc(unsigned int irq) | 161 | struct irq_desc *irq_to_desc(unsigned int irq) |
155 | { | 162 | { |
156 | struct irq_desc *desc; | 163 | struct irq_desc *desc; |
157 | 164 | ||
158 | BUG_ON(irq == -1U); | 165 | desc = sparse_irqs; |
159 | |||
160 | desc = &sparse_irqs[0]; | ||
161 | while (desc) { | 166 | while (desc) { |
162 | if (desc->irq == irq) | 167 | if (desc->irq == irq) |
163 | return desc; | 168 | return desc; |
164 | 169 | ||
165 | if (desc->irq == -1U) | ||
166 | return NULL; | ||
167 | |||
168 | desc = desc->next; | 170 | desc = desc->next; |
169 | } | 171 | } |
170 | return NULL; | 172 | return NULL; |
@@ -174,21 +176,12 @@ struct irq_desc *irq_to_desc_alloc(unsigned int irq) | |||
174 | struct irq_desc *desc, *desc_pri; | 176 | struct irq_desc *desc, *desc_pri; |
175 | int i; | 177 | int i; |
176 | int count = 0; | 178 | int count = 0; |
177 | unsigned long phys; | ||
178 | unsigned long total_bytes; | ||
179 | 179 | ||
180 | BUG_ON(irq == -1U); | 180 | desc_pri = desc = sparse_irqs; |
181 | |||
182 | desc_pri = desc = &sparse_irqs[0]; | ||
183 | while (desc) { | 181 | while (desc) { |
184 | if (desc->irq == irq) | 182 | if (desc->irq == irq) |
185 | return desc; | 183 | return desc; |
186 | 184 | ||
187 | if (desc->irq == -1U) { | ||
188 | desc->irq = irq; | ||
189 | printk(KERN_DEBUG "found new irq_desc for irq %d\n", desc->irq); | ||
190 | return desc; | ||
191 | } | ||
192 | desc_pri = desc; | 185 | desc_pri = desc; |
193 | desc = desc->next; | 186 | desc = desc->next; |
194 | count++; | 187 | count++; |
@@ -197,48 +190,62 @@ struct irq_desc *irq_to_desc_alloc(unsigned int irq) | |||
197 | /* | 190 | /* |
198 | * we run out of pre-allocate ones, allocate more | 191 | * we run out of pre-allocate ones, allocate more |
199 | */ | 192 | */ |
200 | printk(KERN_DEBUG "try to get more irq_desc %d\n", nr_irq_desc); | 193 | if (!sparse_irqs_free) { |
201 | { | 194 | unsigned long phys; |
202 | /* double check if some one mess up the list */ | 195 | unsigned long total_bytes; |
203 | struct irq_desc *desc; | ||
204 | int count = 0; | ||
205 | |||
206 | desc = &sparse_irqs[0]; | ||
207 | while (desc) { | ||
208 | printk(KERN_DEBUG "found irq_desc for irq %d\n", desc->irq); | ||
209 | if (desc->next) | ||
210 | printk(KERN_DEBUG "found irq_desc for irq %d and next will be irq %d\n", desc->irq, desc->next->irq); | ||
211 | desc = desc->next; | ||
212 | count++; | ||
213 | } | ||
214 | printk(KERN_DEBUG "all preallocted %d\n", count); | ||
215 | } | ||
216 | 196 | ||
217 | total_bytes = sizeof(struct irq_desc) * nr_irq_desc; | 197 | printk(KERN_DEBUG "try to get more irq_desc %d\n", nr_irq_desc); |
218 | if (after_bootmem) | ||
219 | desc = kzalloc(total_bytes, GFP_ATOMIC); | ||
220 | else | ||
221 | desc = __alloc_bootmem_nopanic(total_bytes, PAGE_SIZE, 0); | ||
222 | 198 | ||
223 | if (!desc) | 199 | total_bytes = sizeof(struct irq_desc) * nr_irq_desc; |
224 | panic("please boot with nr_irq_desc= %d\n", count * 2); | 200 | if (after_bootmem) |
201 | desc = kzalloc(total_bytes, GFP_ATOMIC); | ||
202 | else | ||
203 | desc = __alloc_bootmem_nopanic(total_bytes, PAGE_SIZE, 0); | ||
225 | 204 | ||
226 | phys = __pa(desc); | 205 | if (!desc) |
227 | printk(KERN_DEBUG "irq_desc ==> [%#lx - %#lx]\n", phys, phys + total_bytes); | 206 | panic("please boot with nr_irq_desc= %d\n", count * 2); |
228 | 207 | ||
229 | for (i = 0; i < nr_irq_desc; i++) | 208 | phys = __pa(desc); |
230 | init_one_irq_desc(&desc[i]); | 209 | printk(KERN_DEBUG "irq_desc ==> [%#lx - %#lx]\n", phys, phys + total_bytes); |
231 | 210 | ||
232 | for (i = 1; i < nr_irq_desc; i++) | 211 | for (i = 0; i < nr_irq_desc; i++) |
233 | desc[i-1].next = &desc[i]; | 212 | init_one_irq_desc(&desc[i]); |
234 | 213 | ||
235 | /* init kstat_irqs, nr_cpu_ids is ready already */ | 214 | for (i = 1; i < nr_irq_desc; i++) |
236 | init_kstat_irqs(desc, nr_irq_desc, nr_cpu_ids); | 215 | desc[i-1].next = &desc[i]; |
237 | 216 | ||
238 | desc->irq = irq; | 217 | /* init kstat_irqs, nr_cpu_ids is ready already */ |
239 | desc_pri->next = desc; | 218 | init_kstat_irqs(desc, nr_irq_desc, nr_cpu_ids); |
240 | printk(KERN_DEBUG "1 found new irq_desc for irq %d and pri will be irq %d\n", desc->irq, desc_pri->irq); | ||
241 | 219 | ||
220 | sparse_irqs_free = desc; | ||
221 | } | ||
222 | |||
223 | desc = sparse_irqs_free; | ||
224 | sparse_irqs_free = sparse_irqs_free->next; | ||
225 | desc->next = NULL; | ||
226 | if (desc_pri) | ||
227 | desc_pri->next = desc; | ||
228 | else | ||
229 | sparse_irqs = desc; | ||
230 | desc->irq = irq; | ||
231 | printk(KERN_DEBUG "found new irq_desc for irq %d\n", desc->irq); | ||
232 | #ifdef CONFIG_HAVE_SPARSE_IRQ_DEBUG | ||
233 | { | ||
234 | /* dump the results */ | ||
235 | struct irq_desc *desc; | ||
236 | unsigned long phys; | ||
237 | unsigned long bytes = sizeof(struct irq_desc); | ||
238 | unsigned int irqx; | ||
239 | |||
240 | printk(KERN_DEBUG "=========================== %d\n", irq); | ||
241 | printk(KERN_DEBUG "irq_desc dump after get that for %d\n", irq); | ||
242 | for_each_irq_desc(irqx, desc) { | ||
243 | phys = __pa(desc); | ||
244 | printk(KERN_DEBUG "irq_desc %d ==> [%#lx - %#lx]\n", irqx, phys, phys + bytes); | ||
245 | } | ||
246 | printk(KERN_DEBUG "===========================\n"); | ||
247 | } | ||
248 | #endif | ||
242 | return desc; | 249 | return desc; |
243 | } | 250 | } |
244 | #else | 251 | #else |