From patchwork Tue Jan 20 23:18:03 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 1709 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=1768951277; bh=CnWaYaLBf4hjJwrUlsWy3flu2iCb7Z1NLVhxVsYqE2s=; 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=opqI81M4EMYmwIF5wPEv+q2gQ3EStX3ZVQT2fxDg+w8RmHuNupimzeuLRv11gPGkh Jp95sgM6qW2trHoyFfMZTBVMd3YQcFobUaAA1rQXrnK/9J64fPybnvyzXhdliLv8z9 pSwweuqAXKo6a4o6d0rEZ9wz1Z89GAWyYvOgVdhQJ3umUbHju9Umi3mpKNJ6LFHdjo GIUXRSvaFdeHjJeMpS3F2TO5ZquzFHjmFp0DyjVOxVpvz8s4FEKKOdtVCG/wQ18lxr n/+izTPFvRwzDii4KdZqd2MazuAhNzvgfXp/Me9sEDZuGz0tPxBmHO3JBZjnR3eU4t QadLv0UP4qgAg== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 1C03F6959E for ; Tue, 20 Jan 2026 16:21:17 -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 uPC3anKQ7f1s for ; Tue, 20 Jan 2026 16:21:17 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1768951277; bh=CnWaYaLBf4hjJwrUlsWy3flu2iCb7Z1NLVhxVsYqE2s=; 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=opqI81M4EMYmwIF5wPEv+q2gQ3EStX3ZVQT2fxDg+w8RmHuNupimzeuLRv11gPGkh Jp95sgM6qW2trHoyFfMZTBVMd3YQcFobUaAA1rQXrnK/9J64fPybnvyzXhdliLv8z9 pSwweuqAXKo6a4o6d0rEZ9wz1Z89GAWyYvOgVdhQJ3umUbHju9Umi3mpKNJ6LFHdjo GIUXRSvaFdeHjJeMpS3F2TO5ZquzFHjmFp0DyjVOxVpvz8s4FEKKOdtVCG/wQ18lxr n/+izTPFvRwzDii4KdZqd2MazuAhNzvgfXp/Me9sEDZuGz0tPxBmHO3JBZjnR3eU4t QadLv0UP4qgAg== Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 0B4A069597 for ; Tue, 20 Jan 2026 16:21:17 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1768951276; bh=CL9xlqWVZpgUNRv9U4TLgBJc9IubwuHFIEV1CSkh4cA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Tik/3D9sDsKCdbSaLE4Fl8boOTv3CuXLrVon/LILLmMqEvCGVF1ZfKtZFloHzyG9D /ZOzb1Udvd8Jvf1PDmC8FIf0jbF06N3Wslek1OFPJhGFKk8MpAXoK2Xo0/XvgV7kGQ aNPk7nng9p+MJfZJ1UrABHYxymj3eDLNcWjHmO+C/Fg+QYd3FRIasT/XMK4b9vfokb SvXiY5+OdwUe8yKJE/961hQ/u9+uQjDjDUiPI+cZ9/07hrtMc6PkCTN0McE6+ZaR40 LAkiElok6XusiX7BNS+mtYZW3jo5blbfKUT1OiMOUeuk17m3kxlDKxEgsOtI9rPyth dtoqukPVbTB2A== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 0E55A69597; Tue, 20 Jan 2026 16:21:16 -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 T0j3nANhTNH9; Tue, 20 Jan 2026 16:21:15 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1768951271; bh=cLuktDKNulRnxBx1u+8F3j01uFc1CMw37NokYd1sm6M=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=UVaSDU+ZBJ/5klTq/z5VYHnHX5VkVDnkKhWScXbK9Ux/1TLZiJRMnjjvamoUCaTb3 gxsWjfvyja3GALh4weXkOdr9JPCg+utab4NDKOd/eyIVDgYni5YEoByZZorBOavoWm MF6mSfYO0gwmUB54ajb9Sapf25prc+U+PTi8U3l9q9qFnfRoA8p5IXIQPdAwQMlME2 sCYSil9+26JZ89bKIkxAWsXVvCBRl9aK9jHwEhZDa4Fu8VW+EtmBG3HJTJS6f/+CkA citbiaMg7zxGoG4UDfbBFm4zughfsaSAWuVZ0drg2uXHUfQTiFSBjvKqw+0XKB/rDc rCkJZ/+R+KyYA== Received: from u-boot.org (unknown [73.34.74.121]) by mail.u-boot.org (Postfix) with ESMTPSA id B9D1D69463; Tue, 20 Jan 2026 16:21:11 -0700 (MST) From: Simon Glass To: U-Boot Concept Date: Tue, 20 Jan 2026 16:18:03 -0700 Message-ID: <20260120231814.2033069-37-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: LGYLHJODYBP7WBVOBB2O5H54W7SLKPQE X-Message-ID-Hash: LGYLHJODYBP7WBVOBB2O5H54W7SLKPQE 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 X-Mailman-Version: 3.3.10 Precedence: list Subject: [Concept] [PATCH 36/36] video: Move context allocation from drivers to uclass 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 Currently each driver allocates its own vidconsole context in its ctx_new() method. This leads to duplication and makes it harder to ensure consistent context setup. Move the responsibility for allocating contexts to the uclass. The ctx_new() ops method now receives an already-allocated context and just needs to initialise driver-specific fields. The uclass now handles: - Allocating memory using plat->ctx_size - Setting up xsize_frac from the video device - Allocating the cursor-save buffer if cursor support is enabled - Calling the driver's ctx_new() for driver-specific initialisation Move the default context creation from vidconsole_pre_probe() to vidconsole_post_probe() using vidconsole_ctx_new(). This allows additional contexts to be set up by calling the same function. For bitmap font drivers, rename console_probe() to console_simple_ctx_new() and move struct console_ctx to vidconsole_internal.h so it can be shared. For the truetype driver, move font selection from console_truetype_probe() to truetype_ctx_new(), using the first font initially. Also fix vidconsole_set_bitmap_font() to always set xsize_frac rather than relying on it being set in vidconsole_pre_probe(). This is a rather large 'flag day' change but it has resisted being broken up further. Signed-off-by: Simon Glass --- drivers/video/console_core.c | 5 ++- drivers/video/console_normal.c | 22 ---------- drivers/video/console_rotate.c | 6 +-- drivers/video/console_truetype.c | 17 +++----- drivers/video/vidconsole-uclass.c | 64 +++++++++++++++++------------ drivers/video/vidconsole_internal.h | 22 ++++++++++ include/video_console.h | 12 +++--- 7 files changed, 77 insertions(+), 71 deletions(-) diff --git a/drivers/video/console_core.c b/drivers/video/console_core.c index 6bd7dc263e6..ee07ffc98e4 100644 --- a/drivers/video/console_core.c +++ b/drivers/video/console_core.c @@ -305,11 +305,12 @@ void console_free_cursor(struct vidconsole_cursor *curs) free(curs->save_data); } -int console_probe(struct udevice *dev) +int console_simple_ctx_new(struct udevice *dev, void *vctx) { + struct console_ctx *ctx = vctx; int ret; - ret = console_set_font(dev, vidconsole_ctx(dev), fonts); + ret = console_set_font(dev, &ctx->com, fonts); if (ret) return ret; diff --git a/drivers/video/console_normal.c b/drivers/video/console_normal.c index c3b7f848b43..d36a5c0ff8f 100644 --- a/drivers/video/console_normal.c +++ b/drivers/video/console_normal.c @@ -15,14 +15,6 @@ #include /* Get font data, width and height */ #include "vidconsole_internal.h" -/** - * struct console_ctx - context for the normal console - * - * @com: Common fields from the vidconsole uclass - */ -struct console_ctx { - struct vidconsole_ctx com; -}; static int console_set_row(struct udevice *dev, uint row, int clr) { @@ -177,20 +169,6 @@ static int console_putc_xy(struct udevice *dev, void *vctx, uint x_frac, return console_normal_putc_xy(dev, vctx, x_frac, y, cp); } -static int console_simple_ctx_new(struct udevice *dev, void **ctxp) -{ - struct console_ctx *ctx; - - ctx = malloc(sizeof(*ctx)); - if (!ctx) - return -ENOMEM; - - memset(ctx, '\0', sizeof(*ctx)); - *ctxp = ctx; - - return 0; -} - struct vidconsole_ops console_ops = { .putc_xy = console_putc_xy, .move_rows = console_move_rows, diff --git a/drivers/video/console_rotate.c b/drivers/video/console_rotate.c index 42c9de888d8..77c814fa09e 100644 --- a/drivers/video/console_rotate.c +++ b/drivers/video/console_rotate.c @@ -294,6 +294,7 @@ struct vidconsole_ops console_ops_1 = { .get_font_size = console_simple_get_font_size, .get_font = console_simple_get_font, .select_font = console_simple_select_font, + .ctx_new = console_simple_ctx_new, }; struct vidconsole_ops console_ops_2 = { @@ -303,6 +304,7 @@ struct vidconsole_ops console_ops_2 = { .get_font_size = console_simple_get_font_size, .get_font = console_simple_get_font, .select_font = console_simple_select_font, + .ctx_new = console_simple_ctx_new, }; struct vidconsole_ops console_ops_3 = { @@ -312,13 +314,13 @@ struct vidconsole_ops console_ops_3 = { .get_font_size = console_simple_get_font_size, .get_font = console_simple_get_font, .select_font = console_simple_select_font, + .ctx_new = console_simple_ctx_new, }; U_BOOT_DRIVER(vidconsole_1) = { .name = "vidconsole1", .id = UCLASS_VIDEO_CONSOLE, .ops = &console_ops_1, - .probe = console_probe, .priv_auto = sizeof(struct console_simple_priv), }; @@ -326,7 +328,6 @@ U_BOOT_DRIVER(vidconsole_2) = { .name = "vidconsole2", .id = UCLASS_VIDEO_CONSOLE, .ops = &console_ops_2, - .probe = console_probe, .priv_auto = sizeof(struct console_simple_priv), }; @@ -334,6 +335,5 @@ U_BOOT_DRIVER(vidconsole_3) = { .name = "vidconsole3", .id = UCLASS_VIDEO_CONSOLE, .ops = &console_ops_3, - .probe = console_probe, .priv_auto = sizeof(struct console_simple_priv), }; diff --git a/drivers/video/console_truetype.c b/drivers/video/console_truetype.c index 4cf7ffebef3..25cc8241bf7 100644 --- a/drivers/video/console_truetype.c +++ b/drivers/video/console_truetype.c @@ -1143,16 +1143,15 @@ static int truetype_nominal(struct udevice *dev, const char *name, uint size, return 0; } -static int truetype_ctx_new(struct udevice *dev, void **ctxp) +static int truetype_ctx_new(struct udevice *dev, void *vctx) { - struct console_tt_ctx *ctx; + struct console_tt_priv *priv = dev_get_priv(dev); + struct console_tt_ctx *ctx = vctx; - ctx = malloc(sizeof(*ctx)); - if (!ctx) - return -ENOMEM; + /* use the first set of metrics by default */ + ctx->cur_met = &priv->metrics[0]; - memset(ctx, '\0', sizeof(*ctx)); - *ctxp = ctx; + select_metrics(dev, ctx, ctx->cur_met); return 0; } @@ -1256,7 +1255,6 @@ static int truetype_mark_start(struct udevice *dev, void *vctx) static int console_truetype_probe(struct udevice *dev) { - struct console_tt_ctx *ctx = vidconsole_ctx(dev); struct console_tt_priv *priv = dev_get_priv(dev); struct udevice *vid_dev = dev->parent; struct video_priv *vid_priv = dev_get_uclass_priv(vid_dev); @@ -1289,9 +1287,6 @@ static int console_truetype_probe(struct udevice *dev) ret = truetype_add_metrics(dev, tab->name, font_size, tab->begin); if (ret < 0) return log_msg_ret("add", ret); - ctx->cur_met = &priv->metrics[ret]; - - select_metrics(dev, ctx, &priv->metrics[ret]); debug("%s: ready\n", __func__); diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c index 147063c4d38..b6bd3133037 100644 --- a/drivers/video/vidconsole-uclass.c +++ b/drivers/video/vidconsole-uclass.c @@ -713,10 +713,14 @@ int vidconsole_nominal(struct udevice *dev, const char *name, uint size, int vidconsole_ctx_new(struct udevice *dev, void **ctxp) { + struct udevice *vid = dev->parent; + struct video_priv *vid_priv = dev_get_uclass_priv(vid); + struct vidconsole_uc_plat *plat = dev_get_uclass_plat(dev); struct vidconsole_priv *priv = dev_get_uclass_priv(dev); struct vidconsole_ops *ops = vidconsole_get_ops(dev); + struct vidconsole_ctx *ctx; + int ret = -ENOMEM, size; void **ptr; - int ret; if (!ops->ctx_new) return -ENOSYS; @@ -726,14 +730,35 @@ int vidconsole_ctx_new(struct udevice *dev, void **ctxp) if (!ptr) return -ENOMEM; - ret = ops->ctx_new(dev, ptr); - if (ret) { - priv->ctx_list.count--; - return ret; + size = plat->ctx_size ?: sizeof(struct vidconsole_ctx); + ctx = calloc(1, size); + if (!ctx) + goto err_alloc; + *ptr = ctx; + + if (CONFIG_IS_ENABLED(CURSOR) && xpl_phase() == PHASE_BOARD_R) { + ret = console_alloc_cursor(dev, &ctx->curs); + if (ret) + goto err_curs; } - *ctxp = *ptr; + + ctx->xsize_frac = VID_TO_POS(vid_priv->xsize); + + ret = ops->ctx_new(dev, ctx); + if (ret) + goto err_new; + *ctxp = ctx; return 0; + +err_new: + console_free_cursor(&ctx->curs); +err_curs: +err_alloc: + priv->ctx_list.count--; + free(ctx); + + return ret; } /** @@ -922,23 +947,9 @@ void vidconsole_pop_colour(struct udevice *dev, struct vidconsole_colour *old) /* Set up the number of rows and colours (rotated drivers override this) */ static int vidconsole_pre_probe(struct udevice *dev) { - struct vidconsole_uc_plat *plat = dev_get_uclass_plat(dev); struct vidconsole_priv *priv = dev_get_uclass_priv(dev); - struct udevice *vid = dev->parent; - struct video_priv *vid_priv = dev_get_uclass_priv(vid); - struct vidconsole_ctx *ctx; - uint size; - - size = plat->ctx_size ?: sizeof(struct vidconsole_ctx); - ctx = calloc(1, size); - if (!ctx) - return -ENOMEM; - priv->ctx = ctx; - - ctx->xsize_frac = VID_TO_POS(vid_priv->xsize); alist_init_struct(&priv->ctx_list, void *); - alist_add(&priv->ctx_list, ctx); return 0; } @@ -947,15 +958,14 @@ static int vidconsole_pre_probe(struct udevice *dev) static int vidconsole_post_probe(struct udevice *dev) { struct vidconsole_priv *priv = dev_get_uclass_priv(dev); - struct vidconsole_ctx *ctx = vidconsole_ctx_from_priv(priv); struct stdio_dev *sdev = &priv->sdev; + struct vidconsole_ctx *ctx; int ret; - if (CONFIG_IS_ENABLED(CURSOR) && xpl_phase() == PHASE_BOARD_R) { - ret = console_alloc_cursor(dev, &ctx->curs); - if (ret) - return ret; - } + ret = vidconsole_ctx_new(dev, (void **)&ctx); + if (ret) + return ret; + priv->ctx = ctx; if (!ctx->tab_width_frac) ctx->tab_width_frac = VID_TO_POS(ctx->x_charsize) * 8; @@ -1049,7 +1059,7 @@ void vidconsole_set_bitmap_font(struct udevice *dev, struct vidconsole_ctx *ctx, } else { ctx->cols = vid_priv->xsize / fontdata->width; ctx->rows = vid_priv->ysize / fontdata->height; - /* xsize_frac is set in vidconsole_pre_probe() */ + ctx->xsize_frac = VID_TO_POS(vid_priv->xsize); } ctx->xstart_frac = 0; } diff --git a/drivers/video/vidconsole_internal.h b/drivers/video/vidconsole_internal.h index b5ffdfad4da..439192ecc1e 100644 --- a/drivers/video/vidconsole_internal.h +++ b/drivers/video/vidconsole_internal.h @@ -8,6 +8,7 @@ #include #include +#include struct udevice; struct vidconsole_cursor; @@ -25,6 +26,15 @@ struct console_simple_priv { struct video_fontdata *fontdata; }; +/** + * struct console_ctx - context for the normal console + * + * @com: Common fields from the vidconsole uclass + */ +struct console_ctx { + struct vidconsole_ctx com; +}; + /** * Checks if bits per pixel supported. * @@ -237,3 +247,15 @@ static inline u8 console_utf_to_cp437(int codepoint) } return codepoint; } + +/** + * console_simple_ctx_new() - Set up a new context for bitmap-font consoles + * + * Initialises the context with the default bitmap font. This is the ctx_new() + * method for bitmap-font console drivers. + * + * @dev: Vidconsole device + * @ctx: Context to initialise (allocated by the uclass) + * Return: 0 on success, -ve on error + */ +int console_simple_ctx_new(struct udevice *dev, void *ctx); diff --git a/include/video_console.h b/include/video_console.h index 8d2f0510534..c047d45cf53 100644 --- a/include/video_console.h +++ b/include/video_console.h @@ -384,16 +384,16 @@ struct vidconsole_ops { uint num_chars, struct vidconsole_bbox *bbox); /** - * ctx_new() - Create a new context for a client + * ctx_new() - Initialise a new context for a client * - * Allocates and initialises a context for a client of the vidconsole. - * The driver determines what information is stored in the context. + * Initialises driver-specific fields of a pre-allocated context. The + * base vidconsole_ctx fields are already initialised by the uclass. * * @dev: Console device to use - * @ctxp: Returns new context, on success - * Return: 0 on success, -ENOMEM if out of memory + * @ctx: Pre-allocated context to initialise + * Return: 0 on success, -ve on error */ - int (*ctx_new)(struct udevice *dev, void **ctxp); + int (*ctx_new)(struct udevice *dev, void *ctx); /** * ctx_dispose() - Dispose of a context