diff options
author | Amelie Delaunay <amelie.delaunay@foss.st.com> | 2021-01-05 10:05:23 +0100 |
---|---|---|
committer | Vinod Koul <vkoul@kernel.org> | 2021-01-13 20:40:21 +0530 |
commit | 56bf858edd17bd4a320aca1a10aea7dbfb0c6699 (patch) | |
tree | 7b862cb0233d2ec1af53f097e65434d19ae4d19e /drivers/phy/st/phy-stm32-usbphyc.c | |
parent | 04edf6d6e22b76aacb23d545a9fe642573f73c9b (diff) | |
download | lwn-56bf858edd17bd4a320aca1a10aea7dbfb0c6699.tar.gz lwn-56bf858edd17bd4a320aca1a10aea7dbfb0c6699.zip |
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>
Diffstat (limited to 'drivers/phy/st/phy-stm32-usbphyc.c')
-rw-r--r-- | drivers/phy/st/phy-stm32-usbphyc.c | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/drivers/phy/st/phy-stm32-usbphyc.c b/drivers/phy/st/phy-stm32-usbphyc.c index 8ef97c8806ff..33367a325612 100644 --- a/drivers/phy/st/phy-stm32-usbphyc.c +++ b/drivers/phy/st/phy-stm32-usbphyc.c @@ -8,7 +8,7 @@ #include <linux/bitfield.h> #include <linux/clk.h> #include <linux/delay.h> -#include <linux/io.h> +#include <linux/iopoll.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/of_platform.h> @@ -334,7 +334,7 @@ static int stm32_usbphyc_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct device_node *child, *np = dev->of_node; struct phy_provider *phy_provider; - u32 version; + u32 pllen, version; int ret, port = 0; usbphyc = devm_kzalloc(dev, sizeof(*usbphyc), GFP_KERNEL); @@ -366,6 +366,19 @@ static int stm32_usbphyc_probe(struct platform_device *pdev) ret = PTR_ERR(usbphyc->rst); if (ret == -EPROBE_DEFER) goto clk_disable; + + stm32_usbphyc_clr_bits(usbphyc->base + STM32_USBPHYC_PLL, PLLEN); + } + + /* + * Wait for minimum width of powerdown pulse (ENABLE = Low): + * we have to ensure the PLL is disabled before phys initialization. + */ + if (readl_relaxed_poll_timeout(usbphyc->base + STM32_USBPHYC_PLL, + pllen, !(pllen & PLLEN), 5, 50)) { + dev_warn(usbphyc->dev, "PLL not reset\n"); + ret = -EPROBE_DEFER; + goto clk_disable; } usbphyc->switch_setup = -EINVAL; |