]> git.proxmox.com Git - mirror_ubuntu-disco-kernel.git/commitdiff
PCI: Cache MSI/MSI-X capability offsets in struct pci_dev
authorGavin Shan <shangw@linux.vnet.ibm.com>
Thu, 4 Apr 2013 16:54:30 +0000 (16:54 +0000)
committerBjorn Helgaas <bhelgaas@google.com>
Tue, 23 Apr 2013 15:50:30 +0000 (09:50 -0600)
The patch caches the MSI and MSI-X capability offset in PCI device
(struct pci_dev) so that we needn't read it from the config space
upon enabling or disabling MSI or MSI-X interrupts.

[bhelgaas: moved pm_cap size change to separate patch]
Signed-off-by: Gavin Shan <shangw@linux.vnet.ibm.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
drivers/pci/msi.c
include/linux/pci.h

index 00cc78c7aa045e9eb5ff747afce8ac3b66a57e7d..99befbd999387369a0073a42632dd90b024fc270 100644 (file)
@@ -111,32 +111,26 @@ void default_restore_msi_irqs(struct pci_dev *dev, int irq)
 }
 #endif
 
-static void msi_set_enable(struct pci_dev *dev, int pos, int enable)
+static void msi_set_enable(struct pci_dev *dev, int enable)
 {
        u16 control;
 
-       BUG_ON(!pos);
-
-       pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &control);
+       pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &control);
        control &= ~PCI_MSI_FLAGS_ENABLE;
        if (enable)
                control |= PCI_MSI_FLAGS_ENABLE;
-       pci_write_config_word(dev, pos + PCI_MSI_FLAGS, control);
+       pci_write_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, control);
 }
 
 static void msix_set_enable(struct pci_dev *dev, int enable)
 {
-       int pos;
        u16 control;
 
-       pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
-       if (pos) {
-               pci_read_config_word(dev, pos + PCI_MSIX_FLAGS, &control);
-               control &= ~PCI_MSIX_FLAGS_ENABLE;
-               if (enable)
-                       control |= PCI_MSIX_FLAGS_ENABLE;
-               pci_write_config_word(dev, pos + PCI_MSIX_FLAGS, control);
-       }
+       pci_read_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, &control);
+       control &= ~PCI_MSIX_FLAGS_ENABLE;
+       if (enable)
+               control |= PCI_MSIX_FLAGS_ENABLE;
+       pci_write_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, control);
 }
 
 static inline __attribute_const__ u32 msi_mask(unsigned x)
@@ -402,7 +396,7 @@ static void __pci_restore_msi_state(struct pci_dev *dev)
        pos = entry->msi_attrib.pos;
 
        pci_intx_for_msi(dev, 0);
-       msi_set_enable(dev, pos, 0);
+       msi_set_enable(dev, 0);
        arch_restore_msi_irqs(dev, dev->irq);
 
        pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &control);
@@ -557,7 +551,7 @@ static int msi_capability_init(struct pci_dev *dev, int nvec)
        unsigned mask;
 
        pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
-       msi_set_enable(dev, pos, 0);    /* Disable MSI during set up */
+       msi_set_enable(dev, 0); /* Disable MSI during set up */
 
        pci_read_config_word(dev, msi_control_reg(pos), &control);
        /* MSI Entry Initialization */
@@ -598,7 +592,7 @@ static int msi_capability_init(struct pci_dev *dev, int nvec)
 
        /* Set MSI enabled bits  */
        pci_intx_for_msi(dev, 0);
-       msi_set_enable(dev, pos, 1);
+       msi_set_enable(dev, 1);
        dev->msi_enabled = 1;
 
        dev->irq = entry->irq;
@@ -885,7 +879,7 @@ void pci_msi_shutdown(struct pci_dev *dev)
        desc = list_first_entry(&dev->msi_list, struct msi_desc, list);
        pos = desc->msi_attrib.pos;
 
-       msi_set_enable(dev, pos, 0);
+       msi_set_enable(dev, 0);
        pci_intx_for_msi(dev, 1);
        dev->msi_enabled = 0;
 
@@ -1048,15 +1042,17 @@ EXPORT_SYMBOL(pci_msi_enabled);
 
 void pci_msi_init_pci_dev(struct pci_dev *dev)
 {
-       int pos;
        INIT_LIST_HEAD(&dev->msi_list);
 
        /* Disable the msi hardware to avoid screaming interrupts
         * during boot.  This is the power on reset default so
         * usually this should be a noop.
         */
-       pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
-       if (pos)
-               msi_set_enable(dev, pos, 0);
-       msix_set_enable(dev, 0);
+       dev->msi_cap = pci_find_capability(dev, PCI_CAP_ID_MSI);
+       if (dev->msi_cap)
+               msi_set_enable(dev, 0);
+
+       dev->msix_cap = pci_find_capability(dev, PCI_CAP_ID_MSIX);
+       if (dev->msix_cap)
+               msix_set_enable(dev, 0);
 }
index 9587d4d19279287c4b9d9a058515e876ee0eada2..b73c2460ad57d1b267bf654df20fe1da68bd37d4 100644 (file)
@@ -232,6 +232,8 @@ struct pci_dev {
        u8              revision;       /* PCI revision, low byte of class word */
        u8              hdr_type;       /* PCI header type (`multi' flag masked out) */
        u8              pcie_cap;       /* PCI-E capability offset */
+       u8              msi_cap;        /* MSI capability offset */
+       u8              msix_cap;       /* MSI-X capability offset */
        u8              pcie_mpss:3;    /* PCI-E Max Payload Size Supported */
        u8              rom_base_reg;   /* which config register controls the ROM */
        u8              pin;            /* which interrupt pin this device uses */