From patchwork Tue Jan 20 23:17:59 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 1705 Return-Path: X-Original-To: u-boot-concept@u-boot.org Delivered-To: u-boot-concept@u-boot.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1768951262; bh=gCCnqdZoMLZBB3QkjxZdo1B6e0rFNT1SOpXTyKHNiP0=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=CQD6ossdD5X0RBhscpJ/XroKu1b9BlRVadwmlngoyiQgGi/gq+uJOEz2kaM5jnigA le3q5+Pmeum6R4JwVLZCClLLRM2+WkQP8kfpALLZ/TVMyeNF0tOxmbGMVhZbMT1rh3 5H/cb8RDSYo4xf+T7Ke2JYe0ol2ghaICUQtI+K2ITRAcJBa6Va9Cyke0zLHgesl/Ca XRhphsgW471Nm19gPcaJm3MZTENOpozcWp/XKC7ujhVUmxWVGlhs90zvyJ5dk04LIm 9N+cH/hf9O5eFTohN18uRkeVnew6kQhGq1IFF4cgf8UuMC72W3HNxodtgCYrfeuKL/ UZN6TG8LvXgHg== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 09F98695A0 for ; Tue, 20 Jan 2026 16:21:02 -0700 (MST) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10024) with ESMTP id MXihxgpV3iaB for ; Tue, 20 Jan 2026 16:21:01 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1768951260; bh=gCCnqdZoMLZBB3QkjxZdo1B6e0rFNT1SOpXTyKHNiP0=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=s8zdiAUEkJzE8yE3l8h4WamSYIKFtZx7Fs+ycGvXmJ0vTi5qU/79FEddT+/THsR6N ymvUH50MZHFRegre6mfRKc5GV2V60qSvEXTBEoYxhZ6FOU92icuoAuBLRN567RmIV/ WTTOXOWK1FiW79YJf+oWwFNwjMT/ScNwJSQTUsn+qJkoQzdoQ+I+M06Pmg9yBXjnkO kAtA4aO07zclBXogiirjI2IEOIl48Xo/xlIoxG2YwrBa31GvHwgD/Xe4mpQjoMPoEF 4AqLf3DVB9Ey9MVD1GRY8JSxUW28KfVBaNDCwEprib5UxuA+Y8hYyMHhVoaBg/RTjY lyc8ZEQglgoTg== Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 0BB1269597 for ; Tue, 20 Jan 2026 16:21:00 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1768951256; bh=Ti/8VCe2AazINSlWmUq/B/imMhv8e1CCO2e90tnRmy4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=UIKmF9HzGI7vE2xHmFZdNiRMyjdMSep0e8DpgnaJQ9X+FcVTuQ04TnuY7EPdJWwl1 W3uwP85V7yOBg79U0HdLhgcv6evEX67sGCmGNbxSZh9OgFbupxvmu/fREz1p1YyUfT M9/AUvfXVbMk09czqregHF0pEr6wugQ4Pt7UyUEB0c8tjSQbCyI28yJQObxcZ9rqpf WedTM2dVqsW6kGTXB8C2IqYt/uZG9sm64V3bdcQ7Qg2q3jzeImU7K6aSj27PwgIL7+ 4H0ZYbF2SFuC9LlMmn34WIH8VszG0D6EJ7qJWsQQ1pTntTHnLFQ3q70CRm000sJpKO ClrY7ry44mHdA== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id DEAEE6959D; Tue, 20 Jan 2026 16:20:56 -0700 (MST) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10026) with ESMTP id 4tRwHn2Ly67r; Tue, 20 Jan 2026 16:20:56 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1768951256; bh=1Alz1H6kEuGsMPK5c4YC4cGgchC8r0vTpGPST1mqRZY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=uHYsANwSbb+s6sqgc2EDQH7Rvn8xnjIteWqWmRqyXY9J0XIBfBk40DmPcxu2qIHq/ ZVC9yvSeJZY+TBsx8RUsQEmZhm0duS2qxwlUe2zqYbIP7kqHeCf8bLvRshydvvHHlY WRbH/6qgpt9F/D/fwJxVZwDzL93XxokMk9uxdR5zpJlxHjwM4J6qL+CU0wppDnGFZk dt9nhzdYkGwejRdFzyCU4M2fP4MO2qOXiosgpF6daHrfjORYn95/Dy3MP7iVsi26H1 5ju3LnWfXHpU0FG6nRo0A5dwDjaafq4ctXZJcSVjzMrLEU47FZ0NRXUQ19qPFTEpa1 TxtC5pRqlyGGw== Received: from u-boot.org (unknown [73.34.74.121]) by mail.u-boot.org (Postfix) with ESMTPSA id 4D3CE69463; Tue, 20 Jan 2026 16:20:56 -0700 (MST) From: Simon Glass To: U-Boot Concept Date: Tue, 20 Jan 2026 16:17:59 -0700 Message-ID: <20260120231814.2033069-33-sjg@u-boot.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260120231814.2033069-1-sjg@u-boot.org> References: <20260120231814.2033069-1-sjg@u-boot.org> MIME-Version: 1.0 Message-ID-Hash: XY6RP2UDYDLZLHMRB4SWLNCUWH3SEATM X-Message-ID-Hash: XY6RP2UDYDLZLHMRB4SWLNCUWH3SEATM X-MailFrom: sjg@u-boot.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Simon Glass , "Claude Opus 4 . 5" X-Mailman-Version: 3.3.10 Precedence: list Subject: [Concept] [PATCH 32/36] video: Maintain a list of contexts in vidconsole List-Id: Discussion and patches related to U-Boot Concept Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Simon Glass Add an alist to track all client-allocated contexts in the vidconsole. This ensures that contexts can be properly cleaned up when the device is removed. Update vidconsole_ctx_new() to add newly created contexts to the list and vidconsole_ctx_dispose() to remove them. Init the list in vidconsole_pre_probe() and dispose of any remaining contexts in vidconsole_pre_remove() Co-developed-by: Claude Opus 4.5 Signed-off-by: Simon Glass --- drivers/video/vidconsole-uclass.c | 65 ++++++++++++++++++++++++------- include/video_console.h | 2 + 2 files changed, 53 insertions(+), 14 deletions(-) diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c index 83872b54b5d..4433920ecb6 100644 --- a/drivers/video/vidconsole-uclass.c +++ b/drivers/video/vidconsole-uclass.c @@ -712,32 +712,64 @@ int vidconsole_nominal(struct udevice *dev, const char *name, uint size, int vidconsole_ctx_new(struct udevice *dev, void **ctxp) { + struct vidconsole_priv *priv = dev_get_uclass_priv(dev); struct vidconsole_ops *ops = vidconsole_get_ops(dev); - void *ctx; + void **ptr; int ret; if (!ops->ctx_new) return -ENOSYS; - ret = ops->ctx_new(dev, &ctx); - if (ret) + /* reserve space first so ctx_new failure doesn't need cleanup */ + ptr = alist_add_placeholder(&priv->ctx_list); + if (!ptr) + return -ENOMEM; + + ret = ops->ctx_new(dev, ptr); + if (ret) { + priv->ctx_list.count--; return ret; - *ctxp = ctx; + } + *ctxp = *ptr; return 0; } -int vidconsole_ctx_dispose(struct udevice *dev, void *ctx) +/** + * vidconsole_free_ctx() - Free a context without removing it from the list + * + * This calls the driver's ctx_dispose method and frees the save_data, but + * does not remove the context from the alist. + * + * @dev: Vidconsole device + * @ctx: Context to free + */ +static void vidconsole_free_ctx(struct udevice *dev, struct vidconsole_ctx *ctx) { struct vidconsole_ops *ops = vidconsole_get_ops(dev); - int ret; - if (!ops->ctx_dispose) - return -ENOSYS; + if (ops->ctx_dispose) + ops->ctx_dispose(dev, ctx); + free(ctx->curs.save_data); +} - ret = ops->ctx_dispose(dev, ctx); - if (ret) - return ret; +int vidconsole_ctx_dispose(struct udevice *dev, void *vctx) +{ + struct vidconsole_priv *priv = dev_get_uclass_priv(dev); + struct vidconsole_ctx *ctx = vctx; + void **ptr, **from; + + if (!ctx) + return 0; + + /* remove the context from the list */ + alist_for_each_filter(ptr, from, &priv->ctx_list) { + if (*ptr != ctx) + *from++ = *ptr; + } + alist_update_end(&priv->ctx_list, from); + + vidconsole_free_ctx(dev, ctx); return 0; } @@ -903,6 +935,9 @@ static int vidconsole_pre_probe(struct udevice *dev) ctx->xsize_frac = VID_TO_POS(vid_priv->xsize); + alist_init_struct(&priv->ctx_list, void *); + alist_add(&priv->ctx_list, ctx); + return 0; } @@ -934,10 +969,12 @@ static int vidconsole_post_probe(struct udevice *dev) static int vidconsole_pre_remove(struct udevice *dev) { struct vidconsole_priv *priv = dev_get_uclass_priv(dev); - struct vidconsole_ctx *ctx = priv->ctx; + void **ptr; - free(ctx->curs.save_data); - free(ctx); + /* free all contexts in the list, including the default ctx */ + alist_for_each(ptr, &priv->ctx_list) + vidconsole_free_ctx(dev, *ptr); + alist_uninit(&priv->ctx_list); priv->ctx = NULL; return 0; diff --git a/include/video_console.h b/include/video_console.h index 6d635fd5971..8d2f0510534 100644 --- a/include/video_console.h +++ b/include/video_console.h @@ -166,11 +166,13 @@ struct vidconsole_uc_plat { * * @sdev: stdio device, acting as an output sink * @ctx: Per-client context (allocated by the uclass) + * @ctx_list: List of additional contexts allocated by clients * @quiet: Suppress all output from stdio */ struct vidconsole_priv { struct stdio_dev sdev; struct vidconsole_ctx *ctx; + struct alist ctx_list; bool quiet; };