diff options
author | Feng Tang <feng.tang@intel.com> | 2009-07-07 23:01:15 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2009-08-28 19:57:27 -0400 |
commit | 2a4ab640d3c28c2952967e5f63ea495555bf2a5f (patch) | |
tree | 0dc9a613926da186286464379966f5c6afbd865f /arch/x86/kernel/apic/io_apic.c | |
parent | 326ba5010a5429a5a528b268b36a5900d4ab0eba (diff) |
ACPI, x86: expose some IO-APIC routines when CONFIG_ACPI=n
Some IO-APIC routines are ACPI specific now, but need to
be exposed when CONFIG_ACPI=n for the benefit of SFI.
Remove #ifdef ACPI around these routines:
io_apic_get_unique_id(int ioapic, int apic_id);
io_apic_get_version(int ioapic);
io_apic_get_redir_entries(int ioapic);
Move these routines from ACPI-specific boot.c to io_apic.c:
uniq_ioapic_id(u8 id)
mp_find_ioapic()
mp_find_ioapic_pin()
mp_register_ioapic()
Also, since uniq_ioapic_id() is now no longer static,
re-name it to io_apic_unique_id() for consistency
with the other public io_apic routines.
For simplicity, do not #ifdef the resulting code ACPI || SFI,
thought that could be done in the future if it is important
to optimize the !ACPI !SFI IO-APIC x86 kernel for size.
Signed-off-by: Feng Tang <feng.tang@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
Cc: x86@kernel.org
Diffstat (limited to 'arch/x86/kernel/apic/io_apic.c')
-rw-r--r-- | arch/x86/kernel/apic/io_apic.c | 103 |
1 files changed, 97 insertions, 6 deletions
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index d2ed6c5ddc80..a8c0232b3893 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c | |||
@@ -85,6 +85,9 @@ int nr_ioapic_registers[MAX_IO_APICS]; | |||
85 | struct mpc_ioapic mp_ioapics[MAX_IO_APICS]; | 85 | struct mpc_ioapic mp_ioapics[MAX_IO_APICS]; |
86 | int nr_ioapics; | 86 | int nr_ioapics; |
87 | 87 | ||
88 | /* IO APIC gsi routing info */ | ||
89 | struct mp_ioapic_gsi mp_gsi_routing[MAX_IO_APICS]; | ||
90 | |||
88 | /* MP IRQ source entries */ | 91 | /* MP IRQ source entries */ |
89 | struct mpc_intsrc mp_irqs[MAX_IRQ_SOURCES]; | 92 | struct mpc_intsrc mp_irqs[MAX_IRQ_SOURCES]; |
90 | 93 | ||
@@ -3941,11 +3944,28 @@ int io_apic_set_pci_routing(struct device *dev, int irq, | |||
3941 | return __io_apic_set_pci_routing(dev, irq, irq_attr); | 3944 | return __io_apic_set_pci_routing(dev, irq, irq_attr); |
3942 | } | 3945 | } |
3943 | 3946 | ||
3944 | /* -------------------------------------------------------------------------- | 3947 | u8 __init io_apic_unique_id(u8 id) |
3945 | ACPI-based IOAPIC Configuration | 3948 | { |
3946 | -------------------------------------------------------------------------- */ | 3949 | #ifdef CONFIG_X86_32 |
3950 | if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) && | ||
3951 | !APIC_XAPIC(apic_version[boot_cpu_physical_apicid])) | ||
3952 | return io_apic_get_unique_id(nr_ioapics, id); | ||
3953 | else | ||
3954 | return id; | ||
3955 | #else | ||
3956 | int i; | ||
3957 | DECLARE_BITMAP(used, 256); | ||
3947 | 3958 | ||
3948 | #ifdef CONFIG_ACPI | 3959 | bitmap_zero(used, 256); |
3960 | for (i = 0; i < nr_ioapics; i++) { | ||
3961 | struct mpc_ioapic *ia = &mp_ioapics[i]; | ||
3962 | __set_bit(ia->apicid, used); | ||
3963 | } | ||
3964 | if (!test_bit(id, used)) | ||
3965 | return id; | ||
3966 | return find_first_zero_bit(used, 256); | ||
3967 | #endif | ||
3968 | } | ||
3949 | 3969 | ||
3950 | #ifdef CONFIG_X86_32 | 3970 | #ifdef CONFIG_X86_32 |
3951 | int __init io_apic_get_unique_id(int ioapic, int apic_id) | 3971 | int __init io_apic_get_unique_id(int ioapic, int apic_id) |
@@ -4054,8 +4074,6 @@ int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity) | |||
4054 | return 0; | 4074 | return 0; |
4055 | } | 4075 | } |
4056 | 4076 | ||
4057 | #endif /* CONFIG_ACPI */ | ||
4058 | |||
4059 | /* | 4077 | /* |
4060 | * This function currently is only a helper for the i386 smp boot process where | 4078 | * This function currently is only a helper for the i386 smp boot process where |
4061 | * we need to reprogram the ioredtbls to cater for the cpus which have come online | 4079 | * we need to reprogram the ioredtbls to cater for the cpus which have come online |
@@ -4201,3 +4219,76 @@ void __init ioapic_insert_resources(void) | |||
4201 | r++; | 4219 | r++; |
4202 | } | 4220 | } |
4203 | } | 4221 | } |
4222 | |||
4223 | int mp_find_ioapic(int gsi) | ||
4224 | { | ||
4225 | int i = 0; | ||
4226 | |||
4227 | /* Find the IOAPIC that manages this GSI. */ | ||
4228 | for (i = 0; i < nr_ioapics; i++) { | ||
4229 | if ((gsi >= mp_gsi_routing[i].gsi_base) | ||
4230 | && (gsi <= mp_gsi_routing[i].gsi_end)) | ||
4231 | return i; | ||
4232 | } | ||
4233 | |||
4234 | printk(KERN_ERR "ERROR: Unable to locate IOAPIC for GSI %d\n", gsi); | ||
4235 | return -1; | ||
4236 | } | ||
4237 | |||
4238 | int mp_find_ioapic_pin(int ioapic, int gsi) | ||
4239 | { | ||
4240 | if (WARN_ON(ioapic == -1)) | ||
4241 | return -1; | ||
4242 | if (WARN_ON(gsi > mp_gsi_routing[ioapic].gsi_end)) | ||
4243 | return -1; | ||
4244 | |||
4245 | return gsi - mp_gsi_routing[ioapic].gsi_base; | ||
4246 | } | ||
4247 | |||
4248 | static int bad_ioapic(unsigned long address) | ||
4249 | { | ||
4250 | if (nr_ioapics >= MAX_IO_APICS) { | ||
4251 | printk(KERN_WARNING "WARING: Max # of I/O APICs (%d) exceeded " | ||
4252 | "(found %d), skipping\n", MAX_IO_APICS, nr_ioapics); | ||
4253 | return 1; | ||
4254 | } | ||
4255 | if (!address) { | ||
4256 | printk(KERN_WARNING "WARNING: Bogus (zero) I/O APIC address" | ||
4257 | " found in table, skipping!\n"); | ||
4258 | return 1; | ||
4259 | } | ||
4260 | return 0; | ||
4261 | } | ||
4262 | |||
4263 | void __init mp_register_ioapic(int id, u32 address, u32 gsi_base) | ||
4264 | { | ||
4265 | int idx = 0; | ||
4266 | |||
4267 | if (bad_ioapic(address)) | ||
4268 | return; | ||
4269 | |||
4270 | idx = nr_ioapics; | ||
4271 | |||
4272 | mp_ioapics[idx].type = MP_IOAPIC; | ||
4273 | mp_ioapics[idx].flags = MPC_APIC_USABLE; | ||
4274 | mp_ioapics[idx].apicaddr = address; | ||
4275 | |||
4276 | set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address); | ||
4277 | mp_ioapics[idx].apicid = io_apic_unique_id(id); | ||
4278 | mp_ioapics[idx].apicver = io_apic_get_version(idx); | ||
4279 | |||
4280 | /* | ||
4281 | * Build basic GSI lookup table to facilitate gsi->io_apic lookups | ||
4282 | * and to prevent reprogramming of IOAPIC pins (PCI GSIs). | ||
4283 | */ | ||
4284 | mp_gsi_routing[idx].gsi_base = gsi_base; | ||
4285 | mp_gsi_routing[idx].gsi_end = gsi_base + | ||
4286 | io_apic_get_redir_entries(idx); | ||
4287 | |||
4288 | printk(KERN_INFO "IOAPIC[%d]: apic_id %d, version %d, address 0x%x, " | ||
4289 | "GSI %d-%d\n", idx, mp_ioapics[idx].apicid, | ||
4290 | mp_ioapics[idx].apicver, mp_ioapics[idx].apicaddr, | ||
4291 | mp_gsi_routing[idx].gsi_base, mp_gsi_routing[idx].gsi_end); | ||
4292 | |||
4293 | nr_ioapics++; | ||
4294 | } | ||