diff options
Diffstat (limited to 'arch/i386/kernel/io_apic.c')
-rw-r--r-- | arch/i386/kernel/io_apic.c | 70 |
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 | ||
2540 | static 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 | |||
2574 | static void msi_msg_teardown(unsigned int irq) | ||
2575 | { | ||
2576 | return; | ||
2577 | } | ||
2578 | |||
2579 | static 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 | |||
2595 | struct 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 | -------------------------------------------------------------------------- */ |