diff options
Diffstat (limited to 'arch/i386/kernel/io_apic.c')
-rw-r--r-- | arch/i386/kernel/io_apic.c | 179 |
1 files changed, 124 insertions, 55 deletions
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index 27bceaf5ce40..2424cc9c7b3d 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/pci.h> | 34 | #include <linux/pci.h> |
35 | #include <linux/msi.h> | 35 | #include <linux/msi.h> |
36 | #include <linux/htirq.h> | 36 | #include <linux/htirq.h> |
37 | #include <linux/freezer.h> | ||
37 | 38 | ||
38 | #include <asm/io.h> | 39 | #include <asm/io.h> |
39 | #include <asm/smp.h> | 40 | #include <asm/smp.h> |
@@ -91,6 +92,46 @@ static struct irq_pin_list { | |||
91 | int apic, pin, next; | 92 | int apic, pin, next; |
92 | } irq_2_pin[PIN_MAP_SIZE]; | 93 | } irq_2_pin[PIN_MAP_SIZE]; |
93 | 94 | ||
95 | struct io_apic { | ||
96 | unsigned int index; | ||
97 | unsigned int unused[3]; | ||
98 | unsigned int data; | ||
99 | }; | ||
100 | |||
101 | static __attribute_const__ struct io_apic __iomem *io_apic_base(int idx) | ||
102 | { | ||
103 | return (void __iomem *) __fix_to_virt(FIX_IO_APIC_BASE_0 + idx) | ||
104 | + (mp_ioapics[idx].mpc_apicaddr & ~PAGE_MASK); | ||
105 | } | ||
106 | |||
107 | static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg) | ||
108 | { | ||
109 | struct io_apic __iomem *io_apic = io_apic_base(apic); | ||
110 | writel(reg, &io_apic->index); | ||
111 | return readl(&io_apic->data); | ||
112 | } | ||
113 | |||
114 | static inline void io_apic_write(unsigned int apic, unsigned int reg, unsigned int value) | ||
115 | { | ||
116 | struct io_apic __iomem *io_apic = io_apic_base(apic); | ||
117 | writel(reg, &io_apic->index); | ||
118 | writel(value, &io_apic->data); | ||
119 | } | ||
120 | |||
121 | /* | ||
122 | * Re-write a value: to be used for read-modify-write | ||
123 | * cycles where the read already set up the index register. | ||
124 | * | ||
125 | * Older SiS APIC requires we rewrite the index register | ||
126 | */ | ||
127 | static inline void io_apic_modify(unsigned int apic, unsigned int reg, unsigned int value) | ||
128 | { | ||
129 | volatile struct io_apic *io_apic = io_apic_base(apic); | ||
130 | if (sis_apic_bug) | ||
131 | writel(reg, &io_apic->index); | ||
132 | writel(value, &io_apic->data); | ||
133 | } | ||
134 | |||
94 | union entry_union { | 135 | union entry_union { |
95 | struct { u32 w1, w2; }; | 136 | struct { u32 w1, w2; }; |
96 | struct IO_APIC_route_entry entry; | 137 | struct IO_APIC_route_entry entry; |
@@ -107,11 +148,39 @@ static struct IO_APIC_route_entry ioapic_read_entry(int apic, int pin) | |||
107 | return eu.entry; | 148 | return eu.entry; |
108 | } | 149 | } |
109 | 150 | ||
110 | static void ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e) | 151 | /* |
152 | * When we write a new IO APIC routing entry, we need to write the high | ||
153 | * word first! If the mask bit in the low word is clear, we will enable | ||
154 | * the interrupt, and we need to make sure the entry is fully populated | ||
155 | * before that happens. | ||
156 | */ | ||
157 | static void | ||
158 | __ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e) | ||
111 | { | 159 | { |
112 | unsigned long flags; | ||
113 | union entry_union eu; | 160 | union entry_union eu; |
114 | eu.entry = e; | 161 | eu.entry = e; |
162 | io_apic_write(apic, 0x11 + 2*pin, eu.w2); | ||
163 | io_apic_write(apic, 0x10 + 2*pin, eu.w1); | ||
164 | } | ||
165 | |||
166 | static void ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e) | ||
167 | { | ||
168 | unsigned long flags; | ||
169 | spin_lock_irqsave(&ioapic_lock, flags); | ||
170 | __ioapic_write_entry(apic, pin, e); | ||
171 | spin_unlock_irqrestore(&ioapic_lock, flags); | ||
172 | } | ||
173 | |||
174 | /* | ||
175 | * When we mask an IO APIC routing entry, we need to write the low | ||
176 | * word first, in order to set the mask bit before we change the | ||
177 | * high bits! | ||
178 | */ | ||
179 | static void ioapic_mask_entry(int apic, int pin) | ||
180 | { | ||
181 | unsigned long flags; | ||
182 | union entry_union eu = { .entry.mask = 1 }; | ||
183 | |||
115 | spin_lock_irqsave(&ioapic_lock, flags); | 184 | spin_lock_irqsave(&ioapic_lock, flags); |
116 | io_apic_write(apic, 0x10 + 2*pin, eu.w1); | 185 | io_apic_write(apic, 0x10 + 2*pin, eu.w1); |
117 | io_apic_write(apic, 0x11 + 2*pin, eu.w2); | 186 | io_apic_write(apic, 0x11 + 2*pin, eu.w2); |
@@ -234,9 +303,7 @@ static void clear_IO_APIC_pin(unsigned int apic, unsigned int pin) | |||
234 | /* | 303 | /* |
235 | * Disable it in the IO-APIC irq-routing table: | 304 | * Disable it in the IO-APIC irq-routing table: |
236 | */ | 305 | */ |
237 | memset(&entry, 0, sizeof(entry)); | 306 | ioapic_mask_entry(apic, pin); |
238 | entry.mask = 1; | ||
239 | ioapic_write_entry(apic, pin, entry); | ||
240 | } | 307 | } |
241 | 308 | ||
242 | static void clear_IO_APIC (void) | 309 | static void clear_IO_APIC (void) |
@@ -776,8 +843,7 @@ static int __init find_isa_irq_pin(int irq, int type) | |||
776 | 843 | ||
777 | if ((mp_bus_id_to_type[lbus] == MP_BUS_ISA || | 844 | if ((mp_bus_id_to_type[lbus] == MP_BUS_ISA || |
778 | mp_bus_id_to_type[lbus] == MP_BUS_EISA || | 845 | mp_bus_id_to_type[lbus] == MP_BUS_EISA || |
779 | mp_bus_id_to_type[lbus] == MP_BUS_MCA || | 846 | mp_bus_id_to_type[lbus] == MP_BUS_MCA |
780 | mp_bus_id_to_type[lbus] == MP_BUS_NEC98 | ||
781 | ) && | 847 | ) && |
782 | (mp_irqs[i].mpc_irqtype == type) && | 848 | (mp_irqs[i].mpc_irqtype == type) && |
783 | (mp_irqs[i].mpc_srcbusirq == irq)) | 849 | (mp_irqs[i].mpc_srcbusirq == irq)) |
@@ -796,8 +862,7 @@ static int __init find_isa_irq_apic(int irq, int type) | |||
796 | 862 | ||
797 | if ((mp_bus_id_to_type[lbus] == MP_BUS_ISA || | 863 | if ((mp_bus_id_to_type[lbus] == MP_BUS_ISA || |
798 | mp_bus_id_to_type[lbus] == MP_BUS_EISA || | 864 | mp_bus_id_to_type[lbus] == MP_BUS_EISA || |
799 | mp_bus_id_to_type[lbus] == MP_BUS_MCA || | 865 | mp_bus_id_to_type[lbus] == MP_BUS_MCA |
800 | mp_bus_id_to_type[lbus] == MP_BUS_NEC98 | ||
801 | ) && | 866 | ) && |
802 | (mp_irqs[i].mpc_irqtype == type) && | 867 | (mp_irqs[i].mpc_irqtype == type) && |
803 | (mp_irqs[i].mpc_srcbusirq == irq)) | 868 | (mp_irqs[i].mpc_srcbusirq == irq)) |
@@ -927,12 +992,6 @@ static int EISA_ELCR(unsigned int irq) | |||
927 | #define default_MCA_trigger(idx) (1) | 992 | #define default_MCA_trigger(idx) (1) |
928 | #define default_MCA_polarity(idx) (0) | 993 | #define default_MCA_polarity(idx) (0) |
929 | 994 | ||
930 | /* NEC98 interrupts are always polarity zero edge triggered, | ||
931 | * when listed as conforming in the MP table. */ | ||
932 | |||
933 | #define default_NEC98_trigger(idx) (0) | ||
934 | #define default_NEC98_polarity(idx) (0) | ||
935 | |||
936 | static int __init MPBIOS_polarity(int idx) | 995 | static int __init MPBIOS_polarity(int idx) |
937 | { | 996 | { |
938 | int bus = mp_irqs[idx].mpc_srcbus; | 997 | int bus = mp_irqs[idx].mpc_srcbus; |
@@ -967,11 +1026,6 @@ static int __init MPBIOS_polarity(int idx) | |||
967 | polarity = default_MCA_polarity(idx); | 1026 | polarity = default_MCA_polarity(idx); |
968 | break; | 1027 | break; |
969 | } | 1028 | } |
970 | case MP_BUS_NEC98: /* NEC 98 pin */ | ||
971 | { | ||
972 | polarity = default_NEC98_polarity(idx); | ||
973 | break; | ||
974 | } | ||
975 | default: | 1029 | default: |
976 | { | 1030 | { |
977 | printk(KERN_WARNING "broken BIOS!!\n"); | 1031 | printk(KERN_WARNING "broken BIOS!!\n"); |
@@ -1041,11 +1095,6 @@ static int MPBIOS_trigger(int idx) | |||
1041 | trigger = default_MCA_trigger(idx); | 1095 | trigger = default_MCA_trigger(idx); |
1042 | break; | 1096 | break; |
1043 | } | 1097 | } |
1044 | case MP_BUS_NEC98: /* NEC 98 pin */ | ||
1045 | { | ||
1046 | trigger = default_NEC98_trigger(idx); | ||
1047 | break; | ||
1048 | } | ||
1049 | default: | 1098 | default: |
1050 | { | 1099 | { |
1051 | printk(KERN_WARNING "broken BIOS!!\n"); | 1100 | printk(KERN_WARNING "broken BIOS!!\n"); |
@@ -1107,7 +1156,6 @@ static int pin_2_irq(int idx, int apic, int pin) | |||
1107 | case MP_BUS_ISA: /* ISA pin */ | 1156 | case MP_BUS_ISA: /* ISA pin */ |
1108 | case MP_BUS_EISA: | 1157 | case MP_BUS_EISA: |
1109 | case MP_BUS_MCA: | 1158 | case MP_BUS_MCA: |
1110 | case MP_BUS_NEC98: | ||
1111 | { | 1159 | { |
1112 | irq = mp_irqs[idx].mpc_srcbusirq; | 1160 | irq = mp_irqs[idx].mpc_srcbusirq; |
1113 | break; | 1161 | break; |
@@ -1175,7 +1223,7 @@ static inline int IO_APIC_irq_trigger(int irq) | |||
1175 | } | 1223 | } |
1176 | 1224 | ||
1177 | /* irq_vectors is indexed by the sum of all RTEs in all I/O APICs. */ | 1225 | /* irq_vectors is indexed by the sum of all RTEs in all I/O APICs. */ |
1178 | u8 irq_vector[NR_IRQ_VECTORS] __read_mostly = { FIRST_DEVICE_VECTOR , 0 }; | 1226 | static u8 irq_vector[NR_IRQ_VECTORS] __read_mostly = { FIRST_DEVICE_VECTOR , 0 }; |
1179 | 1227 | ||
1180 | static int __assign_irq_vector(int irq) | 1228 | static int __assign_irq_vector(int irq) |
1181 | { | 1229 | { |
@@ -1225,11 +1273,13 @@ static void ioapic_register_intr(int irq, int vector, unsigned long trigger) | |||
1225 | { | 1273 | { |
1226 | if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || | 1274 | if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || |
1227 | trigger == IOAPIC_LEVEL) | 1275 | trigger == IOAPIC_LEVEL) |
1228 | set_irq_chip_and_handler(irq, &ioapic_chip, | 1276 | set_irq_chip_and_handler_name(irq, &ioapic_chip, |
1229 | handle_fasteoi_irq); | 1277 | handle_fasteoi_irq, "fasteoi"); |
1230 | else | 1278 | else { |
1231 | set_irq_chip_and_handler(irq, &ioapic_chip, | 1279 | irq_desc[irq].status |= IRQ_DELAYED_DISABLE; |
1232 | handle_edge_irq); | 1280 | set_irq_chip_and_handler_name(irq, &ioapic_chip, |
1281 | handle_edge_irq, "edge"); | ||
1282 | } | ||
1233 | set_intr_gate(vector, interrupt[irq]); | 1283 | set_intr_gate(vector, interrupt[irq]); |
1234 | } | 1284 | } |
1235 | 1285 | ||
@@ -1298,8 +1348,8 @@ static void __init setup_IO_APIC_irqs(void) | |||
1298 | if (!apic && (irq < 16)) | 1348 | if (!apic && (irq < 16)) |
1299 | disable_8259A_irq(irq); | 1349 | disable_8259A_irq(irq); |
1300 | } | 1350 | } |
1301 | ioapic_write_entry(apic, pin, entry); | ||
1302 | spin_lock_irqsave(&ioapic_lock, flags); | 1351 | spin_lock_irqsave(&ioapic_lock, flags); |
1352 | __ioapic_write_entry(apic, pin, entry); | ||
1303 | set_native_irq_info(irq, TARGET_CPUS); | 1353 | set_native_irq_info(irq, TARGET_CPUS); |
1304 | spin_unlock_irqrestore(&ioapic_lock, flags); | 1354 | spin_unlock_irqrestore(&ioapic_lock, flags); |
1305 | } | 1355 | } |
@@ -1864,6 +1914,15 @@ static void __init setup_ioapic_ids_from_mpc(void) | |||
1864 | static void __init setup_ioapic_ids_from_mpc(void) { } | 1914 | static void __init setup_ioapic_ids_from_mpc(void) { } |
1865 | #endif | 1915 | #endif |
1866 | 1916 | ||
1917 | static int no_timer_check __initdata; | ||
1918 | |||
1919 | static int __init notimercheck(char *s) | ||
1920 | { | ||
1921 | no_timer_check = 1; | ||
1922 | return 1; | ||
1923 | } | ||
1924 | __setup("no_timer_check", notimercheck); | ||
1925 | |||
1867 | /* | 1926 | /* |
1868 | * There is a nasty bug in some older SMP boards, their mptable lies | 1927 | * There is a nasty bug in some older SMP boards, their mptable lies |
1869 | * about the timer IRQ. We do the following to work around the situation: | 1928 | * about the timer IRQ. We do the following to work around the situation: |
@@ -1872,10 +1931,13 @@ static void __init setup_ioapic_ids_from_mpc(void) { } | |||
1872 | * - if this function detects that timer IRQs are defunct, then we fall | 1931 | * - if this function detects that timer IRQs are defunct, then we fall |
1873 | * back to ISA timer IRQs | 1932 | * back to ISA timer IRQs |
1874 | */ | 1933 | */ |
1875 | static int __init timer_irq_works(void) | 1934 | int __init timer_irq_works(void) |
1876 | { | 1935 | { |
1877 | unsigned long t1 = jiffies; | 1936 | unsigned long t1 = jiffies; |
1878 | 1937 | ||
1938 | if (no_timer_check) | ||
1939 | return 1; | ||
1940 | |||
1879 | local_irq_enable(); | 1941 | local_irq_enable(); |
1880 | /* Let ten ticks pass... */ | 1942 | /* Let ten ticks pass... */ |
1881 | mdelay((10 * 1000) / HZ); | 1943 | mdelay((10 * 1000) / HZ); |
@@ -2099,9 +2161,15 @@ static inline void unlock_ExtINT_logic(void) | |||
2099 | unsigned char save_control, save_freq_select; | 2161 | unsigned char save_control, save_freq_select; |
2100 | 2162 | ||
2101 | pin = find_isa_irq_pin(8, mp_INT); | 2163 | pin = find_isa_irq_pin(8, mp_INT); |
2164 | if (pin == -1) { | ||
2165 | WARN_ON_ONCE(1); | ||
2166 | return; | ||
2167 | } | ||
2102 | apic = find_isa_irq_apic(8, mp_INT); | 2168 | apic = find_isa_irq_apic(8, mp_INT); |
2103 | if (pin == -1) | 2169 | if (apic == -1) { |
2170 | WARN_ON_ONCE(1); | ||
2104 | return; | 2171 | return; |
2172 | } | ||
2105 | 2173 | ||
2106 | entry0 = ioapic_read_entry(apic, pin); | 2174 | entry0 = ioapic_read_entry(apic, pin); |
2107 | clear_IO_APIC_pin(apic, pin); | 2175 | clear_IO_APIC_pin(apic, pin); |
@@ -2146,7 +2214,7 @@ int timer_uses_ioapic_pin_0; | |||
2146 | * is so screwy. Thanks to Brian Perkins for testing/hacking this beast | 2214 | * is so screwy. Thanks to Brian Perkins for testing/hacking this beast |
2147 | * fanatically on his truly buggy board. | 2215 | * fanatically on his truly buggy board. |
2148 | */ | 2216 | */ |
2149 | static inline void check_timer(void) | 2217 | static inline void __init check_timer(void) |
2150 | { | 2218 | { |
2151 | int apic1, pin1, apic2, pin2; | 2219 | int apic1, pin1, apic2, pin2; |
2152 | int vector; | 2220 | int vector; |
@@ -2235,7 +2303,8 @@ static inline void check_timer(void) | |||
2235 | printk(KERN_INFO "...trying to set up timer as Virtual Wire IRQ..."); | 2303 | printk(KERN_INFO "...trying to set up timer as Virtual Wire IRQ..."); |
2236 | 2304 | ||
2237 | disable_8259A_irq(0); | 2305 | disable_8259A_irq(0); |
2238 | set_irq_chip_and_handler(0, &lapic_chip, handle_fasteoi_irq); | 2306 | set_irq_chip_and_handler_name(0, &lapic_chip, handle_fasteoi_irq, |
2307 | "fasteio"); | ||
2239 | apic_write_around(APIC_LVT0, APIC_DM_FIXED | vector); /* Fixed mode */ | 2308 | apic_write_around(APIC_LVT0, APIC_DM_FIXED | vector); /* Fixed mode */ |
2240 | enable_8259A_irq(0); | 2309 | enable_8259A_irq(0); |
2241 | 2310 | ||
@@ -2416,7 +2485,7 @@ device_initcall(ioapic_init_sysfs); | |||
2416 | int create_irq(void) | 2485 | int create_irq(void) |
2417 | { | 2486 | { |
2418 | /* Allocate an unused irq */ | 2487 | /* Allocate an unused irq */ |
2419 | int irq, new, vector; | 2488 | int irq, new, vector = 0; |
2420 | unsigned long flags; | 2489 | unsigned long flags; |
2421 | 2490 | ||
2422 | irq = -ENOSPC; | 2491 | irq = -ENOSPC; |
@@ -2541,7 +2610,8 @@ int arch_setup_msi_irq(unsigned int irq, struct pci_dev *dev) | |||
2541 | 2610 | ||
2542 | write_msi_msg(irq, &msg); | 2611 | write_msi_msg(irq, &msg); |
2543 | 2612 | ||
2544 | set_irq_chip_and_handler(irq, &msi_chip, handle_edge_irq); | 2613 | set_irq_chip_and_handler_name(irq, &msi_chip, handle_edge_irq, |
2614 | "edge"); | ||
2545 | 2615 | ||
2546 | return 0; | 2616 | return 0; |
2547 | } | 2617 | } |
@@ -2562,18 +2632,16 @@ void arch_teardown_msi_irq(unsigned int irq) | |||
2562 | 2632 | ||
2563 | static void target_ht_irq(unsigned int irq, unsigned int dest) | 2633 | static void target_ht_irq(unsigned int irq, unsigned int dest) |
2564 | { | 2634 | { |
2565 | u32 low, high; | 2635 | struct ht_irq_msg msg; |
2566 | low = read_ht_irq_low(irq); | 2636 | fetch_ht_irq_msg(irq, &msg); |
2567 | high = read_ht_irq_high(irq); | ||
2568 | 2637 | ||
2569 | low &= ~(HT_IRQ_LOW_DEST_ID_MASK); | 2638 | msg.address_lo &= ~(HT_IRQ_LOW_DEST_ID_MASK); |
2570 | high &= ~(HT_IRQ_HIGH_DEST_ID_MASK); | 2639 | msg.address_hi &= ~(HT_IRQ_HIGH_DEST_ID_MASK); |
2571 | 2640 | ||
2572 | low |= HT_IRQ_LOW_DEST_ID(dest); | 2641 | msg.address_lo |= HT_IRQ_LOW_DEST_ID(dest); |
2573 | high |= HT_IRQ_HIGH_DEST_ID(dest); | 2642 | msg.address_hi |= HT_IRQ_HIGH_DEST_ID(dest); |
2574 | 2643 | ||
2575 | write_ht_irq_low(irq, low); | 2644 | write_ht_irq_msg(irq, &msg); |
2576 | write_ht_irq_high(irq, high); | ||
2577 | } | 2645 | } |
2578 | 2646 | ||
2579 | static void set_ht_irq_affinity(unsigned int irq, cpumask_t mask) | 2647 | static void set_ht_irq_affinity(unsigned int irq, cpumask_t mask) |
@@ -2611,7 +2679,7 @@ int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev) | |||
2611 | 2679 | ||
2612 | vector = assign_irq_vector(irq); | 2680 | vector = assign_irq_vector(irq); |
2613 | if (vector >= 0) { | 2681 | if (vector >= 0) { |
2614 | u32 low, high; | 2682 | struct ht_irq_msg msg; |
2615 | unsigned dest; | 2683 | unsigned dest; |
2616 | cpumask_t tmp; | 2684 | cpumask_t tmp; |
2617 | 2685 | ||
@@ -2619,9 +2687,10 @@ int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev) | |||
2619 | cpu_set(vector >> 8, tmp); | 2687 | cpu_set(vector >> 8, tmp); |
2620 | dest = cpu_mask_to_apicid(tmp); | 2688 | dest = cpu_mask_to_apicid(tmp); |
2621 | 2689 | ||
2622 | high = HT_IRQ_HIGH_DEST_ID(dest); | 2690 | msg.address_hi = HT_IRQ_HIGH_DEST_ID(dest); |
2623 | 2691 | ||
2624 | low = HT_IRQ_LOW_BASE | | 2692 | msg.address_lo = |
2693 | HT_IRQ_LOW_BASE | | ||
2625 | HT_IRQ_LOW_DEST_ID(dest) | | 2694 | HT_IRQ_LOW_DEST_ID(dest) | |
2626 | HT_IRQ_LOW_VECTOR(vector) | | 2695 | HT_IRQ_LOW_VECTOR(vector) | |
2627 | ((INT_DEST_MODE == 0) ? | 2696 | ((INT_DEST_MODE == 0) ? |
@@ -2633,10 +2702,10 @@ int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev) | |||
2633 | HT_IRQ_LOW_MT_ARBITRATED) | | 2702 | HT_IRQ_LOW_MT_ARBITRATED) | |
2634 | HT_IRQ_LOW_IRQ_MASKED; | 2703 | HT_IRQ_LOW_IRQ_MASKED; |
2635 | 2704 | ||
2636 | write_ht_irq_low(irq, low); | 2705 | write_ht_irq_msg(irq, &msg); |
2637 | write_ht_irq_high(irq, high); | ||
2638 | 2706 | ||
2639 | set_irq_chip_and_handler(irq, &ht_irq_chip, handle_edge_irq); | 2707 | set_irq_chip_and_handler_name(irq, &ht_irq_chip, |
2708 | handle_edge_irq, "edge"); | ||
2640 | } | 2709 | } |
2641 | return vector; | 2710 | return vector; |
2642 | } | 2711 | } |
@@ -2793,8 +2862,8 @@ int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int a | |||
2793 | if (!ioapic && (irq < 16)) | 2862 | if (!ioapic && (irq < 16)) |
2794 | disable_8259A_irq(irq); | 2863 | disable_8259A_irq(irq); |
2795 | 2864 | ||
2796 | ioapic_write_entry(ioapic, pin, entry); | ||
2797 | spin_lock_irqsave(&ioapic_lock, flags); | 2865 | spin_lock_irqsave(&ioapic_lock, flags); |
2866 | __ioapic_write_entry(ioapic, pin, entry); | ||
2798 | set_native_irq_info(irq, TARGET_CPUS); | 2867 | set_native_irq_info(irq, TARGET_CPUS); |
2799 | spin_unlock_irqrestore(&ioapic_lock, flags); | 2868 | spin_unlock_irqrestore(&ioapic_lock, flags); |
2800 | 2869 | ||