Skip to content

Commit 60e5e48

Browse files
sravnborgbzolnier
authored andcommitted
atmel_lcdfb: support native-mode display-timings
When a device tree set a display-timing using native-mode then according to the bindings doc this should: native-mode: The native mode for the display, in case multiple modes are provided. When omitted, assume the first node is the native. The atmel_lcdfb used the last timing subnode and did not respect the timing mode specified with native-mode. Introduce use of of_get_videomode() which allowed a nice simplification of the code while also added support for native-mode. As a nice side-effect this fixes a memory leak where the data used for timings and the display_np was not freed. Signed-off-by: Sam Ravnborg <sam@ravnborg.org> Cc: Nicolas Ferre <nicolas.ferre@microchip.com> Cc: Alexandre Belloni <alexandre.belloni@bootlin.com> Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
1 parent 811ab8d commit 60e5e48

File tree

1 file changed

+9
-34
lines changed

1 file changed

+9
-34
lines changed

drivers/video/fbdev/atmel_lcdfb.c

Lines changed: 9 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <linux/module.h>
2323
#include <linux/of.h>
2424
#include <linux/of_device.h>
25+
#include <video/of_videomode.h>
2526
#include <video/of_display_timing.h>
2627
#include <linux/regulator/consumer.h>
2728
#include <video/videomode.h>
@@ -1028,11 +1029,11 @@ static int atmel_lcdfb_of_init(struct atmel_lcdfb_info *sinfo)
10281029
struct device *dev = &sinfo->pdev->dev;
10291030
struct device_node *np =dev->of_node;
10301031
struct device_node *display_np;
1031-
struct device_node *timings_np;
1032-
struct display_timings *timings;
10331032
struct atmel_lcdfb_power_ctrl_gpio *og;
10341033
bool is_gpio_power = false;
1034+
struct fb_videomode fb_vm;
10351035
struct gpio_desc *gpiod;
1036+
struct videomode vm;
10361037
int ret = -ENOENT;
10371038
int i;
10381039

@@ -1105,44 +1106,18 @@ static int atmel_lcdfb_of_init(struct atmel_lcdfb_info *sinfo)
11051106
pdata->lcdcon_is_backlight = of_property_read_bool(display_np, "atmel,lcdcon-backlight");
11061107
pdata->lcdcon_pol_negative = of_property_read_bool(display_np, "atmel,lcdcon-backlight-inverted");
11071108

1108-
timings = of_get_display_timings(display_np);
1109-
if (!timings) {
1110-
dev_err(dev, "failed to get display timings\n");
1111-
ret = -EINVAL;
1109+
ret = of_get_videomode(display_np, &vm, OF_USE_NATIVE_MODE);
1110+
if (ret) {
1111+
dev_err(dev, "failed to get videomode from DT\n");
11121112
goto put_display_node;
11131113
}
11141114

1115-
timings_np = of_get_child_by_name(display_np, "display-timings");
1116-
if (!timings_np) {
1117-
dev_err(dev, "failed to find display-timings node\n");
1118-
ret = -ENODEV;
1115+
ret = fb_videomode_from_videomode(&vm, &fb_vm);
1116+
if (ret < 0)
11191117
goto put_display_node;
1120-
}
11211118

1122-
for (i = 0; i < of_get_child_count(timings_np); i++) {
1123-
struct videomode vm;
1124-
struct fb_videomode fb_vm;
1125-
1126-
ret = videomode_from_timings(timings, &vm, i);
1127-
if (ret < 0)
1128-
goto put_timings_node;
1129-
ret = fb_videomode_from_videomode(&vm, &fb_vm);
1130-
if (ret < 0)
1131-
goto put_timings_node;
1132-
1133-
fb_add_videomode(&fb_vm, &info->modelist);
1134-
}
1135-
1136-
/*
1137-
* FIXME: Make sure we are not referencing any fields in display_np
1138-
* and timings_np and drop our references to them before returning to
1139-
* avoid leaking the nodes on probe deferral and driver unbind.
1140-
*/
1141-
1142-
return 0;
1119+
fb_add_videomode(&fb_vm, &info->modelist);
11431120

1144-
put_timings_node:
1145-
of_node_put(timings_np);
11461121
put_display_node:
11471122
of_node_put(display_np);
11481123
return ret;

0 commit comments

Comments
 (0)