mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2025-01-22 05:44:31 +08:00
PCI: imx6: Add speed change timeout message
Currently, the timeout is never detected as count has a value of -1 if a timeout happens, but the code is checking for 0. Also, this patch removes the unneeded final wait if a timeout occurs. [bhelgaas: reworked starting from http://lkml.kernel.org/r/1433543864-7252-1-git-send-email-troy.kisky@boundarydevices.com] Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
This commit is contained in:
parent
5ebe6afaf0
commit
a0427464cf
@ -352,6 +352,23 @@ static int imx6_pcie_wait_for_link(struct pcie_port *pp)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int imx6_pcie_wait_for_speed_change(struct pcie_port *pp)
|
||||||
|
{
|
||||||
|
uint32_t tmp;
|
||||||
|
unsigned int retries;
|
||||||
|
|
||||||
|
for (retries = 0; retries < 200; retries++) {
|
||||||
|
tmp = readl(pp->dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL);
|
||||||
|
/* Test if the speed change finished. */
|
||||||
|
if (!(tmp & PORT_LOGIC_SPEED_CHANGE))
|
||||||
|
return 0;
|
||||||
|
usleep_range(100, 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
dev_err(pp->dev, "Speed change timeout\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
static irqreturn_t imx6_pcie_msi_handler(int irq, void *arg)
|
static irqreturn_t imx6_pcie_msi_handler(int irq, void *arg)
|
||||||
{
|
{
|
||||||
struct pcie_port *pp = arg;
|
struct pcie_port *pp = arg;
|
||||||
@ -363,7 +380,7 @@ static int imx6_pcie_start_link(struct pcie_port *pp)
|
|||||||
{
|
{
|
||||||
struct imx6_pcie *imx6_pcie = to_imx6_pcie(pp);
|
struct imx6_pcie *imx6_pcie = to_imx6_pcie(pp);
|
||||||
uint32_t tmp;
|
uint32_t tmp;
|
||||||
int ret, count;
|
int ret;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Force Gen1 operation when starting the link. In case the link is
|
* Force Gen1 operation when starting the link. In case the link is
|
||||||
@ -397,29 +414,22 @@ static int imx6_pcie_start_link(struct pcie_port *pp)
|
|||||||
tmp |= PORT_LOGIC_SPEED_CHANGE;
|
tmp |= PORT_LOGIC_SPEED_CHANGE;
|
||||||
writel(tmp, pp->dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL);
|
writel(tmp, pp->dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL);
|
||||||
|
|
||||||
count = 200;
|
ret = imx6_pcie_wait_for_speed_change(pp);
|
||||||
while (count--) {
|
if (ret) {
|
||||||
tmp = readl(pp->dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL);
|
dev_err(pp->dev, "Failed to bring link up!\n");
|
||||||
/* Test if the speed change finished. */
|
return ret;
|
||||||
if (!(tmp & PORT_LOGIC_SPEED_CHANGE))
|
|
||||||
break;
|
|
||||||
usleep_range(100, 1000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make sure link training is finished as well! */
|
/* Make sure link training is finished as well! */
|
||||||
if (count)
|
ret = imx6_pcie_wait_for_link(pp);
|
||||||
ret = imx6_pcie_wait_for_link(pp);
|
|
||||||
else
|
|
||||||
ret = -EINVAL;
|
|
||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(pp->dev, "Failed to bring link up!\n");
|
dev_err(pp->dev, "Failed to bring link up!\n");
|
||||||
} else {
|
return ret;
|
||||||
tmp = readl(pp->dbi_base + 0x80);
|
|
||||||
dev_dbg(pp->dev, "Link up, Gen=%i\n", (tmp >> 16) & 0xf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
tmp = readl(pp->dbi_base + 0x80);
|
||||||
|
dev_dbg(pp->dev, "Link up, Gen=%i\n", (tmp >> 16) & 0xf);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void imx6_pcie_host_init(struct pcie_port *pp)
|
static void imx6_pcie_host_init(struct pcie_port *pp)
|
||||||
|
Loading…
Reference in New Issue
Block a user