[PATCH 1/7] drm/bridge: lt9211: drop delayed work

Philipp Zabel <[email protected]>
Newsgroups org.freedesktop.lists.dri-devel,org.kernel.vger.linux-devicetree,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
Replace the delayed work with a delay and synchronous initialization
in atomic_enable. This should fix all 5 issues sashiko flagged as
high priority [1].

The next bridge or panel in the chain may depend on the LVDS signal
being active after atomic_enable, so arbitrarily deferring bridge
initialization is not an option.

[1] https://sashiko.dev/#/patchset/20260719-add-lt9211c-bridge-v6-0-e56d22152586%40oss.qualcomm.com

Signed-off-by: Philipp Zabel <[email protected]>
---
 drivers/gpu/drm/bridge/lontium-lt9211.c | 93 ++++++++-----------------
 1 file changed, 30 insertions(+), 63 deletions(-)

diff --git a/drivers/gpu/drm/bridge/lontium-lt9211.c b/drivers/gpu/drm/bridge/lontium-lt9211.c
index ffd0f9f08e2d..1b5cb601adde 100644
--- a/drivers/gpu/drm/bridge/lontium-lt9211.c
+++ b/drivers/gpu/drm/bridge/lontium-lt9211.c
@@ -62,14 +62,7 @@ struct lt9211 {
 	struct regulator		*vccio;
 	bool				lvds_dual_link;
 	bool				lvds_dual_link_even_odd_swap;
-	/* LT9211C specific fields */
 	enum lt9211_chip_type		chip_type;
-	struct workqueue_struct		*wq;
-	struct delayed_work		lt9211_dw;
-	struct drm_display_mode		mode;
-	bool				bpp24;
-	bool				jeida;
-	bool				de;
 };
 
 static const struct regmap_range lt9211_rw_ranges[] = {
@@ -154,8 +147,6 @@ static const struct regmap_config lt9211c_regmap_config = {
 	.max_register = 0xda00,
 };
 
-static void lt9211_delayed_work_func(struct work_struct *work);
-
 static struct lt9211 *bridge_to_lt9211(struct drm_bridge *bridge)
 {
 	return container_of(bridge, struct lt9211, bridge);
@@ -896,8 +887,8 @@ static int lt9211c_configure_plls(struct lt9211 *ctx,
 	return ret;
 }
 
-static int lt9211c_configure_tx(struct lt9211 *ctx,
-				const struct drm_display_mode *mode)
+static int lt9211c_configure_tx(struct lt9211 *ctx, bool jeida, bool bpp24,
+				bool de, const struct drm_display_mode *mode)
 {
 	const struct reg_sequence lt9211c_tx_phy_off_seq[] = {
 		{ 0x8236, 0x00 },
@@ -949,10 +940,10 @@ static int lt9211c_configure_tx(struct lt9211 *ctx,
 		{ 0x8556, 0x20 },
 
 		{ 0x8568, 0x00 },
-		{ 0x856e, 0x10 | (ctx->de ? BIT(6) : 0) },
-		{ 0x856f, 0x81 | (ctx->jeida ? BIT(6) : 0) |
+		{ 0x856e, 0x10 | (de ? BIT(6) : 0) },
+		{ 0x856f, 0x81 | (jeida ? BIT(6) : 0) |
 				  (ctx->lvds_dual_link ? BIT(4) : 0) |
-				  (ctx->bpp24 ? BIT(2) : 0) },
+				  (bpp24 ? BIT(2) : 0) },
 	};
 
 	const struct reg_sequence lt9211c_tx_ssc_seq[] = {
@@ -995,7 +986,7 @@ static int lt9211c_configure_tx(struct lt9211 *ctx,
 	dev_info(ctx->dev,
 		 "dual_link=%d,even_odd_swap=%d,bpp24=%d,jeida=%d,de=%d\n",
 		 ctx->lvds_dual_link, ctx->lvds_dual_link_even_odd_swap,
-		 ctx->bpp24, ctx->jeida, ctx->de);
+		 bpp24, jeida, de);
 
 	ret = regmap_multi_reg_write(ctx->regmap, lt9211c_tx_phy_off_seq,
 				     ARRAY_SIZE(lt9211c_tx_phy_off_seq));
@@ -1138,39 +1129,6 @@ static int lt9211c_configure_tx(struct lt9211 *ctx,
 	return 0;
 }
 
-static void lt9211_delayed_work_func(struct work_struct *work)
-{
-	struct delayed_work *dw = to_delayed_work(work);
-	struct lt9211 *ctx = container_of(dw, struct lt9211, lt9211_dw);
-	const struct drm_display_mode *mode = &ctx->mode;
-	int ret;
-
-	if (ctx->chip_type != LT9211C) {
-		dev_err(ctx->dev, "LT9211: Delayed work called for non-LT9211C chip\n");
-		return;
-	}
-
-	ret = lt9211c_configure_rx(ctx);
-	if (ret)
-		return;
-
-	ret = lt9211c_autodetect_rx(ctx, mode);
-	if (ret)
-		return;
-
-	ret = lt9211c_configure_timing(ctx, mode);
-	if (ret)
-		return;
-
-	ret = lt9211c_configure_plls(ctx, mode);
-	if (ret)
-		return;
-
-	ret = lt9211c_configure_tx(ctx, mode);
-	if (ret)
-		return;
-}
-
 static void lt9211_atomic_enable(struct drm_bridge *bridge,
 				 struct drm_atomic_commit *state)
 {
@@ -1240,11 +1198,30 @@ static void lt9211_atomic_enable(struct drm_bridge *bridge,
 	if (ret)
 		return;
 
-	if (ctx->chip_type == LT9211C && ctx->wq) {
-		drm_mode_copy(&ctx->mode, mode);
-		/* LT9211C must enable after mipi clock enable */
-		queue_delayed_work(ctx->wq, &ctx->lt9211_dw,
-				   msecs_to_jiffies(100));
+	if (ctx->chip_type == LT9211C) {
+		msleep(100);
+
+		ret = lt9211c_configure_rx(ctx);
+		if (ret)
+			return;
+
+		ret = lt9211c_autodetect_rx(ctx, mode);
+		if (ret)
+			return;
+
+		ret = lt9211c_configure_timing(ctx, mode);
+		if (ret)
+			return;
+
+		ret = lt9211c_configure_plls(ctx, mode);
+		if (ret)
+			return;
+
+		ret = lt9211c_configure_tx(ctx, lvds_format_jeida, lvds_format_24bpp,
+					   bus_flags & DRM_BUS_FLAG_DE_HIGH, mode);
+		if (ret)
+			return;
+
 		dev_dbg(ctx->dev, "LT9211C enabled.\n");
 		return;
 	}
@@ -1501,13 +1478,6 @@ static int lt9211_probe(struct i2c_client *client)
 	if (IS_ERR(ctx->regmap))
 		return PTR_ERR(ctx->regmap);
 
-	if (ctx->chip_type == LT9211C) {
-		ctx->wq = create_workqueue("lt9211_work");
-		if (!ctx->wq)
-			return -ENOMEM;
-		INIT_DELAYED_WORK(&ctx->lt9211_dw, lt9211_delayed_work_func);
-	}
-
 	dev_set_drvdata(dev, ctx);
 	i2c_set_clientdata(client, ctx);
 
@@ -1525,9 +1495,6 @@ static void lt9211_remove(struct i2c_client *client)
 {
 	struct lt9211 *ctx = i2c_get_clientdata(client);
 
-	if (ctx->wq)
-		destroy_workqueue(ctx->wq);
-
 	drm_bridge_remove(&ctx->bridge);
 }
 
-- 
2.47.3
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.