diff mbox

[7/14] PCI ASPM: cleanup initialization

Message ID 4A0A3BFE.2010801@jp.fujitsu.com (mailing list archive)
State Accepted, archived
Headers show

Commit Message

Kenji Kaneshige May 13, 2009, 3:18 a.m. UTC
Clean up ASPM initialization.

Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>

---
 drivers/pci/pcie/aspm.c |  139 +++++++++++++++++++++++++-----------------------
 1 file changed, 73 insertions(+), 66 deletions(-)


--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

Index: 20090508/drivers/pci/pcie/aspm.c
===================================================================
--- 20090508.orig/drivers/pci/pcie/aspm.c
+++ 20090508/drivers/pci/pcie/aspm.c
@@ -126,7 +126,7 @@  static void pcie_set_clock_pm(struct pci
 	link->clkpm_enabled = !!enable;
 }
 
-static void pcie_check_clock_pm(struct pcie_link_state *link, int blacklist)
+static void pcie_clkpm_cap_init(struct pcie_link_state *link, int blacklist)
 {
 	int pos, capable = 1, enabled = 1;
 	u32 reg32;
@@ -151,13 +151,7 @@  static void pcie_check_clock_pm(struct p
 	}
 	link->clkpm_enabled = enabled;
 	link->clkpm_default = enabled;
-	if (!blacklist) {
-		link->clkpm_capable = capable;
-		pcie_set_clock_pm(link, policy_to_clkpm_state(link));
-	} else {
-		link->clkpm_capable = 0;
-		pcie_set_clock_pm(link, 0);
-	}
+	link->clkpm_capable = (blacklist) ? 0 : capable;
 }
 
 static bool pcie_aspm_downstream_has_switch(struct pcie_link_state *link)
@@ -314,12 +308,23 @@  static void pcie_aspm_get_cap_device(str
 	*enabled = reg16 & (PCIE_LINK_STATE_L0S|PCIE_LINK_STATE_L1);
 }
 
