aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/acpi/boot.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/acpi/boot.c')
-rw-r--r--arch/x86/kernel/acpi/boot.c151
1 files changed, 52 insertions, 99 deletions
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 723989d7f80..844e5e25213 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -33,6 +33,7 @@
33#include <linux/irq.h> 33#include <linux/irq.h>
34#include <linux/bootmem.h> 34#include <linux/bootmem.h>
35#include <linux/ioport.h> 35#include <linux/ioport.h>
36#include <linux/pci.h>
36 37
37#include <asm/pgtable.h> 38#include <asm/pgtable.h>
38#include <asm/io_apic.h> 39#include <asm/io_apic.h>
@@ -522,7 +523,7 @@ int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
522 * success: return IRQ number (>=0) 523 * success: return IRQ number (>=0)
523 * failure: return < 0 524 * failure: return < 0
524 */ 525 */
525int acpi_register_gsi(u32 gsi, int triggering, int polarity) 526int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
526{ 527{
527 unsigned int irq; 528 unsigned int irq;
528 unsigned int plat_gsi = gsi; 529 unsigned int plat_gsi = gsi;
@@ -532,14 +533,14 @@ int acpi_register_gsi(u32 gsi, int triggering, int polarity)
532 * Make sure all (legacy) PCI IRQs are set as level-triggered. 533 * Make sure all (legacy) PCI IRQs are set as level-triggered.
533 */ 534 */
534 if (acpi_irq_model == ACPI_IRQ_MODEL_PIC) { 535 if (acpi_irq_model == ACPI_IRQ_MODEL_PIC) {
535 if (triggering == ACPI_LEVEL_SENSITIVE) 536 if (trigger == ACPI_LEVEL_SENSITIVE)
536 eisa_set_level_irq(gsi); 537 eisa_set_level_irq(gsi);
537 } 538 }
538#endif 539#endif
539 540
540#ifdef CONFIG_X86_IO_APIC 541#ifdef CONFIG_X86_IO_APIC
541 if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC) { 542 if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC) {
542 plat_gsi = mp_register_gsi(gsi, triggering, polarity); 543 plat_gsi = mp_register_gsi(dev, gsi, trigger, polarity);
543 } 544 }
544#endif 545#endif
545 acpi_gsi_to_irq(plat_gsi, &irq); 546 acpi_gsi_to_irq(plat_gsi, &irq);
@@ -903,10 +904,8 @@ extern int es7000_plat;
903#endif 904#endif
904 905
905static struct { 906static struct {
906 int apic_id;
907 int gsi_base; 907 int gsi_base;
908 int gsi_end; 908 int gsi_end;
909 DECLARE_BITMAP(pin_programmed, MP_MAX_IOAPIC_PIN + 1);
910} mp_ioapic_routing[MAX_IO_APICS]; 909} mp_ioapic_routing[MAX_IO_APICS];
911 910
912int mp_find_ioapic(int gsi) 911int mp_find_ioapic(int gsi)
@@ -995,7 +994,6 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
995 * Build basic GSI lookup table to facilitate gsi->io_apic lookups 994 * Build basic GSI lookup table to facilitate gsi->io_apic lookups
996 * and to prevent reprogramming of IOAPIC pins (PCI GSIs). 995 * and to prevent reprogramming of IOAPIC pins (PCI GSIs).
997 */ 996 */
998 mp_ioapic_routing[idx].apic_id = mp_ioapics[idx].apicid;
999 mp_ioapic_routing[idx].gsi_base = gsi_base; 997 mp_ioapic_routing[idx].gsi_base = gsi_base;
1000 mp_ioapic_routing[idx].gsi_end = gsi_base + 998 mp_ioapic_routing[idx].gsi_end = gsi_base +
1001 io_apic_get_redir_entries(idx); 999 io_apic_get_redir_entries(idx);
@@ -1158,26 +1156,52 @@ void __init mp_config_acpi_legacy_irqs(void)
1158 } 1156 }
1159} 1157}
1160 1158
1161int mp_register_gsi(u32 gsi, int triggering, int polarity) 1159static int mp_config_acpi_gsi(struct device *dev, u32 gsi, int trigger,
1160 int polarity)
1162{ 1161{
1162#ifdef CONFIG_X86_MPPARSE
1163 struct mpc_intsrc mp_irq;
1164 struct pci_dev *pdev;
1165 unsigned char number;
1166 unsigned int devfn;
1163 int ioapic; 1167 int ioapic;
1164 int ioapic_pin; 1168 u8 pin;
1165#ifdef CONFIG_X86_32
1166#define MAX_GSI_NUM 4096
1167#define IRQ_COMPRESSION_START 64
1168 1169
1169 static int pci_irq = IRQ_COMPRESSION_START; 1170 if (!acpi_ioapic)
1170 /* 1171 return 0;
1171 * Mapping between Global System Interrupts, which 1172 if (!dev)
1172 * represent all possible interrupts, and IRQs 1173 return 0;
1173 * assigned to actual devices. 1174 if (dev->bus != &pci_bus_type)
1174 */ 1175 return 0;
1175 static int gsi_to_irq[MAX_GSI_NUM]; 1176
1176#else 1177 pdev = to_pci_dev(dev);
1178 number = pdev->bus->number;
1179 devfn = pdev->devfn;
1180 pin = pdev->pin;
1181 /* print the entry should happen on mptable identically */
1182 mp_irq.type = MP_INTSRC;
1183 mp_irq.irqtype = mp_INT;
1184 mp_irq.irqflag = (trigger == ACPI_EDGE_SENSITIVE ? 4 : 0x0c) |
1185 (polarity == ACPI_ACTIVE_HIGH ? 1 : 3);
1186 mp_irq.srcbus = number;
1187 mp_irq.srcbusirq = (((devfn >> 3) & 0x1f) << 2) | ((pin - 1) & 3);
1188 ioapic = mp_find_ioapic(gsi);
1189 mp_irq.dstapic = mp_ioapics[ioapic].apicid;
1190 mp_irq.dstirq = mp_find_ioapic_pin(ioapic, gsi);
1191
1192 save_mp_irq(&mp_irq);
1193#endif
1194 return 0;
1195}
1196
1197int mp_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
1198{
1199 int ioapic;
1200 int ioapic_pin;
1201 struct io_apic_irq_attr irq_attr;
1177 1202
1178 if (acpi_irq_model != ACPI_IRQ_MODEL_IOAPIC) 1203 if (acpi_irq_model != ACPI_IRQ_MODEL_IOAPIC)
1179 return gsi; 1204 return gsi;
1180#endif
1181 1205
1182 /* Don't set up the ACPI SCI because it's already set up */ 1206 /* Don't set up the ACPI SCI because it's already set up */
1183 if (acpi_gbl_FADT.sci_interrupt == gsi) 1207 if (acpi_gbl_FADT.sci_interrupt == gsi)
@@ -1196,93 +1220,22 @@ int mp_register_gsi(u32 gsi, int triggering, int polarity)
1196 gsi = ioapic_renumber_irq(ioapic, gsi); 1220 gsi = ioapic_renumber_irq(ioapic, gsi);
1197#endif 1221#endif
1198 1222
1199 /*
1200 * Avoid pin reprogramming. PRTs typically include entries
1201 * with redundant pin->gsi mappings (but unique PCI devices);
1202 * we only program the IOAPIC on the first.
1203 */
1204 if (ioapic_pin > MP_MAX_IOAPIC_PIN) { 1223 if (ioapic_pin > MP_MAX_IOAPIC_PIN) {
1205 printk(KERN_ERR "Invalid reference to IOAPIC pin " 1224 printk(KERN_ERR "Invalid reference to IOAPIC pin "
1206 "%d-%d\n", mp_ioapic_routing[ioapic].apic_id, 1225 "%d-%d\n", mp_ioapics[ioapic].apicid,
1207 ioapic_pin); 1226 ioapic_pin);
1208 return gsi; 1227 return gsi;
1209 } 1228 }
1210 if (test_bit(ioapic_pin, mp_ioapic_routing[ioapic].pin_programmed)) {
1211 pr_debug("Pin %d-%d already programmed\n",
1212 mp_ioapic_routing[ioapic].apic_id, ioapic_pin);
1213#ifdef CONFIG_X86_32
1214 return (gsi < IRQ_COMPRESSION_START ? gsi : gsi_to_irq[gsi]);
1215#else
1216 return gsi;
1217#endif
1218 }
1219
1220 set_bit(ioapic_pin, mp_ioapic_routing[ioapic].pin_programmed);
1221#ifdef CONFIG_X86_32
1222 /*
1223 * For GSI >= 64, use IRQ compression
1224 */
1225 if ((gsi >= IRQ_COMPRESSION_START)
1226 && (triggering == ACPI_LEVEL_SENSITIVE)) {
1227 /*
1228 * For PCI devices assign IRQs in order, avoiding gaps
1229 * due to unused I/O APIC pins.
1230 */
1231 int irq = gsi;
1232 if (gsi < MAX_GSI_NUM) {
1233 /*
1234 * Retain the VIA chipset work-around (gsi > 15), but
1235 * avoid a problem where the 8254 timer (IRQ0) is setup
1236 * via an override (so it's not on pin 0 of the ioapic),
1237 * and at the same time, the pin 0 interrupt is a PCI
1238 * type. The gsi > 15 test could cause these two pins
1239 * to be shared as IRQ0, and they are not shareable.
1240 * So test for this condition, and if necessary, avoid
1241 * the pin collision.
1242 */
1243 gsi = pci_irq++;
1244 /*
1245 * Don't assign IRQ used by ACPI SCI
1246 */
1247 if (gsi == acpi_gbl_FADT.sci_interrupt)
1248 gsi = pci_irq++;
1249 gsi_to_irq[irq] = gsi;
1250 } else {
1251 printk(KERN_ERR "GSI %u is too high\n", gsi);
1252 return gsi;
1253 }
1254 }
1255#endif
1256 io_apic_set_pci_routing(ioapic, ioapic_pin, gsi,
1257 triggering == ACPI_EDGE_SENSITIVE ? 0 : 1,
1258 polarity == ACPI_ACTIVE_HIGH ? 0 : 1);
1259 return gsi;
1260}
1261
1262int mp_config_acpi_gsi(unsigned char number, unsigned int devfn, u8 pin,
1263 u32 gsi, int triggering, int polarity)
1264{
1265#ifdef CONFIG_X86_MPPARSE
1266 struct mpc_intsrc mp_irq;
1267 int ioapic;
1268 1229
1269 if (!acpi_ioapic) 1230 if (enable_update_mptable)
1270 return 0; 1231 mp_config_acpi_gsi(dev, gsi, trigger, polarity);
1271 1232
1272 /* print the entry should happen on mptable identically */ 1233 set_io_apic_irq_attr(&irq_attr, ioapic, ioapic_pin,
1273 mp_irq.type = MP_INTSRC; 1234 trigger == ACPI_EDGE_SENSITIVE ? 0 : 1,
1274 mp_irq.irqtype = mp_INT; 1235 polarity == ACPI_ACTIVE_HIGH ? 0 : 1);
1275 mp_irq.irqflag = (triggering == ACPI_EDGE_SENSITIVE ? 4 : 0x0c) | 1236 io_apic_set_pci_routing(dev, gsi, &irq_attr);
1276 (polarity == ACPI_ACTIVE_HIGH ? 1 : 3);
1277 mp_irq.srcbus = number;
1278 mp_irq.srcbusirq = (((devfn >> 3) & 0x1f) << 2) | ((pin - 1) & 3);
1279 ioapic = mp_find_ioapic(gsi);
1280 mp_irq.dstapic = mp_ioapic_routing[ioapic].apic_id;
1281 mp_irq.dstirq = mp_find_ioapic_pin(ioapic, gsi);
1282 1237
1283 save_mp_irq(&mp_irq); 1238 return gsi;
1284#endif
1285 return 0;
1286} 1239}
1287 1240
1288/* 1241/*