diff options
author | Yinghai Lu <yinghai.lu@oracle.com> | 2011-10-12 03:33:15 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2011-10-12 03:55:18 -0400 |
commit | c5b4712c3fabef4d1f48d24563fc562053baa002 (patch) | |
tree | ace39a7d12cbf081f6688424e541c2c3bc7e3b57 /arch/x86/kernel | |
parent | e4aff81182c01f81d0bedb0685abccf3cba4a2ac (diff) |
x86, ioapic: Split up setup_ioapic_entry()
Ingo pointed out that setup_ioapic_entry() is way too big now.
Split the intr-remap code out into setup_ir_ioapic_entry().
Also pass struct io_apic_irq_attr * instead of 5 parameters
in those two functions.
At last in setup_ir_ioapic_entry() we don't need to panic.
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Cc: Naga Chumbalkar <nagananda.chumbalkar@hp.com>
Cc: Suresh Siddha <suresh.b.siddha@intel.com>
Link: http://lkml.kernel.org/r/4E9542BB.4070807@oracle.com
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r-- | arch/x86/kernel/apic/io_apic.c | 139 |
1 files changed, 80 insertions, 59 deletions
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index a7052fafdd43..2fbb9d6a37ed 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c | |||
@@ -1255,72 +1255,95 @@ static void ioapic_register_intr(unsigned int irq, struct irq_cfg *cfg, | |||
1255 | fasteoi ? "fasteoi" : "edge"); | 1255 | fasteoi ? "fasteoi" : "edge"); |
1256 | } | 1256 | } |
1257 | 1257 | ||
1258 | static int setup_ioapic_entry(int apic_id, int irq, | 1258 | |
1259 | struct IO_APIC_route_entry *entry, | 1259 | static int setup_ir_ioapic_entry(int irq, |
1260 | unsigned int destination, int trigger, | 1260 | struct IR_IO_APIC_route_entry *entry, |
1261 | int polarity, int vector, int pin) | 1261 | unsigned int destination, int vector, |
1262 | struct io_apic_irq_attr *attr) | ||
1262 | { | 1263 | { |
1263 | /* | 1264 | int index; |
1264 | * add it to the IO-APIC irq-routing table: | 1265 | struct irte irte; |
1265 | */ | 1266 | int apic_id = mpc_ioapic_id(attr->ioapic); |
1266 | memset(entry,0,sizeof(*entry)); | 1267 | struct intel_iommu *iommu = map_ioapic_to_ir(apic_id); |
1267 | 1268 | ||
1268 | if (intr_remapping_enabled) { | 1269 | if (!iommu) { |
1269 | struct intel_iommu *iommu = map_ioapic_to_ir(apic_id); | 1270 | pr_warn("No mapping iommu for ioapic %d\n", apic_id); |
1270 | struct irte irte; | 1271 | return -ENODEV; |
1271 | struct IR_IO_APIC_route_entry *ir_entry = | 1272 | } |
1272 | (struct IR_IO_APIC_route_entry *) entry; | ||
1273 | int index; | ||
1274 | 1273 | ||
1275 | if (!iommu) | 1274 | index = alloc_irte(iommu, irq, 1); |
1276 | panic("No mapping iommu for ioapic %d\n", apic_id); | 1275 | if (index < 0) { |
1276 | pr_warn("Failed to allocate IRTE for ioapic %d\n", apic_id); | ||
1277 | return -ENOMEM; | ||
1278 | } | ||
1277 | 1279 | ||
1278 | index = alloc_irte(iommu, irq, 1); | 1280 | prepare_irte(&irte, vector, destination); |
1279 | if (index < 0) | ||
1280 | panic("Failed to allocate IRTE for ioapic %d\n", apic_id); | ||
1281 | 1281 | ||
1282 | prepare_irte(&irte, vector, destination); | 1282 | /* Set source-id of interrupt request */ |
1283 | set_ioapic_sid(&irte, apic_id); | ||
1283 | 1284 | ||
1284 | /* Set source-id of interrupt request */ | 1285 | modify_irte(irq, &irte); |
1285 | set_ioapic_sid(&irte, apic_id); | ||
1286 | 1286 | ||
1287 | modify_irte(irq, &irte); | 1287 | apic_printk(APIC_VERBOSE, KERN_DEBUG "IOAPIC[%d]: " |
1288 | "Set IRTE entry (P:%d FPD:%d Dst_Mode:%d " | ||
1289 | "Redir_hint:%d Trig_Mode:%d Dlvry_Mode:%X " | ||
1290 | "Avail:%X Vector:%02X Dest:%08X " | ||
1291 | "SID:%04X SQ:%X SVT:%X)\n", | ||
1292 | apic_id, irte.present, irte.fpd, irte.dst_mode, | ||
1293 | irte.redir_hint, irte.trigger_mode, irte.dlvry_mode, | ||
1294 | irte.avail, irte.vector, irte.dest_id, | ||
1295 | irte.sid, irte.sq, irte.svt); | ||
1296 | |||
1297 | memset(entry, 0, sizeof(*entry)); | ||
1298 | |||
1299 | entry->index2 = (index >> 15) & 0x1; | ||
1300 | entry->zero = 0; | ||
1301 | entry->format = 1; | ||
1302 | entry->index = (index & 0x7fff); | ||
1303 | /* | ||
1304 | * IO-APIC RTE will be configured with virtual vector. | ||
1305 | * irq handler will do the explicit EOI to the io-apic. | ||
1306 | */ | ||
1307 | entry->vector = attr->ioapic_pin; | ||
1308 | entry->mask = 0; /* enable IRQ */ | ||
1309 | entry->trigger = attr->trigger; | ||
1310 | entry->polarity = attr->polarity; | ||
1288 | 1311 | ||
1289 | ir_entry->index2 = (index >> 15) & 0x1; | 1312 | /* Mask level triggered irqs. |
1290 | ir_entry->zero = 0; | 1313 | * Use IRQ_DELAYED_DISABLE for edge triggered irqs. |
1291 | ir_entry->format = 1; | 1314 | */ |
1292 | ir_entry->index = (index & 0x7fff); | 1315 | if (attr->trigger) |
1293 | /* | 1316 | entry->mask = 1; |
1294 | * IO-APIC RTE will be configured with virtual vector. | ||
1295 | * irq handler will do the explicit EOI to the io-apic. | ||
1296 | */ | ||
1297 | ir_entry->vector = pin; | ||
1298 | |||
1299 | apic_printk(APIC_VERBOSE, KERN_DEBUG "IOAPIC[%d]: " | ||
1300 | "Set IRTE entry (P:%d FPD:%d Dst_Mode:%d " | ||
1301 | "Redir_hint:%d Trig_Mode:%d Dlvry_Mode:%X " | ||
1302 | "Avail:%X Vector:%02X Dest:%08X " | ||
1303 | "SID:%04X SQ:%X SVT:%X)\n", | ||
1304 | apic_id, irte.present, irte.fpd, irte.dst_mode, | ||
1305 | irte.redir_hint, irte.trigger_mode, irte.dlvry_mode, | ||
1306 | irte.avail, irte.vector, irte.dest_id, | ||
1307 | irte.sid, irte.sq, irte.svt); | ||
1308 | } else { | ||
1309 | entry->delivery_mode = apic->irq_delivery_mode; | ||
1310 | entry->dest_mode = apic->irq_dest_mode; | ||
1311 | entry->dest = destination; | ||
1312 | entry->vector = vector; | ||
1313 | } | ||
1314 | 1317 | ||
1315 | entry->mask = 0; /* enable IRQ */ | 1318 | return 0; |
1316 | entry->trigger = trigger; | 1319 | } |
1317 | entry->polarity = polarity; | ||
1318 | 1320 | ||
1319 | /* Mask level triggered irqs. | 1321 | static int setup_ioapic_entry(int irq, struct IO_APIC_route_entry *entry, |
1322 | unsigned int destination, int vector, | ||
1323 | struct io_apic_irq_attr *attr) | ||
1324 | { | ||
1325 | if (intr_remapping_enabled) | ||
1326 | return setup_ir_ioapic_entry(irq, | ||
1327 | (struct IR_IO_APIC_route_entry *)entry, | ||
1328 | destination, vector, attr); | ||
1329 | |||
1330 | memset(entry, 0, sizeof(*entry)); | ||
1331 | |||
1332 | entry->delivery_mode = apic->irq_delivery_mode; | ||
1333 | entry->dest_mode = apic->irq_dest_mode; | ||
1334 | entry->dest = destination; | ||
1335 | entry->vector = vector; | ||
1336 | entry->mask = 0; /* enable IRQ */ | ||
1337 | entry->trigger = attr->trigger; | ||
1338 | entry->polarity = attr->polarity; | ||
1339 | |||
1340 | /* | ||
1341 | * Mask level triggered irqs. | ||
1320 | * Use IRQ_DELAYED_DISABLE for edge triggered irqs. | 1342 | * Use IRQ_DELAYED_DISABLE for edge triggered irqs. |
1321 | */ | 1343 | */ |
1322 | if (trigger) | 1344 | if (attr->trigger) |
1323 | entry->mask = 1; | 1345 | entry->mask = 1; |
1346 | |||
1324 | return 0; | 1347 | return 0; |
1325 | } | 1348 | } |
1326 | 1349 | ||
@@ -1351,13 +1374,11 @@ static void setup_ioapic_irq(unsigned int irq, struct irq_cfg *cfg, | |||
1351 | attr->ioapic, mpc_ioapic_id(attr->ioapic), attr->ioapic_pin, | 1374 | attr->ioapic, mpc_ioapic_id(attr->ioapic), attr->ioapic_pin, |
1352 | cfg->vector, irq, attr->trigger, attr->polarity, dest); | 1375 | cfg->vector, irq, attr->trigger, attr->polarity, dest); |
1353 | 1376 | ||
1354 | 1377 | if (setup_ioapic_entry(irq, &entry, dest, cfg->vector, attr)) { | |
1355 | if (setup_ioapic_entry(mpc_ioapic_id(attr->ioapic), irq, &entry, | 1378 | pr_warn("Failed to setup ioapic entry for ioapic %d, pin %d\n", |
1356 | dest, attr->trigger, attr->polarity, cfg->vector, | 1379 | mpc_ioapic_id(attr->ioapic), attr->ioapic_pin); |
1357 | attr->ioapic_pin)) { | ||
1358 | printk("Failed to setup ioapic entry for ioapic %d, pin %d\n", | ||
1359 | mpc_ioapic_id(attr->ioapic), attr->ioapic_pin); | ||
1360 | __clear_irq_vector(irq, cfg); | 1380 | __clear_irq_vector(irq, cfg); |
1381 | |||
1361 | return; | 1382 | return; |
1362 | } | 1383 | } |
1363 | 1384 | ||