[PATCH] genirq: i386 irq: Move msi message composition into io_apic.c
This removes the hardcoded assumption that irq == vector in the msi composition code, and it allows the msi message composition to setup logical mode, or lowest priorirty delivery mode as we do for other apic interrupts, and with the same selection criteria. Basically this moves the problem of what is in the msi message into the architecture irq management code where it belongs. Not in a generic layer that doesn't have enough information to compose msi messages properly. Signed-off-by: Eric W. Biederman <ebiederm@xmission.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Rajesh Shah <rajesh.shah@intel.com> Cc: Andi Kleen <ak@muc.de> Cc: "Protasevich, Natalie" <Natalie.Protasevich@UNISYS.com> Cc: "Luck, Tony" <tony.luck@intel.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
committed by
Linus Torvalds
parent
589e367f9b
commit
2d3fcc1c54
@@ -31,6 +31,7 @@
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/sysdev.h>
|
||||
#include <linux/pci.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/smp.h>
|
||||
@@ -38,6 +39,7 @@
|
||||
#include <asm/timer.h>
|
||||
#include <asm/i8259.h>
|
||||
#include <asm/nmi.h>
|
||||
#include <asm/msidef.h>
|
||||
|
||||
#include <mach_apic.h>
|
||||
#include <mach_apicdef.h>
|
||||
@@ -2531,6 +2533,74 @@ void destroy_irq(unsigned int irq)
|
||||
}
|
||||
#endif /* CONFIG_PCI_MSI */
|
||||
|
||||
/*
|
||||
* MSI mesage composition
|
||||
*/
|
||||
#ifdef CONFIG_PCI_MSI
|
||||
static int msi_msg_setup(struct pci_dev *pdev, unsigned int irq, struct msi_msg *msg)
|
||||
{
|
||||
/* For now always this code always uses physical delivery
|
||||
* mode.
|
||||
*/
|
||||
int vector;
|
||||
unsigned dest;
|
||||
|
||||
vector = assign_irq_vector(irq);
|
||||
if (vector >= 0) {
|
||||
dest = cpu_mask_to_apicid(TARGET_CPUS);
|
||||
|
||||
msg->address_hi = MSI_ADDR_BASE_HI;
|
||||
msg->address_lo =
|
||||
MSI_ADDR_BASE_LO |
|
||||
((INT_DEST_MODE == 0) ?
|
||||
MSI_ADDR_DEST_MODE_PHYSICAL:
|
||||
MSI_ADDR_DEST_MODE_LOGICAL) |
|
||||
((INT_DELIVERY_MODE != dest_LowestPrio) ?
|
||||
MSI_ADDR_REDIRECTION_CPU:
|
||||
MSI_ADDR_REDIRECTION_LOWPRI) |
|
||||
MSI_ADDR_DEST_ID(dest);
|
||||
|
||||
msg->data =
|
||||
MSI_DATA_TRIGGER_EDGE |
|
||||
MSI_DATA_LEVEL_ASSERT |
|
||||
((INT_DELIVERY_MODE != dest_LowestPrio) ?
|
||||
MSI_DATA_DELIVERY_FIXED:
|
||||
MSI_DATA_DELIVERY_LOWPRI) |
|
||||
MSI_DATA_VECTOR(vector);
|
||||
}
|
||||
return vector;
|
||||
}
|
||||
|
||||
static void msi_msg_teardown(unsigned int irq)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static void msi_msg_set_affinity(unsigned int irq, cpumask_t mask, struct msi_msg *msg)
|
||||
{
|
||||
int vector;
|
||||
unsigned dest;
|
||||
|
||||
vector = assign_irq_vector(irq);
|
||||
if (vector > 0) {
|
||||
dest = cpu_mask_to_apicid(mask);
|
||||
|
||||
msg->data &= ~MSI_DATA_VECTOR_MASK;
|
||||
msg->data |= MSI_DATA_VECTOR(vector);
|
||||
msg->address_lo &= ~MSI_ADDR_DEST_ID_MASK;
|
||||
msg->address_lo |= MSI_ADDR_DEST_ID(dest);
|
||||
}
|
||||
}
|
||||
|
||||
struct msi_ops arch_msi_ops = {
|
||||
.needs_64bit_address = 0,
|
||||
.setup = msi_msg_setup,
|
||||
.teardown = msi_msg_teardown,
|
||||
.target = msi_msg_set_affinity,
|
||||
};
|
||||
|
||||
#endif /* CONFIG_PCI_MSI */
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
ACPI-based IOAPIC Configuration
|
||||
-------------------------------------------------------------------------- */
|
||||
|
Reference in New Issue
Block a user