From 4ce026d5f4ccb89a493b7c57d87d53a3ccb0be59 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 19 Feb 2024 18:58:01 +0200 Subject: [PATCH] auxdisplay: linedisp: Allocate buffer for the string Always allocate a buffer for the currently displayed characters. It makes the line display API simpler. Reviewed-by: Geert Uytterhoeven Tested-by: Geert Uytterhoeven Signed-off-by: Andy Shevchenko --- drivers/auxdisplay/ht16k33.c | 8 +++----- drivers/auxdisplay/img-ascii-lcd.c | 17 +++++++---------- drivers/auxdisplay/line-display.c | 11 +++++++---- drivers/auxdisplay/line-display.h | 3 +-- 4 files changed, 18 insertions(+), 21 deletions(-) diff --git a/drivers/auxdisplay/ht16k33.c b/drivers/auxdisplay/ht16k33.c index 32d3afd29177..19805f39a257 100644 --- a/drivers/auxdisplay/ht16k33.c +++ b/drivers/auxdisplay/ht16k33.c @@ -92,7 +92,6 @@ struct ht16k33_seg { struct seg14_conversion_map seg14; } map; unsigned int map_size; - char curr[4]; }; struct ht16k33_priv { @@ -457,7 +456,7 @@ static void ht16k33_seg7_update(struct work_struct *work) struct ht16k33_priv *priv = container_of(work, struct ht16k33_priv, work.work); struct ht16k33_seg *seg = &priv->seg; - char *s = seg->curr; + char *s = seg->linedisp.buf; uint8_t buf[9]; buf[0] = map_to_seg7(&seg->map.seg7, *s++); @@ -478,7 +477,7 @@ static void ht16k33_seg14_update(struct work_struct *work) struct ht16k33_priv *priv = container_of(work, struct ht16k33_priv, work.work); struct ht16k33_seg *seg = &priv->seg; - char *s = seg->curr; + char *s = seg->linedisp.buf; uint8_t buf[8]; put_unaligned_le16(map_to_seg14(&seg->map.seg14, *s++), buf); @@ -700,8 +699,7 @@ static int ht16k33_seg_probe(struct device *dev, struct ht16k33_priv *priv, if (err) return err; - err = linedisp_register(&seg->linedisp, dev, 4, seg->curr, - &ht16k33_linedisp_ops); + err = linedisp_register(&seg->linedisp, dev, 4, &ht16k33_linedisp_ops); if (err) goto err_remove_map_file; diff --git a/drivers/auxdisplay/img-ascii-lcd.c b/drivers/auxdisplay/img-ascii-lcd.c index ecfb1c05bf55..925c4cd101e9 100644 --- a/drivers/auxdisplay/img-ascii-lcd.c +++ b/drivers/auxdisplay/img-ascii-lcd.c @@ -37,7 +37,6 @@ struct img_ascii_lcd_config { * @regmap: the regmap through which LCD registers are accessed * @offset: the offset within regmap to the start of the LCD registers * @cfg: pointer to the LCD model configuration - * @curr: the string currently displayed on the LCD */ struct img_ascii_lcd_ctx { struct linedisp linedisp; @@ -47,7 +46,6 @@ struct img_ascii_lcd_ctx { }; u32 offset; const struct img_ascii_lcd_config *cfg; - char curr[] __aligned(8); }; /* @@ -61,12 +59,12 @@ static void boston_update(struct linedisp *linedisp) ulong val; #if BITS_PER_LONG == 64 - val = *((u64 *)&ctx->curr[0]); + val = *((u64 *)&linedisp->buf[0]); __raw_writeq(val, ctx->base); #elif BITS_PER_LONG == 32 - val = *((u32 *)&ctx->curr[0]); + val = *((u32 *)&linedisp->buf[0]); __raw_writel(val, ctx->base); - val = *((u32 *)&ctx->curr[4]); + val = *((u32 *)&linedisp->buf[4]); __raw_writel(val, ctx->base + 4); #else # error Not 32 or 64 bit @@ -93,7 +91,7 @@ static void malta_update(struct linedisp *linedisp) for (i = 0; i < linedisp->num_chars; i++) { err = regmap_write(ctx->regmap, - ctx->offset + (i * 8), ctx->curr[i]); + ctx->offset + (i * 8), linedisp->buf[i]); if (err) break; } @@ -195,7 +193,7 @@ static void sead3_update(struct linedisp *linedisp) err = regmap_write(ctx->regmap, ctx->offset + SEAD3_REG_LCD_DATA, - ctx->curr[i]); + linedisp->buf[i]); if (err) break; } @@ -236,7 +234,7 @@ static int img_ascii_lcd_probe(struct platform_device *pdev) struct img_ascii_lcd_ctx *ctx; int err; - ctx = devm_kzalloc(dev, sizeof(*ctx) + cfg->num_chars, GFP_KERNEL); + ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); if (!ctx) return -ENOMEM; @@ -253,8 +251,7 @@ static int img_ascii_lcd_probe(struct platform_device *pdev) return PTR_ERR(ctx->base); } - err = linedisp_register(&ctx->linedisp, dev, cfg->num_chars, ctx->curr, - &cfg->ops); + err = linedisp_register(&ctx->linedisp, dev, cfg->num_chars, &cfg->ops); if (err) return err; diff --git a/drivers/auxdisplay/line-display.c b/drivers/auxdisplay/line-display.c index 13be7c2f6bc3..e2b546210f8d 100644 --- a/drivers/auxdisplay/line-display.c +++ b/drivers/auxdisplay/line-display.c @@ -265,6 +265,7 @@ static void linedisp_release(struct device *dev) kfree(linedisp->map); kfree(linedisp->message); + kfree(linedisp->buf); ida_free(&linedisp_id, linedisp->id); } @@ -316,14 +317,12 @@ static int linedisp_init_map(struct linedisp *linedisp) * @linedisp: pointer to character line display structure * @parent: parent device * @num_chars: the number of characters that can be displayed - * @buf: pointer to a buffer that can hold @num_chars characters * @ops: character line display operations * * Return: zero on success, else a negative error code. */ int linedisp_register(struct linedisp *linedisp, struct device *parent, - unsigned int num_chars, char *buf, - const struct linedisp_ops *ops) + unsigned int num_chars, const struct linedisp_ops *ops) { int err; @@ -331,7 +330,6 @@ int linedisp_register(struct linedisp *linedisp, struct device *parent, linedisp->dev.parent = parent; linedisp->dev.type = &linedisp_type; linedisp->ops = ops; - linedisp->buf = buf; linedisp->num_chars = num_chars; linedisp->scroll_rate = DEFAULT_SCROLL_RATE; @@ -343,6 +341,11 @@ int linedisp_register(struct linedisp *linedisp, struct device *parent, device_initialize(&linedisp->dev); dev_set_name(&linedisp->dev, "linedisp.%u", linedisp->id); + err = -ENOMEM; + linedisp->buf = kzalloc(linedisp->num_chars, GFP_KERNEL); + if (!linedisp->buf) + goto out_put_device; + /* initialise a character mapping, if required */ err = linedisp_init_map(linedisp); if (err) diff --git a/drivers/auxdisplay/line-display.h b/drivers/auxdisplay/line-display.h index 4e310b0e611e..4348d7a2f69a 100644 --- a/drivers/auxdisplay/line-display.h +++ b/drivers/auxdisplay/line-display.h @@ -82,8 +82,7 @@ struct linedisp { }; int linedisp_register(struct linedisp *linedisp, struct device *parent, - unsigned int num_chars, char *buf, - const struct linedisp_ops *ops); + unsigned int num_chars, const struct linedisp_ops *ops); void linedisp_unregister(struct linedisp *linedisp); #endif /* LINEDISP_H */