diff options
author | Joerg Roedel <joerg.roedel@amd.com> | 2010-06-01 03:57:49 -0400 |
---|---|---|
committer | Joerg Roedel <joerg.roedel@amd.com> | 2010-06-01 03:57:49 -0400 |
commit | 1d61e73ab4c7470833241af888939a7aab2b0354 (patch) | |
tree | dd714c2428070a7ea2bf807c2821ac75ff13ec55 /arch/x86/kernel/apic | |
parent | 84fe6c19e4a598e8071e3bd1b2c923454eae1268 (diff) | |
parent | 67a3e12b05e055c0415c556a315a3d3eb637e29e (diff) |
Merge commit 'v2.6.35-rc1' into amd-iommu/2.6.35
Diffstat (limited to 'arch/x86/kernel/apic')
-rw-r--r-- | arch/x86/kernel/apic/apic.c | 41 | ||||
-rw-r--r-- | arch/x86/kernel/apic/es7000_32.c | 19 | ||||
-rw-r--r-- | arch/x86/kernel/apic/io_apic.c | 99 | ||||
-rw-r--r-- | arch/x86/kernel/apic/x2apic_uv_x.c | 3 |
4 files changed, 78 insertions, 84 deletions
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index e5a4a1e01618..c02cc692985c 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c | |||
@@ -51,6 +51,7 @@ | |||
51 | #include <asm/smp.h> | 51 | #include <asm/smp.h> |
52 | #include <asm/mce.h> | 52 | #include <asm/mce.h> |
53 | #include <asm/kvm_para.h> | 53 | #include <asm/kvm_para.h> |
54 | #include <asm/tsc.h> | ||
54 | 55 | ||
55 | unsigned int num_processors; | 56 | unsigned int num_processors; |
56 | 57 | ||
@@ -1151,8 +1152,13 @@ static void __cpuinit lapic_setup_esr(void) | |||
1151 | */ | 1152 | */ |
1152 | void __cpuinit setup_local_APIC(void) | 1153 | void __cpuinit setup_local_APIC(void) |
1153 | { | 1154 | { |
1154 | unsigned int value; | 1155 | unsigned int value, queued; |
1155 | int i, j; | 1156 | int i, j, acked = 0; |
1157 | unsigned long long tsc = 0, ntsc; | ||
1158 | long long max_loops = cpu_khz; | ||
1159 | |||
1160 | if (cpu_has_tsc) | ||
1161 | rdtscll(tsc); | ||
1156 | 1162 | ||
1157 | if (disable_apic) { | 1163 | if (disable_apic) { |
1158 | arch_disable_smp_support(); | 1164 | arch_disable_smp_support(); |
@@ -1204,13 +1210,32 @@ void __cpuinit setup_local_APIC(void) | |||
1204 | * the interrupt. Hence a vector might get locked. It was noticed | 1210 | * the interrupt. Hence a vector might get locked. It was noticed |
1205 | * for timer irq (vector 0x31). Issue an extra EOI to clear ISR. | 1211 | * for timer irq (vector 0x31). Issue an extra EOI to clear ISR. |
1206 | */ | 1212 | */ |
1207 | for (i = APIC_ISR_NR - 1; i >= 0; i--) { | 1213 | do { |
1208 | value = apic_read(APIC_ISR + i*0x10); | 1214 | queued = 0; |
1209 | for (j = 31; j >= 0; j--) { | 1215 | for (i = APIC_ISR_NR - 1; i >= 0; i--) |
1210 | if (value & (1<<j)) | 1216 | queued |= apic_read(APIC_IRR + i*0x10); |
1211 | ack_APIC_irq(); | 1217 | |
1218 | for (i = APIC_ISR_NR - 1; i >= 0; i--) { | ||
1219 | value = apic_read(APIC_ISR + i*0x10); | ||
1220 | for (j = 31; j >= 0; j--) { | ||
1221 | if (value & (1<<j)) { | ||
1222 | ack_APIC_irq(); | ||
1223 | acked++; | ||
1224 | } | ||
1225 | } | ||
1212 | } | 1226 | } |
1213 | } | 1227 | if (acked > 256) { |
1228 | printk(KERN_ERR "LAPIC pending interrupts after %d EOI\n", | ||
1229 | acked); | ||
1230 | break; | ||
1231 | } | ||
1232 | if (cpu_has_tsc) { | ||
1233 | rdtscll(ntsc); | ||
1234 | max_loops = (cpu_khz << 10) - (ntsc - tsc); | ||
1235 | } else | ||
1236 | max_loops--; | ||
1237 | } while (queued && max_loops > 0); | ||
1238 | WARN_ON(max_loops <= 0); | ||
1214 | 1239 | ||
1215 | /* | 1240 | /* |
1216 | * Now that we are all set up, enable the APIC | 1241 | * Now that we are all set up, enable the APIC |
diff --git a/arch/x86/kernel/apic/es7000_32.c b/arch/x86/kernel/apic/es7000_32.c index 03ba1b895f5e..425e53a87feb 100644 --- a/arch/x86/kernel/apic/es7000_32.c +++ b/arch/x86/kernel/apic/es7000_32.c | |||
@@ -131,24 +131,6 @@ int es7000_plat; | |||
131 | 131 | ||
132 | static unsigned int base; | 132 | static unsigned int base; |
133 | 133 | ||
134 | static int | ||
135 | es7000_rename_gsi(int ioapic, int gsi) | ||
136 | { | ||
137 | if (es7000_plat == ES7000_ZORRO) | ||
138 | return gsi; | ||
139 | |||
140 | if (!base) { | ||
141 | int i; | ||
142 | for (i = 0; i < nr_ioapics; i++) | ||
143 | base += nr_ioapic_registers[i]; | ||
144 | } | ||
145 | |||
146 | if (!ioapic && (gsi < 16)) | ||
147 | gsi += base; | ||
148 | |||
149 | return gsi; | ||
150 | } | ||
151 | |||
152 | static int __cpuinit wakeup_secondary_cpu_via_mip(int cpu, unsigned long eip) | 134 | static int __cpuinit wakeup_secondary_cpu_via_mip(int cpu, unsigned long eip) |
153 | { | 135 | { |
154 | unsigned long vect = 0, psaival = 0; | 136 | unsigned long vect = 0, psaival = 0; |
@@ -190,7 +172,6 @@ static void setup_unisys(void) | |||
190 | es7000_plat = ES7000_ZORRO; | 172 | es7000_plat = ES7000_ZORRO; |
191 | else | 173 | else |
192 | es7000_plat = ES7000_CLASSIC; | 174 | es7000_plat = ES7000_CLASSIC; |
193 | ioapic_renumber_irq = es7000_rename_gsi; | ||
194 | } | 175 | } |
195 | 176 | ||
196 | /* | 177 | /* |
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index eb2789c3f721..33f3563a2a52 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c | |||
@@ -89,6 +89,9 @@ int nr_ioapics; | |||
89 | /* IO APIC gsi routing info */ | 89 | /* IO APIC gsi routing info */ |
90 | struct mp_ioapic_gsi mp_gsi_routing[MAX_IO_APICS]; | 90 | struct mp_ioapic_gsi mp_gsi_routing[MAX_IO_APICS]; |
91 | 91 | ||
92 | /* The last gsi number used */ | ||
93 | u32 gsi_end; | ||
94 | |||
92 | /* MP IRQ source entries */ | 95 | /* MP IRQ source entries */ |
93 | struct mpc_intsrc mp_irqs[MAX_IRQ_SOURCES]; | 96 | struct mpc_intsrc mp_irqs[MAX_IRQ_SOURCES]; |
94 | 97 | ||
@@ -1013,10 +1016,9 @@ static inline int irq_trigger(int idx) | |||
1013 | return MPBIOS_trigger(idx); | 1016 | return MPBIOS_trigger(idx); |
1014 | } | 1017 | } |
1015 | 1018 | ||
1016 | int (*ioapic_renumber_irq)(int ioapic, int irq); | ||
1017 | static int pin_2_irq(int idx, int apic, int pin) | 1019 | static int pin_2_irq(int idx, int apic, int pin) |
1018 | { | 1020 | { |
1019 | int irq, i; | 1021 | int irq; |
1020 | int bus = mp_irqs[idx].srcbus; | 1022 | int bus = mp_irqs[idx].srcbus; |
1021 | 1023 | ||
1022 | /* | 1024 | /* |
@@ -1028,18 +1030,12 @@ static int pin_2_irq(int idx, int apic, int pin) | |||
1028 | if (test_bit(bus, mp_bus_not_pci)) { | 1030 | if (test_bit(bus, mp_bus_not_pci)) { |
1029 | irq = mp_irqs[idx].srcbusirq; | 1031 | irq = mp_irqs[idx].srcbusirq; |
1030 | } else { | 1032 | } else { |
1031 | /* | 1033 | u32 gsi = mp_gsi_routing[apic].gsi_base + pin; |
1032 | * PCI IRQs are mapped in order | 1034 | |
1033 | */ | 1035 | if (gsi >= NR_IRQS_LEGACY) |
1034 | i = irq = 0; | 1036 | irq = gsi; |
1035 | while (i < apic) | 1037 | else |
1036 | irq += nr_ioapic_registers[i++]; | 1038 | irq = gsi_end + 1 + gsi; |
1037 | irq += pin; | ||
1038 | /* | ||
1039 | * For MPS mode, so far only needed by ES7000 platform | ||
1040 | */ | ||
1041 | if (ioapic_renumber_irq) | ||
1042 | irq = ioapic_renumber_irq(apic, irq); | ||
1043 | } | 1039 | } |
1044 | 1040 | ||
1045 | #ifdef CONFIG_X86_32 | 1041 | #ifdef CONFIG_X86_32 |
@@ -1950,20 +1946,8 @@ static struct { int pin, apic; } ioapic_i8259 = { -1, -1 }; | |||
1950 | 1946 | ||
1951 | void __init enable_IO_APIC(void) | 1947 | void __init enable_IO_APIC(void) |
1952 | { | 1948 | { |
1953 | union IO_APIC_reg_01 reg_01; | ||
1954 | int i8259_apic, i8259_pin; | 1949 | int i8259_apic, i8259_pin; |
1955 | int apic; | 1950 | int apic; |
1956 | unsigned long flags; | ||
1957 | |||
1958 | /* | ||
1959 | * The number of IO-APIC IRQ registers (== #pins): | ||
1960 | */ | ||
1961 | for (apic = 0; apic < nr_ioapics; apic++) { | ||
1962 | raw_spin_lock_irqsave(&ioapic_lock, flags); | ||
1963 | reg_01.raw = io_apic_read(apic, 1); | ||
1964 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); | ||
1965 | nr_ioapic_registers[apic] = reg_01.bits.entries+1; | ||
1966 | } | ||
1967 | 1951 | ||
1968 | if (!legacy_pic->nr_legacy_irqs) | 1952 | if (!legacy_pic->nr_legacy_irqs) |
1969 | return; | 1953 | return; |
@@ -3858,27 +3842,20 @@ int __init io_apic_get_redir_entries (int ioapic) | |||
3858 | reg_01.raw = io_apic_read(ioapic, 1); | 3842 | reg_01.raw = io_apic_read(ioapic, 1); |
3859 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); | 3843 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); |
3860 | 3844 | ||
3861 | return reg_01.bits.entries; | 3845 | /* The register returns the maximum index redir index |
3846 | * supported, which is one less than the total number of redir | ||
3847 | * entries. | ||
3848 | */ | ||
3849 | return reg_01.bits.entries + 1; | ||
3862 | } | 3850 | } |
3863 | 3851 | ||
3864 | void __init probe_nr_irqs_gsi(void) | 3852 | void __init probe_nr_irqs_gsi(void) |
3865 | { | 3853 | { |
3866 | int nr = 0; | 3854 | int nr; |
3867 | 3855 | ||
3868 | nr = acpi_probe_gsi(); | 3856 | nr = gsi_end + 1 + NR_IRQS_LEGACY; |
3869 | if (nr > nr_irqs_gsi) { | 3857 | if (nr > nr_irqs_gsi) |
3870 | nr_irqs_gsi = nr; | 3858 | nr_irqs_gsi = nr; |
3871 | } else { | ||
3872 | /* for acpi=off or acpi is not compiled in */ | ||
3873 | int idx; | ||
3874 | |||
3875 | nr = 0; | ||
3876 | for (idx = 0; idx < nr_ioapics; idx++) | ||
3877 | nr += io_apic_get_redir_entries(idx) + 1; | ||
3878 | |||
3879 | if (nr > nr_irqs_gsi) | ||
3880 | nr_irqs_gsi = nr; | ||
3881 | } | ||
3882 | 3859 | ||
3883 | printk(KERN_DEBUG "nr_irqs_gsi: %d\n", nr_irqs_gsi); | 3860 | printk(KERN_DEBUG "nr_irqs_gsi: %d\n", nr_irqs_gsi); |
3884 | } | 3861 | } |
@@ -4085,22 +4062,27 @@ int __init io_apic_get_version(int ioapic) | |||
4085 | return reg_01.bits.version; | 4062 | return reg_01.bits.version; |
4086 | } | 4063 | } |
4087 | 4064 | ||
4088 | int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity) | 4065 | int acpi_get_override_irq(u32 gsi, int *trigger, int *polarity) |
4089 | { | 4066 | { |
4090 | int i; | 4067 | int ioapic, pin, idx; |
4091 | 4068 | ||
4092 | if (skip_ioapic_setup) | 4069 | if (skip_ioapic_setup) |
4093 | return -1; | 4070 | return -1; |
4094 | 4071 | ||
4095 | for (i = 0; i < mp_irq_entries; i++) | 4072 | ioapic = mp_find_ioapic(gsi); |
4096 | if (mp_irqs[i].irqtype == mp_INT && | 4073 | if (ioapic < 0) |
4097 | mp_irqs[i].srcbusirq == bus_irq) | ||
4098 | break; | ||
4099 | if (i >= mp_irq_entries) | ||
4100 | return -1; | 4074 | return -1; |
4101 | 4075 | ||
4102 | *trigger = irq_trigger(i); | 4076 | pin = mp_find_ioapic_pin(ioapic, gsi); |
4103 | *polarity = irq_polarity(i); | 4077 | if (pin < 0) |
4078 | return -1; | ||
4079 | |||
4080 | idx = find_irq_entry(ioapic, pin, mp_INT); | ||
4081 | if (idx < 0) | ||
4082 | return -1; | ||
4083 | |||
4084 | *trigger = irq_trigger(idx); | ||
4085 | *polarity = irq_polarity(idx); | ||
4104 | return 0; | 4086 | return 0; |
4105 | } | 4087 | } |
4106 | 4088 | ||
@@ -4241,7 +4223,7 @@ void __init ioapic_insert_resources(void) | |||
4241 | } | 4223 | } |
4242 | } | 4224 | } |
4243 | 4225 | ||
4244 | int mp_find_ioapic(int gsi) | 4226 | int mp_find_ioapic(u32 gsi) |
4245 | { | 4227 | { |
4246 | int i = 0; | 4228 | int i = 0; |
4247 | 4229 | ||
@@ -4256,7 +4238,7 @@ int mp_find_ioapic(int gsi) | |||
4256 | return -1; | 4238 | return -1; |
4257 | } | 4239 | } |
4258 | 4240 | ||
4259 | int mp_find_ioapic_pin(int ioapic, int gsi) | 4241 | int mp_find_ioapic_pin(int ioapic, u32 gsi) |
4260 | { | 4242 | { |
4261 | if (WARN_ON(ioapic == -1)) | 4243 | if (WARN_ON(ioapic == -1)) |
4262 | return -1; | 4244 | return -1; |
@@ -4284,6 +4266,7 @@ static int bad_ioapic(unsigned long address) | |||
4284 | void __init mp_register_ioapic(int id, u32 address, u32 gsi_base) | 4266 | void __init mp_register_ioapic(int id, u32 address, u32 gsi_base) |
4285 | { | 4267 | { |
4286 | int idx = 0; | 4268 | int idx = 0; |
4269 | int entries; | ||
4287 | 4270 | ||
4288 | if (bad_ioapic(address)) | 4271 | if (bad_ioapic(address)) |
4289 | return; | 4272 | return; |
@@ -4302,9 +4285,17 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base) | |||
4302 | * Build basic GSI lookup table to facilitate gsi->io_apic lookups | 4285 | * Build basic GSI lookup table to facilitate gsi->io_apic lookups |
4303 | * and to prevent reprogramming of IOAPIC pins (PCI GSIs). | 4286 | * and to prevent reprogramming of IOAPIC pins (PCI GSIs). |
4304 | */ | 4287 | */ |
4288 | entries = io_apic_get_redir_entries(idx); | ||
4305 | mp_gsi_routing[idx].gsi_base = gsi_base; | 4289 | mp_gsi_routing[idx].gsi_base = gsi_base; |
4306 | mp_gsi_routing[idx].gsi_end = gsi_base + | 4290 | mp_gsi_routing[idx].gsi_end = gsi_base + entries - 1; |
4307 | io_apic_get_redir_entries(idx); | 4291 | |
4292 | /* | ||
4293 | * The number of IO-APIC IRQ registers (== #pins): | ||
4294 | */ | ||
4295 | nr_ioapic_registers[idx] = entries; | ||
4296 | |||
4297 | if (mp_gsi_routing[idx].gsi_end > gsi_end) | ||
4298 | gsi_end = mp_gsi_routing[idx].gsi_end; | ||
4308 | 4299 | ||
4309 | printk(KERN_INFO "IOAPIC[%d]: apic_id %d, version %d, address 0x%x, " | 4300 | printk(KERN_INFO "IOAPIC[%d]: apic_id %d, version %d, address 0x%x, " |
4310 | "GSI %d-%d\n", idx, mp_ioapics[idx].apicid, | 4301 | "GSI %d-%d\n", idx, mp_ioapics[idx].apicid, |
diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c index c085d52dbaf2..e46f98f36e31 100644 --- a/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/arch/x86/kernel/apic/x2apic_uv_x.c | |||
@@ -735,9 +735,6 @@ void __init uv_system_init(void) | |||
735 | uv_node_to_blade[nid] = blade; | 735 | uv_node_to_blade[nid] = blade; |
736 | uv_cpu_to_blade[cpu] = blade; | 736 | uv_cpu_to_blade[cpu] = blade; |
737 | max_pnode = max(pnode, max_pnode); | 737 | max_pnode = max(pnode, max_pnode); |
738 | |||
739 | printk(KERN_DEBUG "UV: cpu %d, apicid 0x%x, pnode %d, nid %d, lcpu %d, blade %d\n", | ||
740 | cpu, apicid, pnode, nid, lcpu, blade); | ||
741 | } | 738 | } |
742 | 739 | ||
743 | /* Add blade/pnode info for nodes without cpus */ | 740 | /* Add blade/pnode info for nodes without cpus */ |