summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjorn Helgaas <bhelgaas@google.com>2026-10-14 15:55:54 -0500
committerBjorn Helgaas <bhelgaas@google.com>2026-10-14 15:55:54 -0500
commitf8581fe47cdce2f2e8e5eb3adfb317f8cd22ba44 (patch)
treec6ec77dcb92bbf08bdd6ca7f4ee6e479522abfcf
parent02e2ed9b6a8c24d9c31ecc22378b3a0fda7907e6 (diff)
parent581cf67cb6f66eabc6bcd7f61dd64b2559270507 (diff)
downloadlinux-next-f8581fe47cdce2f2e8e5eb3adfb317f8cd22ba44.tar.gz
linux-next-f8581fe47cdce2f2e8e5eb3adfb317f8cd22ba44.zip
Merge branch 'pci/mps'
- When pcie_set_mps() changes the MPS, update the value in the saved state so a subsequent restore doesn't restore an invalid value (Niklas Cassel) * pci/mps: PCI: Update saved Max Payload Size in pcie_set_mps()
-rw-r--r--drivers/pci/pci.c24
1 files changed, 23 insertions, 1 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index b2879a6be5f8..5b126cd342ca 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -1736,6 +1736,24 @@ static void pci_restore_pcie_state(struct pci_dev *dev)
pcie_capability_write_word(dev, PCI_EXP_SLTCTL2, cap[i++]);
}
+/*
+ * Update the saved copy of the Device Control register after changing it, so
+ * that pci_restore_state() doesn't put back a stale value. Device Control is
+ * the first register saved by pci_save_pcie_state().
+ */
+static void pcie_update_saved_devctl(struct pci_dev *dev, u16 clear, u16 set)
+{
+ struct pci_cap_saved_state *save_state;
+ u16 *devctl;
+
+ save_state = pci_find_saved_cap(dev, PCI_CAP_ID_EXP);
+ if (!save_state)
+ return;
+
+ devctl = (u16 *)&save_state->cap.data[0];
+ *devctl = (*devctl & ~clear) | set;
+}
+
static int pci_save_pcix_state(struct pci_dev *dev)
{
int pos;
@@ -5970,8 +5988,12 @@ int pcie_set_mps(struct pci_dev *dev, int mps)
ret = pcie_capability_clear_and_set_word(dev, PCI_EXP_DEVCTL,
PCI_EXP_DEVCTL_PAYLOAD, v);
+ if (ret)
+ return pcibios_err_to_errno(ret);
- return pcibios_err_to_errno(ret);
+ pcie_update_saved_devctl(dev, PCI_EXP_DEVCTL_PAYLOAD, v);
+
+ return 0;
}
EXPORT_SYMBOL(pcie_set_mps);