Skip to content

Commit

Permalink
Merge patch series "auxdisplay: charlcd: Refactor memory allocation"
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Andy Shevchenko committed Mar 10, 2025
2 parents 72e1c44 + 2c4849a commit 67200d7
Show file tree
Hide file tree
Showing 7 changed files with 40 additions and 46 deletions.
5 changes: 3 additions & 2 deletions drivers/auxdisplay/charlcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
5 changes: 3 additions & 2 deletions drivers/auxdisplay/charlcd.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ struct charlcd {
unsigned long y;
} addr;

void *drvdata;
void *drvdata; /* Set by charlcd_alloc() */
};

/**
Expand Down Expand Up @@ -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);
Expand Down
19 changes: 6 additions & 13 deletions drivers/auxdisplay/hd44780.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}

Expand All @@ -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[] = {
Expand Down
24 changes: 16 additions & 8 deletions drivers/auxdisplay/hd44780_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");
4 changes: 3 additions & 1 deletion drivers/auxdisplay/hd44780_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
12 changes: 4 additions & 8 deletions drivers/auxdisplay/lcd2s.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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;
Expand Down
17 changes: 5 additions & 12 deletions drivers/auxdisplay/panel.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -1664,7 +1658,7 @@ static void panel_attach(struct parport *port)
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;
Expand All @@ -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;
}

Expand Down

0 comments on commit 67200d7

Please sign in to comment.