Skip to content

Commit 67200d7

Browse files
committed
Merge patch series "auxdisplay: charlcd: Refactor memory allocation"
Andy Shevchenko says: The users of charlcd_alloc() call for additional memory allocation. We may do it at the time of the main call as many other APIs do. For this partially revert the change that brought us to the current state of affairs, and refactor the code based on the original implementation. Link: https://lore.kernel.org/r/20250224173010.219024-1-andriy.shevchenko@linux.intel.com Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
2 parents 72e1c44 + 2c4849a commit 67200d7

File tree

7 files changed

+40
-46
lines changed

7 files changed

+40
-46
lines changed

drivers/auxdisplay/charlcd.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -595,18 +595,19 @@ static int charlcd_init(struct charlcd *lcd)
595595
return 0;
596596
}
597597

598-
struct charlcd *charlcd_alloc(void)
598+
struct charlcd *charlcd_alloc(unsigned int drvdata_size)
599599
{
600600
struct charlcd_priv *priv;
601601
struct charlcd *lcd;
602602

603-
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
603+
priv = kzalloc(sizeof(*priv) + drvdata_size, GFP_KERNEL);
604604
if (!priv)
605605
return NULL;
606606

607607
priv->esc_seq.len = -1;
608608

609609
lcd = &priv->lcd;
610+
lcd->drvdata = priv->drvdata;
610611

611612
return lcd;
612613
}

drivers/auxdisplay/charlcd.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ struct charlcd {
5151
unsigned long y;
5252
} addr;
5353

54-
void *drvdata;
54+
void *drvdata; /* Set by charlcd_alloc() */
5555
};
5656

5757
/**
@@ -95,7 +95,8 @@ struct charlcd_ops {
9595
};
9696

9797
void charlcd_backlight(struct charlcd *lcd, enum charlcd_onoff on);
98-
struct charlcd *charlcd_alloc(void);
98+
99+
struct charlcd *charlcd_alloc(unsigned int drvdata_size);
99100
void charlcd_free(struct charlcd *lcd);
100101

101102
int charlcd_register(struct charlcd *lcd);

drivers/auxdisplay/hd44780.c

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -222,20 +222,17 @@ static int hd44780_probe(struct platform_device *pdev)
222222
return -EINVAL;
223223
}
224224

225-
hdc = hd44780_common_alloc();
226-
if (!hdc)
227-
return -ENOMEM;
228-
229-
lcd = charlcd_alloc();
225+
lcd = hd44780_common_alloc();
230226
if (!lcd)
231-
goto fail1;
227+
return -ENOMEM;
232228

233229
hd = kzalloc(sizeof(*hd), GFP_KERNEL);
234230
if (!hd)
235231
goto fail2;
236232

233+
hdc = lcd->drvdata;
237234
hdc->hd44780 = hd;
238-
lcd->drvdata = hdc;
235+
239236
for (i = 0; i < ifwidth; i++) {
240237
hd->pins[base + i] = devm_gpiod_get_index(dev, "data", i,
241238
GPIOD_OUT_LOW);
@@ -313,9 +310,7 @@ static int hd44780_probe(struct platform_device *pdev)
313310
fail3:
314311
kfree(hd);
315312
fail2:
316-
charlcd_free(lcd);
317-
fail1:
318-
kfree(hdc);
313+
hd44780_common_free(lcd);
319314
return ret;
320315
}
321316

@@ -326,9 +321,7 @@ static void hd44780_remove(struct platform_device *pdev)
326321

327322
charlcd_unregister(lcd);
328323
kfree(hdc->hd44780);
329-
kfree(lcd->drvdata);
330-
331-
charlcd_free(lcd);
324+
hd44780_common_free(lcd);
332325
}
333326

334327
static const struct of_device_id hd44780_of_match[] = {

drivers/auxdisplay/hd44780_common.c

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -351,20 +351,28 @@ int hd44780_common_redefine_char(struct charlcd *lcd, char *esc)
351351
}
352352
EXPORT_SYMBOL_GPL(hd44780_common_redefine_char);
353353

354-
struct hd44780_common *hd44780_common_alloc(void)
354+
struct charlcd *hd44780_common_alloc(void)
355355
{
356-
struct hd44780_common *hd;
356+
struct hd44780_common *hdc;
357+
struct charlcd *lcd;
357358

358-
hd = kzalloc(sizeof(*hd), GFP_KERNEL);
359-
if (!hd)
359+
lcd = charlcd_alloc(sizeof(*hdc));
360+
if (!lcd)
360361
return NULL;
361362

362-
hd->ifwidth = 8;
363-
hd->bwidth = DEFAULT_LCD_BWIDTH;
364-
hd->hwidth = DEFAULT_LCD_HWIDTH;
365-
return hd;
363+
hdc = lcd->drvdata;
364+
hdc->ifwidth = 8;
365+
hdc->bwidth = DEFAULT_LCD_BWIDTH;
366+
hdc->hwidth = DEFAULT_LCD_HWIDTH;
367+
return lcd;
366368
}
367369
EXPORT_SYMBOL_GPL(hd44780_common_alloc);
368370

371+
void hd44780_common_free(struct charlcd *lcd)
372+
{
373+
charlcd_free(lcd);
374+
}
375+
EXPORT_SYMBOL_GPL(hd44780_common_free);
376+
369377
MODULE_DESCRIPTION("Common functions for HD44780 (and compatibles) LCD displays");
370378
MODULE_LICENSE("GPL");

drivers/auxdisplay/hd44780_common.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,6 @@ int hd44780_common_blink(struct charlcd *lcd, enum charlcd_onoff on);
3030
int hd44780_common_fontsize(struct charlcd *lcd, enum charlcd_fontsize size);
3131
int hd44780_common_lines(struct charlcd *lcd, enum charlcd_lines lines);
3232
int hd44780_common_redefine_char(struct charlcd *lcd, char *esc);
33-
struct hd44780_common *hd44780_common_alloc(void);
33+
34+
struct charlcd *hd44780_common_alloc(void);
35+
void hd44780_common_free(struct charlcd *lcd);

drivers/auxdisplay/lcd2s.c

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -298,20 +298,18 @@ static int lcd2s_i2c_probe(struct i2c_client *i2c)
298298
I2C_FUNC_SMBUS_WRITE_BLOCK_DATA))
299299
return -EIO;
300300

301-
lcd2s = devm_kzalloc(&i2c->dev, sizeof(*lcd2s), GFP_KERNEL);
302-
if (!lcd2s)
303-
return -ENOMEM;
304-
305301
/* Test, if the display is responding */
306302
err = lcd2s_i2c_smbus_write_byte(i2c, LCD2S_CMD_DISPLAY_OFF);
307303
if (err < 0)
308304
return err;
309305

