diff options
Diffstat (limited to 'arch/i386/kernel/io_apic.c')
-rw-r--r-- | arch/i386/kernel/io_apic.c | 65 |
1 files changed, 35 insertions, 30 deletions
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index 44c5a3206b2a..e21dcde0790e 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c | |||
@@ -154,14 +154,20 @@ static struct IO_APIC_route_entry ioapic_read_entry(int apic, int pin) | |||
154 | * the interrupt, and we need to make sure the entry is fully populated | 154 | * the interrupt, and we need to make sure the entry is fully populated |
155 | * before that happens. | 155 | * before that happens. |
156 | */ | 156 | */ |
157 | static void ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e) | 157 | static void |
158 | __ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e) | ||
158 | { | 159 | { |
159 | unsigned long flags; | ||
160 | union entry_union eu; | 160 | union entry_union eu; |
161 | eu.entry = e; | 161 | eu.entry = e; |
162 | spin_lock_irqsave(&ioapic_lock, flags); | ||
163 | io_apic_write(apic, 0x11 + 2*pin, eu.w2); | 162 | io_apic_write(apic, 0x11 + 2*pin, eu.w2); |
164 | io_apic_write(apic, 0x10 + 2*pin, eu.w1); | 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); | ||
165 | spin_unlock_irqrestore(&ioapic_lock, flags); | 171 | spin_unlock_irqrestore(&ioapic_lock, flags); |
166 | } | 172 | } |
167 | 173 | ||
@@ -837,8 +843,7 @@ static int __init find_isa_irq_pin(int irq, int type) | |||
837 | 843 | ||
838 | if ((mp_bus_id_to_type[lbus] == MP_BUS_ISA || | 844 | if ((mp_bus_id_to_type[lbus] == MP_BUS_ISA || |
839 | mp_bus_id_to_type[lbus] == MP_BUS_EISA || | 845 | mp_bus_id_to_type[lbus] == MP_BUS_EISA || |
840 | mp_bus_id_to_type[lbus] == MP_BUS_MCA || | 846 | mp_bus_id_to_type[lbus] == MP_BUS_MCA |
841 | mp_bus_id_to_type[lbus] == MP_BUS_NEC98 | ||
842 | ) && | 847 | ) && |
843 | (mp_irqs[i].mpc_irqtype == type) && | 848 | (mp_irqs[i].mpc_irqtype == type) && |
844 | (mp_irqs[i].mpc_srcbusirq == irq)) | 849 | (mp_irqs[i].mpc_srcbusirq == irq)) |
@@ -857,8 +862,7 @@ static int __init find_isa_irq_apic(int irq, int type) | |||
857 | 862 | ||
858 | if ((mp_bus_id_to_type[lbus] == MP_BUS_ISA || | 863 | if ((mp_bus_id_to_type[lbus] == MP_BUS_ISA || |
859 | mp_bus_id_to_type[lbus] == MP_BUS_EISA || | 864 | mp_bus_id_to_type[lbus] == MP_BUS_EISA || |
860 | mp_bus_id_to_type[lbus] == MP_BUS_MCA || | 865 | mp_bus_id_to_type[lbus] == MP_BUS_MCA |
861 | mp_bus_id_to_type[lbus] == MP_BUS_NEC98 | ||
862 | ) && | 866 | ) && |
863 | (mp_irqs[i].mpc_irqtype == type) && | 867 | (mp_irqs[i].mpc_irqtype == type) && |
864 | (mp_irqs[i].mpc_srcbusirq == irq)) | 868 | (mp_irqs[i].mpc_srcbusirq == irq)) |
@@ -988,12 +992,6 @@ static int EISA_ELCR(unsigned int irq) | |||
988 | #define default_MCA_trigger(idx) (1) | 992 | #define default_MCA_trigger(idx) (1) |
989 | #define default_MCA_polarity(idx) (0) | 993 | #define default_MCA_polarity(idx) (0) |
990 | 994 | ||
991 | /* NEC98 interrupts are always polarity zero edge triggered, | ||
992 | * when listed as conforming in the MP table. */ | ||
993 | |||
994 | #define default_NEC98_trigger(idx) (0) | ||
995 | #define default_NEC98_polarity(idx) (0) | ||
996 | |||
997 | static int __init MPBIOS_polarity(int idx) | 995 | static int __init MPBIOS_polarity(int idx) |
998 | { | 996 | { |
999 | int bus = mp_irqs[idx].mpc_srcbus; | 997 | int bus = mp_irqs[idx].mpc_srcbus; |
@@ -1028,11 +1026,6 @@ static int __init MPBIOS_polarity(int idx) | |||
1028 | polarity = default_MCA_polarity(idx); | 1026 | polarity = default_MCA_polarity(idx); |
1029 | break; | 1027 | break; |
1030 | } | 1028 | } |
1031 | case MP_BUS_NEC98: /* NEC 98 pin */ | ||
1032 | { | ||
1033 | polarity = default_NEC98_polarity(idx); | ||
1034 | break; | ||
1035 | } | ||
1036 | default: | 1029 | default: |
1037 | { | 1030 | { |
1038 | printk(KERN_WARNING "broken BIOS!!\n"); | 1031 | printk(KERN_WARNING "broken BIOS!!\n"); |
@@ -1102,11 +1095,6 @@ static int MPBIOS_trigger(int idx) | |||
1102 | trigger = default_MCA_trigger(idx); | 1095 | trigger = default_MCA_trigger(idx); |
1103 | break; | 1096 | break; |
1104 | } | 1097 | } |
1105 | case MP_BUS_NEC98: /* NEC 98 pin */ | ||
1106 | { | ||
1107 | trigger = default_NEC98_trigger(idx); | ||
1108 | break; | ||
1109 | } | ||
1110 | default: | 1098 | default: |
1111 | { | 1099 | { |
1112 | printk(KERN_WARNING "broken BIOS!!\n"); | 1100 | printk(KERN_WARNING "broken BIOS!!\n"); |
@@ -1168,7 +1156,6 @@ static int pin_2_irq(int idx, int apic, int pin) | |||
1168 | case MP_BUS_ISA: /* ISA pin */ | 1156 | case MP_BUS_ISA: /* ISA pin */ |
1169 | case MP_BUS_EISA: | 1157 | case MP_BUS_EISA: |
1170 | case MP_BUS_MCA: | 1158 | case MP_BUS_MCA: |
1171 | case MP_BUS_NEC98: | ||
1172 | { | 1159 | { |
1173 | irq = mp_irqs[idx].mpc_srcbusirq; | 1160 | irq = mp_irqs[idx].mpc_srcbusirq; |
1174 | break; | 1161 | break; |
@@ -1236,7 +1223,7 @@ static inline int IO_APIC_irq_trigger(int irq) | |||
1236 | } | 1223 | } |
1237 | 1224 | ||
1238 | /* 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. */ |
1239 | 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 }; |
1240 | 1227 | ||
1241 | static int __assign_irq_vector(int irq) | 1228 | static int __assign_irq_vector(int irq) |
1242 | { | 1229 | { |
@@ -1361,8 +1348,8 @@ static void __init setup_IO_APIC_irqs(void) | |||
1361 | if (!apic && (irq < 16)) | 1348 | if (!apic && (irq < 16)) |
1362 | disable_8259A_irq(irq); | 1349 | disable_8259A_irq(irq); |
1363 | } | 1350 | } |
1364 | ioapic_write_entry(apic, pin, entry); | ||
1365 | spin_lock_irqsave(&ioapic_lock, flags); | 1351 | spin_lock_irqsave(&ioapic_lock, flags); |
1352 | __ioapic_write_entry(apic, pin, entry); | ||
1366 | set_native_irq_info(irq, TARGET_CPUS); | 1353 | set_native_irq_info(irq, TARGET_CPUS); |
1367 | spin_unlock_irqrestore(&ioapic_lock, flags); | 1354 | spin_unlock_irqrestore(&ioapic_lock, flags); |
1368 | } | 1355 | } |
@@ -1927,6 +1914,15 @@ static void __init setup_ioapic_ids_from_mpc(void) | |||
1927 | static void __init setup_ioapic_ids_from_mpc(void) { } | 1914 | static void __init setup_ioapic_ids_from_mpc(void) { } |
1928 | #endif | 1915 | #endif |
1929 | 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 | |||
1930 | /* | 1926 | /* |
1931 | * 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 |
1932 | * 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: |
@@ -1935,10 +1931,13 @@ static void __init setup_ioapic_ids_from_mpc(void) { } | |||
1935 | * - 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 |
1936 | * back to ISA timer IRQs | 1932 | * back to ISA timer IRQs |
1937 | */ | 1933 | */ |
1938 | static int __init timer_irq_works(void) | 1934 | int __init timer_irq_works(void) |
1939 | { | 1935 | { |
1940 | unsigned long t1 = jiffies; | 1936 | unsigned long t1 = jiffies; |
1941 | 1937 | ||
1938 | if (no_timer_check) | ||
1939 | return 1; | ||
1940 | |||
1942 | local_irq_enable(); | 1941 | local_irq_enable(); |
1943 | /* Let ten ticks pass... */ | 1942 | /* Let ten ticks pass... */ |
1944 | mdelay((10 * 1000) / HZ); | 1943 | mdelay((10 * 1000) / HZ); |
@@ -2162,9 +2161,15 @@ static inline void unlock_ExtINT_logic(void) | |||
2162 | unsigned char save_control, save_freq_select; | 2161 | unsigned char save_control, save_freq_select; |
2163 | 2162 | ||
2164 | 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 | } | ||
2165 | apic = find_isa_irq_apic(8, mp_INT); | 2168 | apic = find_isa_irq_apic(8, mp_INT); |
2166 | if (pin == -1) | 2169 | if (apic == -1) { |
2170 | WARN_ON_ONCE(1); | ||
2167 | return; | 2171 | return; |
2172 | } | ||
2168 | 2173 | ||
2169 | entry0 = ioapic_read_entry(apic, pin); | 2174 | entry0 = ioapic_read_entry(apic, pin); |
2170 | clear_IO_APIC_pin(apic, pin); | 2175 | clear_IO_APIC_pin(apic, pin); |
@@ -2209,7 +2214,7 @@ int timer_uses_ioapic_pin_0; | |||
2209 | * 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 |
2210 | * fanatically on his truly buggy board. | 2215 | * fanatically on his truly buggy board. |
2211 | */ | 2216 | */ |
2212 | static inline void check_timer(void) | 2217 | static inline void __init check_timer(void) |
2213 | { | 2218 | { |
2214 | int apic1, pin1, apic2, pin2; | 2219 | int apic1, pin1, apic2, pin2; |
2215 | int vector; | 2220 | int vector; |
@@ -2857,8 +2862,8 @@ int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int a | |||
2857 | if (!ioapic && (irq < 16)) | 2862 | if (!ioapic && (irq < 16)) |
2858 | disable_8259A_irq(irq); | 2863 | disable_8259A_irq(irq); |
2859 | 2864 | ||
2860 | ioapic_write_entry(ioapic, pin, entry); | ||
2861 | spin_lock_irqsave(&ioapic_lock, flags); | 2865 | spin_lock_irqsave(&ioapic_lock, flags); |
2866 | __ioapic_write_entry(ioapic, pin, entry); | ||
2862 | set_native_irq_info(irq, TARGET_CPUS); | 2867 | set_native_irq_info(irq, TARGET_CPUS); |
2863 | spin_unlock_irqrestore(&ioapic_lock, flags); | 2868 | spin_unlock_irqrestore(&ioapic_lock, flags); |
2864 | 2869 | ||