diff options
author | Gavin Shan <shangw@linux.vnet.ibm.com> | 2013-04-04 20:54:30 +0400 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2013-04-23 19:50:30 +0400 |
commit | e375b561817d9ae098cc4296a729fc88924a0159 (patch) | |
tree | 7cd6f54166d29a1b7c612e407d57ce79b1024610 | |
parent | 703860ed4e36ded696bd44af6107243fdedfb746 (diff) | |
download | linux-e375b561817d9ae098cc4296a729fc88924a0159.tar.xz |
PCI: Cache MSI/MSI-X capability offsets in struct pci_dev
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>
-rw-r--r-- | drivers/pci/msi.c | 42 | ||||
-rw-r--r-- | include/linux/pci.h | 2 |
2 files changed, 21 insertions, 23 deletions
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 00cc78c7aa04..99befbd99938 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -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); } diff --git a/include/linux/pci.h b/include/linux/pci.h index 9587d4d19279..b73c2460ad57 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -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 */ |