Skip to content

Commit 718e05e

Browse files
poeschelojeda
authored andcommitted
auxdisplay: Introduce hd44780_common.[ch]
There is some hd44780 specific code in charlcd and this code is used by multiple drivers. To make charlcd independent from this device specific code this has to be moved to a place where the multiple drivers can share their common code. This common place is now introduced as hd44780_common. Reviewed-by: Willy Tarreau <[email protected]> Signed-off-by: Lars Poeschel <[email protected]> Signed-off-by: Miguel Ojeda <[email protected]>
1 parent 66ce7d5 commit 718e05e

File tree

6 files changed

+91
-17
lines changed

6 files changed

+91
-17
lines changed

drivers/auxdisplay/Kconfig

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,29 @@ menuconfig AUXDISPLAY
1616

1717
if AUXDISPLAY
1818

19+
config CHARLCD
20+
tristate "Character LCD core support" if COMPILE_TEST
21+
help
22+
This is the base system for character-based LCD displays.
23+
It makes no sense to have this alone, you select your display driver
24+
and if it needs the charlcd core, it will select it automatically.
25+
This is some character LCD core interface that multiple drivers can
26+
use.
27+
28+
config HD44780_COMMON
29+
tristate "Common functions for HD44780 (and compatibles) LCD displays" if COMPILE_TEST
30+
help
31+
This is a module with the common symbols for HD44780 (and compatibles)
32+
displays. This is the code that multiple other modules use. It is not
33+
useful alone. If you have some sort of HD44780 compatible display,
34+
you very likely use this. It is selected automatically by selecting
35+
your concrete display.
36+
1937
config HD44780
2038
tristate "HD44780 Character LCD support"
2139
depends on GPIOLIB || COMPILE_TEST
2240
select CHARLCD
41+
select HD44780_COMMON
2342
help
2443
Enable support for Character LCDs using a HD44780 controller.
2544
The LCD is accessible through the /dev/lcd char device (10, 156).
@@ -168,6 +187,7 @@ menuconfig PARPORT_PANEL
168187
tristate "Parallel port LCD/Keypad Panel support"
169188
depends on PARPORT
170189
select CHARLCD
190+
select HD44780_COMMON
171191
help
172192
Say Y here if you have an HD44780 or KS-0074 LCD connected to your
173193
parallel port. This driver also features 4 and 6-key keypads. The LCD

drivers/auxdisplay/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#
55

66
obj-$(CONFIG_CHARLCD) += charlcd.o
7+
obj-$(CONFIG_HD44780_COMMON) += hd44780_common.o
78
obj-$(CONFIG_ARM_CHARLCD) += arm-charlcd.o
89
obj-$(CONFIG_KS0108) += ks0108.o
910
obj-$(CONFIG_CFAG12864B) += cfag12864b.o cfag12864bfb.o

drivers/auxdisplay/hd44780.c

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <linux/slab.h>
1616

1717
#include "charlcd.h"
18+
#include "hd44780_common.h"
1819

1920
enum hd44780_pin {
2021
/* Order does matter due to writing to GPIO array subsets! */
@@ -179,8 +180,9 @@ static int hd44780_probe(struct platform_device *pdev)
179180
struct device *dev = &pdev->dev;
180181
unsigned int i, base;
181182
struct charlcd *lcd;
183+
struct hd44780_common *hdc;
182184
struct hd44780 *hd;
183-
int ifwidth, ret;
185+
int ifwidth, ret = -ENOMEM;
184186

185187
/* Required pins */
186188
ifwidth = gpiod_count(dev, "data");
@@ -198,56 +200,64 @@ static int hd44780_probe(struct platform_device *pdev)
198200
return -EINVAL;
199201
}
200202

203+
hdc = hd44780_common_alloc();
204+
if (!hdc)
205+
return -ENOMEM;
206+
201207
lcd = charlcd_alloc(sizeof(struct hd44780));
202208
if (!lcd)
203-
return -ENOMEM;
209+
goto fail1;
204210

205-
hd = lcd->drvdata;
211+
hd = kzalloc(sizeof(struct hd44780), GFP_KERNEL);
212+
if (!hd)
213+
goto fail2;
206214

215+
hdc->hd44780 = hd;
216+
lcd->drvdata = hdc;
207217
for (i = 0; i < ifwidth; i++) {
208218
hd->pins[base + i] = devm_gpiod_get_index(dev, "data", i,
209219
GPIOD_OUT_LOW);
210220
if (IS_ERR(hd->pins[base + i])) {
211221
ret = PTR_ERR(hd->pins[base + i]);
212-
goto fail;
222+
goto fail3;
213223
}
214224
}
215225

216226
hd->pins[PIN_CTRL_E] = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW);
217227
if (IS_ERR(hd->pins[PIN_CTRL_E])) {
218228
ret = PTR_ERR(hd->pins[PIN_CTRL_E]);
219-
goto fail;
229+
goto fail3;
220230
}
221231

