iommu/vt-d: Convert MSI remapping setup to remap_ops
This patch introduces remapping-ops for setting ups MSI interrupts. Signed-off-by: Joerg Roedel <joerg.roedel@amd.com> Acked-by: Yinghai Lu <yinghai@kernel.org> Cc: David Woodhouse <dwmw2@infradead.org> Cc: Alex Williamson <alex.williamson@redhat.com> Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
This commit is contained in:
parent
9d619f6572
commit
5e2b930b07
@ -26,6 +26,7 @@
|
|||||||
|
|
||||||
struct IO_APIC_route_entry;
|
struct IO_APIC_route_entry;
|
||||||
struct io_apic_irq_attr;
|
struct io_apic_irq_attr;
|
||||||
|
struct pci_dev;
|
||||||
|
|
||||||
extern int intr_remapping_enabled;
|
extern int intr_remapping_enabled;
|
||||||
|
|
||||||
@ -44,6 +45,13 @@ extern int intr_set_affinity(struct irq_data *data,
|
|||||||
const struct cpumask *mask,
|
const struct cpumask *mask,
|
||||||
bool force);
|
bool force);
|
||||||
extern void intr_free_irq(int irq);
|
extern void intr_free_irq(int irq);
|
||||||
|
extern void intr_compose_msi_msg(struct pci_dev *pdev,
|
||||||
|
unsigned int irq, unsigned int dest,
|
||||||
|
struct msi_msg *msg, u8 hpet_id);
|
||||||
|
extern int intr_msi_alloc_irq(struct pci_dev *pdev, int irq, int nvec);
|
||||||
|
extern int intr_msi_setup_irq(struct pci_dev *pdev, unsigned int irq,
|
||||||
|
int index, int sub_handle);
|
||||||
|
extern int intr_setup_hpet_msi(unsigned int irq, unsigned int id);
|
||||||
|
|
||||||
#else /* CONFIG_IRQ_REMAP */
|
#else /* CONFIG_IRQ_REMAP */
|
||||||
|
|
||||||
@ -70,6 +78,24 @@ static inline int intr_set_affinity(struct irq_data *data,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
static inline void intr_free_irq(int irq) { }
|
static inline void intr_free_irq(int irq) { }
|
||||||
|
static inline void intr_compose_msi_msg(struct pci_dev *pdev,
|
||||||
|
unsigned int irq, unsigned int dest,
|
||||||
|
struct msi_msg *msg, u8 hpet_id)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
static inline int intr_msi_alloc_irq(struct pci_dev *pdev, int irq, int nvec)
|
||||||
|
{
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
static inline int intr_msi_setup_irq(struct pci_dev *pdev, unsigned int irq,
|
||||||
|
int index, int sub_handle)
|
||||||
|
{
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
static inline int intr_setup_hpet_msi(unsigned int irq, unsigned int id)
|
||||||
|
{
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
#endif /* CONFIG_IRQ_REMAP */
|
#endif /* CONFIG_IRQ_REMAP */
|
||||||
|
|
||||||
#endif /* __X86_INTR_REMAPPING_H */
|
#endif /* __X86_INTR_REMAPPING_H */
|
||||||
|
@ -5,34 +5,11 @@
|
|||||||
|
|
||||||
#ifdef CONFIG_IRQ_REMAP
|
#ifdef CONFIG_IRQ_REMAP
|
||||||
static void irq_remap_modify_chip_defaults(struct irq_chip *chip);
|
static void irq_remap_modify_chip_defaults(struct irq_chip *chip);
|
||||||
static inline void prepare_irte(struct irte *irte, int vector,
|
|
||||||
unsigned int dest)
|
|
||||||
{
|
|
||||||
memset(irte, 0, sizeof(*irte));
|
|
||||||
|
|
||||||
irte->present = 1;
|
|
||||||
irte->dst_mode = apic->irq_dest_mode;
|
|
||||||
/*
|
|
||||||
* Trigger mode in the IRTE will always be edge, and for IO-APIC, the
|
|
||||||
* actual level or edge trigger will be setup in the IO-APIC
|
|
||||||
* RTE. This will help simplify level triggered irq migration.
|
|
||||||
* For more details, see the comments (in io_apic.c) explainig IO-APIC
|
|
||||||
* irq migration in the presence of interrupt-remapping.
|
|
||||||
*/
|
|
||||||
irte->trigger_mode = 0;
|
|
||||||
irte->dlvry_mode = apic->irq_delivery_mode;
|
|
||||||
irte->vector = vector;
|
|
||||||
irte->dest_id = IRTE_DEST(dest);
|
|
||||||
irte->redir_hint = 1;
|
|
||||||
}
|
|
||||||
static inline bool irq_remapped(struct irq_cfg *cfg)
|
static inline bool irq_remapped(struct irq_cfg *cfg)
|
||||||
{
|
{
|
||||||
return cfg->irq_2_iommu.iommu != NULL;
|
return cfg->irq_2_iommu.iommu != NULL;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static void prepare_irte(struct irte *irte, int vector, unsigned int dest)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
static inline bool irq_remapped(struct irq_cfg *cfg)
|
static inline bool irq_remapped(struct irq_cfg *cfg)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -3070,54 +3070,34 @@ static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq,
|
|||||||
dest = apic->cpu_mask_to_apicid_and(cfg->domain, apic->target_cpus());
|
dest = apic->cpu_mask_to_apicid_and(cfg->domain, apic->target_cpus());
|
||||||
|
|
||||||
if (irq_remapped(cfg)) {
|
if (irq_remapped(cfg)) {
|
||||||
struct irte irte;
|
intr_compose_msi_msg(pdev, irq, dest, msg, hpet_id);
|
||||||
int ir_index;
|
return err;
|
||||||
u16 sub_handle;
|
|
||||||
|
|
||||||
ir_index = map_irq_to_irte_handle(irq, &sub_handle);
|
|
||||||
BUG_ON(ir_index == -1);
|
|
||||||
|
|
||||||
prepare_irte(&irte, cfg->vector, dest);
|
|
||||||
|
|
||||||
/* Set source-id of interrupt request */
|
|
||||||
if (pdev)
|
|
||||||
set_msi_sid(&irte, pdev);
|
|
||||||
else
|
|
||||||
set_hpet_sid(&irte, hpet_id);
|
|
||||||
|
|
||||||
modify_irte(irq, &irte);
|
|
||||||
|
|
||||||
msg->address_hi = MSI_ADDR_BASE_HI;
|
|
||||||
msg->data = sub_handle;
|
|
||||||
msg->address_lo = MSI_ADDR_BASE_LO | MSI_ADDR_IR_EXT_INT |
|
|
||||||
MSI_ADDR_IR_SHV |
|
|
||||||
MSI_ADDR_IR_INDEX1(ir_index) |
|
|
||||||
MSI_ADDR_IR_INDEX2(ir_index);
|
|
||||||
} else {
|
|
||||||
if (x2apic_enabled())
|
|
||||||
msg->address_hi = MSI_ADDR_BASE_HI |
|
|
||||||
MSI_ADDR_EXT_DEST_ID(dest);
|
|
||||||
else
|
|
||||||
msg->address_hi = MSI_ADDR_BASE_HI;
|
|
||||||
|
|
||||||
msg->address_lo =
|
|
||||||
MSI_ADDR_BASE_LO |
|
|
||||||
((apic->irq_dest_mode == 0) ?
|
|
||||||
MSI_ADDR_DEST_MODE_PHYSICAL:
|
|
||||||
MSI_ADDR_DEST_MODE_LOGICAL) |
|
|
||||||
((apic->irq_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 |
|
|
||||||
((apic->irq_delivery_mode != dest_LowestPrio) ?
|
|
||||||
MSI_DATA_DELIVERY_FIXED:
|
|
||||||
MSI_DATA_DELIVERY_LOWPRI) |
|
|
||||||
MSI_DATA_VECTOR(cfg->vector);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (x2apic_enabled())
|
||||||
|
msg->address_hi = MSI_ADDR_BASE_HI |
|
||||||
|
MSI_ADDR_EXT_DEST_ID(dest);
|
||||||
|
else
|
||||||
|
msg->address_hi = MSI_ADDR_BASE_HI;
|
||||||
|
|
||||||
|
msg->address_lo =
|
||||||
|
MSI_ADDR_BASE_LO |
|
||||||
|
((apic->irq_dest_mode == 0) ?
|
||||||
|
MSI_ADDR_DEST_MODE_PHYSICAL:
|
||||||
|
MSI_ADDR_DEST_MODE_LOGICAL) |
|
||||||
|
((apic->irq_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 |
|
||||||
|
((apic->irq_delivery_mode != dest_LowestPrio) ?
|
||||||
|
MSI_DATA_DELIVERY_FIXED:
|
||||||
|
MSI_DATA_DELIVERY_LOWPRI) |
|
||||||
|
MSI_DATA_VECTOR(cfg->vector);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3160,33 +3140,6 @@ static struct irq_chip msi_chip = {
|
|||||||
.irq_retrigger = ioapic_retrigger_irq,
|
.irq_retrigger = ioapic_retrigger_irq,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
* Map the PCI dev to the corresponding remapping hardware unit
|
|
||||||
* and allocate 'nvec' consecutive interrupt-remapping table entries
|
|
||||||
* in it.
|
|
||||||
*/
|
|
||||||
static int msi_alloc_irte(struct pci_dev *dev, int irq, int nvec)
|
|
||||||
{
|
|
||||||
struct intel_iommu *iommu;
|
|
||||||
int index;
|
|
||||||
|
|
||||||
iommu = map_dev_to_ir(dev);
|
|
||||||
if (!iommu) {
|
|
||||||
printk(KERN_ERR
|
|
||||||
"Unable to map PCI %s to iommu\n", pci_name(dev));
|
|
||||||
return -ENOENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
index = alloc_irte(iommu, irq, nvec);
|
|
||||||
if (index < 0) {
|
|
||||||
printk(KERN_ERR
|
|
||||||
"Unable to allocate %d IRTE for PCI %s\n", nvec,
|
|
||||||
pci_name(dev));
|
|
||||||
return -ENOSPC;
|
|
||||||
}
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int irq)
|
static int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int irq)
|
||||||
{
|
{
|
||||||
struct irq_chip *chip = &msi_chip;
|
struct irq_chip *chip = &msi_chip;
|
||||||
@ -3217,7 +3170,6 @@ int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
|
|||||||
int node, ret, sub_handle, index = 0;
|
int node, ret, sub_handle, index = 0;
|
||||||
unsigned int irq, irq_want;
|
unsigned int irq, irq_want;
|
||||||
struct msi_desc *msidesc;
|
struct msi_desc *msidesc;
|
||||||
struct intel_iommu *iommu = NULL;
|
|
||||||
|
|
||||||
/* x86 doesn't support multiple MSI yet */
|
/* x86 doesn't support multiple MSI yet */
|
||||||
if (type == PCI_CAP_ID_MSI && nvec > 1)
|
if (type == PCI_CAP_ID_MSI && nvec > 1)
|
||||||
@ -3239,23 +3191,15 @@ int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
|
|||||||
* allocate the consecutive block of IRTE's
|
* allocate the consecutive block of IRTE's
|
||||||
* for 'nvec'
|
* for 'nvec'
|
||||||
*/
|
*/
|
||||||
index = msi_alloc_irte(dev, irq, nvec);
|
index = intr_msi_alloc_irq(dev, irq, nvec);
|
||||||
if (index < 0) {
|
if (index < 0) {
|
||||||
ret = index;
|
ret = index;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
iommu = map_dev_to_ir(dev);
|
ret = intr_msi_setup_irq(dev, irq, index, sub_handle);
|
||||||
if (!iommu) {
|
if (ret < 0)
|
||||||
ret = -ENOENT;
|
|
||||||
goto error;
|
goto error;
|
||||||
}
|
|
||||||
/*
|
|
||||||
* setup the mapping between the irq and the IRTE
|
|
||||||
* base index, the sub_handle pointing to the
|
|
||||||
* appropriate interrupt remap table entry.
|
|
||||||
*/
|
|
||||||
set_irte_irq(irq, iommu, index, sub_handle);
|
|
||||||
}
|
}
|
||||||
no_ir:
|
no_ir:
|
||||||
ret = setup_msi_irq(dev, msidesc, irq);
|
ret = setup_msi_irq(dev, msidesc, irq);
|
||||||
@ -3374,14 +3318,7 @@ int arch_setup_hpet_msi(unsigned int irq, unsigned int id)
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (intr_remapping_enabled) {
|
if (intr_remapping_enabled) {
|
||||||
struct intel_iommu *iommu = map_hpet_to_ir(id);
|
if (!intr_setup_hpet_msi(irq, id))
|
||||||
int index;
|
|
||||||
|
|
||||||
if (!iommu)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
index = alloc_irte(iommu, irq, 1);
|
|
||||||
if (index < 0)
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include <acpi/acpi.h>
|
#include <acpi/acpi.h>
|
||||||
#include <asm/intr_remapping.h>
|
#include <asm/intr_remapping.h>
|
||||||
#include <asm/pci-direct.h>
|
#include <asm/pci-direct.h>
|
||||||
|
#include <asm/msidef.h>
|
||||||
|
|
||||||
#include "intr_remapping.h"
|
#include "intr_remapping.h"
|
||||||
|
|
||||||
@ -955,6 +956,98 @@ intel_ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void intel_compose_msi_msg(struct pci_dev *pdev,
|
||||||
|
unsigned int irq, unsigned int dest,
|
||||||
|
struct msi_msg *msg, u8 hpet_id)
|
||||||
|
{
|
||||||
|
struct irq_cfg *cfg;
|
||||||
|
struct irte irte;
|
||||||
|
u16 sub_handle;
|
||||||
|
int ir_index;
|
||||||
|
|
||||||
|
cfg = irq_get_chip_data(irq);
|
||||||
|
|
||||||
|
ir_index = map_irq_to_irte_handle(irq, &sub_handle);
|
||||||
|
BUG_ON(ir_index == -1);
|
||||||
|
|
||||||
|
prepare_irte(&irte, cfg->vector, dest);
|
||||||
|
|
||||||
|
/* Set source-id of interrupt request */
|
||||||
|
if (pdev)
|
||||||
|
set_msi_sid(&irte, pdev);
|
||||||
|
else
|
||||||
|
set_hpet_sid(&irte, hpet_id);
|
||||||
|
|
||||||
|
modify_irte(irq, &irte);
|
||||||
|
|
||||||
|
msg->address_hi = MSI_ADDR_BASE_HI;
|
||||||
|
msg->data = sub_handle;
|
||||||
|
msg->address_lo = MSI_ADDR_BASE_LO | MSI_ADDR_IR_EXT_INT |
|
||||||
|
MSI_ADDR_IR_SHV |
|
||||||
|
MSI_ADDR_IR_INDEX1(ir_index) |
|
||||||
|
MSI_ADDR_IR_INDEX2(ir_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Map the PCI dev to the corresponding remapping hardware unit
|
||||||
|
* and allocate 'nvec' consecutive interrupt-remapping table entries
|
||||||
|
* in it.
|
||||||
|
*/
|
||||||
|
static int intel_msi_alloc_irq(struct pci_dev *dev, int irq, int nvec)
|
||||||
|
{
|
||||||
|
struct intel_iommu *iommu;
|
||||||
|
int index;
|
||||||
|
|
||||||
|
iommu = map_dev_to_ir(dev);
|
||||||
|
if (!iommu) {
|
||||||
|
printk(KERN_ERR
|
||||||
|
"Unable to map PCI %s to iommu\n", pci_name(dev));
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
index = alloc_irte(iommu, irq, nvec);
|
||||||
|
if (index < 0) {
|
||||||
|
printk(KERN_ERR
|
||||||
|
"Unable to allocate %d IRTE for PCI %s\n", nvec,
|
||||||
|
pci_name(dev));
|
||||||
|
return -ENOSPC;
|
||||||
|
}
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int intel_msi_setup_irq(struct pci_dev *pdev, unsigned int irq,
|
||||||
|
int index, int sub_handle)
|
||||||
|
{
|
||||||
|
struct intel_iommu *iommu;
|
||||||
|
|
||||||
|
iommu = map_dev_to_ir(pdev);
|
||||||
|
if (!iommu)
|
||||||
|
return -ENOENT;
|
||||||
|
/*
|
||||||
|
* setup the mapping between the irq and the IRTE
|
||||||
|
* base index, the sub_handle pointing to the
|
||||||
|
* appropriate interrupt remap table entry.
|
||||||
|
*/
|
||||||
|
set_irte_irq(irq, iommu, index, sub_handle);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int intel_setup_hpet_msi(unsigned int irq, unsigned int id)
|
||||||
|
{
|
||||||
|
struct intel_iommu *iommu = map_hpet_to_ir(id);
|
||||||
|
int index;
|
||||||
|
|
||||||
|
if (!iommu)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
index = alloc_irte(iommu, irq, 1);
|
||||||
|
if (index < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
struct irq_remap_ops intel_irq_remap_ops = {
|
struct irq_remap_ops intel_irq_remap_ops = {
|
||||||
.supported = intel_intr_remapping_supported,
|
.supported = intel_intr_remapping_supported,
|
||||||
.hardware_init = dmar_table_init,
|
.hardware_init = dmar_table_init,
|
||||||
@ -965,4 +1058,8 @@ struct irq_remap_ops intel_irq_remap_ops = {
|
|||||||
.setup_ioapic_entry = intel_setup_ioapic_entry,
|
.setup_ioapic_entry = intel_setup_ioapic_entry,
|
||||||
.set_affinity = intel_ioapic_set_affinity,
|
.set_affinity = intel_ioapic_set_affinity,
|
||||||
.free_irq = free_irte,
|
.free_irq = free_irte,
|
||||||
|
.compose_msi_msg = intel_compose_msi_msg,
|
||||||
|
.msi_alloc_irq = intel_msi_alloc_irq,
|
||||||
|
.msi_setup_irq = intel_msi_setup_irq,
|
||||||
|
.setup_hpet_msi = intel_setup_hpet_msi,
|
||||||
};
|
};
|
||||||
|
@ -127,3 +127,38 @@ void intr_free_irq(int irq)
|
|||||||
|
|
||||||
remap_ops->free_irq(irq);
|
remap_ops->free_irq(irq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void intr_compose_msi_msg(struct pci_dev *pdev,
|
||||||
|
unsigned int irq, unsigned int dest,
|
||||||
|
struct msi_msg *msg, u8 hpet_id)
|
||||||
|
{
|
||||||
|
if (!remap_ops || !remap_ops->compose_msi_msg)
|
||||||
|
return;
|
||||||
|
|
||||||
|
remap_ops->compose_msi_msg(pdev, irq, dest, msg, hpet_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
int intr_msi_alloc_irq(struct pci_dev *pdev, int irq, int nvec)
|
||||||
|
{
|
||||||
|
if (!remap_ops || !remap_ops->msi_alloc_irq)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
return remap_ops->msi_alloc_irq(pdev, irq, nvec);
|
||||||
|
}
|
||||||
|
|
||||||
|
int intr_msi_setup_irq(struct pci_dev *pdev, unsigned int irq,
|
||||||
|
int index, int sub_handle)
|
||||||
|
{
|
||||||
|
if (!remap_ops || !remap_ops->msi_setup_irq)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
return remap_ops->msi_setup_irq(pdev, irq, index, sub_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
int intr_setup_hpet_msi(unsigned int irq, unsigned int id)
|
||||||
|
{
|
||||||
|
if (!remap_ops || !remap_ops->setup_hpet_msi)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
return remap_ops->setup_hpet_msi(irq, id);
|
||||||
|
}
|
||||||
|
@ -28,6 +28,8 @@ struct IO_APIC_route_entry;
|
|||||||
struct io_apic_irq_attr;
|
struct io_apic_irq_attr;
|
||||||
struct irq_data;
|
struct irq_data;
|
||||||
struct cpumask;
|
struct cpumask;
|
||||||
|
struct pci_dev;
|
||||||
|
struct msi_msg;
|
||||||
|
|
||||||
extern int disable_intremap;
|
extern int disable_intremap;
|
||||||
extern int disable_sourceid_checking;
|
extern int disable_sourceid_checking;
|
||||||
@ -63,6 +65,20 @@ struct irq_remap_ops {
|
|||||||
|
|
||||||
/* Free an IRQ */
|
/* Free an IRQ */
|
||||||
int (*free_irq)(int);
|
int (*free_irq)(int);
|
||||||
|
|
||||||
|
/* Create MSI msg to use for interrupt remapping */
|
||||||
|
void (*compose_msi_msg)(struct pci_dev *,
|
||||||
|
unsigned int, unsigned int,
|
||||||
|
struct msi_msg *, u8);
|
||||||
|
|
||||||
|
/* Allocate remapping resources for MSI */
|
||||||
|
int (*msi_alloc_irq)(struct pci_dev *, int, int);
|
||||||
|
|
||||||
|
/* Setup the remapped MSI irq */
|
||||||
|
int (*msi_setup_irq)(struct pci_dev *, unsigned int, int, int);
|
||||||
|
|
||||||
|
/* Setup interrupt remapping for an HPET MSI */
|
||||||
|
int (*setup_hpet_msi)(unsigned int, unsigned int);
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct irq_remap_ops intel_irq_remap_ops;
|
extern struct irq_remap_ops intel_irq_remap_ops;
|
||||||
|
Loading…
Reference in New Issue
Block a user