aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/io_apic.c
diff options
context:
space:
mode:
authorYinghai Lu <yhlu.kernel@gmail.com>2008-08-19 23:50:51 -0400
committerIngo Molnar <mingo@elte.hu>2008-10-16 10:52:57 -0400
commit8f09cd20a24c5f13c571bc73ddcd47be0af3b70f (patch)
tree7b4188221e5ac41d6ec9f773b87a5f8413f530b4 /arch/x86/kernel/io_apic.c
parentffd5aae7817fba22c5c3e304a31c44fa0a4e9a97 (diff)
x86: make HAVE_SPARSE_IRQ support selectable
Ingo said sparse_irq is some intrusive. need to make it selectable to make it simple, remove irq_desc as parameter in some functions. (ack, eoi, set_affinity). may need to make member if irq_chip to take irq_desc, or struct irq later. Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/io_apic.c')
-rw-r--r--arch/x86/kernel/io_apic.c71
1 files changed, 49 insertions, 22 deletions
diff --git a/arch/x86/kernel/io_apic.c b/arch/x86/kernel/io_apic.c
index bf0e66d73030..f853b667fa5c 100644
--- a/arch/x86/kernel/io_apic.c
+++ b/arch/x86/kernel/io_apic.c
@@ -107,7 +107,9 @@ struct irq_cfg;
107struct irq_pin_list; 107struct irq_pin_list;
108struct irq_cfg { 108struct irq_cfg {
109 unsigned int irq; 109 unsigned int irq;
110#ifdef CONFIG_HAVE_SPARSE_IRQ
110 struct irq_cfg *next; 111 struct irq_cfg *next;
112#endif
111 struct irq_pin_list *irq_2_pin; 113 struct irq_pin_list *irq_2_pin;
112 cpumask_t domain; 114 cpumask_t domain;
113 cpumask_t old_domain; 115 cpumask_t old_domain;
@@ -137,20 +139,6 @@ static struct irq_cfg irq_cfg_legacy[] __initdata = {
137}; 139};
138 140
139static struct irq_cfg irq_cfg_init = { .irq = -1U, }; 141static struct irq_cfg irq_cfg_init = { .irq = -1U, };
140/* need to be biger than size of irq_cfg_legacy */
141static int nr_irq_cfg = 32;
142
143static int __init parse_nr_irq_cfg(char *arg)
144{
145 if (arg) {
146 nr_irq_cfg = simple_strtoul(arg, NULL, 0);
147 if (nr_irq_cfg < 32)
148 nr_irq_cfg = 32;
149 }
150 return 0;
151}
152
153early_param("nr_irq_cfg", parse_nr_irq_cfg);
154 142
155static void init_one_irq_cfg(struct irq_cfg *cfg) 143static void init_one_irq_cfg(struct irq_cfg *cfg)
156{ 144{
@@ -158,7 +146,9 @@ static void init_one_irq_cfg(struct irq_cfg *cfg)
158} 146}
159 147
160static struct irq_cfg *irq_cfgx; 148static struct irq_cfg *irq_cfgx;
149#ifdef CONFIG_HAVE_SPARSE_IRQ
161static struct irq_cfg *irq_cfgx_free; 150static struct irq_cfg *irq_cfgx_free;
151#endif
162static void __init init_work(void *data) 152static void __init init_work(void *data)
163{ 153{
164 struct dyn_array *da = data; 154 struct dyn_array *da = data;
@@ -174,15 +164,34 @@ static void __init init_work(void *data)
174 for (i = legacy_count; i < *da->nr; i++) 164 for (i = legacy_count; i < *da->nr; i++)
175 init_one_irq_cfg(&cfg[i]); 165 init_one_irq_cfg(&cfg[i]);
176 166
167#ifdef CONFIG_HAVE_SPARSE_IRQ
177 for (i = 1; i < *da->nr; i++) 168 for (i = 1; i < *da->nr; i++)
178 cfg[i-1].next = &cfg[i]; 169 cfg[i-1].next = &cfg[i];
179 170
180 irq_cfgx_free = &irq_cfgx[legacy_count]; 171 irq_cfgx_free = &irq_cfgx[legacy_count];
181 irq_cfgx[legacy_count - 1].next = NULL; 172 irq_cfgx[legacy_count - 1].next = NULL;
173#endif
174}
175
176#ifdef CONFIG_HAVE_SPARSE_IRQ
177/* need to be biger than size of irq_cfg_legacy */
178static int nr_irq_cfg = 32;
179
180static int __init parse_nr_irq_cfg(char *arg)
181{
182 if (arg) {
183 nr_irq_cfg = simple_strtoul(arg, NULL, 0);
184 if (nr_irq_cfg < 32)
185 nr_irq_cfg = 32;
186 }
187 return 0;
182} 188}
183 189
184#define for_each_irq_cfg(cfg) \ 190early_param("nr_irq_cfg", parse_nr_irq_cfg);
185 for (cfg = irq_cfgx; cfg; cfg = cfg->next) 191
192#define for_each_irq_cfg(irqX, cfg) \
193 for (cfg = irq_cfgx, irqX = cfg->irq; cfg; cfg = cfg->next, irqX = cfg ? cfg->irq : -1U)
194
186 195
187DEFINE_DYN_ARRAY(irq_cfgx, sizeof(struct irq_cfg), nr_irq_cfg, PAGE_SIZE, init_work); 196DEFINE_DYN_ARRAY(irq_cfgx, sizeof(struct irq_cfg), nr_irq_cfg, PAGE_SIZE, init_work);
188 197
@@ -273,7 +282,26 @@ static struct irq_cfg *irq_cfg_alloc(unsigned int irq)
273#endif 282#endif
274 return cfg; 283 return cfg;
275} 284}
285#else
286
287#define for_each_irq_cfg(irq, cfg) \
288 for (irq = 0, cfg = &irq_cfgx[irq]; irq < nr_irqs; irq++, cfg = &irq_cfgx[irq])
289
290DEFINE_DYN_ARRAY(irq_cfgx, sizeof(struct irq_cfg), nr_irqs, PAGE_SIZE, init_work);
276 291
292struct irq_cfg *irq_cfg(unsigned int irq)
293{
294 if (irq < nr_irqs)
295 return &irq_cfgx[irq];
296
297 return NULL;
298}
299struct irq_cfg *irq_cfg_alloc(unsigned int irq)
300{
301 return irq_cfg(irq);
302}
303
304#endif
277/* 305/*
278 * This is performance-critical, we want to do it O(1) 306 * This is performance-critical, we want to do it O(1)
279 * 307 *
@@ -1282,11 +1310,10 @@ void __setup_vector_irq(int cpu)
1282 struct irq_cfg *cfg; 1310 struct irq_cfg *cfg;
1283 1311
1284 /* Mark the inuse vectors */ 1312 /* Mark the inuse vectors */
1285 for_each_irq_cfg(cfg) { 1313 for_each_irq_cfg(irq, cfg) {
1286 if (!cpu_isset(cpu, cfg->domain)) 1314 if (!cpu_isset(cpu, cfg->domain))
1287 continue; 1315 continue;
1288 vector = cfg->vector; 1316 vector = cfg->vector;
1289 irq = cfg->irq;
1290 per_cpu(vector_irq, cpu)[vector] = irq; 1317 per_cpu(vector_irq, cpu)[vector] = irq;
1291 } 1318 }
1292 /* Mark the free vectors */ 1319 /* Mark the free vectors */
@@ -1563,6 +1590,7 @@ __apicdebuginit(void) print_IO_APIC(void)
1563 union IO_APIC_reg_03 reg_03; 1590 union IO_APIC_reg_03 reg_03;
1564 unsigned long flags; 1591 unsigned long flags;
1565 struct irq_cfg *cfg; 1592 struct irq_cfg *cfg;
1593 unsigned int irq;
1566 1594
1567 if (apic_verbosity == APIC_QUIET) 1595 if (apic_verbosity == APIC_QUIET)
1568 return; 1596 return;
@@ -1651,11 +1679,11 @@ __apicdebuginit(void) print_IO_APIC(void)
1651 } 1679 }
1652 } 1680 }
1653 printk(KERN_DEBUG "IRQ to pin mappings:\n"); 1681 printk(KERN_DEBUG "IRQ to pin mappings:\n");
1654 for_each_irq_cfg(cfg) { 1682 for_each_irq_cfg(irq, cfg) {
1655 struct irq_pin_list *entry = cfg->irq_2_pin; 1683 struct irq_pin_list *entry = cfg->irq_2_pin;
1656 if (!entry) 1684 if (!entry)
1657 continue; 1685 continue;
1658 printk(KERN_DEBUG "IRQ%d ", cfg->irq); 1686 printk(KERN_DEBUG "IRQ%d ", irq);
1659 for (;;) { 1687 for (;;) {
1660 printk("-> %d:%d", entry->apic, entry->pin); 1688 printk("-> %d:%d", entry->apic, entry->pin);
1661 if (!entry->next) 1689 if (!entry->next)
@@ -2535,8 +2563,7 @@ static inline void init_IO_APIC_traps(void)
2535 * Also, we've got to be careful not to trash gate 2563 * Also, we've got to be careful not to trash gate
2536 * 0x80, because int 0x80 is hm, kind of importantish. ;) 2564 * 0x80, because int 0x80 is hm, kind of importantish. ;)
2537 */ 2565 */
2538 for_each_irq_cfg(cfg) { 2566 for_each_irq_cfg(irq, cfg) {
2539 irq = cfg->irq;
2540 if (IO_APIC_IRQ(irq) && !cfg->vector) { 2567 if (IO_APIC_IRQ(irq) && !cfg->vector) {
2541 /* 2568 /*
2542 * Hmm.. We don't have an entry for this, 2569 * Hmm.. We don't have an entry for this,