|
@@ -671,7 +671,7 @@ static struct pci_ops iproc_pcie_ops = {
|
|
|
.write = iproc_pcie_config_write32,
|
|
|
};
|
|
|
|
|
|
-static void iproc_pcie_reset(struct iproc_pcie *pcie)
|
|
|
+static void iproc_pcie_perst_ctrl(struct iproc_pcie *pcie, bool assert)
|
|
|
{
|
|
|
u32 val;
|
|
|
|
|
@@ -683,20 +683,28 @@ static void iproc_pcie_reset(struct iproc_pcie *pcie)
|
|
|
if (pcie->ep_is_internal)
|
|
|
return;
|
|
|
|
|
|
- /*
|
|
|
- * Select perst_b signal as reset source. Put the device into reset,
|
|
|
- * and then bring it out of reset
|
|
|
- */
|
|
|
- val = iproc_pcie_read_reg(pcie, IPROC_PCIE_CLK_CTRL);
|
|
|
- val &= ~EP_PERST_SOURCE_SELECT & ~EP_MODE_SURVIVE_PERST &
|
|
|
- ~RC_PCIE_RST_OUTPUT;
|
|
|
- iproc_pcie_write_reg(pcie, IPROC_PCIE_CLK_CTRL, val);
|
|
|
- udelay(250);
|
|
|
-
|
|
|
- val |= RC_PCIE_RST_OUTPUT;
|
|
|
- iproc_pcie_write_reg(pcie, IPROC_PCIE_CLK_CTRL, val);
|
|
|
- msleep(100);
|
|
|
+ if (assert) {
|
|
|
+ val = iproc_pcie_read_reg(pcie, IPROC_PCIE_CLK_CTRL);
|
|
|
+ val &= ~EP_PERST_SOURCE_SELECT & ~EP_MODE_SURVIVE_PERST &
|
|
|
+ ~RC_PCIE_RST_OUTPUT;
|
|
|
+ iproc_pcie_write_reg(pcie, IPROC_PCIE_CLK_CTRL, val);
|
|
|
+ udelay(250);
|
|
|
+ } else {
|
|
|
+ val = iproc_pcie_read_reg(pcie, IPROC_PCIE_CLK_CTRL);
|
|
|
+ val |= RC_PCIE_RST_OUTPUT;
|
|
|
+ iproc_pcie_write_reg(pcie, IPROC_PCIE_CLK_CTRL, val);
|
|
|
+ msleep(100);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+int iproc_pcie_shutdown(struct iproc_pcie *pcie)
|
|
|
+{
|
|
|
+ iproc_pcie_perst_ctrl(pcie, true);
|
|
|
+ msleep(500);
|
|
|
+
|
|
|
+ return 0;
|
|
|
}
|
|
|
+EXPORT_SYMBOL_GPL(iproc_pcie_shutdown);
|
|
|
|
|
|
static int iproc_pcie_check_link(struct iproc_pcie *pcie)
|
|
|
{
|
|
@@ -1379,7 +1387,8 @@ int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res)
|
|
|
goto err_exit_phy;
|
|
|
}
|
|
|
|
|
|
- iproc_pcie_reset(pcie);
|
|
|
+ iproc_pcie_perst_ctrl(pcie, true);
|
|
|
+ iproc_pcie_perst_ctrl(pcie, false);
|
|
|
|
|
|
if (pcie->need_ob_cfg) {
|
|
|
ret = iproc_pcie_map_ranges(pcie, res);
|