aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86_64
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86_64')
-rw-r--r--arch/x86_64/kernel/io_apic.c104
1 files changed, 61 insertions, 43 deletions
diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c
index eaf0b708e67d..2a1dcd5f69c2 100644
--- a/arch/x86_64/kernel/io_apic.c
+++ b/arch/x86_64/kernel/io_apic.c
@@ -789,27 +789,65 @@ static void ioapic_register_intr(int irq, int vector, unsigned long trigger)
789 handle_edge_irq, "edge"); 789 handle_edge_irq, "edge");
790 } 790 }
791} 791}
792 792static void __init setup_IO_APIC_irq(int apic, int pin, int idx, int irq)
793static void __init setup_IO_APIC_irqs(void)
794{ 793{
795 struct IO_APIC_route_entry entry; 794 struct IO_APIC_route_entry entry;
796 int apic, pin, idx, irq, first_notcon = 1, vector; 795 int vector;
797 unsigned long flags; 796 unsigned long flags;
798 797
799 apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n");
800 798
801 for (apic = 0; apic < nr_ioapics; apic++) { 799 /*
802 for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) { 800 * add it to the IO-APIC irq-routing table:
801 */
802 memset(&entry,0,sizeof(entry));
803 803
804 /* 804 entry.delivery_mode = INT_DELIVERY_MODE;
805 * add it to the IO-APIC irq-routing table: 805 entry.dest_mode = INT_DEST_MODE;
806 */ 806 entry.mask = 0; /* enable IRQ */
807 memset(&entry,0,sizeof(entry)); 807 entry.dest.logical.logical_dest = cpu_mask_to_apicid(TARGET_CPUS);
808
809 entry.trigger = irq_trigger(idx);
810 entry.polarity = irq_polarity(idx);
808 811
809 entry.delivery_mode = INT_DELIVERY_MODE; 812 if (irq_trigger(idx)) {
810 entry.dest_mode = INT_DEST_MODE; 813 entry.trigger = 1;
811 entry.mask = 0; /* enable IRQ */ 814 entry.mask = 1;
812 entry.dest.logical.logical_dest = cpu_mask_to_apicid(TARGET_CPUS); 815 entry.dest.logical.logical_dest = cpu_mask_to_apicid(TARGET_CPUS);
816 }
817
818 if (!apic && !IO_APIC_IRQ(irq))
819 return;
820
821 if (IO_APIC_IRQ(irq)) {
822 cpumask_t mask;
823 vector = assign_irq_vector(irq, TARGET_CPUS, &mask);
824 if (vector < 0)
825 return;
826
827 entry.dest.logical.logical_dest = cpu_mask_to_apicid(mask);
828 entry.vector = vector;
829
830 ioapic_register_intr(irq, vector, IOAPIC_AUTO);
831 if (!apic && (irq < 16))
832 disable_8259A_irq(irq);
833 }
834
835 ioapic_write_entry(apic, pin, entry);
836
837 spin_lock_irqsave(&ioapic_lock, flags);
838 set_native_irq_info(irq, TARGET_CPUS);
839 spin_unlock_irqrestore(&ioapic_lock, flags);
840
841}
842
843static void __init setup_IO_APIC_irqs(void)
844{
845 int apic, pin, idx, irq, first_notcon = 1;
846
847 apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n");
848
849 for (apic = 0; apic < nr_ioapics; apic++) {
850 for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) {
813 851
814 idx = find_irq_entry(apic,pin,mp_INT); 852 idx = find_irq_entry(apic,pin,mp_INT);
815 if (idx == -1) { 853 if (idx == -1) {
@@ -821,39 +859,11 @@ static void __init setup_IO_APIC_irqs(void)
821 continue; 859 continue;
822 } 860 }
823 861
824 entry.trigger = irq_trigger(idx);
825 entry.polarity = irq_polarity(idx);
826
827 if (irq_trigger(idx)) {
828 entry.trigger = 1;
829 entry.mask = 1;
830 entry.dest.logical.logical_dest = cpu_mask_to_apicid(TARGET_CPUS);
831 }
832
833 irq = pin_2_irq(idx, apic, pin); 862 irq = pin_2_irq(idx, apic, pin);
834 add_pin_to_irq(irq, apic, pin); 863 add_pin_to_irq(irq, apic, pin);
835 864
836 if (!apic && !IO_APIC_IRQ(irq)) 865 setup_IO_APIC_irq(apic, pin, idx, irq);
837 continue;
838 866
839 if (IO_APIC_IRQ(irq)) {
840 cpumask_t mask;
841 vector = assign_irq_vector(irq, TARGET_CPUS, &mask);
842 if (vector < 0)
843 continue;
844
845 entry.dest.logical.logical_dest = cpu_mask_to_apicid(mask);
846 entry.vector = vector;
847
848 ioapic_register_intr(irq, vector, IOAPIC_AUTO);
849 if (!apic && (irq < 16))
850 disable_8259A_irq(irq);
851 }
852 ioapic_write_entry(apic, pin, entry);
853
854 spin_lock_irqsave(&ioapic_lock, flags);
855 set_native_irq_info(irq, TARGET_CPUS);
856 spin_unlock_irqrestore(&ioapic_lock, flags);
857 } 867 }
858 } 868 }
859 869
@@ -2139,7 +2149,15 @@ void __init setup_ioapic_dest(void)
2139 if (irq_entry == -1) 2149 if (irq_entry == -1)
2140 continue; 2150 continue;
2141 irq = pin_2_irq(irq_entry, ioapic, pin); 2151 irq = pin_2_irq(irq_entry, ioapic, pin);
2142 set_ioapic_affinity_irq(irq, TARGET_CPUS); 2152
2153 /* setup_IO_APIC_irqs could fail to get vector for some device
2154 * when you have too many devices, because at that time only boot
2155 * cpu is online.
2156 */
2157 if(!irq_vector[irq])
2158 setup_IO_APIC_irq(ioapic, pin, irq_entry, irq);
2159 else
2160 set_ioapic_affinity_irq(irq, TARGET_CPUS);
2143 } 2161 }
2144 2162
2145 } 2163 }