From patchwork Fri Jan 16 17:14:04 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 1530 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=1768583699; bh=8yPxxCmyX2jRR7pDKcu/kTE/kTMhUm7lCMHbOsYVIys=; 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=XAL4hGALcHEIM18jUW1M8kjoa4oXz8AFbDRqnSYddqZBDgWtlejKXP6j2W+rVh2yo cxurgy2dXYM656c4q8YuyHnZmsXHxAmGOK0M+JSRQW9pkBO7QjxDe9N2ZGd3wyqfaP qV3s/WL5eXWJaA8EGgYTGgtSWkXt/KENwaEN4zU9Dqn13IMbFsBOBZ6155HwnqkYTA lttCP8YZgfzuXt3YOYSnFJbtVtV/XQ2GaenEOohIACTgqoh3C5zIemef1F7fQsA18c 5A7Gl/FDC2uYxrkzdik3xoQiiJ0MjFfrUmuJwD2lhw7uJi5C1+t/oyXvI5H/3TtjRD o+djgyzK3raVg== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 5041C693C0 for ; Fri, 16 Jan 2026 10:14:59 -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 Umc1n4etXDmN for ; Fri, 16 Jan 2026 10:14:59 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1768583698; bh=8yPxxCmyX2jRR7pDKcu/kTE/kTMhUm7lCMHbOsYVIys=; 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=TF4qRSysIyfl1zA4A61XYIF8+ptRxfdCIe/IxRYdbgF5uFyBCOJmI1CIGXr32VcrN rmSInne46tse5ulc9Zb06AwrCUNJFtMsUD8BL66VQplve8Cp0vKzWYFAxBmNSb1wIJ xdAdPhVjC9zYY94bC3xZ8qeJm5LPjRkm+gjEeJ/LzabNez35/E+4nFoVQAZ+NvCDqb XFDcGtlA5iPaSoEKoKQaW2sogmJ6vlD/uk2FBhr4bY08tEnAhAodxCPl10s9SojLrM Z3RoTQsBn8IJDH6mpTIGaj3JXsBAckQjMs7VSHWSFRvfHSxX8XoUpDClNZ6gDnCtI0 JlJdBUoKWvcsw== Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 4AFAF693CB for ; Fri, 16 Jan 2026 10:14:58 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1768583692; bh=O0qMXt5sWmZP6L0DgMeGNEITy3Ia7bWjtbPNM63OSA0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=snI3o5XdBQcJ9DHHiR38IDPWAgJOSkfel4g8w6fbyWkLHXwiTq0+OV6MJuHAO1rTt jZwHOoMA5+z5Lnj0fcFvnA4KfM43x24hm79aj+A/ratFRGvU6MrhNZPh+nkJ1Vsizv 2anvrq4Ws4Uz0+MpegwzhglahpDkN37CqT9hsualKMJ0X5zLwD/+0VSXH24cbQrJTW Xooh55ATLrQOFuqCJhoTgQRgOuCJZYzHZtt2JbnT/1t8za1lwwxI3hKDy5gUM/26og jNXK532oVEUz2QlHIXX+yi73se7OrrJX8i+YhIzipMcUm/KeJHsiE4yiXSaQIBOrr6 JUJQJvRTTNZFw== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 868536932F; Fri, 16 Jan 2026 10:14:52 -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 UDIK04y0GFlz; Fri, 16 Jan 2026 10:14:52 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1768583687; bh=B5n0yEU6I9XcbZk231r70qfYr2bx1X2S+WBJuKj0tpU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=mXFV75OmagOna7AQExw5qnLYI62tRAjkRp9XgvcbEdvn/jNEkmrjg4gcPCnZXGyAZ bQgVq3vat0p2mZ7+Hac+lwFpIClyPZ5e1S3NSjiwXwnytGmOLO1EqgWoSLpmpAEINT wkRmP2EZxrnoXPF4mfJtb8Kutz95ABZrN8D7BCcOKvwed9uxvwmjQXWWLBt9cOXDRn HDFzyrk1PDynah30MPq78bBngh6rn8UKmJDScwS94j25YrbVwMuUcLxuKyRwn9bBD9 i2B6oDAq3CJYAMUH2/JO7C7gHdF7xXlWRztOIgb88R/90v4Kwi69Da5NGnw7uZBwwT bsqKec+1dQJDQ== Received: from u-boot.org (unknown [73.34.74.121]) by mail.u-boot.org (Postfix) with ESMTPSA id E4C4A6913F; Fri, 16 Jan 2026 10:14:46 -0700 (MST) From: Simon Glass To: U-Boot Concept Date: Fri, 16 Jan 2026 10:14:04 -0700 Message-ID: <20260116171424.398597-3-sjg@u-boot.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260116171424.398597-1-sjg@u-boot.org> References: <20260116171424.398597-1-sjg@u-boot.org> MIME-Version: 1.0 Message-ID-Hash: I3QHL2V4UBXO6TW4PBVHEK2GIF4JLWYW X-Message-ID-Hash: I3QHL2V4UBXO6TW4PBVHEK2GIF4JLWYW 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 02/14] video: Add vidconsole context creation and disposal 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 ctx_new and ctx_dispose operations to the vidconsole interface. These allow clients to create and dispose of their own context, with the driver determining what state is stored in the context buffer. The wrapper functions provide default implementations that just initialise or free the abuf if the driver does not implement the ops. Co-developed-by: Claude Opus 4.5 Signed-off-by: Simon Glass --- drivers/video/console_normal.c | 24 +++++++++++++++++ drivers/video/console_truetype.c | 23 ++++++++++++++++ drivers/video/vidconsole-uclass.c | 32 ++++++++++++++++++++++ include/video_console.h | 44 +++++++++++++++++++++++++++++++ test/dm/video.c | 22 ++++++++++++++++ 5 files changed, 145 insertions(+) diff --git a/drivers/video/console_normal.c b/drivers/video/console_normal.c index cfe6196fced..f6dc37bc6be 100644 --- a/drivers/video/console_normal.c +++ b/drivers/video/console_normal.c @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -188,6 +189,27 @@ static int console_putc_xy(struct udevice *dev, uint x_frac, uint y, int cp) return console_normal_putc_xy(dev, 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; +} + +static int console_simple_ctx_dispose(struct udevice *dev, void *ctx) +{ + free(ctx); + + return 0; +} + struct vidconsole_ops console_ops = { .putc_xy = console_putc_xy, .move_rows = console_move_rows, @@ -195,6 +217,8 @@ struct vidconsole_ops console_ops = { .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, + .ctx_dispose = console_simple_ctx_dispose, #ifdef CONFIG_CURSOR .get_cursor_info = console_get_cursor_info, .entry_save = normal_entry_save, diff --git a/drivers/video/console_truetype.c b/drivers/video/console_truetype.c index c2d165a8b8e..d707ac3c864 100644 --- a/drivers/video/console_truetype.c +++ b/drivers/video/console_truetype.c @@ -1149,6 +1149,27 @@ static int truetype_nominal(struct udevice *dev, const char *name, uint size, return 0; } +static int truetype_ctx_new(struct udevice *dev, void **ctxp) +{ + struct console_tt_ctx *ctx; + + ctx = malloc(sizeof(*ctx)); + if (!ctx) + return -ENOMEM; + + memset(ctx, '\0', sizeof(*ctx)); + *ctxp = ctx; + + return 0; +} + +static int truetype_ctx_dispose(struct udevice *dev, void *ctx) +{ + free(ctx); + + return 0; +} + static int truetype_entry_save(struct udevice *dev, struct abuf *buf) { struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev); @@ -1331,6 +1352,8 @@ struct vidconsole_ops console_truetype_ops = { .select_font = truetype_select_font, .measure = truetype_measure, .nominal = truetype_nominal, + .ctx_new = truetype_ctx_new, + .ctx_dispose = truetype_ctx_dispose, .entry_save = truetype_entry_save, .entry_restore = truetype_entry_restore, .get_cursor_info = truetype_get_cursor_info, diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c index 8efe458287a..8ef9f4c90d6 100644 --- a/drivers/video/vidconsole-uclass.c +++ b/drivers/video/vidconsole-uclass.c @@ -690,6 +690,38 @@ int vidconsole_nominal(struct udevice *dev, const char *name, uint size, return 0; } +int vidconsole_ctx_new(struct udevice *dev, void **ctxp) +{ + struct vidconsole_ops *ops = vidconsole_get_ops(dev); + void *ctx; + int ret; + + if (!ops->ctx_new) + return -ENOSYS; + + ret = ops->ctx_new(dev, &ctx); + if (ret) + return ret; + *ctxp = ctx; + + return 0; +} + +int vidconsole_ctx_dispose(struct udevice *dev, void *ctx) +{ + struct vidconsole_ops *ops = vidconsole_get_ops(dev); + int ret; + + if (!ops->ctx_dispose) + return -ENOSYS; + + ret = ops->ctx_dispose(dev, ctx); + if (ret) + return ret; + + return 0; +} + int vidconsole_entry_save(struct udevice *dev, struct abuf *buf) { struct vidconsole_ops *ops = vidconsole_get_ops(dev); diff --git a/include/video_console.h b/include/video_console.h index 0acc7ab2737..adc4537ceb7 100644 --- a/include/video_console.h +++ b/include/video_console.h @@ -348,6 +348,28 @@ struct vidconsole_ops { int (*nominal)(struct udevice *dev, const char *name, uint size, uint num_chars, struct vidconsole_bbox *bbox); + /** + * ctx_new() - Create 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. + * + * @dev: Console device to use + * @ctxp: Returns new context, on success + * Return: 0 on success, -ENOMEM if out of memory + */ + int (*ctx_new)(struct udevice *dev, void **ctxp); + + /** + * ctx_dispose() - Dispose of a context + * + * Frees any memory allocated for the context. + * + * @dev: Console device to use + * @ctx: Context to dispose of + */ + int (*ctx_dispose)(struct udevice *dev, void *ctx); + /** * entry_save() - Save any text-entry information for later use * @@ -456,6 +478,28 @@ int vidconsole_measure(struct udevice *dev, const char *name, uint size, int vidconsole_nominal(struct udevice *dev, const char *name, uint size, uint num_chars, struct vidconsole_bbox *bbox); +/** + * vidconsole_ctx_new() - Create 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. + * + * @dev: Console device to use + * @ctxp: Returns new context, on success + * Return: 0 on success, -ENOMEM if out of memory + */ +int vidconsole_ctx_new(struct udevice *dev, void **ctxp); + +/** + * vidconsole_ctx_dispose() - Dispose of a context + * + * Frees any memory allocated for the context. + * + * @dev: Console device to use + * @ctx: Context to dispose of + */ +int vidconsole_ctx_dispose(struct udevice *dev, void *ctx); + /** * vidconsole_entry_save() - Save any text-entry information for later use * diff --git a/test/dm/video.c b/test/dm/video.c index 6029fa3d5cc..d802a5cc24d 100644 --- a/test/dm/video.c +++ b/test/dm/video.c @@ -1493,3 +1493,25 @@ static int dm_test_video_sync_damage(struct unit_test_state *uts) return 0; } DM_TEST(dm_test_video_sync_damage, UTF_SCAN_PDATA | UTF_SCAN_FDT); + +/* Test vidconsole context allocation */ +static int dm_test_video_context_alloc(struct unit_test_state *uts) +{ + struct udevice *dev, *con; + void *ctx; + + ut_assertok(select_vidconsole(uts, "vidconsole0")); + ut_assertok(video_get_nologo(uts, &dev)); + ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con)); + + ut_assertok(vidconsole_ctx_new(con, &ctx)); + ut_assertnonnull(ctx); + + ut_assertok(vidconsole_ctx_dispose(con, ctx)); + + /* Dispose should handle NULL gracefully */ + ut_assertok(vidconsole_ctx_dispose(con, NULL)); + + return 0; +} +DM_TEST(dm_test_video_context_alloc, UTF_SCAN_PDATA | UTF_SCAN_FDT);