Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

phy: stm32: ensure pll is disabled before phys creation

To ensure a good balancing of regulators, force PLL disable either by
reset or by clearing the PLLEN bit.
If waiting the powerdown pulse delay isn't enough, return -EPROBE_DEFER
instead of polling the PLLEN bit, which will be low at the next probe.

Signed-off-by: Amelie Delaunay <amelie.delaunay@foss.st.com>
Link: https://lore.kernel.org/r/20210105090525.23164-5-amelie.delaunay@foss.st.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>

authored by

Amelie Delaunay and committed by
Vinod Koul
56bf858e 04edf6d6

+15 -2
+15 -2
drivers/phy/st/phy-stm32-usbphyc.c
··· 8 8 #include <linux/bitfield.h> 9 9 #include <linux/clk.h> 10 10 #include <linux/delay.h> 11 - #include <linux/io.h> 11 + #include <linux/iopoll.h> 12 12 #include <linux/kernel.h> 13 13 #include <linux/module.h> 14 14 #include <linux/of_platform.h> ··· 334 334 struct device *dev = &pdev->dev; 335 335 struct device_node *child, *np = dev->of_node; 336 336 struct phy_provider *phy_provider; 337 - u32 version; 337 + u32 pllen, version; 338 338 int ret, port = 0; 339 339 340 340 usbphyc = devm_kzalloc(dev, sizeof(*usbphyc), GFP_KERNEL); ··· 366 366 ret = PTR_ERR(usbphyc->rst); 367 367 if (ret == -EPROBE_DEFER) 368 368 goto clk_disable; 369 + 370 + stm32_usbphyc_clr_bits(usbphyc->base + STM32_USBPHYC_PLL, PLLEN); 371 + } 372 + 373 + /* 374 + * Wait for minimum width of powerdown pulse (ENABLE = Low): 375 + * we have to ensure the PLL is disabled before phys initialization. 376 + */ 377 + if (readl_relaxed_poll_timeout(usbphyc->base + STM32_USBPHYC_PLL, 378 + pllen, !(pllen & PLLEN), 5, 50)) { 379 + dev_warn(usbphyc->dev, "PLL not reset\n"); 380 + ret = -EPROBE_DEFER; 381 + goto clk_disable; 369 382 } 370 383 371 384 usbphyc->switch_setup = -EINVAL;