aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/Kconfig3
-rw-r--r--arch/x86/Kconfig12
-rw-r--r--arch/x86/kernel/io_apic.c71
-rw-r--r--arch/x86/kernel/irq_32.c2
-rw-r--r--arch/x86/kernel/irq_64.c2
5 files changed, 62 insertions, 28 deletions
diff --git a/arch/Kconfig b/arch/Kconfig
index b36762246265..c8a7c2eb6490 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -106,6 +106,3 @@ config HAVE_CLK
106config HAVE_DYN_ARRAY 106config HAVE_DYN_ARRAY
107 def_bool n 107 def_bool n
108 108
109config HAVE_SPARSE_IRQ
110 def_bool n
111
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index b157e94637bf..600584b7a497 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -34,7 +34,6 @@ config X86
34 select HAVE_GENERIC_DMA_COHERENT if X86_32 34 select HAVE_GENERIC_DMA_COHERENT if X86_32
35 select HAVE_EFFICIENT_UNALIGNED_ACCESS 35 select HAVE_EFFICIENT_UNALIGNED_ACCESS
36 select HAVE_DYN_ARRAY 36 select HAVE_DYN_ARRAY
37 select HAVE_SPARSE_IRQ
38 37
39config ARCH_DEFCONFIG 38config ARCH_DEFCONFIG
40 string 39 string
@@ -238,6 +237,17 @@ config SMP
238 237
239 If you don't know what to do here, say N. 238 If you don't know what to do here, say N.
240 239
240config HAVE_SPARSE_IRQ
241 bool "Support sparse irq numbering"
242 depends on PCI_MSI || HT_IRQ
243 default y
244 help
245 This enables support for sparse irq, esp for msi/msi-x. the irq
246 number will be bus/dev/fn + 12bit. You may need if you have lots of
247 cards supports msi-x installed.
248
249 If you don't know what to do here, say Y.
250
241config X86_FIND_SMP_CONFIG 251config X86_FIND_SMP_CONFIG
242 def_bool y 252 def_bool y
243 depends on X86_MPPARSE || X86_VOYAGER 253 depends on X86_MPPARSE || X86_VOYAGER
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,
diff --git a/arch/x86/kernel/irq_32.c b/arch/x86/kernel/irq_32.c
index cc929f2f84f1..b2e1082cf5ad 100644
--- a/arch/x86/kernel/irq_32.c
+++ b/arch/x86/kernel/irq_32.c
@@ -269,7 +269,7 @@ int show_interrupts(struct seq_file *p, void *v)
269 struct irqaction * action; 269 struct irqaction * action;
270 unsigned long flags; 270 unsigned long flags;
271 unsigned int entries; 271 unsigned int entries;
272 struct irq_desc *desc; 272 struct irq_desc *desc = NULL;
273 int tail = 0; 273 int tail = 0;
274 274
275#ifdef CONFIG_HAVE_SPARSE_IRQ 275#ifdef CONFIG_HAVE_SPARSE_IRQ
diff --git a/arch/x86/kernel/irq_64.c b/arch/x86/kernel/irq_64.c
index 348a11168c2b..c2fca89a3f7e 100644
--- a/arch/x86/kernel/irq_64.c
+++ b/arch/x86/kernel/irq_64.c
@@ -74,7 +74,7 @@ int show_interrupts(struct seq_file *p, void *v)
74 struct irqaction * action; 74 struct irqaction * action;
75 unsigned long flags; 75 unsigned long flags;
76 unsigned int entries; 76 unsigned int entries;
77 struct irq_desc *desc; 77 struct irq_desc *desc = NULL;
78 int tail = 0; 78 int tail = 0;
79 79
80#ifdef CONFIG_HAVE_SPARSE_IRQ 80#ifdef CONFIG_HAVE_SPARSE_IRQ