diff options
author | Jiang Liu <jiang.liu@linux.intel.com> | 2015-04-13 22:29:53 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2015-04-24 09:36:53 -0400 |
commit | 4467715a44cca2fa41d25f3d32b737bd2331a8d9 (patch) | |
tree | 70c261a65217b3d58440caa3436529cad2926568 | |
parent | 9c72496698a4dadd406d159f7735851a63ef9412 (diff) |
x86/irq: Move irq_cfg.irq_2_pin into io_apic.c
Now only io_apic.c accesses struct irq_cfg.irq_2_pin, so move irq_2_pin
into struct mp_chip_data in io_apic.c to clean up struct irq_cfg further.
Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com>
Tested-by: Joerg Roedel <jroedel@suse.de>
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: David Cohen <david.a.cohen@linux.intel.com>
Cc: Sander Eikelenboom <linux@eikelenboom.it>
Cc: David Vrabel <david.vrabel@citrix.com>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Joerg Roedel <joro@8bytes.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
Cc: Randy Dunlap <rdunlap@infradead.org>
Cc: Yinghai Lu <yinghai@kernel.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dimitri Sivanich <sivanich@sgi.com>
Cc: Grant Likely <grant.likely@linaro.org>
Link: http://lkml.kernel.org/r/1428978610-28986-17-git-send-email-jiang.liu@linux.intel.com
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r-- | arch/x86/include/asm/hw_irq.h | 7 | ||||
-rw-r--r-- | arch/x86/kernel/apic/io_apic.c | 164 | ||||
-rw-r--r-- | arch/x86/kernel/apic/vector.c | 3 |
3 files changed, 77 insertions, 97 deletions
diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h index e47bc4de5630..f000b58cbc0c 100644 --- a/arch/x86/include/asm/hw_irq.h +++ b/arch/x86/include/asm/hw_irq.h | |||
@@ -176,13 +176,6 @@ struct irq_cfg { | |||
176 | unsigned int dest_apicid; | 176 | unsigned int dest_apicid; |
177 | u8 vector; | 177 | u8 vector; |
178 | u8 move_in_progress : 1; | 178 | u8 move_in_progress : 1; |
179 | union { | ||
180 | #ifdef CONFIG_X86_IO_APIC | ||
181 | struct { | ||
182 | struct list_head irq_2_pin; | ||
183 | }; | ||
184 | #endif | ||
185 | }; | ||
186 | }; | 179 | }; |
187 | 180 | ||
188 | extern struct irq_domain *x86_vector_domain; | 181 | extern struct irq_domain *x86_vector_domain; |
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 998fefad820e..a1abdcf2cb5f 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c | |||
@@ -78,7 +78,13 @@ static DEFINE_MUTEX(ioapic_mutex); | |||
78 | static unsigned int ioapic_dynirq_base; | 78 | static unsigned int ioapic_dynirq_base; |
79 | static int ioapic_initialized; | 79 | static int ioapic_initialized; |
80 | 80 | ||
81 | struct irq_pin_list { | ||
82 | struct list_head list; | ||
83 | int apic, pin; | ||
84 | }; | ||
85 | |||
81 | struct mp_chip_data { | 86 | struct mp_chip_data { |
87 | struct list_head irq_2_pin; | ||
82 | struct IO_APIC_route_entry entry; | 88 | struct IO_APIC_route_entry entry; |
83 | int trigger; | 89 | int trigger; |
84 | int polarity; | 90 | int polarity; |
@@ -215,16 +221,6 @@ void mp_save_irq(struct mpc_intsrc *m) | |||
215 | panic("Max # of irq sources exceeded!!\n"); | 221 | panic("Max # of irq sources exceeded!!\n"); |
216 | } | 222 | } |
217 | 223 | ||
218 | struct irq_pin_list { | ||
219 | struct list_head list; | ||
220 | int apic, pin; | ||
221 | }; | ||
222 | |||
223 | static struct irq_pin_list *alloc_irq_pin_list(int node) | ||
224 | { | ||
225 | return kzalloc_node(sizeof(struct irq_pin_list), GFP_ATOMIC, node); | ||
226 | } | ||
227 | |||
228 | static void alloc_ioapic_saved_registers(int idx) | 224 | static void alloc_ioapic_saved_registers(int idx) |
229 | { | 225 | { |
230 | size_t size; | 226 | size_t size; |
@@ -379,16 +375,17 @@ static void ioapic_mask_entry(int apic, int pin) | |||
379 | * shared ISA-space IRQs, so we have to support them. We are super | 375 | * shared ISA-space IRQs, so we have to support them. We are super |
380 | * fast in the common case, and fast for shared ISA-space IRQs. | 376 | * fast in the common case, and fast for shared ISA-space IRQs. |
381 | */ | 377 | */ |
382 | static int __add_pin_to_irq_node(struct irq_cfg *cfg, int node, int apic, int pin) | 378 | static int __add_pin_to_irq_node(struct mp_chip_data *data, |
379 | int node, int apic, int pin) | ||
383 | { | 380 | { |
384 | struct irq_pin_list *entry; | 381 | struct irq_pin_list *entry; |
385 | 382 | ||
386 | /* don't allow duplicates */ | 383 | /* don't allow duplicates */ |
387 | for_each_irq_pin(entry, cfg->irq_2_pin) | 384 | for_each_irq_pin(entry, data->irq_2_pin) |
388 | if (entry->apic == apic && entry->pin == pin) | 385 | if (entry->apic == apic && entry->pin == pin) |
389 | return 0; | 386 | return 0; |
390 | 387 | ||
391 | entry = alloc_irq_pin_list(node); | 388 | entry = kzalloc_node(sizeof(struct irq_pin_list), GFP_ATOMIC, node); |
392 | if (!entry) { | 389 | if (!entry) { |
393 | pr_err("can not alloc irq_pin_list (%d,%d,%d)\n", | 390 | pr_err("can not alloc irq_pin_list (%d,%d,%d)\n", |
394 | node, apic, pin); | 391 | node, apic, pin); |
@@ -396,16 +393,16 @@ static int __add_pin_to_irq_node(struct irq_cfg *cfg, int node, int apic, int pi | |||
396 | } | 393 | } |
397 | entry->apic = apic; | 394 | entry->apic = apic; |
398 | entry->pin = pin; | 395 | entry->pin = pin; |
396 | list_add_tail(&entry->list, &data->irq_2_pin); | ||
399 | 397 | ||
400 | list_add_tail(&entry->list, &cfg->irq_2_pin); | ||
401 | return 0; | 398 | return 0; |
402 | } | 399 | } |
403 | 400 | ||
404 | static void __remove_pin_from_irq(struct irq_cfg *cfg, int apic, int pin) | 401 | static void __remove_pin_from_irq(struct mp_chip_data *data, int apic, int pin) |
405 | { | 402 | { |
406 | struct irq_pin_list *tmp, *entry; | 403 | struct irq_pin_list *tmp, *entry; |
407 | 404 | ||
408 | list_for_each_entry_safe(entry, tmp, &cfg->irq_2_pin, list) | 405 | list_for_each_entry_safe(entry, tmp, &data->irq_2_pin, list) |
409 | if (entry->apic == apic && entry->pin == pin) { | 406 | if (entry->apic == apic && entry->pin == pin) { |
410 | list_del(&entry->list); | 407 | list_del(&entry->list); |
411 | kfree(entry); | 408 | kfree(entry); |
@@ -413,22 +410,23 @@ static void __remove_pin_from_irq(struct irq_cfg *cfg, int apic, int pin) | |||
413 | } | 410 | } |
414 | } | 411 | } |
415 | 412 | ||
416 | static void add_pin_to_irq_node(struct irq_cfg *cfg, int node, int apic, int pin) | 413 | static void add_pin_to_irq_node(struct mp_chip_data *data, |
414 | int node, int apic, int pin) | ||
417 | { | 415 | { |
418 | if (__add_pin_to_irq_node(cfg, node, apic, pin)) | 416 | if (__add_pin_to_irq_node(data, node, apic, pin)) |
419 | panic("IO-APIC: failed to add irq-pin. Can not proceed\n"); | 417 | panic("IO-APIC: failed to add irq-pin. Can not proceed\n"); |
420 | } | 418 | } |
421 | 419 | ||
422 | /* | 420 | /* |
423 | * Reroute an IRQ to a different pin. | 421 | * Reroute an IRQ to a different pin. |
424 | */ | 422 | */ |
425 | static void __init replace_pin_at_irq_node(struct irq_cfg *cfg, int node, | 423 | static void __init replace_pin_at_irq_node(struct mp_chip_data *data, int node, |
426 | int oldapic, int oldpin, | 424 | int oldapic, int oldpin, |
427 | int newapic, int newpin) | 425 | int newapic, int newpin) |
428 | { | 426 | { |
429 | struct irq_pin_list *entry; | 427 | struct irq_pin_list *entry; |
430 | 428 | ||
431 | for_each_irq_pin(entry, cfg->irq_2_pin) { | 429 | for_each_irq_pin(entry, data->irq_2_pin) { |
432 | if (entry->apic == oldapic && entry->pin == oldpin) { | 430 | if (entry->apic == oldapic && entry->pin == oldpin) { |
433 | entry->apic = newapic; | 431 | entry->apic = newapic; |
434 | entry->pin = newpin; | 432 | entry->pin = newpin; |
@@ -438,7 +436,7 @@ static void __init replace_pin_at_irq_node(struct irq_cfg *cfg, int node, | |||
438 | } | 436 | } |
439 | 437 | ||
440 | /* old apic/pin didn't exist, so just add new ones */ | 438 | /* old apic/pin didn't exist, so just add new ones */ |
441 | add_pin_to_irq_node(cfg, node, newapic, newpin); | 439 | add_pin_to_irq_node(data, node, newapic, newpin); |
442 | } | 440 | } |
443 | 441 | ||
444 | static void __io_apic_modify_irq(struct irq_pin_list *entry, | 442 | static void __io_apic_modify_irq(struct irq_pin_list *entry, |
@@ -456,13 +454,13 @@ static void __io_apic_modify_irq(struct irq_pin_list *entry, | |||
456 | final(entry); | 454 | final(entry); |
457 | } | 455 | } |
458 | 456 | ||
459 | static void io_apic_modify_irq(struct irq_cfg *cfg, | 457 | static void io_apic_modify_irq(struct mp_chip_data *data, |
460 | int mask_and, int mask_or, | 458 | int mask_and, int mask_or, |
461 | void (*final)(struct irq_pin_list *entry)) | 459 | void (*final)(struct irq_pin_list *entry)) |
462 | { | 460 | { |
463 | struct irq_pin_list *entry; | 461 | struct irq_pin_list *entry; |
464 | 462 | ||
465 | for_each_irq_pin(entry, cfg->irq_2_pin) | 463 | for_each_irq_pin(entry, data->irq_2_pin) |
466 | __io_apic_modify_irq(entry, mask_and, mask_or, final); | 464 | __io_apic_modify_irq(entry, mask_and, mask_or, final); |
467 | } | 465 | } |
468 | 466 | ||
@@ -478,39 +476,31 @@ static void io_apic_sync(struct irq_pin_list *entry) | |||
478 | readl(&io_apic->data); | 476 | readl(&io_apic->data); |
479 | } | 477 | } |
480 | 478 | ||
481 | static void mask_ioapic(struct irq_cfg *cfg) | 479 | static void mask_ioapic_irq(struct irq_data *irq_data) |
482 | { | 480 | { |
481 | struct mp_chip_data *data = irq_data->chip_data; | ||
483 | unsigned long flags; | 482 | unsigned long flags; |
484 | 483 | ||
485 | raw_spin_lock_irqsave(&ioapic_lock, flags); | 484 | raw_spin_lock_irqsave(&ioapic_lock, flags); |
486 | io_apic_modify_irq(cfg, ~0, IO_APIC_REDIR_MASKED, &io_apic_sync); | 485 | io_apic_modify_irq(data, ~0, IO_APIC_REDIR_MASKED, &io_apic_sync); |
487 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); | 486 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); |
488 | } | 487 | } |
489 | 488 | ||
490 | static void mask_ioapic_irq(struct irq_data *data) | 489 | static void __unmask_ioapic(struct mp_chip_data *data) |
491 | { | ||
492 | mask_ioapic(irqd_cfg(data)); | ||
493 | } | ||
494 | |||
495 | static void __unmask_ioapic(struct irq_cfg *cfg) | ||
496 | { | 490 | { |
497 | io_apic_modify_irq(cfg, ~IO_APIC_REDIR_MASKED, 0, NULL); | 491 | io_apic_modify_irq(data, ~IO_APIC_REDIR_MASKED, 0, NULL); |
498 | } | 492 | } |
499 | 493 | ||
500 | static void unmask_ioapic(struct irq_cfg *cfg) | 494 | static void unmask_ioapic_irq(struct irq_data *irq_data) |
501 | { | 495 | { |
496 | struct mp_chip_data *data = irq_data->chip_data; | ||
502 | unsigned long flags; | 497 | unsigned long flags; |
503 | 498 | ||
504 | raw_spin_lock_irqsave(&ioapic_lock, flags); | 499 | raw_spin_lock_irqsave(&ioapic_lock, flags); |
505 | __unmask_ioapic(cfg); | 500 | __unmask_ioapic(data); |
506 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); | 501 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); |
507 | } | 502 | } |
508 | 503 | ||
509 | static void unmask_ioapic_irq(struct irq_data *data) | ||
510 | { | ||
511 | unmask_ioapic(irqd_cfg(data)); | ||
512 | } | ||
513 | |||
514 | /* | 504 | /* |
515 | * IO-APIC versions below 0x20 don't support EOI register. | 505 | * IO-APIC versions below 0x20 don't support EOI register. |
516 | * For the record, here is the information about various versions: | 506 | * For the record, here is the information about various versions: |
@@ -551,13 +541,13 @@ static void __eoi_ioapic_pin(int apic, int pin, int vector) | |||
551 | } | 541 | } |
552 | } | 542 | } |
553 | 543 | ||
554 | void eoi_ioapic_pin(int vector, struct irq_cfg *cfg) | 544 | void eoi_ioapic_pin(int vector, struct mp_chip_data *data) |
555 | { | 545 | { |
556 | unsigned long flags; | 546 | unsigned long flags; |
557 | struct irq_pin_list *entry; | 547 | struct irq_pin_list *entry; |
558 | 548 | ||
559 | raw_spin_lock_irqsave(&ioapic_lock, flags); | 549 | raw_spin_lock_irqsave(&ioapic_lock, flags); |
560 | for_each_irq_pin(entry, cfg->irq_2_pin) | 550 | for_each_irq_pin(entry, data->irq_2_pin) |
561 | __eoi_ioapic_pin(entry->apic, entry->pin, vector); | 551 | __eoi_ioapic_pin(entry->apic, entry->pin, vector); |
562 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); | 552 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); |
563 | } | 553 | } |
@@ -1068,11 +1058,10 @@ static int alloc_isa_irq_from_domain(struct irq_domain *domain, | |||
1068 | * entry. The IOAPIC entry | 1058 | * entry. The IOAPIC entry |
1069 | */ | 1059 | */ |
1070 | if (irq_data && irq_data->parent_data) { | 1060 | if (irq_data && irq_data->parent_data) { |
1071 | struct irq_cfg *cfg = irqd_cfg(irq_data); | ||
1072 | |||
1073 | if (!mp_check_pin_attr(irq, info)) | 1061 | if (!mp_check_pin_attr(irq, info)) |
1074 | return -EBUSY; | 1062 | return -EBUSY; |
1075 | if (__add_pin_to_irq_node(cfg, node, ioapic, info->ioapic_pin)) | 1063 | if (__add_pin_to_irq_node(irq_data->chip_data, node, ioapic, |
1064 | info->ioapic_pin)) | ||
1076 | return -ENOMEM; | 1065 | return -ENOMEM; |
1077 | } else { | 1066 | } else { |
1078 | irq = __irq_domain_alloc_irqs(domain, irq, 1, node, info, true); | 1067 | irq = __irq_domain_alloc_irqs(domain, irq, 1, node, info, true); |
@@ -1394,9 +1383,7 @@ static void __init print_IO_APIC(int ioapic_idx) | |||
1394 | void __init print_IO_APICs(void) | 1383 | void __init print_IO_APICs(void) |
1395 | { | 1384 | { |
1396 | int ioapic_idx; | 1385 | int ioapic_idx; |
1397 | struct irq_cfg *cfg; | ||
1398 | unsigned int irq; | 1386 | unsigned int irq; |
1399 | struct irq_chip *chip; | ||
1400 | 1387 | ||
1401 | printk(KERN_DEBUG "number of MP IRQ sources: %d.\n", mp_irq_entries); | 1388 | printk(KERN_DEBUG "number of MP IRQ sources: %d.\n", mp_irq_entries); |
1402 | for_each_ioapic(ioapic_idx) | 1389 | for_each_ioapic(ioapic_idx) |
@@ -1416,18 +1403,20 @@ void __init print_IO_APICs(void) | |||
1416 | printk(KERN_DEBUG "IRQ to pin mappings:\n"); | 1403 | printk(KERN_DEBUG "IRQ to pin mappings:\n"); |
1417 | for_each_active_irq(irq) { | 1404 | for_each_active_irq(irq) { |
1418 | struct irq_pin_list *entry; | 1405 | struct irq_pin_list *entry; |
1406 | struct irq_chip *chip; | ||
1407 | struct mp_chip_data *data; | ||
1419 | 1408 | ||
1420 | chip = irq_get_chip(irq); | 1409 | chip = irq_get_chip(irq); |
1421 | if (chip != &ioapic_chip && chip != &ioapic_ir_chip) | 1410 | if (chip != &ioapic_chip && chip != &ioapic_ir_chip) |
1422 | continue; | 1411 | continue; |
1423 | 1412 | data = irq_get_chip_data(irq); | |
1424 | cfg = irq_cfg(irq); | 1413 | if (!data) |
1425 | if (!cfg) | ||
1426 | continue; | 1414 | continue; |
1427 | if (list_empty(&cfg->irq_2_pin)) | 1415 | if (list_empty(&data->irq_2_pin)) |
1428 | continue; | 1416 | continue; |
1417 | |||
1429 | printk(KERN_DEBUG "IRQ%d ", irq); | 1418 | printk(KERN_DEBUG "IRQ%d ", irq); |
1430 | for_each_irq_pin(entry, cfg->irq_2_pin) | 1419 | for_each_irq_pin(entry, data->irq_2_pin) |
1431 | pr_cont("-> %d:%d", entry->apic, entry->pin); | 1420 | pr_cont("-> %d:%d", entry->apic, entry->pin); |
1432 | pr_cont("\n"); | 1421 | pr_cont("\n"); |
1433 | } | 1422 | } |
@@ -1740,7 +1729,7 @@ static unsigned int startup_ioapic_irq(struct irq_data *data) | |||
1740 | if (legacy_pic->irq_pending(irq)) | 1729 | if (legacy_pic->irq_pending(irq)) |
1741 | was_pending = 1; | 1730 | was_pending = 1; |
1742 | } | 1731 | } |
1743 | __unmask_ioapic(irqd_cfg(data)); | 1732 | __unmask_ioapic(data->chip_data); |
1744 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); | 1733 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); |
1745 | 1734 | ||
1746 | return was_pending; | 1735 | return was_pending; |
@@ -1755,13 +1744,15 @@ static unsigned int startup_ioapic_irq(struct irq_data *data) | |||
1755 | * races. | 1744 | * races. |
1756 | */ | 1745 | */ |
1757 | 1746 | ||
1758 | static void __target_IO_APIC_irq(unsigned int irq, unsigned int dest, struct irq_cfg *cfg) | 1747 | static void __target_IO_APIC_irq(unsigned int irq, struct irq_cfg *cfg, |
1748 | struct mp_chip_data *data) | ||
1759 | { | 1749 | { |
1760 | int apic, pin; | 1750 | int apic, pin; |
1761 | struct irq_pin_list *entry; | 1751 | struct irq_pin_list *entry; |
1762 | u8 vector = cfg->vector; | 1752 | u8 vector = cfg->vector; |
1753 | unsigned int dest = SET_APIC_LOGICAL_ID(cfg->dest_apicid); | ||
1763 | 1754 | ||
1764 | for_each_irq_pin(entry, cfg->irq_2_pin) { | 1755 | for_each_irq_pin(entry, data->irq_2_pin) { |
1765 | unsigned int reg; | 1756 | unsigned int reg; |
1766 | 1757 | ||
1767 | apic = entry->apic; | 1758 | apic = entry->apic; |
@@ -1778,13 +1769,13 @@ static void __target_IO_APIC_irq(unsigned int irq, unsigned int dest, struct irq | |||
1778 | atomic_t irq_mis_count; | 1769 | atomic_t irq_mis_count; |
1779 | 1770 | ||
1780 | #ifdef CONFIG_GENERIC_PENDING_IRQ | 1771 | #ifdef CONFIG_GENERIC_PENDING_IRQ |
1781 | static bool io_apic_level_ack_pending(struct irq_cfg *cfg) | 1772 | static bool io_apic_level_ack_pending(struct mp_chip_data *data) |
1782 | { | 1773 | { |
1783 | struct irq_pin_list *entry; | 1774 | struct irq_pin_list *entry; |
1784 | unsigned long flags; | 1775 | unsigned long flags; |
1785 | 1776 | ||
1786 | raw_spin_lock_irqsave(&ioapic_lock, flags); | 1777 | raw_spin_lock_irqsave(&ioapic_lock, flags); |
1787 | for_each_irq_pin(entry, cfg->irq_2_pin) { | 1778 | for_each_irq_pin(entry, data->irq_2_pin) { |
1788 | unsigned int reg; | 1779 | unsigned int reg; |
1789 | int pin; | 1780 | int pin; |
1790 | 1781 | ||
@@ -1801,18 +1792,17 @@ static bool io_apic_level_ack_pending(struct irq_cfg *cfg) | |||
1801 | return false; | 1792 | return false; |
1802 | } | 1793 | } |
1803 | 1794 | ||
1804 | static inline bool ioapic_irqd_mask(struct irq_data *data, struct irq_cfg *cfg) | 1795 | static inline bool ioapic_irqd_mask(struct irq_data *data) |
1805 | { | 1796 | { |
1806 | /* If we are moving the irq we need to mask it */ | 1797 | /* If we are moving the irq we need to mask it */ |
1807 | if (unlikely(irqd_is_setaffinity_pending(data))) { | 1798 | if (unlikely(irqd_is_setaffinity_pending(data))) { |
1808 | mask_ioapic(cfg); | 1799 | mask_ioapic_irq(data); |
1809 | return true; | 1800 | return true; |
1810 | } | 1801 | } |
1811 | return false; | 1802 | return false; |
1812 | } | 1803 | } |
1813 | 1804 | ||
1814 | static inline void ioapic_irqd_unmask(struct irq_data *data, | 1805 | static inline void ioapic_irqd_unmask(struct irq_data *data, bool masked) |
1815 | struct irq_cfg *cfg, bool masked) | ||
1816 | { | 1806 | { |
1817 | if (unlikely(masked)) { | 1807 | if (unlikely(masked)) { |
1818 | /* Only migrate the irq if the ack has been received. | 1808 | /* Only migrate the irq if the ack has been received. |
@@ -1841,31 +1831,30 @@ static inline void ioapic_irqd_unmask(struct irq_data *data, | |||
1841 | * accurate and is causing problems then it is a hardware bug | 1831 | * accurate and is causing problems then it is a hardware bug |
1842 | * and you can go talk to the chipset vendor about it. | 1832 | * and you can go talk to the chipset vendor about it. |
1843 | */ | 1833 | */ |
1844 | if (!io_apic_level_ack_pending(cfg)) | 1834 | if (!io_apic_level_ack_pending(data->chip_data)) |
1845 | irq_move_masked_irq(data); | 1835 | irq_move_masked_irq(data); |
1846 | unmask_ioapic(cfg); | 1836 | unmask_ioapic_irq(data); |
1847 | } | 1837 | } |
1848 | } | 1838 | } |
1849 | #else | 1839 | #else |
1850 | static inline bool ioapic_irqd_mask(struct irq_data *data, struct irq_cfg *cfg) | 1840 | static inline bool ioapic_irqd_mask(struct irq_data *data) |
1851 | { | 1841 | { |
1852 | return false; | 1842 | return false; |
1853 | } | 1843 | } |
1854 | static inline void ioapic_irqd_unmask(struct irq_data *data, | 1844 | static inline void ioapic_irqd_unmask(struct irq_data *data, bool masked) |
1855 | struct irq_cfg *cfg, bool masked) | ||
1856 | { | 1845 | { |
1857 | } | 1846 | } |
1858 | #endif | 1847 | #endif |
1859 | 1848 | ||
1860 | static void ioapic_ack_level(struct irq_data *data) | 1849 | static void ioapic_ack_level(struct irq_data *irq_data) |
1861 | { | 1850 | { |
1862 | struct irq_cfg *cfg = irqd_cfg(data); | 1851 | struct irq_cfg *cfg = irqd_cfg(irq_data); |
1863 | unsigned long v; | 1852 | unsigned long v; |
1864 | bool masked; | 1853 | bool masked; |
1865 | int i; | 1854 | int i; |
1866 | 1855 | ||
1867 | irq_complete_move(cfg); | 1856 | irq_complete_move(cfg); |
1868 | masked = ioapic_irqd_mask(data, cfg); | 1857 | masked = ioapic_irqd_mask(irq_data); |
1869 | 1858 | ||
1870 | /* | 1859 | /* |
1871 | * It appears there is an erratum which affects at least version 0x11 | 1860 | * It appears there is an erratum which affects at least version 0x11 |
@@ -1917,10 +1906,10 @@ static void ioapic_ack_level(struct irq_data *data) | |||
1917 | */ | 1906 | */ |
1918 | if (!(v & (1 << (i & 0x1f)))) { | 1907 | if (!(v & (1 << (i & 0x1f)))) { |
1919 | atomic_inc(&irq_mis_count); | 1908 | atomic_inc(&irq_mis_count); |
1920 | eoi_ioapic_pin(cfg->vector, cfg); | 1909 | eoi_ioapic_pin(cfg->vector, irq_data->chip_data); |
1921 | } | 1910 | } |
1922 | 1911 | ||
1923 | ioapic_irqd_unmask(data, cfg, masked); | 1912 | ioapic_irqd_unmask(irq_data, masked); |
1924 | } | 1913 | } |
1925 | 1914 | ||
1926 | static void ioapic_ir_ack_level(struct irq_data *irq_data) | 1915 | static void ioapic_ir_ack_level(struct irq_data *irq_data) |
@@ -1934,7 +1923,7 @@ static void ioapic_ir_ack_level(struct irq_data *irq_data) | |||
1934 | * EOI we use the pin number. | 1923 | * EOI we use the pin number. |
1935 | */ | 1924 | */ |
1936 | ack_APIC_irq(); | 1925 | ack_APIC_irq(); |
1937 | eoi_ioapic_pin(data->entry.vector, irqd_cfg(irq_data)); | 1926 | eoi_ioapic_pin(data->entry.vector, data); |
1938 | } | 1927 | } |
1939 | 1928 | ||
1940 | static int ioapic_set_affinity(struct irq_data *irq_data, | 1929 | static int ioapic_set_affinity(struct irq_data *irq_data, |
@@ -1942,7 +1931,6 @@ static int ioapic_set_affinity(struct irq_data *irq_data, | |||
1942 | { | 1931 | { |
1943 | struct irq_data *parent = irq_data->parent_data; | 1932 | struct irq_data *parent = irq_data->parent_data; |
1944 | struct mp_chip_data *data = irq_data->chip_data; | 1933 | struct mp_chip_data *data = irq_data->chip_data; |
1945 | unsigned int dest, irq = irq_data->irq; | ||
1946 | struct irq_cfg *cfg; | 1934 | struct irq_cfg *cfg; |
1947 | unsigned long flags; | 1935 | unsigned long flags; |
1948 | int ret; | 1936 | int ret; |
@@ -1953,9 +1941,7 @@ static int ioapic_set_affinity(struct irq_data *irq_data, | |||
1953 | cfg = irqd_cfg(irq_data); | 1941 | cfg = irqd_cfg(irq_data); |
1954 | data->entry.dest = cfg->dest_apicid; | 1942 | data->entry.dest = cfg->dest_apicid; |
1955 | data->entry.vector = cfg->vector; | 1943 | data->entry.vector = cfg->vector; |
1956 | /* Only the high 8 bits are valid. */ | 1944 | __target_IO_APIC_irq(irq_data->irq, cfg, irq_data->chip_data); |
1957 | dest = SET_APIC_LOGICAL_ID(cfg->dest_apicid); | ||
1958 | __target_IO_APIC_irq(irq, dest, cfg); | ||
1959 | } | 1945 | } |
1960 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); | 1946 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); |
1961 | 1947 | ||
@@ -2116,10 +2102,11 @@ early_param("disable_timer_pin_1", disable_timer_pin_setup); | |||
2116 | static int mp_alloc_timer_irq(int ioapic, int pin) | 2102 | static int mp_alloc_timer_irq(int ioapic, int pin) |
2117 | { | 2103 | { |
2118 | int irq = -1; | 2104 | int irq = -1; |
2119 | struct irq_alloc_info info; | ||
2120 | struct irq_domain *domain = mp_ioapic_irqdomain(ioapic); | 2105 | struct irq_domain *domain = mp_ioapic_irqdomain(ioapic); |
2121 | 2106 | ||
2122 | if (domain) { | 2107 | if (domain) { |
2108 | struct irq_alloc_info info; | ||
2109 | |||
2123 | ioapic_set_alloc_attr(&info, NUMA_NO_NODE, 0, 0); | 2110 | ioapic_set_alloc_attr(&info, NUMA_NO_NODE, 0, 0); |
2124 | info.ioapic_id = mpc_ioapic_id(ioapic); | 2111 | info.ioapic_id = mpc_ioapic_id(ioapic); |
2125 | info.ioapic_pin = pin; | 2112 | info.ioapic_pin = pin; |
@@ -2141,7 +2128,9 @@ static int mp_alloc_timer_irq(int ioapic, int pin) | |||
2141 | */ | 2128 | */ |
2142 | static inline void __init check_timer(void) | 2129 | static inline void __init check_timer(void) |
2143 | { | 2130 | { |
2144 | struct irq_cfg *cfg = irq_cfg(0); | 2131 | struct irq_data *irq_data = irq_get_irq_data(0); |
2132 | struct mp_chip_data *data = irq_data->chip_data; | ||
2133 | struct irq_cfg *cfg = irqd_cfg(irq_data); | ||
2145 | int node = cpu_to_node(0); | 2134 | int node = cpu_to_node(0); |
2146 | int apic1, pin1, apic2, pin2; | 2135 | int apic1, pin1, apic2, pin2; |
2147 | unsigned long flags; | 2136 | unsigned long flags; |
@@ -2205,9 +2194,9 @@ static inline void __init check_timer(void) | |||
2205 | int idx; | 2194 | int idx; |
2206 | idx = find_irq_entry(apic1, pin1, mp_INT); | 2195 | idx = find_irq_entry(apic1, pin1, mp_INT); |
2207 | if (idx != -1 && irq_trigger(idx)) | 2196 | if (idx != -1 && irq_trigger(idx)) |
2208 | unmask_ioapic(cfg); | 2197 | unmask_ioapic_irq(irq_get_chip_data(0)); |
2209 | } | 2198 | } |
2210 | irq_domain_activate_irq(irq_get_irq_data(0)); | 2199 | irq_domain_activate_irq(irq_data); |
2211 | if (timer_irq_works()) { | 2200 | if (timer_irq_works()) { |
2212 | if (disable_timer_pin_1 > 0) | 2201 | if (disable_timer_pin_1 > 0) |
2213 | clear_IO_APIC_pin(0, pin1); | 2202 | clear_IO_APIC_pin(0, pin1); |
@@ -2227,8 +2216,8 @@ static inline void __init check_timer(void) | |||
2227 | /* | 2216 | /* |
2228 | * legacy devices should be connected to IO APIC #0 | 2217 | * legacy devices should be connected to IO APIC #0 |
2229 | */ | 2218 | */ |
2230 | replace_pin_at_irq_node(cfg, node, apic1, pin1, apic2, pin2); | 2219 | replace_pin_at_irq_node(data, node, apic1, pin1, apic2, pin2); |
2231 | irq_domain_activate_irq(irq_get_irq_data(0)); | 2220 | irq_domain_activate_irq(irq_data); |
2232 | legacy_pic->unmask(0); | 2221 | legacy_pic->unmask(0); |
2233 | if (timer_irq_works()) { | 2222 | if (timer_irq_works()) { |
2234 | apic_printk(APIC_QUIET, KERN_INFO "....... works.\n"); | 2223 | apic_printk(APIC_QUIET, KERN_INFO "....... works.\n"); |
@@ -3044,6 +3033,7 @@ int mp_irqdomain_alloc(struct irq_domain *domain, unsigned int virq, | |||
3044 | return ret; | 3033 | return ret; |
3045 | } | 3034 | } |
3046 | 3035 | ||
3036 | INIT_LIST_HEAD(&data->irq_2_pin); | ||
3047 | irq_data->hwirq = info->ioapic_pin; | 3037 | irq_data->hwirq = info->ioapic_pin; |
3048 | irq_data->chip = (domain->parent == x86_vector_domain) ? | 3038 | irq_data->chip = (domain->parent == x86_vector_domain) ? |
3049 | &ioapic_chip : &ioapic_ir_chip; | 3039 | &ioapic_chip : &ioapic_ir_chip; |
@@ -3051,7 +3041,7 @@ int mp_irqdomain_alloc(struct irq_domain *domain, unsigned int virq, | |||
3051 | mp_irqdomain_get_attr(mp_pin_to_gsi(ioapic, pin), data, info); | 3041 | mp_irqdomain_get_attr(mp_pin_to_gsi(ioapic, pin), data, info); |
3052 | 3042 | ||
3053 | cfg = irqd_cfg(irq_data); | 3043 | cfg = irqd_cfg(irq_data); |
3054 | add_pin_to_irq_node(cfg, info->ioapic_node, ioapic, pin); | 3044 | add_pin_to_irq_node(data, ioapic_alloc_attr_node(info), ioapic, pin); |
3055 | if (info->ioapic_entry) | 3045 | if (info->ioapic_entry) |
3056 | mp_setup_entry(cfg, data, info->ioapic_entry); | 3046 | mp_setup_entry(cfg, data, info->ioapic_entry); |
3057 | mp_register_handler(virq, data->trigger); | 3047 | mp_register_handler(virq, data->trigger); |
@@ -3069,15 +3059,16 @@ int mp_irqdomain_alloc(struct irq_domain *domain, unsigned int virq, | |||
3069 | void mp_irqdomain_free(struct irq_domain *domain, unsigned int virq, | 3059 | void mp_irqdomain_free(struct irq_domain *domain, unsigned int virq, |
3070 | unsigned int nr_irqs) | 3060 | unsigned int nr_irqs) |
3071 | { | 3061 | { |
3072 | struct irq_cfg *cfg = irq_cfg(virq); | ||
3073 | struct irq_data *irq_data; | 3062 | struct irq_data *irq_data; |
3063 | struct mp_chip_data *data; | ||
3074 | 3064 | ||
3075 | BUG_ON(nr_irqs != 1); | 3065 | BUG_ON(nr_irqs != 1); |
3076 | irq_data = irq_domain_get_irq_data(domain, virq); | 3066 | irq_data = irq_domain_get_irq_data(domain, virq); |
3077 | if (irq_data && irq_data->chip_data) { | 3067 | if (irq_data && irq_data->chip_data) { |
3078 | __remove_pin_from_irq(cfg, mp_irqdomain_ioapic_idx(domain), | 3068 | data = irq_data->chip_data; |
3069 | __remove_pin_from_irq(data, mp_irqdomain_ioapic_idx(domain), | ||
3079 | (int)irq_data->hwirq); | 3070 | (int)irq_data->hwirq); |
3080 | WARN_ON(!list_empty(&cfg->irq_2_pin)); | 3071 | WARN_ON(!list_empty(&data->irq_2_pin)); |
3081 | kfree(irq_data->chip_data); | 3072 | kfree(irq_data->chip_data); |
3082 | } | 3073 | } |
3083 | irq_domain_free_irqs_top(domain, virq, nr_irqs); | 3074 | irq_domain_free_irqs_top(domain, virq, nr_irqs); |
@@ -3089,10 +3080,9 @@ void mp_irqdomain_activate(struct irq_domain *domain, | |||
3089 | unsigned long flags; | 3080 | unsigned long flags; |
3090 | struct irq_pin_list *entry; | 3081 | struct irq_pin_list *entry; |
3091 | struct mp_chip_data *data = irq_data->chip_data; | 3082 | struct mp_chip_data *data = irq_data->chip_data; |
3092 | struct irq_cfg *cfg = irqd_cfg(irq_data); | ||
3093 | 3083 | ||
3094 | raw_spin_lock_irqsave(&ioapic_lock, flags); | 3084 | raw_spin_lock_irqsave(&ioapic_lock, flags); |
3095 | for_each_irq_pin(entry, cfg->irq_2_pin) | 3085 | for_each_irq_pin(entry, data->irq_2_pin) |
3096 | __ioapic_write_entry(entry->apic, entry->pin, data->entry); | 3086 | __ioapic_write_entry(entry->apic, entry->pin, data->entry); |
3097 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); | 3087 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); |
3098 | } | 3088 | } |
diff --git a/arch/x86/kernel/apic/vector.c b/arch/x86/kernel/apic/vector.c index 37bb9e82b919..af224e6774d8 100644 --- a/arch/x86/kernel/apic/vector.c +++ b/arch/x86/kernel/apic/vector.c | |||
@@ -68,9 +68,6 @@ static struct irq_cfg *alloc_irq_cfg(int node) | |||
68 | goto out_cfg; | 68 | goto out_cfg; |
69 | if (!zalloc_cpumask_var_node(&cfg->old_domain, GFP_KERNEL, node)) | 69 | if (!zalloc_cpumask_var_node(&cfg->old_domain, GFP_KERNEL, node)) |
70 | goto out_domain; | 70 | goto out_domain; |
71 | #ifdef CONFIG_X86_IO_APIC | ||
72 | INIT_LIST_HEAD(&cfg->irq_2_pin); | ||
73 | #endif | ||
74 | return cfg; | 71 | return cfg; |
75 | out_domain: | 72 | out_domain: |
76 | free_cpumask_var(cfg->domain); | 73 | free_cpumask_var(cfg->domain); |