aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/msi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/msi.c')
-rw-r--r--drivers/pci/msi.c29
1 files changed, 18 insertions, 11 deletions
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index b4a90badd0a6..44f15ff70c1d 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -103,6 +103,16 @@ static void msix_set_enable(struct pci_dev *dev, int enable)
103 } 103 }
104} 104}
105 105
106/*
107 * Essentially, this is ((1 << (1 << x)) - 1), but without the
108 * undefinedness of a << 32.
109 */
110static inline __attribute_const__ u32 msi_mask(unsigned x)
111{
112 static const u32 mask[] = { 1, 2, 4, 0xf, 0xff, 0xffff, 0xffffffff };
113 return mask[x];
114}
115
106static void msix_flush_writes(struct irq_desc *desc) 116static void msix_flush_writes(struct irq_desc *desc)
107{ 117{
108 struct msi_desc *entry; 118 struct msi_desc *entry;
@@ -398,21 +408,18 @@ static int msi_capability_init(struct pci_dev *dev)
398 entry->msi_attrib.masked = 1; 408 entry->msi_attrib.masked = 1;
399 entry->msi_attrib.default_irq = dev->irq; /* Save IOAPIC IRQ */ 409 entry->msi_attrib.default_irq = dev->irq; /* Save IOAPIC IRQ */
400 entry->msi_attrib.pos = pos; 410 entry->msi_attrib.pos = pos;
401 if (entry->msi_attrib.maskbit) {
402 entry->mask_base = (void __iomem *)(long)msi_mask_bits_reg(pos,
403 entry->msi_attrib.is_64);
404 }
405 entry->dev = dev; 411 entry->dev = dev;
406 if (entry->msi_attrib.maskbit) { 412 if (entry->msi_attrib.maskbit) {
407 unsigned int maskbits, temp; 413 unsigned int base, maskbits, temp;
414
415 base = msi_mask_bits_reg(pos, entry->msi_attrib.is_64);
416 entry->mask_base = (void __iomem *)(long)base;
417
408 /* All MSIs are unmasked by default, Mask them all */ 418 /* All MSIs are unmasked by default, Mask them all */
409 pci_read_config_dword(dev, 419 pci_read_config_dword(dev, base, &maskbits);
410 msi_mask_bits_reg(pos, entry->msi_attrib.is_64), 420 temp = msi_mask((control & PCI_MSI_FLAGS_QMASK) >> 1);
411 &maskbits);
412 temp = (1 << multi_msi_capable(control));
413 temp = ((temp - 1) & ~temp);
414 maskbits |= temp; 421 maskbits |= temp;
415 pci_write_config_dword(dev, entry->msi_attrib.is_64, maskbits); 422 pci_write_config_dword(dev, base, maskbits);
416 entry->msi_attrib.maskbits_mask = temp; 423 entry->msi_attrib.maskbits_mask = temp;
417 } 424 }
418 list_add_tail(&entry->list, &dev->msi_list); 425 list_add_tail(&entry->list, &dev->msi_list);