aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
authorSuresh Siddha <suresh.b.siddha@intel.com>2011-05-18 19:31:33 -0400
committerIngo Molnar <mingo@elte.hu>2011-05-20 07:40:52 -0400
commit31dce14a3269843f98ce1bc37d0c91b22f1991ee (patch)
tree66a02547580d22cc31648fd27169940b50c01ce4 /arch/x86
parent4c79185cdb1425fb74241d0be772ff1a9913091a (diff)
x86, ioapic: Use ioapic_saved_data while enabling intr-remapping
Code flow for enabling interrupt-remapping was allocating/freeing buffers for saving/restoring io-apic RTE's. ioapic suspend/resume code uses boot time allocated ioapic_saved_data that is a perfect match for reuse here. This will remove the unnecessary allocation/free of the temporary buffers during suspend/resume of interrupt-remapping enabled platforms aswell as paving the way for further code consolidation. Tested-by: Daniel J Blueman <daniel.blueman@gmail.com> Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com> Link: http://lkml.kernel.org/r/20110518233157.574469296@sbsiddha-MOBL3.sc.intel.com Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/include/asm/io_apic.h20
-rw-r--r--arch/x86/kernel/apic/apic.c48
-rw-r--r--arch/x86/kernel/apic/io_apic.c80
3 files changed, 37 insertions, 111 deletions
diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
index a97a240f67f3..f46984e45094 100644
--- a/arch/x86/include/asm/io_apic.h
+++ b/arch/x86/include/asm/io_apic.h
@@ -152,11 +152,9 @@ extern void ioapic_insert_resources(void);
152 152
153int io_apic_setup_irq_pin_once(unsigned int irq, int node, struct io_apic_irq_attr *attr); 153int io_apic_setup_irq_pin_once(unsigned int irq, int node, struct io_apic_irq_attr *attr);
154 154
155extern struct IO_APIC_route_entry **alloc_ioapic_entries(void); 155extern int save_ioapic_entries(void);
156extern void free_ioapic_entries(struct IO_APIC_route_entry **ioapic_entries); 156extern void mask_ioapic_entries(void);
157extern int save_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries); 157extern int restore_ioapic_entries(void);
158extern void mask_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries);
159extern int restore_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries);
160 158
161extern int get_nr_irqs_gsi(void); 159extern int get_nr_irqs_gsi(void);
162 160
@@ -192,19 +190,13 @@ struct io_apic_irq_attr;
192static inline int io_apic_set_pci_routing(struct device *dev, int irq, 190static inline int io_apic_set_pci_routing(struct device *dev, int irq,
193 struct io_apic_irq_attr *irq_attr) { return 0; } 191 struct io_apic_irq_attr *irq_attr) { return 0; }
194 192
195static inline struct IO_APIC_route_entry **alloc_ioapic_entries(void) 193static inline int save_ioapic_entries(void)
196{
197 return NULL;
198}
199
200static inline void free_ioapic_entries(struct IO_APIC_route_entry **ent) { }
201static inline int save_IO_APIC_setup(struct IO_APIC_route_entry **ent)
202{ 194{
203 return -ENOMEM; 195 return -ENOMEM;
204} 196}
205 197
206static inline void mask_IO_APIC_setup(struct IO_APIC_route_entry **ent) { } 198static inline void mask_ioapic_entries(void) { }
207static inline int restore_IO_APIC_setup(struct IO_APIC_route_entry **ent) 199static inline int restore_ioapic_entries(void)
208{ 200{
209 return -ENOMEM; 201 return -ENOMEM;
210} 202}
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index f92a8e5d1e21..b961af86bfea 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -1461,7 +1461,6 @@ int __init enable_IR(void)
1461void __init enable_IR_x2apic(void) 1461void __init enable_IR_x2apic(void)
1462{ 1462{
1463 unsigned long flags; 1463 unsigned long flags;
1464 struct IO_APIC_route_entry **ioapic_entries;
1465 int ret, x2apic_enabled = 0; 1464 int ret, x2apic_enabled = 0;
1466 int dmar_table_init_ret; 1465 int dmar_table_init_ret;
1467 1466
@@ -1469,13 +1468,7 @@ void __init enable_IR_x2apic(void)
1469 if (dmar_table_init_ret && !x2apic_supported()) 1468 if (dmar_table_init_ret && !x2apic_supported())
1470 return; 1469 return;
1471 1470
1472 ioapic_entries = alloc_ioapic_entries(); 1471 ret = save_ioapic_entries();
1473 if (!ioapic_entries) {
1474 pr_err("Allocate ioapic_entries failed\n");
1475 goto out;
1476 }
1477
1478 ret = save_IO_APIC_setup(ioapic_entries);
1479 if (ret) { 1472 if (ret) {
1480 pr_info("Saving IO-APIC state failed: %d\n", ret); 1473 pr_info("Saving IO-APIC state failed: %d\n", ret);
1481 goto out; 1474 goto out;
@@ -1483,7 +1476,7 @@ void __init enable_IR_x2apic(void)
1483 1476
1484 local_irq_save(flags); 1477 local_irq_save(flags);
1485 legacy_pic->mask_all(); 1478 legacy_pic->mask_all();
1486 mask_IO_APIC_setup(ioapic_entries); 1479 mask_ioapic_entries();
1487 1480
1488 if (dmar_table_init_ret) 1481 if (dmar_table_init_ret)
1489 ret = 0; 1482 ret = 0;
@@ -1514,14 +1507,11 @@ void __init enable_IR_x2apic(void)
1514 1507
1515nox2apic: 1508nox2apic:
1516 if (!ret) /* IR enabling failed */ 1509 if (!ret) /* IR enabling failed */
1517 restore_IO_APIC_setup(ioapic_entries); 1510 restore_ioapic_entries();
1518 legacy_pic->restore_mask(); 1511 legacy_pic->restore_mask();
1519 local_irq_restore(flags); 1512 local_irq_restore(flags);
1520 1513
1521out: 1514out:
1522 if (ioapic_entries)
1523 free_ioapic_entries(ioapic_entries);
1524
1525 if (x2apic_enabled) 1515 if (x2apic_enabled)
1526 return; 1516 return;
1527 1517
@@ -2095,28 +2085,20 @@ static void lapic_resume(void)
2095{ 2085{
2096 unsigned int l, h; 2086 unsigned int l, h;
2097 unsigned long flags; 2087 unsigned long flags;
2098 int maxlvt, ret; 2088 int maxlvt;
2099 struct IO_APIC_route_entry **ioapic_entries = NULL;
2100 2089
2101 if (!apic_pm_state.active) 2090 if (!apic_pm_state.active)
2102 return; 2091 return;
2103 2092
2104 local_irq_save(flags); 2093 local_irq_save(flags);
2105 if (intr_remapping_enabled) { 2094 if (intr_remapping_enabled) {
2106 ioapic_entries = alloc_ioapic_entries(); 2095 /*
2107 if (!ioapic_entries) { 2096 * IO-APIC and PIC have their own resume routines.
2108 WARN(1, "Alloc ioapic_entries in lapic resume failed."); 2097 * We just mask them here to make sure the interrupt
2109 goto restore; 2098 * subsystem is completely quiet while we enable x2apic
2110 } 2099 * and interrupt-remapping.
2111 2100 */
2112 ret = save_IO_APIC_setup(ioapic_entries); 2101 mask_ioapic_entries();
2113 if (ret) {
2114 WARN(1, "Saving IO-APIC state failed: %d\n", ret);
2115 free_ioapic_entries(ioapic_entries);
2116 goto restore;
2117 }
2118
2119 mask_IO_APIC_setup(ioapic_entries);
2120 legacy_pic->mask_all(); 2102 legacy_pic->mask_all();
2121 } 2103 }
2122 2104
@@ -2159,13 +2141,9 @@ static void lapic_resume(void)
2159 apic_write(APIC_ESR, 0); 2141 apic_write(APIC_ESR, 0);
2160 apic_read(APIC_ESR); 2142 apic_read(APIC_ESR);
2161 2143
2162 if (intr_remapping_enabled) { 2144 if (intr_remapping_enabled)
2163 reenable_intr_remapping(x2apic_mode); 2145 reenable_intr_remapping(x2apic_mode);
2164 legacy_pic->restore_mask(); 2146
2165 restore_IO_APIC_setup(ioapic_entries);
2166 free_ioapic_entries(ioapic_entries);
2167 }
2168restore:
2169 local_irq_restore(flags); 2147 local_irq_restore(flags);
2170} 2148}
2171 2149
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 8e771d32ada1..08b794d07a52 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -101,7 +101,7 @@ int mp_irq_entries;
101static int nr_irqs_gsi = NR_IRQS_LEGACY; 101static int nr_irqs_gsi = NR_IRQS_LEGACY;
102 102
103/* 103/*
104 * Saved I/O APIC state during suspend/resume. 104 * Saved I/O APIC state during suspend/resume, or while enabling intr-remap.
105*/ 105*/
106static struct IO_APIC_route_entry *ioapic_saved_data[MAX_IO_APICS]; 106static struct IO_APIC_route_entry *ioapic_saved_data[MAX_IO_APICS];
107 107
@@ -628,74 +628,43 @@ static int __init ioapic_pirq_setup(char *str)
628__setup("pirq=", ioapic_pirq_setup); 628__setup("pirq=", ioapic_pirq_setup);
629#endif /* CONFIG_X86_32 */ 629#endif /* CONFIG_X86_32 */
630 630
631struct IO_APIC_route_entry **alloc_ioapic_entries(void)
632{
633 int apic;
634 struct IO_APIC_route_entry **ioapic_entries;
635
636 ioapic_entries = kzalloc(sizeof(*ioapic_entries) * nr_ioapics,
637 GFP_ATOMIC);
638 if (!ioapic_entries)
639 return 0;
640
641 for (apic = 0; apic < nr_ioapics; apic++) {
642 ioapic_entries[apic] =
643 kzalloc(sizeof(struct IO_APIC_route_entry) *
644 nr_ioapic_registers[apic], GFP_ATOMIC);
645 if (!ioapic_entries[apic])
646 goto nomem;
647 }
648
649 return ioapic_entries;
650
651nomem:
652 while (--apic >= 0)
653 kfree(ioapic_entries[apic]);
654 kfree(ioapic_entries);
655
656 return 0;
657}
658
659/* 631/*
660 * Saves all the IO-APIC RTE's 632 * Saves all the IO-APIC RTE's
661 */ 633 */
662int save_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries) 634int save_ioapic_entries(void)
663{ 635{
664 int apic, pin; 636 int apic, pin;
665 637 int err = 0;
666 if (!ioapic_entries)
667 return -ENOMEM;
668 638
669 for (apic = 0; apic < nr_ioapics; apic++) { 639 for (apic = 0; apic < nr_ioapics; apic++) {
670 if (!ioapic_entries[apic]) 640 if (!ioapic_saved_data[apic]) {
671 return -ENOMEM; 641 err = -ENOMEM;
642 continue;
643 }
672 644
673 for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) 645 for (pin = 0; pin < nr_ioapic_registers[apic]; pin++)
674 ioapic_entries[apic][pin] = 646 ioapic_saved_data[apic][pin] =
675 ioapic_read_entry(apic, pin); 647 ioapic_read_entry(apic, pin);
676 } 648 }
677 649
678 return 0; 650 return err;
679} 651}
680 652
681/* 653/*
682 * Mask all IO APIC entries. 654 * Mask all IO APIC entries.
683 */ 655 */
684void mask_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries) 656void mask_ioapic_entries(void)
685{ 657{
686 int apic, pin; 658 int apic, pin;
687 659
688 if (!ioapic_entries)
689 return;
690
691 for (apic = 0; apic < nr_ioapics; apic++) { 660 for (apic = 0; apic < nr_ioapics; apic++) {
692 if (!ioapic_entries[apic]) 661 if (!ioapic_saved_data[apic])
693 break; 662 continue;
694 663
695 for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) { 664 for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) {
696 struct IO_APIC_route_entry entry; 665 struct IO_APIC_route_entry entry;
697 666
698 entry = ioapic_entries[apic][pin]; 667 entry = ioapic_saved_data[apic][pin];
699 if (!entry.mask) { 668 if (!entry.mask) {
700 entry.mask = 1; 669 entry.mask = 1;
701 ioapic_write_entry(apic, pin, entry); 670 ioapic_write_entry(apic, pin, entry);
@@ -705,36 +674,23 @@ void mask_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries)
705} 674}
706 675
707/* 676/*
708 * Restore IO APIC entries which was saved in ioapic_entries. 677 * Restore IO APIC entries which was saved in ioapic_saved_data
709 */ 678 */
710int restore_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries) 679int restore_ioapic_entries(void)
711{ 680{
712 int apic, pin; 681 int apic, pin;
713 682
714 if (!ioapic_entries)
715 return -ENOMEM;
716
717 for (apic = 0; apic < nr_ioapics; apic++) { 683 for (apic = 0; apic < nr_ioapics; apic++) {
718 if (!ioapic_entries[apic]) 684 if (!ioapic_saved_data[apic])
719 return -ENOMEM; 685 continue;
720 686
721 for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) 687 for (pin = 0; pin < nr_ioapic_registers[apic]; pin++)
722 ioapic_write_entry(apic, pin, 688 ioapic_write_entry(apic, pin,
723 ioapic_entries[apic][pin]); 689 ioapic_saved_data[apic][pin]);
724 } 690 }
725 return 0; 691 return 0;
726} 692}
727 693
728void free_ioapic_entries(struct IO_APIC_route_entry **ioapic_entries)
729{
730 int apic;
731
732 for (apic = 0; apic < nr_ioapics; apic++)
733 kfree(ioapic_entries[apic]);
734
735 kfree(ioapic_entries);
736}
737
738/* 694/*
739 * Find the IRQ entry number of a certain pin. 695 * Find the IRQ entry number of a certain pin.
740 */ 696 */