aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/kernel/io_apic.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/i386/kernel/io_apic.c')
-rw-r--r--arch/i386/kernel/io_apic.c70
1 files changed, 70 insertions, 0 deletions
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
index fca689cfb0c9..85e7d5d465a2 100644
--- a/arch/i386/kernel/io_apic.c
+++ b/arch/i386/kernel/io_apic.c
@@ -31,6 +31,7 @@
31#include <linux/acpi.h> 31#include <linux/acpi.h>
32#include <linux/module.h> 32#include <linux/module.h>
33#include <linux/sysdev.h> 33#include <linux/sysdev.h>
34#include <linux/pci.h>
34 35
35#include <asm/io.h> 36#include <asm/io.h>
36#include <asm/smp.h> 37#include <asm/smp.h>
@@ -38,6 +39,7 @@
38#include <asm/timer.h> 39#include <asm/timer.h>
39#include <asm/i8259.h> 40#include <asm/i8259.h>
40#include <asm/nmi.h> 41#include <asm/nmi.h>
42#include <asm/msidef.h>
41 43
42#include <mach_apic.h> 44#include <mach_apic.h>
43#include <mach_apicdef.h> 45#include <mach_apicdef.h>
@@ -2531,6 +2533,74 @@ void destroy_irq(unsigned int irq)
2531} 2533}
2532#endif /* CONFIG_PCI_MSI */ 2534#endif /* CONFIG_PCI_MSI */
2533 2535
2536/*
2537 * MSI mesage composition
2538 */
2539#ifdef CONFIG_PCI_MSI
2540static int msi_msg_setup(struct pci_dev *pdev, unsigned int irq, struct msi_msg *msg)
2541{
2542 /* For now always this code always uses physical delivery
2543 * mode.
2544 */
2545 int vector;
2546 unsigned dest;
2547
2548 vector = assign_irq_vector(irq);
2549 if (vector >= 0) {
2550 dest = cpu_mask_to_apicid(TARGET_CPUS);
2551
2552 msg->address_hi = MSI_ADDR_BASE_HI;
2553 msg->address_lo =
2554 MSI_ADDR_BASE_LO |
2555 ((INT_DEST_MODE == 0) ?
2556 MSI_ADDR_DEST_MODE_PHYSICAL:
2557 MSI_ADDR_DEST_MODE_LOGICAL) |
2558 ((INT_DELIVERY_MODE != dest_LowestPrio) ?
2559 MSI_ADDR_REDIRECTION_CPU:
2560 MSI_ADDR_REDIRECTION_LOWPRI) |
2561 MSI_ADDR_DEST_ID(dest);
2562
2563 msg->data =
2564 MSI_DATA_TRIGGER_EDGE |
2565 MSI_DATA_LEVEL_ASSERT |
2566 ((INT_DELIVERY_MODE != dest_LowestPrio) ?
2567 MSI_DATA_DELIVERY_FIXED:
2568 MSI_DATA_DELIVERY_LOWPRI) |
2569 MSI_DATA_VECTOR(vector);
2570 }
2571 return vector;
2572}
2573
2574static void msi_msg_teardown(unsigned int irq)
2575{
2576 return;
2577}
2578
2579static void msi_msg_set_affinity(unsigned int irq, cpumask_t mask, struct msi_msg *msg)
2580{
2581 int vector;
2582 unsigned dest;
2583
2584 vector = assign_irq_vector(irq);
2585 if (vector > 0) {
2586 dest = cpu_mask_to_apicid(mask);
2587
2588 msg->data &= ~MSI_DATA_VECTOR_MASK;
2589 msg->data |= MSI_DATA_VECTOR(vector);
2590 msg->address_lo &= ~MSI_ADDR_DEST_ID_MASK;
2591 msg->address_lo |= MSI_ADDR_DEST_ID(dest);
2592 }
2593}
2594
2595struct msi_ops arch_msi_ops = {
2596 .needs_64bit_address = 0,
2597 .setup = msi_msg_setup,
2598 .teardown = msi_msg_teardown,
2599 .target = msi_msg_set_affinity,
2600};
2601
2602#endif /* CONFIG_PCI_MSI */
2603
2534/* -------------------------------------------------------------------------- 2604/* --------------------------------------------------------------------------
2535 ACPI-based IOAPIC Configuration 2605 ACPI-based IOAPIC Configuration
2536 -------------------------------------------------------------------------- */ 2606 -------------------------------------------------------------------------- */