From: Miquel Raynal <miquel.raynal@bootlin.com> To: Gregory Clement <gregory.clement@bootlin.com>, Jason Cooper <jason@lakedaemon.net>, Andrew Lunn <andrew@lunn.ch>, Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>, Kishon Vijay Abraham I <kishon@ti.com> Cc: devicetree@vger.kernel.org, Antoine Tenart <antoine.tenart@bootlin.com>, Grzegorz Jaszczyk <jaz@semihalf.com>, Russell King <linux@armlinux.org.uk>, Maxime Chevallier <maxime.chevallier@bootlin.com>, Nadav Haklai <nadavh@marvell.com>, Rob Herring <robh+dt@kernel.org>, Thomas Petazzoni <thomas.petazzoni@bootlin.com>, Miquel Raynal <miquel.raynal@bootlin.com>, linux-arm-kernel@lists.infradead.org Subject: [PATCH v2 01/19] phy: mvebu-cp110-comphy: Add clocks support Date: Thu, 27 Jun 2019 11:50:46 +0200 [thread overview] Message-ID: <20190627095104.22529-2-miquel.raynal@bootlin.com> (raw) In-Reply-To: <20190627095104.22529-1-miquel.raynal@bootlin.com> There is no public clock tree that implies such dependencies between the MG/MG-core/AXI clocks and the COMPHY IP but accessing the COMPHY registers while one of the three clocks are disabled stalls the CPU. This happens if, for instance, the COMPHY driver probe is deferred (eg. the USB Vbus regulator driver is not yet visible). The MVPP2 driver which also needs these clocks (among others) will prepare/enable the clocks, then be deferred, and disable/unprepare them. Next COMPHY lane to be configured would produce an infinite stall. Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> --- drivers/phy/marvell/phy-mvebu-cp110-comphy.c | 91 ++++++++++++++++++-- 1 file changed, 86 insertions(+), 5 deletions(-) diff --git a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c index d98e0451f6a1..c3a178747f54 100644 --- a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c +++ b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c @@ -5,6 +5,7 @@ * Antoine Tenart <antoine.tenart@free-electrons.com> */ +#include <linux/clk.h> #include <linux/io.h> #include <linux/iopoll.h> #include <linux/mfd/syscon.h> @@ -160,6 +161,9 @@ struct mvebu_comphy_priv { void __iomem *base; struct regmap *regmap; struct device *dev; + struct clk *mg_domain_clk; + struct clk *mg_core_clk; + struct clk *axi_clk; }; struct mvebu_comphy_lane { @@ -585,12 +589,72 @@ static struct phy *mvebu_comphy_xlate(struct device *dev, return phy; } +static int mvebu_comphy_init_clks(struct mvebu_comphy_priv *priv) +{ + int ret; + + priv->mg_domain_clk = devm_clk_get(priv->dev, "mg_clk"); + if (IS_ERR(priv->mg_domain_clk)) + return PTR_ERR(priv->mg_domain_clk); + + ret = clk_prepare_enable(priv->mg_domain_clk); + if (ret < 0) + return ret; + + priv->mg_core_clk = devm_clk_get(priv->dev, "mg_core_clk"); + if (IS_ERR(priv->mg_core_clk)) { + ret = PTR_ERR(priv->mg_core_clk); + goto dis_mg_domain_clk; + } + + ret = clk_prepare_enable(priv->mg_core_clk); + if (ret < 0) + goto dis_mg_domain_clk; + + priv->axi_clk = devm_clk_get(priv->dev, "axi_clk"); + if (IS_ERR(priv->axi_clk)) { + ret = PTR_ERR(priv->axi_clk); + goto dis_mg_core_clk; + } + + ret = clk_prepare_enable(priv->axi_clk); + if (ret < 0) + goto dis_mg_core_clk; + + return 0; + +dis_mg_core_clk: + clk_disable_unprepare(priv->mg_core_clk); + +dis_mg_domain_clk: + clk_disable_unprepare(priv->mg_domain_clk); + + priv->mg_domain_clk = NULL; + priv->mg_core_clk = NULL; + priv->axi_clk = NULL; + + return ret; +}; + +static void mvebu_comphy_disable_unprepare_clks(struct mvebu_comphy_priv *priv) +{ + if (priv->axi_clk) + clk_disable_unprepare(priv->axi_clk); + + if (priv->mg_core_clk) + clk_disable_unprepare(priv->mg_core_clk); + + if (priv->mg_domain_clk) + clk_disable_unprepare(priv->mg_domain_clk); +} + static int mvebu_comphy_probe(struct platform_device *pdev) { struct mvebu_comphy_priv *priv; struct phy_provider *provider; struct device_node *child; struct resource *res; + int ret; priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); if (!priv) @@ -607,10 +671,17 @@ static int mvebu_comphy_probe(struct platform_device *pdev) if (IS_ERR(priv->base)) return PTR_ERR(priv->base); + /* + * Ignore error if clocks have not been initialized properly for DT + * compatibility reasons. + */ + ret = mvebu_comphy_init_clks(priv); + if (ret) + dev_warn(&pdev->dev, "cannot initialize clocks\n"); + for_each_available_child_of_node(pdev->dev.of_node, child) { struct mvebu_comphy_lane *lane; struct phy *phy; - int ret; u32 val; ret = of_property_read_u32(child, "reg", &val); @@ -626,12 +697,16 @@ static int mvebu_comphy_probe(struct platform_device *pdev) } lane = devm_kzalloc(&pdev->dev, sizeof(*lane), GFP_KERNEL); - if (!lane) - return -ENOMEM; + if (!lane) { + ret = -ENOMEM; + goto disable_clks; + } phy = devm_phy_create(&pdev->dev, child, &mvebu_comphy_ops); - if (IS_ERR(phy)) - return PTR_ERR(phy); + if (IS_ERR(phy)) { + ret = PTR_ERR(phy); + goto disable_clks; + } lane->priv = priv; lane->mode = PHY_MODE_INVALID; @@ -649,7 +724,13 @@ static int mvebu_comphy_probe(struct platform_device *pdev) dev_set_drvdata(&pdev->dev, priv); provider = devm_of_phy_provider_register(&pdev->dev, mvebu_comphy_xlate); + return PTR_ERR_OR_ZERO(provider); + +disable_clks: + mvebu_comphy_disable_unprepare_clks(priv); + + return ret; } static const struct of_device_id mvebu_comphy_of_match_table[] = { -- 2.19.1
WARNING: multiple messages have this Message-ID (diff)
From: Miquel Raynal <miquel.raynal@bootlin.com> To: Gregory Clement <gregory.clement@bootlin.com>, Jason Cooper <jason@lakedaemon.net>, Andrew Lunn <andrew@lunn.ch>, Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>, Kishon Vijay Abraham I <kishon@ti.com> Cc: devicetree@vger.kernel.org, Antoine Tenart <antoine.tenart@bootlin.com>, Grzegorz Jaszczyk <jaz@semihalf.com>, Russell King <linux@armlinux.org.uk>, Maxime Chevallier <maxime.chevallier@bootlin.com>, Nadav Haklai <nadavh@marvell.com>, Rob Herring <robh+dt@kernel.org>, Thomas Petazzoni <thomas.petazzoni@bootlin.com>, Miquel Raynal <miquel.raynal@bootlin.com>, linux-arm-kernel@lists.infradead.org Subject: [PATCH v2 01/19] phy: mvebu-cp110-comphy: Add clocks support Date: Thu, 27 Jun 2019 11:50:46 +0200 [thread overview] Message-ID: <20190627095104.22529-2-miquel.raynal@bootlin.com> (raw) In-Reply-To: <20190627095104.22529-1-miquel.raynal@bootlin.com> There is no public clock tree that implies such dependencies between the MG/MG-core/AXI clocks and the COMPHY IP but accessing the COMPHY registers while one of the three clocks are disabled stalls the CPU. This happens if, for instance, the COMPHY driver probe is deferred (eg. the USB Vbus regulator driver is not yet visible). The MVPP2 driver which also needs these clocks (among others) will prepare/enable the clocks, then be deferred, and disable/unprepare them. Next COMPHY lane to be configured would produce an infinite stall. Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> --- drivers/phy/marvell/phy-mvebu-cp110-comphy.c | 91 ++++++++++++++++++-- 1 file changed, 86 insertions(+), 5 deletions(-) diff --git a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c index d98e0451f6a1..c3a178747f54 100644 --- a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c +++ b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c @@ -5,6 +5,7 @@ * Antoine Tenart <antoine.tenart@free-electrons.com> */ +#include <linux/clk.h> #include <linux/io.h> #include <linux/iopoll.h> #include <linux/mfd/syscon.h> @@ -160,6 +161,9 @@ struct mvebu_comphy_priv { void __iomem *base; struct regmap *regmap; struct device *dev; + struct clk *mg_domain_clk; + struct clk *mg_core_clk; + struct clk *axi_clk; }; struct mvebu_comphy_lane { @@ -585,12 +589,72 @@ static struct phy *mvebu_comphy_xlate(struct device *dev, return phy; } +static int mvebu_comphy_init_clks(struct mvebu_comphy_priv *priv) +{ + int ret; + + priv->mg_domain_clk = devm_clk_get(priv->dev, "mg_clk"); + if (IS_ERR(priv->mg_domain_clk)) + return PTR_ERR(priv->mg_domain_clk); + + ret = clk_prepare_enable(priv->mg_domain_clk); + if (ret < 0) + return ret; + + priv->mg_core_clk = devm_clk_get(priv->dev, "mg_core_clk"); + if (IS_ERR(priv->mg_core_clk)) { + ret = PTR_ERR(priv->mg_core_clk); + goto dis_mg_domain_clk; + } + + ret = clk_prepare_enable(priv->mg_core_clk); + if (ret < 0) + goto dis_mg_domain_clk; + + priv->axi_clk = devm_clk_get(priv->dev, "axi_clk"); + if (IS_ERR(priv->axi_clk)) { + ret = PTR_ERR(priv->axi_clk); + goto dis_mg_core_clk; + } + + ret = clk_prepare_enable(priv->axi_clk); + if (ret < 0) + goto dis_mg_core_clk; + + return 0; + +dis_mg_core_clk: + clk_disable_unprepare(priv->mg_core_clk); + +dis_mg_domain_clk: + clk_disable_unprepare(priv->mg_domain_clk); + + priv->mg_domain_clk = NULL; + priv->mg_core_clk = NULL; + priv->axi_clk = NULL; + + return ret; +}; + +static void mvebu_comphy_disable_unprepare_clks(struct mvebu_comphy_priv *priv) +{ + if (priv->axi_clk) + clk_disable_unprepare(priv->axi_clk); + + if (priv->mg_core_clk) + clk_disable_unprepare(priv->mg_core_clk); + + if (priv->mg_domain_clk) + clk_disable_unprepare(priv->mg_domain_clk); +} + static int mvebu_comphy_probe(struct platform_device *pdev) { struct mvebu_comphy_priv *priv; struct phy_provider *provider; struct device_node *child; struct resource *res; + int ret; priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); if (!priv) @@ -607,10 +671,17 @@ static int mvebu_comphy_probe(struct platform_device *pdev) if (IS_ERR(priv->base)) return PTR_ERR(priv->base); + /* + * Ignore error if clocks have not been initialized properly for DT + * compatibility reasons. + */ + ret = mvebu_comphy_init_clks(priv); + if (ret) + dev_warn(&pdev->dev, "cannot initialize clocks\n"); + for_each_available_child_of_node(pdev->dev.of_node, child) { struct mvebu_comphy_lane *lane; struct phy *phy; - int ret; u32 val; ret = of_property_read_u32(child, "reg", &val); @@ -626,12 +697,16 @@ static int mvebu_comphy_probe(struct platform_device *pdev) } lane = devm_kzalloc(&pdev->dev, sizeof(*lane), GFP_KERNEL); - if (!lane) - return -ENOMEM; + if (!lane) { + ret = -ENOMEM; + goto disable_clks; + } phy = devm_phy_create(&pdev->dev, child, &mvebu_comphy_ops); - if (IS_ERR(phy)) - return PTR_ERR(phy); + if (IS_ERR(phy)) { + ret = PTR_ERR(phy); + goto disable_clks; + } lane->priv = priv; lane->mode = PHY_MODE_INVALID; @@ -649,7 +724,13 @@ static int mvebu_comphy_probe(struct platform_device *pdev) dev_set_drvdata(&pdev->dev, priv); provider = devm_of_phy_provider_register(&pdev->dev, mvebu_comphy_xlate); + return PTR_ERR_OR_ZERO(provider); + +disable_clks: + mvebu_comphy_disable_unprepare_clks(priv); + + return ret; } static const struct of_device_id mvebu_comphy_of_match_table[] = { -- 2.19.1 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2019-06-27 9:50 UTC|newest] Thread overview: 49+ messages / expand[flat|nested] mbox.gz Atom feed top 2019-06-27 9:50 [PATCH v2 00/19] Enhance CP110 COMPHY support Miquel Raynal 2019-06-27 9:50 ` Miquel Raynal [this message] 2019-06-27 9:50 ` [PATCH v2 01/19] phy: mvebu-cp110-comphy: Add clocks support Miquel Raynal 2019-07-29 8:06 ` Grzegorz Jaszczyk 2019-07-29 8:10 ` Grzegorz Jaszczyk 2019-06-27 9:50 ` [PATCH v2 02/19] phy: mvebu-cp110-comphy: Explicitly initialize the lane submode Miquel Raynal 2019-06-27 9:50 ` Miquel Raynal 2019-06-27 9:50 ` [PATCH v2 03/19] phy: mvebu-cp110-comphy: Add SMC call support Miquel Raynal 2019-06-27 9:50 ` Miquel Raynal 2019-07-23 8:48 ` Maxime Chevallier 2019-07-23 8:48 ` Maxime Chevallier 2019-06-27 9:50 ` [PATCH v2 04/19] phy: mvebu-cp110-comphy: List already supported Ethernet modes Miquel Raynal 2019-06-27 9:50 ` Miquel Raynal 2019-06-27 9:50 ` [PATCH v2 05/19] phy: mvebu-cp110-comphy: Add RXAUI support Miquel Raynal 2019-06-27 9:50 ` Miquel Raynal 2019-06-27 9:50 ` [PATCH v2 06/19] phy: mvebu-cp110-comphy: Rename the macro handling only Ethernet modes Miquel Raynal 2019-06-27 9:50 ` Miquel Raynal 2019-06-27 9:50 ` [PATCH v2 07/19] phy: mvebu-cp110-comphy: Allow non-Ethernet modes to be configured Miquel Raynal 2019-06-27 9:50 ` Miquel Raynal 2019-06-27 9:50 ` [PATCH v2 08/19] phy: mvebu-cp110-comphy: Add USB3 host/device support Miquel Raynal 2019-06-27 9:50 ` Miquel Raynal 2019-06-27 9:50 ` [PATCH v2 09/19] phy: mvebu-cp110-comphy: Add SATA support Miquel Raynal 2019-06-27 9:50 ` Miquel Raynal 2019-06-27 9:50 ` [PATCH v2 10/19] phy: mvebu-cp110-comphy: Cosmetic change in a helper Miquel Raynal 2019-06-27 9:50 ` Miquel Raynal 2019-06-27 9:50 ` [PATCH v2 11/19] phy: mvebu-cp110-comphy: Add PCIe support Miquel Raynal 2019-06-27 9:50 ` Miquel Raynal 2019-06-27 9:50 ` [PATCH v2 12/19] phy: mvebu-cp110-comphy: Update comment about powering off all lanes at boot Miquel Raynal 2019-06-27 9:50 ` Miquel Raynal 2019-06-27 12:24 ` [PATCH v2 13/19] dt-bindings: phy: Add Marvell COMPHY clocks Miquel Raynal 2019-06-27 12:24 ` Miquel Raynal 2019-06-27 12:25 ` [PATCH v2 14/19] dt-bindings: pci: add PHY properties to Armada 7K/8K controller bindings Miquel Raynal 2019-06-27 12:25 ` Miquel Raynal 2019-07-22 17:52 ` Rob Herring 2019-07-22 17:52 ` Rob Herring 2019-07-23 8:35 ` Miquel Raynal 2019-07-24 15:56 ` Miquel Raynal 2019-06-27 12:25 ` [PATCH v2 15/19] arm64: dts: marvell: Add CP110 COMPHY clocks Miquel Raynal 2019-06-27 12:25 ` Miquel Raynal 2019-06-27 12:25 ` [PATCH v2 16/19] arm64: dts: marvell: Add 7k/8k per-port PHYs in SATA nodes Miquel Raynal 2019-06-27 12:25 ` Miquel Raynal 2019-06-27 12:25 ` [PATCH v2 17/19] arm64: dts: marvell: Add 7k/8k PHYs in USB3 nodes Miquel Raynal 2019-06-27 12:25 ` Miquel Raynal 2019-06-27 12:25 ` [PATCH v2 18/19] arm64: dts: marvell: Add 7k/8k PHYs in PCIe nodes Miquel Raynal 2019-06-27 12:25 ` Miquel Raynal 2019-06-27 12:25 ` [PATCH v2 19/19] arm64: dts: marvell: Convert 7k/8k usb-phy properties to phy-supply Miquel Raynal 2019-06-27 12:25 ` Miquel Raynal 2019-07-22 17:51 ` [PATCH v2 13/19] dt-bindings: phy: Add Marvell COMPHY clocks Rob Herring 2019-07-22 17:51 ` Rob Herring
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20190627095104.22529-2-miquel.raynal@bootlin.com \ --to=miquel.raynal@bootlin.com \ --cc=andrew@lunn.ch \ --cc=antoine.tenart@bootlin.com \ --cc=devicetree@vger.kernel.org \ --cc=gregory.clement@bootlin.com \ --cc=jason@lakedaemon.net \ --cc=jaz@semihalf.com \ --cc=kishon@ti.com \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux@armlinux.org.uk \ --cc=maxime.chevallier@bootlin.com \ --cc=nadavh@marvell.com \ --cc=robh+dt@kernel.org \ --cc=sebastian.hesselbarth@gmail.com \ --cc=thomas.petazzoni@bootlin.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.