diff options
Diffstat (limited to 'arch/x86_64/kernel/io_apic.c')
-rw-r--r-- | arch/x86_64/kernel/io_apic.c | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c index fd52fcb6fa16..437b6f96cc80 100644 --- a/arch/x86_64/kernel/io_apic.c +++ b/arch/x86_64/kernel/io_apic.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/delay.h> | 26 | #include <linux/delay.h> |
27 | #include <linux/sched.h> | 27 | #include <linux/sched.h> |
28 | #include <linux/smp_lock.h> | 28 | #include <linux/smp_lock.h> |
29 | #include <linux/pci.h> | ||
29 | #include <linux/mc146818rtc.h> | 30 | #include <linux/mc146818rtc.h> |
30 | #include <linux/acpi.h> | 31 | #include <linux/acpi.h> |
31 | #include <linux/sysdev.h> | 32 | #include <linux/sysdev.h> |
@@ -41,6 +42,7 @@ | |||
41 | #include <asm/acpi.h> | 42 | #include <asm/acpi.h> |
42 | #include <asm/dma.h> | 43 | #include <asm/dma.h> |
43 | #include <asm/nmi.h> | 44 | #include <asm/nmi.h> |
45 | #include <asm/msidef.h> | ||
44 | 46 | ||
45 | #define __apicdebuginit __init | 47 | #define __apicdebuginit __init |
46 | 48 | ||
@@ -1739,6 +1741,78 @@ void destroy_irq(unsigned int irq) | |||
1739 | } | 1741 | } |
1740 | #endif | 1742 | #endif |
1741 | 1743 | ||
1744 | /* | ||
1745 | * MSI mesage composition | ||
1746 | */ | ||
1747 | #ifdef CONFIG_PCI_MSI | ||
1748 | static int msi_msg_setup(struct pci_dev *pdev, unsigned int irq, struct msi_msg *msg) | ||
1749 | { | ||
1750 | /* For now always this code always uses physical delivery | ||
1751 | * mode. | ||
1752 | */ | ||
1753 | int vector; | ||
1754 | unsigned dest; | ||
1755 | |||
1756 | vector = assign_irq_vector(irq); | ||
1757 | if (vector >= 0) { | ||
1758 | cpumask_t tmp; | ||
1759 | |||
1760 | cpus_clear(tmp); | ||
1761 | cpu_set(first_cpu(cpu_online_map), tmp); | ||
1762 | dest = cpu_mask_to_apicid(tmp); | ||
1763 | |||
1764 | msg->address_hi = MSI_ADDR_BASE_HI; | ||
1765 | msg->address_lo = | ||
1766 | MSI_ADDR_BASE_LO | | ||
1767 | ((INT_DEST_MODE == 0) ? | ||
1768 | MSI_ADDR_DEST_MODE_PHYSICAL: | ||
1769 | MSI_ADDR_DEST_MODE_LOGICAL) | | ||
1770 | ((INT_DELIVERY_MODE != dest_LowestPrio) ? | ||
1771 | MSI_ADDR_REDIRECTION_CPU: | ||
1772 | MSI_ADDR_REDIRECTION_LOWPRI) | | ||
1773 | MSI_ADDR_DEST_ID(dest); | ||
1774 | |||
1775 | msg->data = | ||
1776 | MSI_DATA_TRIGGER_EDGE | | ||
1777 | MSI_DATA_LEVEL_ASSERT | | ||
1778 | ((INT_DELIVERY_MODE != dest_LowestPrio) ? | ||
1779 | MSI_DATA_DELIVERY_FIXED: | ||
1780 | MSI_DATA_DELIVERY_LOWPRI) | | ||
1781 | MSI_DATA_VECTOR(vector); | ||
1782 | } | ||
1783 | return vector; | ||
1784 | } | ||
1785 | |||
1786 | static void msi_msg_teardown(unsigned int irq) | ||
1787 | { | ||
1788 | return; | ||
1789 | } | ||
1790 | |||
1791 | static void msi_msg_set_affinity(unsigned int irq, cpumask_t mask, struct msi_msg *msg) | ||
1792 | { | ||
1793 | int vector; | ||
1794 | unsigned dest; | ||
1795 | |||
1796 | vector = assign_irq_vector(irq); | ||
1797 | if (vector > 0) { | ||
1798 | dest = cpu_mask_to_apicid(mask); | ||
1799 | |||
1800 | msg->data &= ~MSI_DATA_VECTOR_MASK; | ||
1801 | msg->data |= MSI_DATA_VECTOR(vector); | ||
1802 | msg->address_lo &= ~MSI_ADDR_DEST_ID_MASK; | ||
1803 | msg->address_lo |= MSI_ADDR_DEST_ID(dest); | ||
1804 | } | ||
1805 | } | ||
1806 | |||
1807 | struct msi_ops arch_msi_ops = { | ||
1808 | .needs_64bit_address = 0, | ||
1809 | .setup = msi_msg_setup, | ||
1810 | .teardown = msi_msg_teardown, | ||
1811 | .target = msi_msg_set_affinity, | ||
1812 | }; | ||
1813 | |||
1814 | #endif | ||
1815 | |||
1742 | /* -------------------------------------------------------------------------- | 1816 | /* -------------------------------------------------------------------------- |
1743 | ACPI-based IOAPIC Configuration | 1817 | ACPI-based IOAPIC Configuration |
1744 | -------------------------------------------------------------------------- */ | 1818 | -------------------------------------------------------------------------- */ |