diff options
author | Andy Shevchenko <andriy.shevchenko@linux.intel.com> | 2025-03-04 17:32:07 +0300 |
---|---|---|
committer | Andy Shevchenko <andriy.shevchenko@linux.intel.com> | 2025-03-10 19:03:02 +0300 |
commit | 67200d70e45982f5120c43b3724f1b6e4a8a01e4 (patch) | |
tree | 4e9b0d3fc4f28769e6b399364170da7e2440d323 | |
parent | 72e1c440c848624ad4cfac93d69d8a999a20355b (diff) | |
parent | 2c4849a41326b37a33b91595cba81f1f0f6a62f7 (diff) | |
download | linux-67200d70e45982f5120c43b3724f1b6e4a8a01e4.tar.xz |
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>
-rw-r--r-- | drivers/auxdisplay/charlcd.c | 5 | ||||
-rw-r--r-- | drivers/auxdisplay/charlcd.h | 5 | ||||
-rw-r--r-- | drivers/auxdisplay/hd44780.c | 19 | ||||
-rw-r--r-- | drivers/auxdisplay/hd44780_common.c | 24 | ||||
-rw-r--r-- | drivers/auxdisplay/hd44780_common.h | 4 | ||||
-rw-r--r-- | drivers/auxdisplay/lcd2s.c | 12 | ||||
-rw-r--r-- | drivers/auxdisplay/panel.c | 17 |
7 files changed, 40 insertions, 46 deletions
diff --git a/drivers/auxdisplay/charlcd.c b/drivers/auxdisplay/charlcd.c index 19b619376d48..09020bb8ad15 100644 --- a/drivers/auxdisplay/charlcd.c +++ b/drivers/auxdisplay/charlcd.c @@ -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; } diff --git a/drivers/auxdisplay/charlcd.h b/drivers/auxdisplay/charlcd.h index 4d4287209d04..d10b89740bca 100644 --- a/drivers/auxdisplay/charlcd.h +++ b/drivers/auxdisplay/charlcd.h @@ -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); diff --git a/drivers/auxdisplay/hd44780.c b/drivers/auxdisplay/hd44780.c index 9d0ae9c02e9b..cef42656c4b0 100644 --- a/drivers/auxdisplay/hd44780.c +++ b/drivers/auxdisplay/hd44780.c @@ -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[] = { diff --git a/drivers/auxdisplay/hd44780_common.c b/drivers/auxdisplay/hd44780_common.c index 4ef87c3118c0..1792fe2a4460 100644 --- a/drivers/auxdisplay/hd44780_common.c +++ b/drivers/auxdisplay/hd44780_common.c @@ -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"); diff --git a/drivers/auxdisplay/hd44780_common.h b/drivers/auxdisplay/hd44780_common.h index a16aa8c29c99..4c87f55722b6 100644 --- a/drivers/auxdisplay/hd44780_common.h +++ b/drivers/auxdisplay/hd44780_common.h @@ -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); diff --git a/drivers/auxdisplay/lcd2s.c b/drivers/auxdisplay/lcd2s.c index a28daa4ffbf7..045dbef49dee 100644 --- a/drivers/auxdisplay/lcd2s.c +++ b/drivers/auxdisplay/lcd2s.c @@ -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; diff --git a/drivers/auxdisplay/panel.c b/drivers/auxdisplay/panel.c index 6dc8798d01f9..91ccb9789d43 100644 --- a/drivers/auxdisplay/panel.c +++ b/drivers/auxdisplay/panel.c @@ -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; } |