phy: stm32: replace regulator_bulk* by multiple regulator_*
authorAmelie Delaunay <amelie.delaunay@foss.st.com>
Tue, 5 Jan 2021 09:05:22 +0000 (10:05 +0100)
committerVinod Koul <vkoul@kernel.org>
Wed, 13 Jan 2021 15:10:21 +0000 (20:40 +0530)
Due to async_schedule_domain call in regulator_bulk_enable,
scheduling while atomic bug can raise if regulator_bulk_enable is called
under atomic context.
To avoid this issue, this patch replaces all regulator_bulk* by regulator_
per regulators.

Signed-off-by: Amelie Delaunay <amelie.delaunay@foss.st.com>
Link: https://lore.kernel.org/r/20210105090525.23164-4-amelie.delaunay@foss.st.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
drivers/phy/st/phy-stm32-usbphyc.c

index c78a2c7..8ef97c8 100644 (file)
 #define MINREV                 GENMASK(3, 0)
 #define MAJREV                 GENMASK(7, 4)
 
-static const char * const supplies_names[] = {
-       "vdda1v1",      /* 1V1 */
-       "vdda1v8",      /* 1V8 */
-};
-
-#define NUM_SUPPLIES           ARRAY_SIZE(supplies_names)
-
 #define PLL_LOCK_TIME_US       100
 #define PLL_PWR_DOWN_TIME_US   5
 #define PLL_FVCO_MHZ           2880
@@ -69,7 +62,8 @@ struct stm32_usbphyc {
        struct reset_control *rst;
        struct stm32_usbphyc_phy **phys;
        int nphys;
-       struct regulator_bulk_data supplies[NUM_SUPPLIES];
+       struct regulator *vdda1v1;
+       struct regulator *vdda1v8;
        int switch_setup;
 };
 
@@ -83,6 +77,41 @@ static inline void stm32_usbphyc_clr_bits(void __iomem *reg, u32 bits)
        writel_relaxed(readl_relaxed(reg) & ~bits, reg);
 }
 
+static int stm32_usbphyc_regulators_enable(struct stm32_usbphyc *usbphyc)
+{
+       int ret;
+
+       ret = regulator_enable(usbphyc->vdda1v1);
+       if (ret)
+               return ret;
+
+       ret = regulator_enable(usbphyc->vdda1v8);
+       if (ret)
+               goto vdda1v1_disable;
+
+       return 0;
+
+vdda1v1_disable:
+       regulator_disable(usbphyc->vdda1v1);
+
+       return ret;
+}
+
+static int stm32_usbphyc_regulators_disable(struct stm32_usbphyc *usbphyc)
+{
+       int ret;
+
+       ret = regulator_disable(usbphyc->vdda1v8);
+       if (ret)
+               return ret;
+
+       ret = regulator_disable(usbphyc->vdda1v1);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
 static void stm32_usbphyc_get_pll_params(u32 clk_rate,
                                         struct pll_params *pll_params)
 {
@@ -170,7 +199,7 @@ static int stm32_usbphyc_pll_disable(struct stm32_usbphyc *usbphyc)
                return -EIO;
        }
 
-       return regulator_bulk_disable(NUM_SUPPLIES, usbphyc->supplies);
+       return stm32_usbphyc_regulators_disable(usbphyc);
 }
 
 static int stm32_usbphyc_pll_enable(struct stm32_usbphyc *usbphyc)
@@ -189,7 +218,7 @@ static int stm32_usbphyc_pll_enable(struct stm32_usbphyc *usbphyc)
                        return ret;
        }
 
-       ret = regulator_bulk_enable(NUM_SUPPLIES, usbphyc->supplies);
+       ret = stm32_usbphyc_regulators_enable(usbphyc);
        if (ret)
                return ret;
 
@@ -210,7 +239,7 @@ static int stm32_usbphyc_pll_enable(struct stm32_usbphyc *usbphyc)
        return 0;
 
 reg_disable:
-       regulator_bulk_disable(NUM_SUPPLIES, usbphyc->supplies);
+       stm32_usbphyc_regulators_disable(usbphyc);
 
        return ret;
 }
@@ -306,7 +335,7 @@ static int stm32_usbphyc_probe(struct platform_device *pdev)
        struct device_node *child, *np = dev->of_node;
        struct phy_provider *phy_provider;
        u32 version;
-       int ret, i, port = 0;
+       int ret, port = 0;
 
        usbphyc = devm_kzalloc(dev, sizeof(*usbphyc), GFP_KERNEL);
        if (!usbphyc)
@@ -348,13 +377,19 @@ static int stm32_usbphyc_probe(struct platform_device *pdev)
                goto clk_disable;
        }
 
-       for (i = 0; i < NUM_SUPPLIES; i++)
-               usbphyc->supplies[i].supply = supplies_names[i];
+       usbphyc->vdda1v1 = devm_regulator_get(dev, "vdda1v1");
+       if (IS_ERR(usbphyc->vdda1v1)) {
+               ret = PTR_ERR(usbphyc->vdda1v1);
+               if (ret != -EPROBE_DEFER)
+                       dev_err(dev, "failed to get vdda1v1 supply: %d\n", ret);
+               goto clk_disable;
+       }
 
-       ret = devm_regulator_bulk_get(dev, NUM_SUPPLIES, usbphyc->supplies);
-       if (ret) {
+       usbphyc->vdda1v8 = devm_regulator_get(dev, "vdda1v8");
+       if (IS_ERR(usbphyc->vdda1v8)) {
+               ret = PTR_ERR(usbphyc->vdda1v8);
                if (ret != -EPROBE_DEFER)
-                       dev_err(dev, "failed to get regulators: %d\n", ret);
+                       dev_err(dev, "failed to get vdda1v8 supply: %d\n", ret);
                goto clk_disable;
        }