diff mbox series

[RFC,v3,2/5] PCI/ASPM: Remove struct pcie_link_state.parent

Message ID 20211106175503.27178-3-refactormyself@gmail.com (mailing list archive)
State Superseded
Delegated to: Bjorn Helgaas
Headers show
Series Remove unncessary linked list from aspm.c | expand

Commit Message

Saheed O. Bolarinwa Nov. 6, 2021, 5:55 p.m. UTC
From: "Bolarinwa O. Saheed" <refactormyself@gmail.com>

Information cached in struct pcie_link_state.parent is accessible
via struct pci_dev.

 - remove *parent* from the struct pcie_link_state
 - creates pcie_upstream_link() to obtain this value directly
 - replaces references to pcie_link_state.parent with a call to
   pcie_upstream_link()
 - remove BUG_ON(root->parent), instead obtain the root of the
   device returned by pcie_upstream_link

NOTE/CLARIFICATION:
The logic of pcie_upstream_link() especially as expressed in its
use within alloc_pcie_link_state() assumes that:

pdev->bus->parent->self == pdev->bus->self->bus->self

Signed-off-by: Saheed O. Bolarinwa <refactormyself@gmail.com>
---
 drivers/pci/pcie/aspm.c | 39 ++++++++++++++++++++++++++-------------
 1 file changed, 26 insertions(+), 13 deletions(-)
diff mbox series

Patch

diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index 013a47f587ce..75618302fb87 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -50,7 +50,6 @@  struct pcie_link_state {
 	struct pci_dev *pdev;		/* Upstream component of the Link */
 	struct pci_dev *downstream;	/* Downstream component, function 0 */
 	struct pcie_link_state *root;	/* pointer to the root port link */
-	struct pcie_link_state *parent;	/* pointer to the parent Link state */
 	struct list_head sibling;	/* node in link_list */
 
 	/* ASPM state */
@@ -139,6 +138,18 @@  static int policy_to_clkpm_state(struct pcie_link_state *link)
 	return 0;
 }
 
+static struct pcie_link_state *pcie_upstream_link(struct pci_dev *dev)
+{
+	struct pci_dev *bridge;
+
+	bridge = pci_upstream_bridge(dev);
+	if (!bridge)
+		return NULL;
+
+	bridge = pci_upstream_bridge(bridge);
+	return bridge ? bridge->link_state : NULL;
+}
+
 static void pcie_set_clkpm_nocheck(struct pcie_link_state *link, int enable)
 {
 	struct pci_dev *child;
@@ -419,7 +430,7 @@  static void pcie_aspm_check_latency(struct pci_dev *endpoint)
 			link->aspm_capable &= ~ASPM_STATE_L1;
 		l1_switch_latency += 1000;
 
-		link = link->parent;
+		link = pcie_upstream_link(link->pdev);
 	}
 }
 
@@ -795,7 +806,7 @@  static void pcie_config_aspm_path(struct pcie_link_state *link)
 {
 	while (link) {
 		pcie_config_aspm_link(link, policy_to_aspm_state(link));
-		link = link->parent;
+		link = pcie_upstream_link(link->pdev);
 	}
 }
 
@@ -864,16 +875,15 @@  static struct pcie_link_state *alloc_pcie_link_state(struct pci_dev *pdev)
 	    !pdev->bus->parent->self) {
 		link->root = link;
 	} else {
-		struct pcie_link_state *parent;
+		struct pcie_link_state *uplink_bridge;
 
-		parent = pdev->bus->parent->self->link_state;
-		if (!parent) {
+		uplink_bridge = pcie_upstream_link(pdev);
+		if (!uplink_bridge) {
 			kfree(link);
 			return NULL;
 		}
 
-		link->parent = parent;
-		link->root = link->parent->root;
+		link->root = ulink_bridge->root;
 	}
 
 	list_add(&link->sibling, &link_list);
@@ -962,7 +972,10 @@  void pcie_aspm_init_link_state(struct pci_dev *pdev)
 static void pcie_update_aspm_capable(struct pcie_link_state *root)
 {
 	struct pcie_link_state *link;
-	BUG_ON(root->parent);
+	struct pcie_link_state *uplink = pcie_upstream_link(root->pdev);
+
+	root = uplink ? uplink->root : root;
+
 	list_for_each_entry(link, &link_list, sibling) {
 		if (link->root != root)
 			continue;
@@ -986,7 +999,7 @@  static void pcie_update_aspm_capable(struct pcie_link_state *root)
 void pcie_aspm_exit_link_state(struct pci_dev *pdev)
 {
 	struct pci_dev *parent = pdev->bus->self;
-	struct pcie_link_state *link, *root, *parent_link;
+	struct pcie_link_state *link, *root, *uplink_bridge;
 
 	if (!parent || !parent->link_state)
 		return;
@@ -1002,7 +1015,7 @@  void pcie_aspm_exit_link_state(struct pci_dev *pdev)
 
 	link = parent->link_state;
 	root = link->root;
-	parent_link = link->parent;
+	uplink_bridge = pcie_upstream_link(link->pdev);
 
 	/* All functions are removed, so just disable ASPM for the link */
 	pcie_config_aspm_link(link, 0);
@@ -1011,9 +1024,9 @@  void pcie_aspm_exit_link_state(struct pci_dev *pdev)
 	free_link_state(link);
 
 	/* Recheck latencies and configure upstream links */
-	if (parent_link) {
+	if (uplink_bridge) {
 		pcie_update_aspm_capable(root);
-		pcie_config_aspm_path(parent_link);
+		pcie_config_aspm_path(uplink_bridge);
 	}
 out:
 	mutex_unlock(&aspm_lock);