All of lore.kernel.org
 help / color / mirror / Atom feed
From: Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>
To: Bjorn Helgaas <bhelgaas@google.com>
Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org,
	mani@kernel.org,
	Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>
Subject: [PATCH v6 2/3] PCI/ASPM: Disable/restore ASPM on every function for multi-function devices
Date: Mon, 27 Jul 2026 19:32:37 +0530	[thread overview]
Message-ID: <20260727-aspm-v6-2-2ebb3ee7ef71@oss.qualcomm.com> (raw)
In-Reply-To: <20260727-aspm-v6-0-2ebb3ee7ef71@oss.qualcomm.com>

pcie_aspm_cap_init() disables ASPM L0s/L1 before touching L1SS config,
then restores the pre-existing state afterward. Both steps only ever
touched link->downstream, i.e. function 0 of the downstream component,
leaving sibling functions (>0) on a multi-function device untouched.

This means the "disable" step does not actually disable ASPM link-wide
on a multi-function device: a sibling function can still have L1
enabled even after this step runs. PCIe r6.2 sec 7.5.3.7 recommends
programming the same ASPM Control value for all functions of a
multi-function device, and pcie_config_aspm_link() already loops over
every function on the bus for exactly this reason.

Loop over every function on linkbus->devices for both the disable and
restore steps, keeping the existing PCIe r6.2 sec 7.5.3.7 ordering
(disable downstream functions before upstream, restore upstream before
downstream functions). The masked pcie_capability_clear_and_set_word()
accessor from the previous commit makes this safe: it only ever
touches the ASPM Control bits, so function-specific bits elsewhere in
LNKCTL (e.g. Read Completion Boundary, CLKREQ Enable) on sibling
functions are left untouched.

Fixes: 7447990137bf ("PCI/ASPM: Disable L1 before disabling L1 PM Substates")
Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>
---
 drivers/pci/pcie/aspm.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index 3f9c0f9a1cc7..544f35bb2555 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -861,6 +861,7 @@ static void pcie_aspm_override_default_link_state(struct pcie_link_state *link)
 static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
 {
 	struct pci_dev *child = link->downstream, *parent = link->pdev;
+	struct pci_dev *fn;
 	u16 parent_lnkctl, child_lnkctl;
 	struct pci_bus *linkbus = parent->subordinate;
 
@@ -894,8 +895,9 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
 	/* Disable L0s/L1 before updating L1SS config */
 	if (FIELD_GET(PCI_EXP_LNKCTL_ASPMC, child_lnkctl) ||
 	    FIELD_GET(PCI_EXP_LNKCTL_ASPMC, parent_lnkctl)) {
-		pcie_capability_clear_and_set_word(child, PCI_EXP_LNKCTL,
-						   PCI_EXP_LNKCTL_ASPMC, 0);
+		list_for_each_entry(fn, &linkbus->devices, bus_list)
+			pcie_capability_clear_and_set_word(fn, PCI_EXP_LNKCTL,
+							   PCI_EXP_LNKCTL_ASPMC, 0);
 		pcie_capability_clear_and_set_word(parent, PCI_EXP_LNKCTL,
 						   PCI_EXP_LNKCTL_ASPMC, 0);
 	}
@@ -930,9 +932,10 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
 		pcie_capability_clear_and_set_word(parent, PCI_EXP_LNKCTL,
 						   PCI_EXP_LNKCTL_ASPMC,
 						   parent_lnkctl & PCI_EXP_LNKCTL_ASPMC);
-		pcie_capability_clear_and_set_word(child, PCI_EXP_LNKCTL,
-						   PCI_EXP_LNKCTL_ASPMC,
-						   child_lnkctl & PCI_EXP_LNKCTL_ASPMC);
+		list_for_each_entry(fn, &linkbus->devices, bus_list)
+			pcie_capability_clear_and_set_word(fn, PCI_EXP_LNKCTL,
+							   PCI_EXP_LNKCTL_ASPMC,
+							   child_lnkctl & PCI_EXP_LNKCTL_ASPMC);
 	}
 
 	/* Save default state */

-- 
2.34.1


  parent reply	other threads:[~2026-07-27 14:02 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-27 14:02 [PATCH v6 0/3] PCI/ASPM: Mask ASPM states based on Devicetree properties Krishna Chaitanya Chundru
2026-07-27 14:02 ` [PATCH v6 1/3] PCI/ASPM: Use pcie_capability_clear_and_set_word() for ASPM disable/restore Krishna Chaitanya Chundru
2026-07-27 14:11   ` sashiko-bot
2026-07-27 14:02 ` Krishna Chaitanya Chundru [this message]
2026-07-27 14:15   ` [PATCH v6 2/3] PCI/ASPM: Disable/restore ASPM on every function for multi-function devices sashiko-bot
2026-07-27 14:02 ` [PATCH v6 3/3] PCI/ASPM: Mask ASPM states based on Devicetree properties Krishna Chaitanya Chundru
2026-07-27 14:16   ` sashiko-bot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260727-aspm-v6-2-2ebb3ee7ef71@oss.qualcomm.com \
    --to=krishna.chundru@oss.qualcomm.com \
    --cc=bhelgaas@google.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=mani@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.