222232
hd->pins[PIN_CTRL_RS] = devm_gpiod_get(dev, "rs", GPIOD_OUT_HIGH);
223233
if (IS_ERR(hd->pins[PIN_CTRL_RS])) {
224234
ret = PTR_ERR(hd->pins[PIN_CTRL_RS]);
225-
goto fail;
235+
goto fail3;
226236
}
227237

228238
/* Optional pins */
229239
hd->pins[PIN_CTRL_RW] = devm_gpiod_get_optional(dev, "rw",
230240
GPIOD_OUT_LOW);
231241
if (IS_ERR(hd->pins[PIN_CTRL_RW])) {
232242
ret = PTR_ERR(hd->pins[PIN_CTRL_RW]);
233-
goto fail;
243+
goto fail3;
234244
}
235245

236246
hd->pins[PIN_CTRL_BL] = devm_gpiod_get_optional(dev, "backlight",
237247
GPIOD_OUT_LOW);
238248
if (IS_ERR(hd->pins[PIN_CTRL_BL])) {
239249
ret = PTR_ERR(hd->pins[PIN_CTRL_BL]);
240-
goto fail;
250+
goto fail3;
241251
}
242252

243253
/* Required properties */
244254
ret = device_property_read_u32(dev, "display-height-chars",
245255
&lcd->height);
246256
if (ret)
247-
goto fail;
257+
goto fail3;
248258
ret = device_property_read_u32(dev, "display-width-chars", &lcd->width);
249259
if (ret)
250-
goto fail;
260+
goto fail3;
251261

252262
/*
253263
* On displays with more than two rows, the internal buffer width is
@@ -264,23 +274,28 @@ static int hd44780_probe(struct platform_device *pdev)
264274

265275
ret = charlcd_register(lcd);
266276
if (ret)
267-
goto fail;
277+
goto fail3;
268278

269279
platform_set_drvdata(pdev, lcd);
270280
return 0;
271281

272-
fail:
273-
charlcd_free(lcd);
282+
fail3:
283+
kfree(hd);
284+
fail2:
285+
kfree(lcd);
286+
fail1:
287+
kfree(hdc);
274288
return ret;
275289
}
276290

277291
static int hd44780_remove(struct platform_device *pdev)
278292
{
279293
struct charlcd *lcd = platform_get_drvdata(pdev);
280294

295+
kfree(lcd->drvdata);
281296
charlcd_unregister(lcd);
282297

283-
charlcd_free(lcd);
298+
kfree(lcd);
284299
return 0;
285300
}
286301

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// SPDX-License-Identifier: GPL-2.0-or-later
2+
#include <linux/module.h>
3+
#include <linux/slab.h>
4+
5+
#include "hd44780_common.h"
6+
7+
struct hd44780_common *hd44780_common_alloc(void)
8+
{
9+
struct hd44780_common *hd;
10+
11+
hd = kzalloc(sizeof(*hd), GFP_KERNEL);
12+
if (!hd)
13+
return NULL;
14+
15+
return hd;
16+
}
17+
EXPORT_SYMBOL_GPL(hd44780_common_alloc);
18+
19+
MODULE_LICENSE("GPL");
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/* SPDX-License-Identifier: GPL-2.0-or-later */
2+
3+
struct hd44780_common {
4+
void *hd44780;
5+
};
6+
7+
struct hd44780_common *hd44780_common_alloc(void);

drivers/auxdisplay/panel.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
#include <linux/uaccess.h>
5757

5858
#include "charlcd.h"
59+
#include "hd44780_common.h"
5960

6061
#define LCD_MAXBYTES 256 /* max burst write */
6162

@@ -895,10 +896,20 @@ static const struct charlcd_ops charlcd_tilcd_ops = {
895896
static void lcd_init(void)
896897
{
897898
struct charlcd *charlcd;
899+
struct hd44780_common *hdc;
900+
901+
hdc = hd44780_common_alloc();
902+
if (!hdc)
903+
return;
898904

899905
charlcd = charlcd_alloc(0);
900-
if (!charlcd)
906+
if (!charlcd) {
907+
kfree(hdc);
901908
return;
909+
}
910+
911+
hdc->hd44780 = &lcd;
912+
charlcd->drvdata = hdc;
902913

903914
/*
904915
* Init lcd struct with load-time values to preserve exact
@@ -1620,7 +1631,7 @@ static void panel_attach(struct parport *port)
16201631
if (lcd.enabled)
16211632
charlcd_unregister(lcd.charlcd);
16221633
err_unreg_device:
1623-
charlcd_free(lcd.charlcd);
1634+
kfree(lcd.charlcd);
16241635
lcd.charlcd = NULL;
16251636
parport_unregister_device(pprt);
16261637
pprt = NULL;
@@ -1647,7 +1658,8 @@ static void panel_detach(struct parport *port)
16471658
if (lcd.enabled) {
16481659
charlcd_unregister(lcd.charlcd);
16491660
lcd.initialized = false;
1650-
charlcd_free(lcd.charlcd);
1661+
kfree(lcd.charlcd->drvdata);
1662+
kfree(lcd.charlcd);
16511663
lcd.charlcd = NULL;
16521664
}
16531665

0 commit comments

Comments
 (0)