aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/pci/ats.c17
-rw-r--r--drivers/pci/pci.c1
-rw-r--r--drivers/pci/pci.h8
3 files changed, 26 insertions, 0 deletions
diff --git a/drivers/pci/ats.c b/drivers/pci/ats.c
index e11ebafaf77..a4a1b369853 100644
--- a/drivers/pci/ats.c
+++ b/drivers/pci/ats.c
@@ -128,6 +128,23 @@ void pci_disable_ats(struct pci_dev *dev)
}
EXPORT_SYMBOL_GPL(pci_disable_ats);
+void pci_restore_ats_state(struct pci_dev *dev)
+{
+ u16 ctrl;
+
+ if (!pci_ats_enabled(dev))
+ return;
+ if (!pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ATS))
+ BUG();
+
+ ctrl = PCI_ATS_CTRL_ENABLE;
+ if (!dev->is_virtfn)
+ ctrl |= PCI_ATS_CTRL_STU(dev->ats->stu - PCI_ATS_MIN_STU);
+
+ pci_write_config_word(dev, dev->ats->pos + PCI_ATS_CTRL, ctrl);
+}
+EXPORT_SYMBOL_GPL(pci_restore_ats_state);
+
/**
* pci_ats_queue_depth - query the ATS Invalidate Queue Depth
* @dev: the PCI device
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 54343aa5b30..97fff785e97 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -965,6 +965,7 @@ void pci_restore_state(struct pci_dev *dev)
/* PCI Express register must be restored first */
pci_restore_pcie_state(dev);
+ pci_restore_ats_state(dev);
/*
* The Base Address register should be programmed before the command
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 3b6e4ed306b..1009a5e88e5 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -251,6 +251,14 @@ struct pci_sriov {
u8 __iomem *mstate; /* VF Migration State Array */
};
+#ifdef CONFIG_PCI_ATS
+extern void pci_restore_ats_state(struct pci_dev *dev);
+#else
+static inline void pci_restore_ats_state(struct pci_dev *dev)
+{
+}
+#endif /* CONFIG_PCI_ATS */
+
#ifdef CONFIG_PCI_IOV
extern int pci_iov_init(struct pci_dev *dev);
extern void pci_iov_release(struct pci_dev *dev);