[PATCH 16/16] PCI: samsung: Make handling of regulators generic
From: Shradha Todi <hidden>
Date: 2023-02-14 14:31:16
Also in:
linux-devicetree, linux-pci, linux-samsung-soc, lkml
Subsystem:
pci native host bridge and endpoint drivers, pci subsystem, the rest · Maintainers:
Lorenzo Pieralisi, Krzysztof Wilczyński, Manivannan Sadhasivam, Bjorn Helgaas, Linus Torvalds
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 <redacted> Signed-off-by: Shradha Todi <redacted> --- 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
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel