[Concept,10/18] video: Allocate vidconsole_ctx dynamically using ctx_size
Commit Message
From: Simon Glass <simon.glass@canonical.com>
Change the ctx field in vidconsole_priv from an embedded struct to a
pointer, and allocate it dynamically in vidconsole_pre_probe(). The
size is taken from the ctx_size field in vidconsole_uc_plat, falling
back to sizeof(struct vidconsole_ctx) if ctx_size is 0
This allows drivers to specify a larger context size if they need to
store additional per-context data beyond the base vidconsole_ctx.
The context is freed in vidconsole_pre_remove() along with the cursor
save data.
Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
---
board/atmel/common/video_display.c | 4 ++--
drivers/video/vidconsole-uclass.c | 18 +++++++++++++++---
include/video_console.h | 17 +++++++++--------
3 files changed, 26 insertions(+), 13 deletions(-)
@@ -68,8 +68,8 @@ int at91_video_show_board_info(void)
priv = dev_get_uclass_priv(con);
vidconsole_position_cursor(con, 0, (logo_info.logo_height +
- priv->ctx.y_charsize - 1) /
- priv->ctx.y_charsize);
+ priv->ctx->y_charsize - 1) /
+ priv->ctx->y_charsize);
for (s = buf, i = 0; i < len; s++, i++)
vidconsole_put_char(con, *s);
@@ -878,9 +878,18 @@ 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_ctx *ctx = vidconsole_ctx(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);
@@ -914,9 +923,12 @@ static int vidconsole_post_probe(struct udevice *dev)
static int vidconsole_pre_remove(struct udevice *dev)
{
- struct vidconsole_ctx *ctx = vidconsole_ctx(dev);
+ struct vidconsole_priv *priv = dev_get_uclass_priv(dev);
+ struct vidconsole_ctx *ctx = priv->ctx;
free(ctx->curs.save_data);
+ free(ctx);
+ priv->ctx = NULL;
return 0;
}
@@ -1036,5 +1048,5 @@ void *vidconsole_ctx(struct udevice *dev)
{
struct vidconsole_priv *uc_priv = dev_get_uclass_priv(dev);
- return &uc_priv->ctx;
+ return uc_priv->ctx;
}
@@ -152,24 +152,25 @@ struct vidconsole_uc_plat {
/**
* struct vidconsole_priv - uclass-private data about a console device
*
- * Drivers must set up @ctx.rows, @ctx.cols, @ctx.x_charsize, @ctx.y_charsize
- * in their probe() method. Drivers may set up @ctx.xstart_frac if desired.
+ * Drivers must set up @ctx->rows, @ctx->cols, @ctx->x_charsize,
+ * @ctx->y_charsize in their probe() method. Drivers may set up
+ * @ctx->xstart_frac if desired.
*
* Note that these values relate to the rotated console, so that an 80x25
* console which is rotated 90 degrees will have rows=80 and cols=25
*
- * The ctx.xcur_frac and ctx.ycur values refer to the unrotated coordinates,
- * that is ctx.xcur_frac always advances with each character, even if its limit
- * might be vid_priv->ysize instead of vid_priv->xsize if the console is
+ * The ctx->xcur_frac and ctx->ycur values refer to the unrotated coordinates,
+ * that is ctx->xcur_frac always advances with each character, even if its
+ * limit might be vid_priv->ysize instead of vid_priv->xsize if the console is
* rotated 90 or 270 degrees.
*
* @sdev: stdio device, acting as an output sink
- * @ctx: Per-client context
+ * @ctx: Per-client context (allocated by the uclass)
* @quiet: Suppress all output from stdio
*/
struct vidconsole_priv {
struct stdio_dev sdev;
- struct vidconsole_ctx ctx;
+ struct vidconsole_ctx *ctx;
bool quiet;
};
@@ -461,7 +462,7 @@ void *vidconsole_ctx(struct udevice *dev);
*/
static inline void *vidconsole_ctx_from_priv(struct vidconsole_priv *uc_priv)
{
- return &uc_priv->ctx;
+ return uc_priv->ctx;
}
/**