-static void pcie_aspm_cap_init(struct pcie_link_state *link)
+static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
 {
 	u32 support, l0s, l1, enabled;
 	struct pci_dev *child, *parent = link->pdev;
 	struct pci_bus *linkbus = parent->subordinate;
 
+	if (blacklist) {
+		/* Set support state to 0, so we will disable ASPM later */
+		link->aspm_support = 0;
+		link->aspm_default = 0;
+		link->aspm_enabled = PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1;
+		return;
+	}
+
+	/* Configure common clock before checking latencies */
+	pcie_aspm_configure_common_clock(link);
+
 	/* upstream component states */
 	pcie_aspm_get_cap_device(parent, &support, &l0s, &l1, &enabled);
 	link->aspm_support = support;
@@ -590,6 +595,42 @@  static int pcie_aspm_sanity_check(struct
 	return 0;
 }
 
+static struct pcie_link_state *pcie_aspm_setup_link_state(struct pci_dev *pdev)
+{
+	struct pcie_link_state *link;
+	int blacklist = !!pcie_aspm_sanity_check(pdev);
+
+	link = kzalloc(sizeof(*link), GFP_KERNEL);
+	if (!link)
+		return NULL;
+	INIT_LIST_HEAD(&link->sibling);
+	INIT_LIST_HEAD(&link->children);
+	INIT_LIST_HEAD(&link->link);
+	link->pdev = pdev;
+	link->has_switch = pcie_aspm_downstream_has_switch(link);
+	if (pdev->pcie_type == PCI_EXP_TYPE_DOWNSTREAM) {
+		struct pcie_link_state *parent;
+		parent = pdev->bus->parent->self->link_state;
+		if (!parent) {
+			kfree(link);
+			return NULL;
+		}
+		link->parent = parent;
+		list_add(&link->link, &parent->children);
+	}
+	list_add(&link->sibling, &link_list);
+
+	pdev->link_state = link;
+
+	/* Check ASPM capability */
+	pcie_aspm_cap_init(link, blacklist);
+
+	/* Check Clock PM capability */
+	pcie_clkpm_cap_init(link, blacklist);
+
+	return link;
+}
+
 /*
  * pcie_aspm_init_link_state: Initiate PCI express link state.
  * It is called after the pcie and its children devices are scaned.
@@ -597,76 +638,42 @@  static int pcie_aspm_sanity_check(struct
  */
 void pcie_aspm_init_link_state(struct pci_dev *pdev)
 {
-	unsigned int state;
-	struct pcie_link_state *link_state;
-	int error = 0;
-	int blacklist;
+	u32 state;
+	struct pcie_link_state *link;
 
 	if (aspm_disabled || !pdev->is_pcie || pdev->link_state)
 		return;
 	if (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT &&
-		pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)
+	    pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)
 		return;
+
 	down_read(&pci_bus_sem);
 	if (list_empty(&pdev->subordinate->devices))
 		goto out;
 
-	blacklist = !!pcie_aspm_sanity_check(pdev);
-
 	mutex_lock(&aspm_lock);
-
-	link_state = kzalloc(sizeof(*link_state), GFP_KERNEL);
-	if (!link_state)
-		goto unlock_out;
-
-	INIT_LIST_HEAD(&link_state->children);
-	INIT_LIST_HEAD(&link_state->link);
-	if (pdev->bus->self) {/* this is a switch */
-		struct pcie_link_state *parent_link_state;
-
-		parent_link_state = pdev->bus->parent->self->link_state;
-		if (!parent_link_state) {
-			kfree(link_state);
-			goto unlock_out;
-		}
-		list_add(&link_state->link, &parent_link_state->children);
-		link_state->parent = parent_link_state;
-	}
-	link_state->pdev = pdev;
-	link_state->has_switch = pcie_aspm_downstream_has_switch(link_state);
-	pdev->link_state = link_state;
-
-	if (!blacklist) {
-		pcie_aspm_configure_common_clock(link_state);
-		pcie_aspm_cap_init(link_state);
+	link = pcie_aspm_setup_link_state(pdev);
+	if (!link)
+		goto unlock;
+	/*
+	 * Setup initial ASPM state
+	 *
+	 * If link has switch, delay the link config. The leaf link
+	 * initialization will config the whole hierarchy. But we must
+	 * make sure BIOS doesn't set unsupported link state.
+	 */
+	if (link->has_switch) {
+		state = pcie_aspm_check_state(link, link->aspm_default);
+		__pcie_aspm_config_link(link, state);
 	} else {
-		link_state->aspm_enabled =
-			(PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1);
-		link_state->aspm_default = 0;
-		/* Set support state to 0, so we will disable ASPM later */
-		link_state->aspm_support = 0;
+		state = policy_to_aspm_state(link);
+		__pcie_aspm_configure_link_state(link, state);
 	}
 
-	list_add(&link_state->sibling, &link_list);
-
-	if (link_state->has_switch) {
-		/*
-		 * If link has switch, delay the link config. The leaf link
-		 * initialization will config the whole hierarchy. but we must
-		 * make sure BIOS doesn't set unsupported link state
-		 **/
-		state = pcie_aspm_check_state(link_state,
-					      link_state->aspm_default);
-		__pcie_aspm_config_link(link_state, state);
-	} else
-		__pcie_aspm_configure_link_state(link_state,
-			policy_to_aspm_state(link_state));
-
-	pcie_check_clock_pm(link_state, blacklist);
-
-unlock_out:
-	if (error)
-		free_link_state(link_state);
+	/* Setup initial Clock PM state */
+	state = (link->clkpm_capable) ? policy_to_clkpm_state(link) : 0;
+	pcie_set_clock_pm(link, state);
+unlock:
 	mutex_unlock(&aspm_lock);
 out:
 	up_read(&pci_bus_sem);