Loading drivers/pci/pcie/aspm.c +25 −42 Original line number Diff line number Diff line Loading @@ -370,56 +370,39 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist) } } static unsigned int __pcie_aspm_check_state_one(struct pci_dev *pdev, unsigned int state) /** * __pcie_aspm_check_state_one - check latency for endpoint device. * @endpoint: pointer to the struct pci_dev of endpoint device * * TBD: The latency from the endpoint to root complex vary per switch's * upstream link state above the device. Here we just do a simple check * which assumes all links above the device can be in L1 state, that * is we just consider the worst case. If switch's upstream link can't * be put into L0S/L1, then our check is too strictly. */ static u32 __pcie_aspm_check_state_one(struct pci_dev *endpoint, u32 state) { struct pci_dev *parent_dev, *tmp_dev; unsigned int l1_latency = 0; struct pcie_link_state *link_state; u32 l1_switch_latency = 0; struct aspm_latency *acceptable; struct pcie_link_state *link; parent_dev = pdev->bus->self; link_state = parent_dev->link_state; state &= link_state->aspm_support; if (state == 0) return 0; acceptable = &link_state->acceptable[PCI_FUNC(pdev->devfn)]; link = endpoint->bus->self->link_state; state &= link->aspm_support; acceptable = &link->acceptable[PCI_FUNC(endpoint->devfn)]; /* * Check latency for endpoint device. * TBD: The latency from the endpoint to root complex vary per * switch's upstream link state above the device. Here we just do a * simple check which assumes all links above the device can be in L1 * state, that is we just consider the worst case. If switch's upstream * link can't be put into L0S/L1, then our check is too strictly. */ tmp_dev = pdev; while (state & (PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1)) { parent_dev = tmp_dev->bus->self; link_state = parent_dev->link_state; while (link && state) { if ((state & PCIE_LINK_STATE_L0S) && (link_state->latency.l0s > acceptable->l0s)) (link->latency.l0s > acceptable->l0s)) state &= ~PCIE_LINK_STATE_L0S; if ((state & PCIE_LINK_STATE_L1) && (link_state->latency.l1 + l1_latency > acceptable->l1)) (link->latency.l1 + l1_switch_latency > acceptable->l1)) state &= ~PCIE_LINK_STATE_L1; if (!parent_dev->bus->self) /* parent_dev is a root port */ break; else { link = link->parent; /* * parent_dev is the downstream port of a switch, make * tmp_dev the upstream port of the switch * Every switch on the path to root complex need 1 * more microsecond for L1. Spec doesn't mention L0s. */ tmp_dev = parent_dev->bus->self; /* * every switch on the path to root complex need 1 more * microsecond for L1. Spec doesn't mention L0S. */ if (state & PCIE_LINK_STATE_L1) l1_latency += 1000; } l1_switch_latency += 1000; } return state; } Loading Loading
drivers/pci/pcie/aspm.c +25 −42 Original line number Diff line number Diff line Loading @@ -370,56 +370,39 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist) } } static unsigned int __pcie_aspm_check_state_one(struct pci_dev *pdev, unsigned int state) /** * __pcie_aspm_check_state_one - check latency for endpoint device. * @endpoint: pointer to the struct pci_dev of endpoint device * * TBD: The latency from the endpoint to root complex vary per switch's * upstream link state above the device. Here we just do a simple check * which assumes all links above the device can be in L1 state, that * is we just consider the worst case. If switch's upstream link can't * be put into L0S/L1, then our check is too strictly. */ static u32 __pcie_aspm_check_state_one(struct pci_dev *endpoint, u32 state) { struct pci_dev *parent_dev, *tmp_dev; unsigned int l1_latency = 0; struct pcie_link_state *link_state; u32 l1_switch_latency = 0; struct aspm_latency *acceptable; struct pcie_link_state *link; parent_dev = pdev->bus->self; link_state = parent_dev->link_state; state &= link_state->aspm_support; if (state == 0) return 0; acceptable = &link_state->acceptable[PCI_FUNC(pdev->devfn)]; link = endpoint->bus->self->link_state; state &= link->aspm_support; acceptable = &link->acceptable[PCI_FUNC(endpoint->devfn)]; /* * Check latency for endpoint device. * TBD: The latency from the endpoint to root complex vary per * switch's upstream link state above the device. Here we just do a * simple check which assumes all links above the device can be in L1 * state, that is we just consider the worst case. If switch's upstream * link can't be put into L0S/L1, then our check is too strictly. */ tmp_dev = pdev; while (state & (PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1)) { parent_dev = tmp_dev->bus->self; link_state = parent_dev->link_state; while (link && state) { if ((state & PCIE_LINK_STATE_L0S) && (link_state->latency.l0s > acceptable->l0s)) (link->latency.l0s > acceptable->l0s)) state &= ~PCIE_LINK_STATE_L0S; if ((state & PCIE_LINK_STATE_L1) && (link_state->latency.l1 + l1_latency > acceptable->l1)) (link->latency.l1 + l1_switch_latency > acceptable->l1)) state &= ~PCIE_LINK_STATE_L1; if (!parent_dev->bus->self) /* parent_dev is a root port */ break; else { link = link->parent; /* * parent_dev is the downstream port of a switch, make * tmp_dev the upstream port of the switch * Every switch on the path to root complex need 1 * more microsecond for L1. Spec doesn't mention L0s. */ tmp_dev = parent_dev->bus->self; /* * every switch on the path to root complex need 1 more * microsecond for L1. Spec doesn't mention L0S. */ if (state & PCIE_LINK_STATE_L1) l1_latency += 1000; } l1_switch_latency += 1000; } return state; } Loading