|
@@ -53,21 +53,20 @@ static void msi_set_mask_bit(unsigned int irq, int flag)
|
|
struct msi_desc *entry;
|
|
struct msi_desc *entry;
|
|
|
|
|
|
entry = msi_desc[irq];
|
|
entry = msi_desc[irq];
|
|
- if (!entry || !entry->dev || !entry->mask_base)
|
|
|
|
- return;
|
|
|
|
|
|
+ BUG_ON(!entry || !entry->dev);
|
|
switch (entry->msi_attrib.type) {
|
|
switch (entry->msi_attrib.type) {
|
|
case PCI_CAP_ID_MSI:
|
|
case PCI_CAP_ID_MSI:
|
|
- {
|
|
|
|
- int pos;
|
|
|
|
- u32 mask_bits;
|
|
|
|
-
|
|
|
|
- pos = (long)entry->mask_base;
|
|
|
|
- pci_read_config_dword(entry->dev, pos, &mask_bits);
|
|
|
|
- mask_bits &= ~(1);
|
|
|
|
- mask_bits |= flag;
|
|
|
|
- pci_write_config_dword(entry->dev, pos, mask_bits);
|
|
|
|
|
|
+ if (entry->msi_attrib.maskbit) {
|
|
|
|
+ int pos;
|
|
|
|
+ u32 mask_bits;
|
|
|
|
+
|
|
|
|
+ pos = (long)entry->mask_base;
|
|
|
|
+ pci_read_config_dword(entry->dev, pos, &mask_bits);
|
|
|
|
+ mask_bits &= ~(1);
|
|
|
|
+ mask_bits |= flag;
|
|
|
|
+ pci_write_config_dword(entry->dev, pos, mask_bits);
|
|
|
|
+ }
|
|
break;
|
|
break;
|
|
- }
|
|
|
|
case PCI_CAP_ID_MSIX:
|
|
case PCI_CAP_ID_MSIX:
|
|
{
|
|
{
|
|
int offset = entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE +
|
|
int offset = entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE +
|
|
@@ -76,6 +75,7 @@ static void msi_set_mask_bit(unsigned int irq, int flag)
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
default:
|
|
default:
|
|
|
|
+ BUG();
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -186,83 +186,21 @@ static void unmask_MSI_irq(unsigned int irq)
|
|
msi_set_mask_bit(irq, 0);
|
|
msi_set_mask_bit(irq, 0);
|
|
}
|
|
}
|
|
|
|
|
|
-static unsigned int startup_msi_irq_wo_maskbit(unsigned int irq)
|
|
|
|
-{
|
|
|
|
- return 0; /* never anything pending */
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static unsigned int startup_msi_irq_w_maskbit(unsigned int irq)
|
|
|
|
-{
|
|
|
|
- startup_msi_irq_wo_maskbit(irq);
|
|
|
|
- unmask_MSI_irq(irq);
|
|
|
|
- return 0; /* never anything pending */
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static void shutdown_msi_irq(unsigned int irq)
|
|
|
|
-{
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static void end_msi_irq_wo_maskbit(unsigned int irq)
|
|
|
|
|
|
+static void ack_msi_irq(unsigned int irq)
|
|
{
|
|
{
|
|
move_native_irq(irq);
|
|
move_native_irq(irq);
|
|
ack_APIC_irq();
|
|
ack_APIC_irq();
|
|
}
|
|
}
|
|
|
|
|
|
-static void end_msi_irq_w_maskbit(unsigned int irq)
|
|
|
|
-{
|
|
|
|
- move_native_irq(irq);
|
|
|
|
- unmask_MSI_irq(irq);
|
|
|
|
- ack_APIC_irq();
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static void do_nothing(unsigned int irq)
|
|
|
|
-{
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/*
|
|
|
|
- * Interrupt Type for MSI-X PCI/PCI-X/PCI-Express Devices,
|
|
|
|
- * which implement the MSI-X Capability Structure.
|
|
|
|
- */
|
|
|
|
-static struct hw_interrupt_type msix_irq_type = {
|
|
|
|
- .typename = "PCI-MSI-X",
|
|
|
|
- .startup = startup_msi_irq_w_maskbit,
|
|
|
|
- .shutdown = shutdown_msi_irq,
|
|
|
|
- .enable = unmask_MSI_irq,
|
|
|
|
- .disable = mask_MSI_irq,
|
|
|
|
- .ack = mask_MSI_irq,
|
|
|
|
- .end = end_msi_irq_w_maskbit,
|
|
|
|
- .set_affinity = set_msi_affinity
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
-/*
|
|
|
|
- * Interrupt Type for MSI PCI/PCI-X/PCI-Express Devices,
|
|
|
|
- * which implement the MSI Capability Structure with
|
|
|
|
- * Mask-and-Pending Bits.
|
|
|
|
- */
|
|
|
|
-static struct hw_interrupt_type msi_irq_w_maskbit_type = {
|
|
|
|
- .typename = "PCI-MSI",
|
|
|
|
- .startup = startup_msi_irq_w_maskbit,
|
|
|
|
- .shutdown = shutdown_msi_irq,
|
|
|
|
- .enable = unmask_MSI_irq,
|
|
|
|
- .disable = mask_MSI_irq,
|
|
|
|
- .ack = mask_MSI_irq,
|
|
|
|
- .end = end_msi_irq_w_maskbit,
|
|
|
|
- .set_affinity = set_msi_affinity
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
/*
|
|
/*
|
|
- * Interrupt Type for MSI PCI/PCI-X/PCI-Express Devices,
|
|
|
|
- * which implement the MSI Capability Structure without
|
|
|
|
- * Mask-and-Pending Bits.
|
|
|
|
|
|
+ * IRQ Chip for MSI PCI/PCI-X/PCI-Express Devices,
|
|
|
|
+ * which implement the MSI or MSI-X Capability Structure.
|
|
*/
|
|
*/
|
|
-static struct hw_interrupt_type msi_irq_wo_maskbit_type = {
|
|
|
|
- .typename = "PCI-MSI",
|
|
|
|
- .startup = startup_msi_irq_wo_maskbit,
|
|
|
|
- .shutdown = shutdown_msi_irq,
|
|
|
|
- .enable = do_nothing,
|
|
|
|
- .disable = do_nothing,
|
|
|
|
- .ack = do_nothing,
|
|
|
|
- .end = end_msi_irq_wo_maskbit,
|
|
|
|
|
|
+static struct irq_chip msi_chip = {
|
|
|
|
+ .name = "PCI-MSI",
|
|
|
|
+ .unmask = unmask_MSI_irq,
|
|
|
|
+ .mask = mask_MSI_irq,
|
|
|
|
+ .ack = ack_msi_irq,
|
|
.set_affinity = set_msi_affinity
|
|
.set_affinity = set_msi_affinity
|
|
};
|
|
};
|
|
|
|
|
|
@@ -330,7 +268,7 @@ static void attach_msi_entry(struct msi_desc *entry, int irq)
|
|
spin_unlock_irqrestore(&msi_lock, flags);
|
|
spin_unlock_irqrestore(&msi_lock, flags);
|
|
}
|
|
}
|
|
|
|
|
|
-static int create_msi_irq(struct hw_interrupt_type *handler)
|
|
|
|
|
|
+static int create_msi_irq(struct irq_chip *chip)
|
|
{
|
|
{
|
|
struct msi_desc *entry;
|
|
struct msi_desc *entry;
|
|
int irq;
|
|
int irq;
|
|
@@ -345,7 +283,7 @@ static int create_msi_irq(struct hw_interrupt_type *handler)
|
|
return -EBUSY;
|
|
return -EBUSY;
|
|
}
|
|
}
|
|
|
|
|
|
- set_irq_chip(irq, handler);
|
|
|
|
|
|
+ set_irq_chip_and_handler(irq, chip, handle_edge_irq);
|
|
set_irq_data(irq, entry);
|
|
set_irq_data(irq, entry);
|
|
|
|
|
|
return irq;
|
|
return irq;
|
|
@@ -634,16 +572,11 @@ static int msi_capability_init(struct pci_dev *dev)
|
|
struct msi_desc *entry;
|
|
struct msi_desc *entry;
|
|
int pos, irq;
|
|
int pos, irq;
|
|
u16 control;
|
|
u16 control;
|
|
- struct hw_interrupt_type *handler;
|
|
|
|
|
|
|
|
pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
|
|
pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
|
|
pci_read_config_word(dev, msi_control_reg(pos), &control);
|
|
pci_read_config_word(dev, msi_control_reg(pos), &control);
|
|
/* MSI Entry Initialization */
|
|
/* MSI Entry Initialization */
|
|
- handler = &msi_irq_wo_maskbit_type;
|
|
|
|
- if (is_mask_bit_support(control))
|
|
|
|
- handler = &msi_irq_w_maskbit_type;
|
|
|
|
-
|
|
|
|
- irq = create_msi_irq(handler);
|
|
|
|
|
|
+ irq = create_msi_irq(&msi_chip);
|
|
if (irq < 0)
|
|
if (irq < 0)
|
|
return irq;
|
|
return irq;
|
|
|
|
|
|
@@ -715,7 +648,7 @@ static int msix_capability_init(struct pci_dev *dev,
|
|
|
|
|
|
/* MSI-X Table Initialization */
|
|
/* MSI-X Table Initialization */
|
|
for (i = 0; i < nvec; i++) {
|
|
for (i = 0; i < nvec; i++) {
|
|
- irq = create_msi_irq(&msix_irq_type);
|
|
|
|
|
|
+ irq = create_msi_irq(&msi_chip);
|
|
if (irq < 0)
|
|
if (irq < 0)
|
|
break;
|
|
break;
|
|
|
|
|