]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
PCI ASPM: cleanup initialization
authorKenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
Wed, 13 May 2009 03:18:22 +0000 (12:18 +0900)
committerJesse Barnes <jbarnes@virtuousgeek.org>
Thu, 18 Jun 2009 21:02:15 +0000 (14:02 -0700)
Clean up ASPM initialization by refactoring some functionality, renaming
functions, and moving things around.

Acked-by: Shaohua Li <shaohua.li@intel.com>
Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
drivers/pci/pcie/aspm.c

index 9eaaf95f65a2e28f3cbfd96381e116ee2a9b0756..68a4d4b15f9f38d0f6562f786f33f5ce178587cf 100644 (file)
@@ -126,7 +126,7 @@ static void pcie_set_clock_pm(struct pcie_link_state *link, int enable)
        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 pcie_link_state *link, int blacklist)
        }
        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(struct pci_dev *pdev, u32 *state,
        *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 pci_dev *pdev)
        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,80 +638,47 @@ static int pcie_aspm_sanity_check(struct pci_dev *pdev)
  */
 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;
+
        /* VIA has a strange chipset, root port is under a bridge */
        if (pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT &&
-               pdev->bus->self)
+           pdev->bus->self)
                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);