summary refs log tree commit diff
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 e11ebafaf774..a4a1b369853b 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 54343aa5b30a..97fff785e97e 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 3b6e4ed306b6..1009a5e88e53 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);