}
}
-static void msix_flush_writes(unsigned int irq)
+static inline __attribute_const__ u32 msi_mask(unsigned x)
+{
+ /* Don't shift by >= width of type */
+ if (x >= 5)
+ return 0xffffffff;
+ return (1 << (1 << x)) - 1;
+}
+
+static void msix_flush_writes(struct irq_desc *desc)
{
struct msi_desc *entry;
- entry = get_irq_msi(irq);
+ entry = get_irq_desc_msi(desc);
BUG_ON(!entry || !entry->dev);
switch (entry->msi_attrib.type) {
case PCI_CAP_ID_MSI:
* Returns 1 if it succeeded in masking the interrupt and 0 if the device
* doesn't support MSI masking.
*/
-static int msi_set_mask_bits(unsigned int irq, u32 mask, u32 flag)
+static int msi_set_mask_bits(struct irq_desc *desc, u32 mask, u32 flag)
{
struct msi_desc *entry;
- entry = get_irq_msi(irq);
+ entry = get_irq_desc_msi(desc);
BUG_ON(!entry || !entry->dev);
switch (entry->msi_attrib.type) {
case PCI_CAP_ID_MSI:
return 1;
}
-void read_msi_msg(unsigned int irq, struct msi_msg *msg)
+void read_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg)
{
- struct msi_desc *entry = get_irq_msi(irq);
+ struct msi_desc *entry = get_irq_desc_msi(desc);
switch(entry->msi_attrib.type) {
case PCI_CAP_ID_MSI:
{
}
}
-void write_msi_msg(unsigned int irq, struct msi_msg *msg)
+void read_msi_msg(unsigned int irq, struct msi_msg *msg)
+{
+ struct irq_desc *desc = irq_to_desc(irq);
+
+ read_msi_msg_desc(desc, msg);
+}
+
+void write_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg)
{
- struct msi_desc *entry = get_irq_msi(irq);
+ struct msi_desc *entry = get_irq_desc_msi(desc);
switch (entry->msi_attrib.type) {
case PCI_CAP_ID_MSI:
{
entry->msg = *msg;
}
+void write_msi_msg(unsigned int irq, struct msi_msg *msg)
+{
+ struct irq_desc *desc = irq_to_desc(irq);
+
+ write_msi_msg_desc(desc, msg);
+}
+
void mask_msi_irq(unsigned int irq)
{
- msi_set_mask_bits(irq, 1, 1);
- msix_flush_writes(irq);
+ struct irq_desc *desc = irq_to_desc(irq);
+
+ msi_set_mask_bits(desc, 1, 1);
+ msix_flush_writes(desc);
}
void unmask_msi_irq(unsigned int irq)
{
- msi_set_mask_bits(irq, 1, 0);
- msix_flush_writes(irq);
+ struct irq_desc *desc = irq_to_desc(irq);
+
+ msi_set_mask_bits(desc, 1, 0);
+ msix_flush_writes(desc);
}
static int msi_free_irqs(struct pci_dev* dev);
-
static struct msi_desc* alloc_msi_entry(void)
{
struct msi_desc *entry;
pci_intx_for_msi(dev, 0);
msi_set_enable(dev, 0);
write_msi_msg(dev->irq, &entry->msg);
- if (entry->msi_attrib.maskbit)
- msi_set_mask_bits(dev->irq, entry->msi_attrib.maskbits_mask,
+ if (entry->msi_attrib.maskbit) {
+ struct irq_desc *desc = irq_to_desc(dev->irq);
+ msi_set_mask_bits(desc, entry->msi_attrib.maskbits_mask,
entry->msi_attrib.masked);
+ }
pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &control);
control &= ~PCI_MSI_FLAGS_QSIZE;
msix_set_enable(dev, 0);
list_for_each_entry(entry, &dev->msi_list, list) {
+ struct irq_desc *desc = irq_to_desc(entry->irq);
write_msi_msg(entry->irq, &entry->msg);
- msi_set_mask_bits(entry->irq, 1, entry->msi_attrib.masked);
+ msi_set_mask_bits(desc, 1, entry->msi_attrib.masked);
}
BUG_ON(list_empty(&dev->msi_list));
entry->msi_attrib.masked = 1;
entry->msi_attrib.default_irq = dev->irq; /* Save IOAPIC IRQ */
entry->msi_attrib.pos = pos;
- if (entry->msi_attrib.maskbit) {
- entry->mask_base = (void __iomem *)(long)msi_mask_bits_reg(pos,
- entry->msi_attrib.is_64);
- }
entry->dev = dev;
if (entry->msi_attrib.maskbit) {
- unsigned int maskbits, temp;
+ unsigned int base, maskbits, temp;
+
+ base = msi_mask_bits_reg(pos, entry->msi_attrib.is_64);
+ entry->mask_base = (void __iomem *)(long)base;
+
/* All MSIs are unmasked by default, Mask them all */
- pci_read_config_dword(dev,
- msi_mask_bits_reg(pos, entry->msi_attrib.is_64),
- &maskbits);
- temp = (1 << multi_msi_capable(control));
- temp = ((temp - 1) & ~temp);
+ pci_read_config_dword(dev, base, &maskbits);
+ temp = msi_mask((control & PCI_MSI_FLAGS_QMASK) >> 1);
maskbits |= temp;
- pci_write_config_dword(dev, entry->msi_attrib.is_64, maskbits);
+ pci_write_config_dword(dev, base, maskbits);
entry->msi_attrib.maskbits_mask = temp;
}
list_add_tail(&entry->list, &dev->msi_list);
/* Return the the pci reset with msi irqs unmasked */
if (entry->msi_attrib.maskbit) {
u32 mask = entry->msi_attrib.maskbits_mask;
- msi_set_mask_bits(dev->irq, mask, ~mask);
+ struct irq_desc *desc = irq_to_desc(dev->irq);
+ msi_set_mask_bits(desc, mask, ~mask);
}
if (!entry->dev || entry->msi_attrib.type != PCI_CAP_ID_MSI)
return;
pci_msi_enable = 0;
}
-void pci_msi_init_pci_dev(struct pci_dev *dev)
-{
- INIT_LIST_HEAD(&dev->msi_list);
-}
-
-#ifdef CONFIG_ACPI
-#include <linux/acpi.h>
-#include <linux/pci-acpi.h>
-static void __devinit msi_acpi_init(void)
+/**
+ * pci_msi_enabled - is MSI enabled?
+ *
+ * Returns true if MSI has not been disabled by the command-line option
+ * pci=nomsi.
+ **/
+int pci_msi_enabled(void)
{
- if (acpi_pci_disabled)
- return;
- pci_osc_support_set(OSC_MSI_SUPPORT);
- pcie_osc_support_set(OSC_MSI_SUPPORT);
+ return pci_msi_enable;
}
-#else
-static inline void msi_acpi_init(void) { }
-#endif /* CONFIG_ACPI */
+EXPORT_SYMBOL(pci_msi_enabled);
-void __devinit msi_init(void)
+void pci_msi_init_pci_dev(struct pci_dev *dev)
{
- if (!pci_msi_enable)
- return;
- msi_acpi_init();
+ INIT_LIST_HEAD(&dev->msi_list);
}