Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / Atom feed
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 v3 01/19] phy: mvebu-cp110-comphy: Add clocks support
Date: Wed, 31 Jul 2019 14:21:08 +0200
Message-ID: <20190731122126.3049-2-miquel.raynal@bootlin.com> (raw)
In-Reply-To: <20190731122126.3049-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 | 94 ++++++++++++++++++--
 1 file changed, 89 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..83d173d298ed 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,20 @@ 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) {
+		if (ret == -EPROBE_DEFER)
+			return 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 +700,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 +727,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.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  reply index

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-07-31 12:21 [PATCH v3 00/19] Enhance CP110 COMPHY support Miquel Raynal
2019-07-31 12:21 ` Miquel Raynal [this message]
2019-07-31 12:21 ` [PATCH v3 02/19] phy: mvebu-cp110-comphy: Explicitly initialize the lane submode Miquel Raynal
2019-07-31 12:21 ` [PATCH v3 03/19] phy: mvebu-cp110-comphy: Add SMC call support Miquel Raynal
2019-07-31 12:21 ` [PATCH v3 04/19] phy: mvebu-cp110-comphy: List already supported Ethernet modes Miquel Raynal
2019-07-31 12:21 ` [PATCH v3 05/19] phy: mvebu-cp110-comphy: Add RXAUI support Miquel Raynal
2019-07-31 12:21 ` [PATCH v3 06/19] phy: mvebu-cp110-comphy: Rename the macro handling only Ethernet modes Miquel Raynal
2019-07-31 12:21 ` [PATCH v3 07/19] phy: mvebu-cp110-comphy: Allow non-Ethernet modes to be configured Miquel Raynal
2019-07-31 12:21 ` [PATCH v3 08/19] phy: mvebu-cp110-comphy: Add USB3 host/device support Miquel Raynal
2019-07-31 12:21 ` [PATCH v3 09/19] phy: mvebu-cp110-comphy: Add SATA support Miquel Raynal
2019-07-31 12:21 ` [PATCH v3 10/19] phy: mvebu-cp110-comphy: Cosmetic change in a helper Miquel Raynal
2019-07-31 12:21 ` [PATCH v3 11/19] phy: mvebu-cp110-comphy: Add PCIe support Miquel Raynal
2019-07-31 12:21 ` [PATCH v3 12/19] phy: mvebu-cp110-comphy: Update comment about powering off all lanes at boot Miquel Raynal
2019-07-31 12:21 ` [PATCH v3 13/19] dt-bindings: phy: Add Marvell COMPHY clocks Miquel Raynal
2019-08-12 21:29   ` Rob Herring
2019-08-19  8:40     ` Miquel Raynal
2019-07-31 12:21 ` [PATCH v3 14/19] dt-bindings: pci: add PHY properties to Armada 7K/8K controller bindings Miquel Raynal
2019-08-21 18:28   ` Rob Herring
2019-08-24 10:15     ` Miquel Raynal
2019-07-31 12:21 ` [PATCH v3 15/19] arm64: dts: marvell: Add CP110 COMPHY clocks Miquel Raynal
2019-07-31 12:21 ` [PATCH v3 16/19] arm64: dts: marvell: Add 7k/8k per-port PHYs in SATA nodes Miquel Raynal
2019-07-31 12:21 ` [PATCH v3 17/19] arm64: dts: marvell: Add 7k/8k PHYs in USB3 nodes Miquel Raynal
2019-07-31 12:21 ` [PATCH v3 18/19] arm64: dts: marvell: Add 7k/8k PHYs in PCIe nodes Miquel Raynal
2019-07-31 12:21 ` [PATCH v3 19/19] arm64: dts: marvell: Convert 7k/8k usb-phy properties to phy-supply Miquel Raynal
2019-08-23  3:16 ` [PATCH v3 00/19] Enhance CP110 COMPHY support Kishon Vijay Abraham I
2019-08-23  7:33   ` Miquel Raynal
2019-08-24 11:54   ` Miquel Raynal
2019-08-26 11:51     ` Kishon Vijay Abraham I
2019-08-26 12:23       ` Miquel Raynal
2019-08-27 14:22 ` Gregory CLEMENT

Reply instructions:

You may reply publically 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=20190731122126.3049-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: link

Linux-ARM-Kernel Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-arm-kernel/0 linux-arm-kernel/git/0.git
	git clone --mirror https://lore.kernel.org/linux-arm-kernel/1 linux-arm-kernel/git/1.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-arm-kernel linux-arm-kernel/ https://lore.kernel.org/linux-arm-kernel \
		linux-arm-kernel@lists.infradead.org infradead-linux-arm-kernel@archiver.kernel.org
	public-inbox-index linux-arm-kernel

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.infradead.lists.linux-arm-kernel


AGPL code for this site: git clone https://public-inbox.org/ public-inbox