aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSrinivas Kandagatla <srinivas.kandagatla@linaro.org>2016-12-01 11:06:43 +0000
committerDaniel Thompson <daniel.thompson@linaro.org>2017-01-31 16:04:55 +0000
commitffa2323d118b577acb7cad163e28150adba537bd (patch)
treec14807c313682042cd8bb399bc12cccc3e0c3a91
parente2702e7a5fd1b0ca9fb99dd7f1272ad7dc84b0c8 (diff)
PCI: designware: add host_init error handlinghacking/db820c-v4.10
This patch add support to return value from host_init() callback from drivers, so that the designware libary can handle or pass it to proper place. Issue with void return type is that errors or error handling within host_init() callback are never know to designware code, which could go ahead and access registers even in error cases. Typical case in qcom controller driver is to turn off clks in case of errors, if designware code continues to read/write register when clocks are turned off the board would reboot/lockup. Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-rw-r--r--drivers/pci/host/pci-dra7xx.c4
-rw-r--r--drivers/pci/host/pci-exynos.c4
-rw-r--r--drivers/pci/host/pci-imx6.c4
-rw-r--r--drivers/pci/host/pci-keystone.c4
-rw-r--r--drivers/pci/host/pci-layerscape.c12
-rw-r--r--drivers/pci/host/pcie-armada8k.c4
-rw-r--r--drivers/pci/host/pcie-designware-plat.c4
-rw-r--r--drivers/pci/host/pcie-designware.c4
-rw-r--r--drivers/pci/host/pcie-designware.h2
-rw-r--r--drivers/pci/host/pcie-qcom.c6
-rw-r--r--drivers/pci/host/pcie-spear13xx.c4
11 files changed, 37 insertions, 15 deletions
diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-dra7xx.c
index 9595fad63f6f..f63491c38d50 100644
--- a/drivers/pci/host/pci-dra7xx.c
+++ b/drivers/pci/host/pci-dra7xx.c
@@ -127,7 +127,7 @@ static void dra7xx_pcie_enable_interrupts(struct dra7xx_pcie *dra7xx)
LEG_EP_INTERRUPTS);
}
-static void dra7xx_pcie_host_init(struct pcie_port *pp)
+static int dra7xx_pcie_host_init(struct pcie_port *pp)
{
struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pp);
@@ -142,6 +142,8 @@ static void dra7xx_pcie_host_init(struct pcie_port *pp)
if (IS_ENABLED(CONFIG_PCI_MSI))
dw_pcie_msi_init(pp);
dra7xx_pcie_enable_interrupts(dra7xx);
+
+ return 0;
}
static struct pcie_host_ops dra7xx_pcie_host_ops = {
diff --git a/drivers/pci/host/pci-exynos.c b/drivers/pci/host/pci-exynos.c
index f1c544bb8b68..b5a8f1117a54 100644
--- a/drivers/pci/host/pci-exynos.c
+++ b/drivers/pci/host/pci-exynos.c
@@ -458,12 +458,14 @@ static int exynos_pcie_link_up(struct pcie_port *pp)
return 0;
}
-static void exynos_pcie_host_init(struct pcie_port *pp)
+static int exynos_pcie_host_init(struct pcie_port *pp)
{
struct exynos_pcie *exynos_pcie = to_exynos_pcie(pp);
exynos_pcie_establish_link(exynos_pcie);
exynos_pcie_enable_interrupts(exynos_pcie);
+
+ return 0;
}
static struct pcie_host_ops exynos_pcie_host_ops = {
diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c
index c8cefb078218..4844367bfdb1 100644
--- a/drivers/pci/host/pci-imx6.c
+++ b/drivers/pci/host/pci-imx6.c
@@ -550,7 +550,7 @@ err_reset_phy:
return ret;
}
-static void imx6_pcie_host_init(struct pcie_port *pp)
+static int imx6_pcie_host_init(struct pcie_port *pp)
{
struct imx6_pcie *imx6_pcie = to_imx6_pcie(pp);
@@ -562,6 +562,8 @@ static void imx6_pcie_host_init(struct pcie_port *pp)
if (IS_ENABLED(CONFIG_PCI_MSI))
dw_pcie_msi_init(pp);
+
+ return 0;
}
static int imx6_pcie_link_up(struct pcie_port *pp)
diff --git a/drivers/pci/host/pci-keystone.c b/drivers/pci/host/pci-keystone.c
index 043c19a05da1..fded7f98adac 100644
--- a/drivers/pci/host/pci-keystone.c
+++ b/drivers/pci/host/pci-keystone.c
@@ -260,7 +260,7 @@ static int keystone_pcie_fault(unsigned long addr, unsigned int fsr,
return 0;
}
-static void __init ks_pcie_host_init(struct pcie_port *pp)
+static int __init ks_pcie_host_init(struct pcie_port *pp)
{
struct keystone_pcie *ks_pcie = to_keystone_pcie(pp);
u32 val;
@@ -287,6 +287,8 @@ static void __init ks_pcie_host_init(struct pcie_port *pp)
*/
hook_fault_code(17, keystone_pcie_fault, SIGBUS, 0,
"Asynchronous external abort");
+
+ return 0;
}
static struct pcie_host_ops keystone_pcie_host_ops = {
diff --git a/drivers/pci/host/pci-layerscape.c b/drivers/pci/host/pci-layerscape.c
index ea789138531b..693a5d1ba6b7 100644
--- a/drivers/pci/host/pci-layerscape.c
+++ b/drivers/pci/host/pci-layerscape.c
@@ -101,7 +101,7 @@ static int ls1021_pcie_link_up(struct pcie_port *pp)
return 1;
}
-static void ls1021_pcie_host_init(struct pcie_port *pp)
+static int ls1021_pcie_host_init(struct pcie_port *pp)
{
struct device *dev = pp->dev;
struct ls_pcie *pcie = to_ls_pcie(pp);
@@ -112,19 +112,21 @@ static void ls1021_pcie_host_init(struct pcie_port *pp)
if (IS_ERR(pcie->scfg)) {
dev_err(dev, "No syscfg phandle specified\n");
pcie->scfg = NULL;
- return;
+ return 0;
}
if (of_property_read_u32_array(dev->of_node,
"fsl,pcie-scfg", index, 2)) {
pcie->scfg = NULL;
- return;
+ return 0;
}
pcie->index = index[1];
dw_pcie_setup_rc(pp);
ls_pcie_drop_msg_tlp(pcie);
+
+ return 0;
}
static int ls_pcie_link_up(struct pcie_port *pp)
@@ -142,7 +144,7 @@ static int ls_pcie_link_up(struct pcie_port *pp)
return 1;
}
-static void ls_pcie_host_init(struct pcie_port *pp)
+static int ls_pcie_host_init(struct pcie_port *pp)
{
struct ls_pcie *pcie = to_ls_pcie(pp);
@@ -151,6 +153,8 @@ static void ls_pcie_host_init(struct pcie_port *pp)
ls_pcie_clear_multifunction(pcie);
ls_pcie_drop_msg_tlp(pcie);
iowrite32(0, pcie->pp.dbi_base + PCIE_DBI_RO_WR_EN);
+
+ return 0;
}
static int ls_pcie_msi_host_init(struct pcie_port *pp,
diff --git a/drivers/pci/host/pcie-armada8k.c b/drivers/pci/host/pcie-armada8k.c
index 0ac0f18690f2..29bdd8b0c456 100644
--- a/drivers/pci/host/pcie-armada8k.c
+++ b/drivers/pci/host/pcie-armada8k.c
@@ -134,12 +134,14 @@ static void armada8k_pcie_establish_link(struct armada8k_pcie *pcie)
dev_err(pp->dev, "Link not up after reconfiguration\n");
}
-static void armada8k_pcie_host_init(struct pcie_port *pp)
+static int armada8k_pcie_host_init(struct pcie_port *pp)
{
struct armada8k_pcie *pcie = to_armada8k_pcie(pp);
dw_pcie_setup_rc(pp);
armada8k_pcie_establish_link(pcie);
+
+ return 0;
}
static irqreturn_t armada8k_pcie_irq_handler(int irq, void *arg)
diff --git a/drivers/pci/host/pcie-designware-plat.c b/drivers/pci/host/pcie-designware-plat.c
index 1a02038c4640..0223e7b1501d 100644
--- a/drivers/pci/host/pcie-designware-plat.c
+++ b/drivers/pci/host/pcie-designware-plat.c
@@ -35,13 +35,15 @@ static irqreturn_t dw_plat_pcie_msi_irq_handler(int irq, void *arg)
return dw_handle_msi_irq(pp);
}
-static void dw_plat_pcie_host_init(struct pcie_port *pp)
+static int dw_plat_pcie_host_init(struct pcie_port *pp)
{
dw_pcie_setup_rc(pp);
dw_pcie_wait_for_link(pp);
if (IS_ENABLED(CONFIG_PCI_MSI))
dw_pcie_msi_init(pp);
+
+ return 0;
}
static struct pcie_host_ops dw_plat_pcie_host_ops = {
diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c
index af8f6e92e885..41714fb01c84 100644
--- a/drivers/pci/host/pcie-designware.c
+++ b/drivers/pci/host/pcie-designware.c
@@ -638,7 +638,9 @@ int dw_pcie_host_init(struct pcie_port *pp)
}
if (pp->ops->host_init)
- pp->ops->host_init(pp);
+ ret = pp->ops->host_init(pp);
+ if (ret < 0)
+ goto error;
pp->root_bus_nr = pp->busn->start;
if (IS_ENABLED(CONFIG_PCI_MSI)) {
diff --git a/drivers/pci/host/pcie-designware.h b/drivers/pci/host/pcie-designware.h
index a567ea288ee2..eacf18f9fc79 100644
--- a/drivers/pci/host/pcie-designware.h
+++ b/drivers/pci/host/pcie-designware.h
@@ -63,7 +63,7 @@ struct pcie_host_ops {
int (*wr_other_conf)(struct pcie_port *pp, struct pci_bus *bus,
unsigned int devfn, int where, int size, u32 val);
int (*link_up)(struct pcie_port *pp);
- void (*host_init)(struct pcie_port *pp);
+ int (*host_init)(struct pcie_port *pp);
void (*msi_set_irq)(struct pcie_port *pp, int irq);
void (*msi_clear_irq)(struct pcie_port *pp, int irq);
phys_addr_t (*get_msi_addr)(struct pcie_port *pp);
diff --git a/drivers/pci/host/pcie-qcom.c b/drivers/pci/host/pcie-qcom.c
index 9853a9ba90fb..d3f3a7e2e0dd 100644
--- a/drivers/pci/host/pcie-qcom.c
+++ b/drivers/pci/host/pcie-qcom.c
@@ -582,7 +582,7 @@ static void qcom_pcie_deinit_v2(struct qcom_pcie *pcie)
clk_disable_unprepare(res->aux_clk);
}
-static void qcom_pcie_host_init(struct pcie_port *pp)
+static int qcom_pcie_host_init(struct pcie_port *pp)
{
struct qcom_pcie *pcie = to_qcom_pcie(pp);
int ret;
@@ -614,13 +614,15 @@ static void qcom_pcie_host_init(struct pcie_port *pp)
if (ret)
goto err;
- return;
+ return ret;
err:
qcom_ep_reset_assert(pcie);
phy_power_off(pcie->phy);
err_deinit:
pcie->ops->deinit(pcie);
pm_runtime_put_sync(pp->dev);
+
+ return ret;
}
static int qcom_pcie_rd_own_conf(struct pcie_port *pp, int where, int size,
diff --git a/drivers/pci/host/pcie-spear13xx.c b/drivers/pci/host/pcie-spear13xx.c
index dafe8b88d97d..415cf5989407 100644
--- a/drivers/pci/host/pcie-spear13xx.c
+++ b/drivers/pci/host/pcie-spear13xx.c
@@ -174,12 +174,14 @@ static int spear13xx_pcie_link_up(struct pcie_port *pp)
return 0;
}
-static void spear13xx_pcie_host_init(struct pcie_port *pp)
+static int spear13xx_pcie_host_init(struct pcie_port *pp)
{
struct spear13xx_pcie *spear13xx_pcie = to_spear13xx_pcie(pp);
spear13xx_pcie_establish_link(spear13xx_pcie);
spear13xx_pcie_enable_interrupts(spear13xx_pcie);
+
+ return 0;
}
static struct pcie_host_ops spear13xx_pcie_host_ops = {