mirror of
https://github.com/adulau/aha.git
synced 2024-12-29 12:16:20 +00:00
PCI ASPM: cleanup __pcie_aspm_check_state_one
Clean up and simplify __pcie_aspm_check_state_one(). 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>
This commit is contained in:
parent
8d349ace9a
commit
f7ea3d7fc0
1 changed files with 25 additions and 42 deletions
|
@ -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 {
|
||||
/*
|
||||
* parent_dev is the downstream port of a switch, make
|
||||
* tmp_dev the upstream port of the switch
|
||||
*/
|
||||
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;
|
||||
}
|
||||
link = link->parent;
|
||||
/*
|
||||
* Every switch on the path to root complex need 1
|
||||
* more microsecond for L1. Spec doesn't mention L0s.
|
||||
*/
|
||||
l1_switch_latency += 1000;
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue