aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/irq
diff options
context:
space:
mode:
authorYinghai Lu <yhlu.kernel@gmail.com>2008-08-19 23:50:18 -0400
committerIngo Molnar <mingo@elte.hu>2008-10-16 10:52:51 -0400
commit67fb283e148e9bd761f73691d3173b6eab9ba8db (patch)
tree88ba8337dc5bc90e5f95d84d981f750bb7173dd2 /kernel/irq
parentcb5bc83225a86ca53bbb889ed8439e4fd6cf44ac (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.c115
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
116static struct irq_desc *sparse_irqs_free;
117struct irq_desc *sparse_irqs;
118#endif
119
115static void __init init_work(void *data) 120static 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
149early_param("nr_irq_desc", parse_nr_irq_desc); 157early_param("nr_irq_desc", parse_nr_irq_desc);
150 158
151struct irq_desc *sparse_irqs;
152DEFINE_DYN_ARRAY(sparse_irqs, sizeof(struct irq_desc), nr_irq_desc, PAGE_SIZE, init_work); 159DEFINE_DYN_ARRAY(sparse_irqs, sizeof(struct irq_desc), nr_irq_desc, PAGE_SIZE, init_work);
153 160
154struct irq_desc *irq_to_desc(unsigned int irq) 161struct 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