196f3d586f
5.4.102 backported a lot of stuff that our WireGuard backport already did, in addition to other patches we had, so those patches were removed from that part of the series. In the process other patches were refreshed or reworked to account for upstream changes. This commit involved `update_kernel.sh -v -u 5.4`. Cc: John Audia <graysky@archlinux.us> Cc: David Bauer <mail@david-bauer.net> Cc: Petr Štetiar <ynezz@true.cz> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
229 lines
6.5 KiB
Diff
229 lines
6.5 KiB
Diff
From 6a114526af4689938863bf34976c83bfd279f517 Mon Sep 17 00:00:00 2001
|
|
From: Ansuel Smith <ansuelsmth@gmail.com>
|
|
Date: Mon, 15 Jun 2020 23:06:02 +0200
|
|
Subject: PCI: qcom: Use bulk clk api and assert on error
|
|
|
|
Rework 2.1.0 revision to use bulk clk api and fix missing assert on
|
|
reset_control_deassert error.
|
|
|
|
Link: https://lore.kernel.org/r/20200615210608.21469-7-ansuelsmth@gmail.com
|
|
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
|
|
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
|
|
Reviewed-by: Rob Herring <robh@kernel.org>
|
|
Acked-by: Stanimir Varbanov <svarbanov@mm-sol.com>
|
|
---
|
|
drivers/pci/controller/dwc/pcie-qcom.c | 131 ++++++++++++---------------------
|
|
1 file changed, 46 insertions(+), 85 deletions(-)
|
|
|
|
--- a/drivers/pci/controller/dwc/pcie-qcom.c
|
|
+++ b/drivers/pci/controller/dwc/pcie-qcom.c
|
|
@@ -99,12 +99,9 @@
|
|
#define SLV_ADDR_SPACE_SZ 0x10000000
|
|
|
|
#define QCOM_PCIE_2_1_0_MAX_SUPPLY 3
|
|
+#define QCOM_PCIE_2_1_0_MAX_CLOCKS 5
|
|
struct qcom_pcie_resources_2_1_0 {
|
|
- struct clk *iface_clk;
|
|
- struct clk *core_clk;
|
|
- struct clk *phy_clk;
|
|
- struct clk *aux_clk;
|
|
- struct clk *ref_clk;
|
|
+ struct clk_bulk_data clks[QCOM_PCIE_2_1_0_MAX_CLOCKS];
|
|
struct reset_control *pci_reset;
|
|
struct reset_control *axi_reset;
|
|
struct reset_control *ahb_reset;
|
|
@@ -244,25 +241,21 @@ static int qcom_pcie_get_resources_2_1_0
|
|
if (ret)
|
|
return ret;
|
|
|
|
- res->iface_clk = devm_clk_get(dev, "iface");
|
|
- if (IS_ERR(res->iface_clk))
|
|
- return PTR_ERR(res->iface_clk);
|
|
-
|
|
- res->core_clk = devm_clk_get(dev, "core");
|
|
- if (IS_ERR(res->core_clk))
|
|
- return PTR_ERR(res->core_clk);
|
|
-
|
|
- res->phy_clk = devm_clk_get(dev, "phy");
|
|
- if (IS_ERR(res->phy_clk))
|
|
- return PTR_ERR(res->phy_clk);
|
|
-
|
|
- res->aux_clk = devm_clk_get_optional(dev, "aux");
|
|
- if (IS_ERR(res->aux_clk))
|
|
- return PTR_ERR(res->aux_clk);
|
|
-
|
|
- res->ref_clk = devm_clk_get_optional(dev, "ref");
|
|
- if (IS_ERR(res->ref_clk))
|
|
- return PTR_ERR(res->ref_clk);
|
|
+ res->clks[0].id = "iface";
|
|
+ res->clks[1].id = "core";
|
|
+ res->clks[2].id = "phy";
|
|
+ res->clks[3].id = "aux";
|
|
+ res->clks[4].id = "ref";
|
|
+
|
|
+ /* iface, core, phy are required */
|
|
+ ret = devm_clk_bulk_get(dev, 3, res->clks);
|
|
+ if (ret < 0)
|
|
+ return ret;
|
|
+
|
|
+ /* aux, ref are optional */
|
|
+ ret = devm_clk_bulk_get_optional(dev, 2, res->clks + 3);
|
|
+ if (ret < 0)
|
|
+ return ret;
|
|
|
|
res->pci_reset = devm_reset_control_get_exclusive(dev, "pci");
|
|
if (IS_ERR(res->pci_reset))
|
|
@@ -292,17 +285,13 @@ static void qcom_pcie_deinit_2_1_0(struc
|
|
{
|
|
struct qcom_pcie_resources_2_1_0 *res = &pcie->res.v2_1_0;
|
|
|
|
- clk_disable_unprepare(res->phy_clk);
|
|
+ clk_bulk_disable_unprepare(ARRAY_SIZE(res->clks), res->clks);
|
|
reset_control_assert(res->pci_reset);
|
|
reset_control_assert(res->axi_reset);
|
|
reset_control_assert(res->ahb_reset);
|
|
reset_control_assert(res->por_reset);
|
|
reset_control_assert(res->ext_reset);
|
|
reset_control_assert(res->phy_reset);
|
|
- clk_disable_unprepare(res->iface_clk);
|
|
- clk_disable_unprepare(res->core_clk);
|
|
- clk_disable_unprepare(res->aux_clk);
|
|
- clk_disable_unprepare(res->ref_clk);
|
|
|
|
writel(1, pcie->parf + PCIE20_PARF_PHY_CTRL);
|
|
|
|
@@ -334,47 +323,45 @@ static int qcom_pcie_init_2_1_0(struct q
|
|
return ret;
|
|
}
|
|
|
|
- ret = reset_control_assert(res->ahb_reset);
|
|
+ ret = reset_control_deassert(res->ahb_reset);
|
|
if (ret) {
|
|
- dev_err(dev, "cannot assert ahb reset\n");
|
|
- goto err_assert_ahb;
|
|
+ dev_err(dev, "cannot deassert ahb reset\n");
|
|
+ goto err_deassert_ahb;
|
|
}
|
|
|
|
- ret = clk_prepare_enable(res->iface_clk);
|
|
+ ret = reset_control_deassert(res->ext_reset);
|
|
if (ret) {
|
|
- dev_err(dev, "cannot prepare/enable iface clock\n");
|
|
- goto err_assert_ahb;
|
|
+ dev_err(dev, "cannot deassert ext reset\n");
|
|
+ goto err_deassert_ext;
|
|
}
|
|
|
|
- ret = clk_prepare_enable(res->core_clk);
|
|
+ ret = reset_control_deassert(res->phy_reset);
|
|
if (ret) {
|
|
- dev_err(dev, "cannot prepare/enable core clock\n");
|
|
- goto err_clk_core;
|
|
+ dev_err(dev, "cannot deassert phy reset\n");
|
|
+ goto err_deassert_phy;
|
|
}
|
|
|
|
- ret = clk_prepare_enable(res->aux_clk);
|
|
+ ret = reset_control_deassert(res->pci_reset);
|
|
if (ret) {
|
|
- dev_err(dev, "cannot prepare/enable aux clock\n");
|
|
- goto err_clk_aux;
|
|
+ dev_err(dev, "cannot deassert pci reset\n");
|
|
+ goto err_deassert_pci;
|
|
}
|
|
|
|
- ret = clk_prepare_enable(res->ref_clk);
|
|
+ ret = reset_control_deassert(res->por_reset);
|
|
if (ret) {
|
|
- dev_err(dev, "cannot prepare/enable ref clock\n");
|
|
- goto err_clk_ref;
|
|
+ dev_err(dev, "cannot deassert por reset\n");
|
|
+ goto err_deassert_por;
|
|
}
|
|
|
|
- ret = reset_control_deassert(res->ahb_reset);
|
|
+ ret = reset_control_deassert(res->axi_reset);
|
|
if (ret) {
|
|
- dev_err(dev, "cannot deassert ahb reset\n");
|
|
- goto err_deassert_ahb;
|
|
+ dev_err(dev, "cannot deassert axi reset\n");
|
|
+ goto err_deassert_axi;
|
|
}
|
|
|
|
- ret = reset_control_deassert(res->ext_reset);
|
|
- if (ret) {
|
|
- dev_err(dev, "cannot deassert ext reset\n");
|
|
- goto err_deassert_ahb;
|
|
- }
|
|
+ ret = clk_bulk_prepare_enable(ARRAY_SIZE(res->clks), res->clks);
|
|
+ if (ret)
|
|
+ goto err_clks;
|
|
|
|
/* enable PCIe clocks and resets */
|
|
val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL);
|
|
@@ -408,36 +395,6 @@ static int qcom_pcie_init_2_1_0(struct q
|
|
val |= PHY_REFCLK_SSP_EN;
|
|
writel(val, pcie->parf + PCIE20_PARF_PHY_REFCLK);
|
|
|
|
- ret = reset_control_deassert(res->phy_reset);
|
|
- if (ret) {
|
|
- dev_err(dev, "cannot deassert phy reset\n");
|
|
- return ret;
|
|
- }
|
|
-
|
|
- ret = reset_control_deassert(res->pci_reset);
|
|
- if (ret) {
|
|
- dev_err(dev, "cannot deassert pci reset\n");
|
|
- return ret;
|
|
- }
|
|
-
|
|
- ret = reset_control_deassert(res->por_reset);
|
|
- if (ret) {
|
|
- dev_err(dev, "cannot deassert por reset\n");
|
|
- return ret;
|
|
- }
|
|
-
|
|
- ret = reset_control_deassert(res->axi_reset);
|
|
- if (ret) {
|
|
- dev_err(dev, "cannot deassert axi reset\n");
|
|
- return ret;
|
|
- }
|
|
-
|
|
- ret = clk_prepare_enable(res->phy_clk);
|
|
- if (ret) {
|
|
- dev_err(dev, "cannot prepare/enable phy clock\n");
|
|
- goto err_deassert_ahb;
|
|
- }
|
|
-
|
|
/* wait for clock acquisition */
|
|
usleep_range(1000, 1500);
|
|
|
|
@@ -450,15 +407,19 @@ static int qcom_pcie_init_2_1_0(struct q
|
|
|
|
return 0;
|
|
|
|
+err_clks:
|
|
+ reset_control_assert(res->axi_reset);
|
|
+err_deassert_axi:
|
|
+ reset_control_assert(res->por_reset);
|
|
+err_deassert_por:
|
|
+ reset_control_assert(res->pci_reset);
|
|
+err_deassert_pci:
|
|
+ reset_control_assert(res->phy_reset);
|
|
+err_deassert_phy:
|
|
+ reset_control_assert(res->ext_reset);
|
|
+err_deassert_ext:
|
|
+ reset_control_assert(res->ahb_reset);
|
|
err_deassert_ahb:
|
|
- clk_disable_unprepare(res->ref_clk);
|
|
-err_clk_ref:
|
|
- clk_disable_unprepare(res->aux_clk);
|
|
-err_clk_aux:
|
|
- clk_disable_unprepare(res->core_clk);
|
|
-err_clk_core:
|
|
- clk_disable_unprepare(res->iface_clk);
|
|
-err_assert_ahb:
|
|
regulator_bulk_disable(ARRAY_SIZE(res->supplies), res->supplies);
|
|
|
|
return ret;
|