Commit 04edf6d6 authored by Amelie Delaunay's avatar Amelie Delaunay Committed by Vinod Koul
Browse files

phy: stm32: replace regulator_bulk* by multiple regulator_*



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: default avatarAmelie Delaunay <amelie.delaunay@foss.st.com>
Link: https://lore.kernel.org/r/20210105090525.23164-4-amelie.delaunay@foss.st.com


Signed-off-by: default avatarVinod Koul <vkoul@kernel.org>
parent 613a475f
Loading
Loading
Loading
Loading
+52 −17
Original line number Diff line number Diff line
@@ -36,13 +36,6 @@
#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;
	}