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>
This commit is contained in:
Andy Shevchenko
2025-03-04 16:32:07 +02:00
7 changed files with 40 additions and 46 deletions
+3 -2
View File
@@ -595,18 +595,19 @@ static int charlcd_init(struct charlcd *lcd)
return 0;
}
struct charlcd *charlcd_alloc(void)
struct charlcd *charlcd_alloc(unsigned int drvdata_size)
{
struct charlcd_priv *priv;
struct charlcd *lcd;
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
priv = kzalloc(sizeof(*priv) + drvdata_size, GFP_KERNEL);
if (!priv)
return NULL;
priv->esc_seq.len = -1;
lcd = &priv->lcd;
lcd->drvdata = priv->drvdata;
return lcd;
}
+3 -2
View File
@@ -51,7 +51,7 @@ struct charlcd {
unsigned long y;
} addr;
void *drvdata;
void *drvdata; /* Set by charlcd_alloc() */
};
/**
@@ -95,7 +95,8 @@ struct charlcd_ops {
};
void charlcd_backlight(struct charlcd *lcd, enum charlcd_onoff on);
struct charlcd *charlcd_alloc(void);
struct charlcd *charlcd_alloc(unsigned int drvdata_size);
void charlcd_free(struct charlcd *lcd);
int charlcd_register(struct charlcd *lcd);
+6 -13
View File
@@ -222,20 +222,17 @@ static int hd44780_probe(struct platform_device *pdev)
return -EINVAL;
}
hdc = hd44780_common_alloc();
if (!hdc)
return -ENOMEM;
lcd = charlcd_alloc();
lcd = hd44780_common_alloc();
if (!lcd)
goto fail1;
return -ENOMEM;
hd = kzalloc(sizeof(*hd), GFP_KERNEL);
if (!hd)
goto fail2;
hdc = lcd->drvdata;
hdc->hd44780 = hd;
lcd->drvdata = hdc;
for (i = 0; i < ifwidth; i++) {
hd->pins[base + i] = devm_gpiod_get_index(dev, "data", i,
GPIOD_OUT_LOW);
@@ -313,9 +310,7 @@ static int hd44780_probe(struct platform_device *pdev)
fail3:
kfree(hd);
fail2:
charlcd_free(lcd);
fail1:
kfree(hdc);
hd44780_common_free(lcd);
return ret;
}
@@ -326,9 +321,7 @@ static void hd44780_remove(struct platform_device *pdev)
charlcd_unregister(lcd);
kfree(hdc->hd44780);
kfree(lcd->drvdata);
charlcd_free(lcd);
hd44780_common_free(lcd);
}
static const struct of_device_id hd44780_of_match[] = {
+16 -8
View File
@@ -351,20 +351,28 @@ int hd44780_common_redefine_char(struct charlcd *lcd, char *esc)
}
EXPORT_SYMBOL_GPL(hd44780_common_redefine_char);
struct hd44780_common *hd44780_common_alloc(void)
struct charlcd *hd44780_common_alloc(void)
{
struct hd44780_common *hd;
struct hd44780_common *hdc;
struct charlcd *lcd;
hd = kzalloc(sizeof(*hd), GFP_KERNEL);
if (!hd)
lcd = charlcd_alloc(sizeof(*hdc));
if (!lcd)
return NULL;
hd->ifwidth = 8;
hd->bwidth = DEFAULT_LCD_BWIDTH;
hd->hwidth = DEFAULT_LCD_HWIDTH;
return hd;
hdc = lcd->drvdata;
hdc->ifwidth = 8;
hdc->bwidth = DEFAULT_LCD_BWIDTH;
hdc->hwidth = DEFAULT_LCD_HWIDTH;
return lcd;
}
EXPORT_SYMBOL_GPL(hd44780_common_alloc);
void hd44780_common_free(struct charlcd *lcd)
{
charlcd_free(lcd);
}
EXPORT_SYMBOL_GPL(hd44780_common_free);
MODULE_DESCRIPTION("Common functions for HD44780 (and compatibles) LCD displays");
MODULE_LICENSE("GPL");
+3 -1
View File
@@ -30,4 +30,6 @@ int hd44780_common_blink(struct charlcd *lcd, enum charlcd_onoff on);
int hd44780_common_fontsize(struct charlcd *lcd, enum charlcd_fontsize size);
int hd44780_common_lines(struct charlcd *lcd, enum charlcd_lines lines);
int hd44780_common_redefine_char(struct charlcd *lcd, char *esc);
struct hd44780_common *hd44780_common_alloc(void);
struct charlcd *hd44780_common_alloc(void);
void hd44780_common_free(struct charlcd *lcd);
+4 -8
View File
@@ -298,20 +298,18 @@ static int lcd2s_i2c_probe(struct i2c_client *i2c)
I2C_FUNC_SMBUS_WRITE_BLOCK_DATA))
return -EIO;
lcd2s = devm_kzalloc(&i2c->dev, sizeof(*lcd2s), GFP_KERNEL);
if (!lcd2s)
return -ENOMEM;
/* Test, if the display is responding */
err = lcd2s_i2c_smbus_write_byte(i2c, LCD2S_CMD_DISPLAY_OFF);
if (err < 0)
return err;
lcd = charlcd_alloc();
lcd = charlcd_alloc(sizeof(*lcd2s));
if (!lcd)
return -ENOMEM;
lcd->drvdata = lcd2s;
lcd->ops = &lcd2s_ops;
lcd2s = lcd->drvdata;
lcd2s->i2c = i2c;
lcd2s->charlcd = lcd;
@@ -326,8 +324,6 @@ static int lcd2s_i2c_probe(struct i2c_client *i2c)
if (err)
goto fail1;
lcd->ops = &lcd2s_ops;
err = charlcd_register(lcd2s->charlcd);
if (err)
goto fail1;
+5 -12
View File
@@ -831,18 +831,12 @@ static void lcd_init(void)
struct charlcd *charlcd;
struct hd44780_common *hdc;
hdc = hd44780_common_alloc();
if (!hdc)
charlcd = hd44780_common_alloc();
if (!charlcd)
return;
charlcd = charlcd_alloc();
if (!charlcd) {
kfree(hdc);
return;
}
hdc = charlcd->drvdata;
hdc->hd44780 = &lcd;
charlcd->drvdata = hdc;
/*
* Init lcd struct with load-time values to preserve exact
@@ -1664,7 +1658,7 @@ err_lcd_unreg:
if (lcd.enabled)
charlcd_unregister(lcd.charlcd);
err_unreg_device:
charlcd_free(lcd.charlcd);
hd44780_common_free(lcd.charlcd);
lcd.charlcd = NULL;
parport_unregister_device(pprt);
pprt = NULL;
@@ -1691,8 +1685,7 @@ static void panel_detach(struct parport *port)
if (lcd.enabled) {
charlcd_unregister(lcd.charlcd);
lcd.initialized = false;
kfree(lcd.charlcd->drvdata);
charlcd_free(lcd.charlcd);
hd44780_common_free(lcd.charlcd);
lcd.charlcd = NULL;
}