diff options
| author | Yinghai Lu <yhlu.kernel@gmail.com> | 2008-08-19 23:50:51 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2008-10-16 10:52:57 -0400 |
| commit | 8f09cd20a24c5f13c571bc73ddcd47be0af3b70f (patch) | |
| tree | 7b4188221e5ac41d6ec9f773b87a5f8413f530b4 /arch/x86/kernel | |
| parent | ffd5aae7817fba22c5c3e304a31c44fa0a4e9a97 (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')
| -rw-r--r-- | arch/x86/kernel/io_apic.c | 71 | ||||
| -rw-r--r-- | arch/x86/kernel/irq_32.c | 2 | ||||
| -rw-r--r-- | arch/x86/kernel/irq_64.c | 2 |
3 files changed, 51 insertions, 24 deletions
diff --git a/arch/x86/kernel/io_apic.c b/arch/x86/kernel/io_apic.c index bf0e66d7303..f853b667fa5 100644 --- a/arch/x86/kernel/io_apic.c +++ b/arch/x86/kernel/io_apic.c | |||
| @@ -107,7 +107,9 @@ struct irq_cfg; | |||
| 107 | struct irq_pin_list; | 107 | struct irq_pin_list; |
| 108 | struct irq_cfg { | 108 | struct 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 | ||
| 139 | static struct irq_cfg irq_cfg_init = { .irq = -1U, }; | 141 | static struct irq_cfg irq_cfg_init = { .irq = -1U, }; |
| 140 | /* need to be biger than size of irq_cfg_legacy */ | ||
| 141 | static int nr_irq_cfg = 32; | ||
| 142 | |||
| 143 | static 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 | |||
| 153 | early_param("nr_irq_cfg", parse_nr_irq_cfg); | ||
| 154 | 142 | ||
| 155 | static void init_one_irq_cfg(struct irq_cfg *cfg) | 143 | static 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 | ||
| 160 | static struct irq_cfg *irq_cfgx; | 148 | static struct irq_cfg *irq_cfgx; |
| 149 | #ifdef CONFIG_HAVE_SPARSE_IRQ | ||
| 161 | static struct irq_cfg *irq_cfgx_free; | 150 | static struct irq_cfg *irq_cfgx_free; |
| 151 | #endif | ||
| 162 | static void __init init_work(void *data) | 152 | static 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 */ | ||
| 178 | static int nr_irq_cfg = 32; | ||
| 179 | |||
| 180 | static 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) \ | 190 | early_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 | ||
| 187 | DEFINE_DYN_ARRAY(irq_cfgx, sizeof(struct irq_cfg), nr_irq_cfg, PAGE_SIZE, init_work); | 196 | DEFINE_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 | |||
| 290 | DEFINE_DYN_ARRAY(irq_cfgx, sizeof(struct irq_cfg), nr_irqs, PAGE_SIZE, init_work); | ||
| 276 | 291 | ||
| 292 | struct irq_cfg *irq_cfg(unsigned int irq) | ||
| 293 | { | ||
| 294 | if (irq < nr_irqs) | ||
| 295 | return &irq_cfgx[irq]; | ||
| 296 | |||
| 297 | return NULL; | ||
| 298 | } | ||
| 299 | struct 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 cc929f2f84f..b2e1082cf5a 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 348a11168c2..c2fca89a3f7 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 |
