From: Simon Glass <simon.glass@canonical.com> 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 <simon.glass@canonical.com> --- 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 <video_font.h> /* 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 <charset.h> #include <config.h> +#include <video_console.h> 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 -- 2.43.0