diff options
Diffstat (limited to 'arch/x86/kernel/apic/io_apic.c')
| -rw-r--r-- | arch/x86/kernel/apic/io_apic.c | 99 |
1 files changed, 45 insertions, 54 deletions
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, |
