From michael@ozlabs.org Thu Jan 25 14:14:57 2007 From: Michael Ellerman Date: Thu, 25 Jan 2007 19:34:09 +1100 Subject: MSI: Abstract MSI suspend To: linux-pci@atrey.karlin.mff.cuni.cz Cc: Greg Kroah-Hartman , Eric W. Biederman , David S. Miller , Kyle McMartin , , Brice Goglin , Message-ID: <20070125083410.631EEDE277@ozlabs.org> Currently pci_disable_device() disables MSI on a device by twiddling bits in config space via disable_msi_mode(). On some platforms that may not be appropriate, so abstract the MSI suspend logic into pci_disable_device_msi(). Signed-off-by: Michael Ellerman Signed-off-by: Greg Kroah-Hartman --- drivers/pci/msi.c | 11 +++++++++++ drivers/pci/pci.c | 7 +------ drivers/pci/pci.h | 2 ++ 3 files changed, 14 insertions(+), 6 deletions(-) --- gregkh-2.6.orig/drivers/pci/msi.c +++ gregkh-2.6/drivers/pci/msi.c @@ -272,6 +272,17 @@ void disable_msi_mode(struct pci_dev *de pci_intx(dev, 1); /* enable intx */ } +void pci_disable_device_msi(struct pci_dev *dev) +{ + if (dev->msi_enabled) + disable_msi_mode(dev, pci_find_capability(dev, PCI_CAP_ID_MSI), + PCI_CAP_ID_MSI); + + if (dev->msix_enabled) + disable_msi_mode(dev, pci_find_capability(dev, PCI_CAP_ID_MSI), + PCI_CAP_ID_MSIX); +} + static int msi_lookup_irq(struct pci_dev *dev, int type) { int irq; --- gregkh-2.6.orig/drivers/pci/pci.c +++ gregkh-2.6/drivers/pci/pci.c @@ -772,12 +772,7 @@ pci_disable_device(struct pci_dev *dev) if (atomic_sub_return(1, &dev->enable_cnt) != 0) return; - if (dev->msi_enabled) - disable_msi_mode(dev, pci_find_capability(dev, PCI_CAP_ID_MSI), - PCI_CAP_ID_MSI); - if (dev->msix_enabled) - disable_msi_mode(dev, pci_find_capability(dev, PCI_CAP_ID_MSI), - PCI_CAP_ID_MSIX); + pci_disable_device_msi(dev); pci_read_config_word(dev, PCI_COMMAND, &pci_command); if (pci_command & PCI_COMMAND_MASTER) { --- gregkh-2.6.orig/drivers/pci/pci.h +++ gregkh-2.6/drivers/pci/pci.h @@ -47,9 +47,11 @@ extern unsigned int pci_pm_d3_delay; #ifdef CONFIG_PCI_MSI void disable_msi_mode(struct pci_dev *dev, int pos, int type); +extern void pci_disable_device_msi(struct pci_dev *dev); void pci_no_msi(void); #else static inline void disable_msi_mode(struct pci_dev *dev, int pos, int type) { } +static inline void pci_disable_device_msi(struct pci_dev *dev) { } static inline void pci_no_msi(void) { } #endif