310-
lcd = charlcd_alloc();
306+
lcd = charlcd_alloc(sizeof(*lcd2s));
311307
if (!lcd)
312308
return -ENOMEM;
313309

314-
lcd->drvdata = lcd2s;
310+
lcd->ops = &lcd2s_ops;
311+
312+
lcd2s = lcd->drvdata;
315313
lcd2s->i2c = i2c;
316314
lcd2s->charlcd = lcd;
317315

@@ -326,8 +324,6 @@ static int lcd2s_i2c_probe(struct i2c_client *i2c)
326324
if (err)
327325
goto fail1;
328326

329-
lcd->ops = &lcd2s_ops;
330-
331327
err = charlcd_register(lcd2s->charlcd);
332328
if (err)
333329
goto fail1;

drivers/auxdisplay/panel.c

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -831,18 +831,12 @@ static void lcd_init(void)
831831
struct charlcd *charlcd;
832832
struct hd44780_common *hdc;
833833

834-
hdc = hd44780_common_alloc();
835-
if (!hdc)
834+
charlcd = hd44780_common_alloc();
835+
if (!charlcd)
836836
return;
837837

838-
charlcd = charlcd_alloc();
839-
if (!charlcd) {
840-
kfree(hdc);
841-
return;
842-
}
843-
838+
hdc = charlcd->drvdata;
844839
hdc->hd44780 = &lcd;
845-
charlcd->drvdata = hdc;
846840

847841
/*
848842
* Init lcd struct with load-time values to preserve exact
@@ -1664,7 +1658,7 @@ static void panel_attach(struct parport *port)
16641658
if (lcd.enabled)
16651659
charlcd_unregister(lcd.charlcd);
16661660
err_unreg_device:
1667-
charlcd_free(lcd.charlcd);
1661+
hd44780_common_free(lcd.charlcd);
16681662
lcd.charlcd = NULL;
16691663
parport_unregister_device(pprt);
16701664
pprt = NULL;
@@ -1691,8 +1685,7 @@ static void panel_detach(struct parport *port)
16911685
if (lcd.enabled) {
16921686
charlcd_unregister(lcd.charlcd);
16931687
lcd.initialized = false;
1694-
kfree(lcd.charlcd->drvdata);
1695-
charlcd_free(lcd.charlcd);
1688+
hd44780_common_free(lcd.charlcd);
16961689
lcd.charlcd = NULL;
16971690
}
16981691

0 commit comments

Comments
 (0)