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@xxxxxxxxxxx> Signed-off-by: Shradha Todi <shradha.t@xxxxxxxxxxx> --- 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