[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20230214121333.1837-17-shradha.t@samsung.com>
Date: Tue, 14 Feb 2023 17:43:33 +0530
From: Shradha Todi <shradha.t@...sung.com>
To: lpieralisi@...nel.org, kw@...ux.com, robh@...nel.org,
bhelgaas@...gle.com, krzysztof.kozlowski+dt@...aro.org,
alim.akhtar@...sung.com, jingoohan1@...il.com,
Sergey.Semin@...kalelectronics.ru, lukas.bulwahn@...il.com,
hongxing.zhu@....com, tglx@...utronix.de, m.szyprowski@...sung.com,
jh80.chung@...sung.co, pankaj.dubey@...sung.com
Cc: linux-pci@...r.kernel.org, devicetree@...r.kernel.org,
linux-arm-kernel@...ts.infradead.org,
linux-samsung-soc@...r.kernel.org, linux-kernel@...r.kernel.org,
Shradha Todi <shradha.t@...sung.com>
Subject: [PATCH 16/16] PCI: samsung: Make handling of regulators generic
Use pointers instead of fixed size array to store
regulator related information. Add common regulator
initialization and de-initialization functions.
For platform specific init, add a res_ops function
pointer.
Suggested-by: Pankaj Dubey <pankaj.dubey@...sung.com>
Signed-off-by: Shradha Todi <shradha.t@...sung.com>
---
drivers/pci/controller/dwc/pci-samsung.c | 79 +++++++++++++++++++-----
1 file changed, 64 insertions(+), 15 deletions(-)
diff --git a/drivers/pci/controller/dwc/pci-samsung.c b/drivers/pci/controller/dwc/pci-samsung.c
index 01882f2d06c7..bf18020c14da 100644
--- a/drivers/pci/controller/dwc/pci-samsung.c
+++ b/drivers/pci/controller/dwc/pci-samsung.c
@@ -66,7 +66,8 @@ struct samsung_pcie_pdata {
* @clks: list of clocks required for the controller
* @clk_cnt: count of clocks required for the controller
* @phy: PHY device associated with the controller
- * @supplies: array of regulators required for the controller
+ * @supplies: list of regulators required for the controller
+ * @supplies_cnt: count of regulators required for the controller
*/
struct samsung_pcie {
struct dw_pcie pci;
@@ -75,10 +76,12 @@ struct samsung_pcie {
struct clk_bulk_data *clks;
int clk_cnt;
struct phy *phy;
- struct regulator_bulk_data supplies[2];
+ struct regulator_bulk_data *supplies;
+ int supplies_cnt;
};
struct samsung_res_ops {
+ int (*init_regulator)(struct samsung_pcie *sp);
int (*irq_init)(struct samsung_pcie *sp, struct platform_device *pdev);
};
@@ -111,6 +114,34 @@ static unsigned int samsung_pcie_appl_readl(struct samsung_pcie *sp, u32 reg)
return readl(sp->appl_base + reg);
}
+static int samsung_regulator_enable(struct samsung_pcie *sp)
+{
+ struct device *dev = sp->pci.dev;
+ int ret;
+
+ if (sp->supplies_cnt == 0)
+ return 0;
+
+ ret = devm_regulator_bulk_get(dev, sp->supplies_cnt,
+ sp->supplies);
+ if (ret)
+ return ret;
+
+ ret = regulator_bulk_enable(sp->supplies_cnt, sp->supplies);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static void samsung_regulator_disable(struct samsung_pcie *sp)
+{
+ if (sp->supplies_cnt == 0)
+ return;
+
+ regulator_bulk_disable(sp->supplies_cnt, sp->supplies);
+}
+
static void exynos_pcie_sideband_dbi_w_mode(struct samsung_pcie *sp, bool on)
{
u32 val;
@@ -281,6 +312,24 @@ static const struct dw_pcie_host_ops exynos_pcie_host_ops = {
.host_init = exynos_pcie_host_init,
};
+static int exynos_init_regulator(struct samsung_pcie *sp)
+{
+ struct device *dev = sp->pci.dev;
+
+ sp->supplies_cnt = 2;
+
+ sp->supplies = devm_kcalloc(dev, sp->supplies_cnt,
+ sizeof(*sp->supplies),
+ GFP_KERNEL);
+ if (!sp->supplies)
+ return -ENOMEM;
+
+ sp->supplies[0].supply = "vdd18";
+ sp->supplies[1].supply = "vdd10";
+
+ return 0;
+}
+
static int exynos_irq_init(struct samsung_pcie *sp,
struct platform_device *pdev)
{
@@ -313,6 +362,7 @@ static const struct dw_pcie_ops exynos_dw_pcie_ops = {
};
static const struct samsung_res_ops exynos_res_ops_data = {
+ .init_regulator = exynos_init_regulator,
.irq_init = exynos_irq_init,
};
@@ -346,16 +396,15 @@ static int samsung_pcie_probe(struct platform_device *pdev)
if (ret < 0)
return ret;
- sp->supplies[0].supply = "vdd18";
- sp->supplies[1].supply = "vdd10";
- ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(sp->supplies),
- sp->supplies);
- if (ret)
- return ret;
+ if (pdata->res_ops && pdata->res_ops->init_regulator) {
+ ret = sp->pdata->res_ops->init_regulator(sp);
+ if (ret)
+ goto fail_regulator;
+ }
- ret = regulator_bulk_enable(ARRAY_SIZE(sp->supplies), sp->supplies);
+ ret = samsung_regulator_enable(sp);
if (ret)
- return ret;
+ goto fail_regulator;
platform_set_drvdata(pdev, sp);
@@ -372,7 +421,8 @@ static int samsung_pcie_probe(struct platform_device *pdev)
fail_probe:
phy_exit(sp->phy);
- regulator_bulk_disable(ARRAY_SIZE(sp->supplies), sp->supplies);
+ samsung_regulator_disable(sp);
+fail_regulator:
samsung_pcie_deinit_clk_resources(sp);
return ret;
@@ -387,8 +437,7 @@ static int __exit samsung_pcie_remove(struct platform_device *pdev)
phy_power_off(sp->phy);
phy_exit(sp->phy);
samsung_pcie_deinit_clk_resources(sp);
- regulator_bulk_disable(ARRAY_SIZE(sp->supplies), sp->supplies);
-
+ samsung_regulator_disable(sp);
return 0;
}
@@ -399,7 +448,7 @@ static int samsung_pcie_suspend_noirq(struct device *dev)
exynos_pcie_assert_core_reset(sp);
phy_power_off(sp->phy);
phy_exit(sp->phy);
- regulator_bulk_disable(ARRAY_SIZE(sp->supplies), sp->supplies);
+ samsung_regulator_disable(sp);
return 0;
}
@@ -411,7 +460,7 @@ static int samsung_pcie_resume_noirq(struct device *dev)
struct dw_pcie_rp *pp = &pci->pp;
int ret;
- ret = regulator_bulk_enable(ARRAY_SIZE(sp->supplies), sp->supplies);
+ ret = samsung_regulator_enable(sp);
if (ret)
return ret;
--
2.17.1
Powered by blists - more mailing lists