aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kernel/io_apic.c130
-rw-r--r--arch/x86/kernel/irq_32.c8
-rw-r--r--arch/x86/kernel/irq_64.c8
3 files changed, 4 insertions, 142 deletions
diff --git a/arch/x86/kernel/io_apic.c b/arch/x86/kernel/io_apic.c
index f959acbc0db2..683610517d2a 100644
--- a/arch/x86/kernel/io_apic.c
+++ b/arch/x86/kernel/io_apic.c
@@ -111,9 +111,6 @@ struct irq_cfg;
111struct irq_pin_list; 111struct irq_pin_list;
112struct irq_cfg { 112struct irq_cfg {
113 unsigned int irq; 113 unsigned int irq;
114#ifdef CONFIG_HAVE_SPARSE_IRQ
115 struct irq_cfg *next;
116#endif
117 struct irq_pin_list *irq_2_pin; 114 struct irq_pin_list *irq_2_pin;
118 cpumask_t domain; 115 cpumask_t domain;
119 cpumask_t old_domain; 116 cpumask_t old_domain;
@@ -151,15 +148,6 @@ static void init_one_irq_cfg(struct irq_cfg *cfg)
151 148
152static struct irq_cfg *irq_cfgx; 149static struct irq_cfg *irq_cfgx;
153 150
154#ifdef CONFIG_HAVE_SPARSE_IRQ
155/*
156 * Protect the irq_cfgx_free freelist:
157 */
158static DEFINE_SPINLOCK(irq_cfg_lock);
159
160static struct irq_cfg *irq_cfgx_free;
161#endif
162
163static void __init init_work(void *data) 151static void __init init_work(void *data)
164{ 152{
165 struct dyn_array *da = data; 153 struct dyn_array *da = data;
@@ -174,114 +162,7 @@ static void __init init_work(void *data)
174 legacy_count = ARRAY_SIZE(irq_cfg_legacy); 162 legacy_count = ARRAY_SIZE(irq_cfg_legacy);
175 for (i = legacy_count; i < *da->nr; i++) 163 for (i = legacy_count; i < *da->nr; i++)
176 init_one_irq_cfg(&cfg[i]); 164 init_one_irq_cfg(&cfg[i]);
177
178#ifdef CONFIG_HAVE_SPARSE_IRQ
179 for (i = 1; i < *da->nr; i++)
180 cfg[i-1].next = &cfg[i];
181
182 irq_cfgx_free = &irq_cfgx[legacy_count];
183 irq_cfgx[legacy_count - 1].next = NULL;
184#endif
185}
186
187#ifdef CONFIG_HAVE_SPARSE_IRQ
188/* need to be biger than size of irq_cfg_legacy */
189static int nr_irq_cfg = 32;
190
191static int __init parse_nr_irq_cfg(char *arg)
192{
193 if (arg) {
194 nr_irq_cfg = simple_strtoul(arg, NULL, 0);
195 if (nr_irq_cfg < 32)
196 nr_irq_cfg = 32;
197 }
198 return 0;
199}
200
201early_param("nr_irq_cfg", parse_nr_irq_cfg);
202
203#define for_each_irq_cfg(irqX, cfg) \
204 for (cfg = irq_cfgx, irqX = cfg->irq; cfg; cfg = cfg->next, irqX = cfg ? cfg->irq : -1U)
205
206
207DEFINE_DYN_ARRAY(irq_cfgx, sizeof(struct irq_cfg), nr_irq_cfg, PAGE_SIZE, init_work);
208
209static struct irq_cfg *irq_cfg(unsigned int irq)
210{
211 struct irq_cfg *cfg;
212
213 cfg = irq_cfgx;
214 while (cfg) {
215 if (cfg->irq == irq)
216 return cfg;
217
218 cfg = cfg->next;
219 }
220
221 return NULL;
222}
223
224static struct irq_cfg *irq_cfg_alloc(unsigned int irq)
225{
226 struct irq_cfg *cfg, *cfg_pri;
227 unsigned long flags;
228 int count = 0;
229 int i;
230
231 cfg_pri = cfg = irq_cfgx;
232 while (cfg) {
233 if (cfg->irq == irq)
234 return cfg;
235
236 cfg_pri = cfg;
237 cfg = cfg->next;
238 count++;
239 }
240
241 spin_lock_irqsave(&irq_cfg_lock, flags);
242 if (!irq_cfgx_free) {
243 unsigned long phys;
244 unsigned long total_bytes;
245 /*
246 * we run out of pre-allocate ones, allocate more
247 */
248 printk(KERN_DEBUG "try to get more irq_cfg %d\n", nr_irq_cfg);
249
250 total_bytes = sizeof(struct irq_cfg) * nr_irq_cfg;
251 if (after_bootmem)
252 cfg = kzalloc(total_bytes, GFP_ATOMIC);
253 else
254 cfg = __alloc_bootmem_nopanic(total_bytes, PAGE_SIZE, 0);
255
256 if (!cfg)
257 panic("please boot with nr_irq_cfg= %d\n", count * 2);
258
259 phys = __pa(cfg);
260 printk(KERN_DEBUG "irq_cfg ==> [%#lx - %#lx]\n", phys, phys + total_bytes);
261
262 for (i = 0; i < nr_irq_cfg; i++)
263 init_one_irq_cfg(&cfg[i]);
264
265 for (i = 1; i < nr_irq_cfg; i++)
266 cfg[i-1].next = &cfg[i];
267
268 irq_cfgx_free = cfg;
269 }
270
271 cfg = irq_cfgx_free;
272 irq_cfgx_free = irq_cfgx_free->next;
273 cfg->next = NULL;
274 if (cfg_pri)
275 cfg_pri->next = cfg;
276 else
277 irq_cfgx = cfg;
278 cfg->irq = irq;
279
280 spin_unlock_irqrestore(&irq_cfg_lock, flags);
281
282 return cfg;
283} 165}
284#else
285 166
286#define for_each_irq_cfg(irq, cfg) \ 167#define for_each_irq_cfg(irq, cfg) \
287 for (irq = 0, cfg = &irq_cfgx[irq]; irq < nr_irqs; irq++, cfg = &irq_cfgx[irq]) 168 for (irq = 0, cfg = &irq_cfgx[irq]; irq < nr_irqs; irq++, cfg = &irq_cfgx[irq])
@@ -290,17 +171,16 @@ DEFINE_DYN_ARRAY(irq_cfgx, sizeof(struct irq_cfg), nr_irqs, PAGE_SIZE, init_work
290 171
291struct irq_cfg *irq_cfg(unsigned int irq) 172struct irq_cfg *irq_cfg(unsigned int irq)
292{ 173{
293 if (irq < nr_irqs) 174 if (irq < nr_irqs)
294 return &irq_cfgx[irq]; 175 return &irq_cfgx[irq];
295 176
296 return NULL; 177 return NULL;
297} 178}
298struct irq_cfg *irq_cfg_alloc(unsigned int irq) 179struct irq_cfg *irq_cfg_alloc(unsigned int irq)
299{ 180{
300 return irq_cfg(irq); 181 return irq_cfg(irq);
301} 182}
302 183
303#endif
304/* 184/*
305 * This is performance-critical, we want to do it O(1) 185 * This is performance-critical, we want to do it O(1)
306 * 186 *
@@ -3068,9 +2948,7 @@ unsigned int create_irq_nr(unsigned int irq_want)
3068 unsigned long flags; 2948 unsigned long flags;
3069 struct irq_cfg *cfg_new; 2949 struct irq_cfg *cfg_new;
3070 2950
3071#ifndef CONFIG_HAVE_SPARSE_IRQ
3072 irq_want = nr_irqs - 1; 2951 irq_want = nr_irqs - 1;
3073#endif
3074 2952
3075 irq = 0; 2953 irq = 0;
3076 spin_lock_irqsave(&vector_lock, flags); 2954 spin_lock_irqsave(&vector_lock, flags);
diff --git a/arch/x86/kernel/irq_32.c b/arch/x86/kernel/irq_32.c
index 001772ffc918..ccf6c1bf7120 100644
--- a/arch/x86/kernel/irq_32.c
+++ b/arch/x86/kernel/irq_32.c
@@ -272,20 +272,12 @@ int show_interrupts(struct seq_file *p, void *v)
272 struct irq_desc *desc = NULL; 272 struct irq_desc *desc = NULL;
273 int tail = 0; 273 int tail = 0;
274 274
275#ifdef CONFIG_HAVE_SPARSE_IRQ
276 desc = (struct irq_desc *)v;
277 entries = -1U;
278 i = desc->irq;
279 if (!desc->next)
280 tail = 1;
281#else
282 entries = nr_irqs - 1; 275 entries = nr_irqs - 1;
283 i = *(loff_t *) v; 276 i = *(loff_t *) v;
284 if (i == nr_irqs) 277 if (i == nr_irqs)
285 tail = 1; 278 tail = 1;
286 else 279 else
287 desc = irq_to_desc(i); 280 desc = irq_to_desc(i);
288#endif
289 281
290 if (i == 0) { 282 if (i == 0) {
291 seq_printf(p, " "); 283 seq_printf(p, " ");
diff --git a/arch/x86/kernel/irq_64.c b/arch/x86/kernel/irq_64.c
index ec2661091283..21f53b911113 100644
--- a/arch/x86/kernel/irq_64.c
+++ b/arch/x86/kernel/irq_64.c
@@ -77,20 +77,12 @@ int show_interrupts(struct seq_file *p, void *v)
77 struct irq_desc *desc = NULL; 77 struct irq_desc *desc = NULL;
78 int tail = 0; 78 int tail = 0;
79 79
80#ifdef CONFIG_HAVE_SPARSE_IRQ
81 desc = (struct irq_desc *)v;
82 entries = -1U;
83 i = desc->irq;
84 if (!desc->next)
85 tail = 1;
86#else
87 entries = nr_irqs - 1; 80 entries = nr_irqs - 1;
88 i = *(loff_t *) v; 81 i = *(loff_t *) v;
89 if (i == nr_irqs) 82 if (i == nr_irqs)
90 tail = 1; 83 tail = 1;
91 else 84 else
92 desc = irq_to_desc(i); 85 desc = irq_to_desc(i);
93#endif
94 86
95 if (i == 0) { 87 if (i == 0) {
96 seq_printf(p, " "); 88 seq_printf(p, " ");