提交 5fe5db05 编写于 作者: S Sheng Yang 提交者: Jesse Barnes

PCI: Speed up device reset function

For all devices need to do function level reset, currently we need wait for
at least 200ms, which can be too long if we have lots of devices...

The patch checked pending bit before msleep() to skip some unnecessary
sleeping interval.
Signed-off-by: NSheng Yang <sheng@linux.intel.com>
Signed-off-by: NJesse Barnes <jbarnes@virtuousgeek.org>
上级 4c9c1686
...@@ -2028,18 +2028,24 @@ static int __pcie_flr(struct pci_dev *dev, int probe) ...@@ -2028,18 +2028,24 @@ static int __pcie_flr(struct pci_dev *dev, int probe)
pci_block_user_cfg_access(dev); pci_block_user_cfg_access(dev);
/* Wait for Transaction Pending bit clean */ /* Wait for Transaction Pending bit clean */
pci_read_config_word(dev, exppos + PCI_EXP_DEVSTA, &status);
if (!(status & PCI_EXP_DEVSTA_TRPND))
goto transaction_done;
msleep(100); msleep(100);
pci_read_config_word(dev, exppos + PCI_EXP_DEVSTA, &status); pci_read_config_word(dev, exppos + PCI_EXP_DEVSTA, &status);
if (status & PCI_EXP_DEVSTA_TRPND) { if (!(status & PCI_EXP_DEVSTA_TRPND))
dev_info(&dev->dev, "Busy after 100ms while trying to reset; " goto transaction_done;
dev_info(&dev->dev, "Busy after 100ms while trying to reset; "
"sleeping for 1 second\n"); "sleeping for 1 second\n");
ssleep(1); ssleep(1);
pci_read_config_word(dev, exppos + PCI_EXP_DEVSTA, &status); pci_read_config_word(dev, exppos + PCI_EXP_DEVSTA, &status);
if (status & PCI_EXP_DEVSTA_TRPND) if (status & PCI_EXP_DEVSTA_TRPND)
dev_info(&dev->dev, "Still busy after 1s; " dev_info(&dev->dev, "Still busy after 1s; "
"proceeding with reset anyway\n"); "proceeding with reset anyway\n");
}
transaction_done:
pci_write_config_word(dev, exppos + PCI_EXP_DEVCTL, pci_write_config_word(dev, exppos + PCI_EXP_DEVCTL,
PCI_EXP_DEVCTL_BCR_FLR); PCI_EXP_DEVCTL_BCR_FLR);
mdelay(100); mdelay(100);
...@@ -2066,18 +2072,24 @@ static int __pci_af_flr(struct pci_dev *dev, int probe) ...@@ -2066,18 +2072,24 @@ static int __pci_af_flr(struct pci_dev *dev, int probe)
pci_block_user_cfg_access(dev); pci_block_user_cfg_access(dev);
/* Wait for Transaction Pending bit clean */ /* Wait for Transaction Pending bit clean */
pci_read_config_byte(dev, cappos + PCI_AF_STATUS, &status);
if (!(status & PCI_AF_STATUS_TP))
goto transaction_done;
msleep(100); msleep(100);
pci_read_config_byte(dev, cappos + PCI_AF_STATUS, &status); pci_read_config_byte(dev, cappos + PCI_AF_STATUS, &status);
if (status & PCI_AF_STATUS_TP) { if (!(status & PCI_AF_STATUS_TP))
dev_info(&dev->dev, "Busy after 100ms while trying to" goto transaction_done;
" reset; sleeping for 1 second\n");
ssleep(1); dev_info(&dev->dev, "Busy after 100ms while trying to"
pci_read_config_byte(dev, " reset; sleeping for 1 second\n");
cappos + PCI_AF_STATUS, &status); ssleep(1);
if (status & PCI_AF_STATUS_TP) pci_read_config_byte(dev, cappos + PCI_AF_STATUS, &status);
dev_info(&dev->dev, "Still busy after 1s; " if (status & PCI_AF_STATUS_TP)
"proceeding with reset anyway\n"); dev_info(&dev->dev, "Still busy after 1s; "
} "proceeding with reset anyway\n");
transaction_done:
pci_write_config_byte(dev, cappos + PCI_AF_CTRL, PCI_AF_CTRL_FLR); pci_write_config_byte(dev, cappos + PCI_AF_CTRL, PCI_AF_CTRL_FLR);
mdelay(100); mdelay(100);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册