drm/omap: dss: Cleanup DSS ports on initialisation failure
When the DSS initialises its output DPI and SDI ports, failures don't clean up previous successfully initialised ports. This can lead to resource leak or memory corruption. Fix it. Reported-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ti.com> Acked-by: Sam Ravnborg <sam@ravnborg.org> Tested-by: Sebastian Reichel <sebastian.reichel@collabora.com> Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> Link: https://patchwork.freedesktop.org/patch/msgid/20200226112514.12455-22-laurent.pinchart@ideasonboard.com
This commit is contained in:
parent
5e20bdf3d3
commit
2a0a3ae17d
@ -1151,6 +1151,31 @@ static const struct dss_features dra7xx_dss_feats = {
|
||||
.has_lcd_clk_src = true,
|
||||
};
|
||||
|
||||
static void __dss_uninit_ports(struct dss_device *dss, unsigned int num_ports)
|
||||
{
|
||||
struct platform_device *pdev = dss->pdev;
|
||||
struct device_node *parent = pdev->dev.of_node;
|
||||
struct device_node *port;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < num_ports; i++) {
|
||||
port = of_graph_get_port_by_id(parent, i);
|
||||
if (!port)
|
||||
continue;
|
||||
|
||||
switch (dss->feat->ports[i]) {
|
||||
case OMAP_DISPLAY_TYPE_DPI:
|
||||
dpi_uninit_port(port);
|
||||
break;
|
||||
case OMAP_DISPLAY_TYPE_SDI:
|
||||
sdi_uninit_port(port);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int dss_init_ports(struct dss_device *dss)
|
||||
{
|
||||
struct platform_device *pdev = dss->pdev;
|
||||
@ -1168,13 +1193,13 @@ static int dss_init_ports(struct dss_device *dss)
|
||||
case OMAP_DISPLAY_TYPE_DPI:
|
||||
r = dpi_init_port(dss, pdev, port, dss->feat->model);
|
||||
if (r)
|
||||
return r;
|
||||
goto error;
|
||||
break;
|
||||
|
||||
case OMAP_DISPLAY_TYPE_SDI:
|
||||
r = sdi_init_port(dss, pdev, port);
|
||||
if (r)
|
||||
return r;
|
||||
goto error;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -1183,31 +1208,15 @@ static int dss_init_ports(struct dss_device *dss)
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
__dss_uninit_ports(dss, i);
|
||||
return r;
|
||||
}
|
||||
|
||||
static void dss_uninit_ports(struct dss_device *dss)
|
||||
{
|
||||
struct platform_device *pdev = dss->pdev;
|
||||
struct device_node *parent = pdev->dev.of_node;
|
||||
struct device_node *port;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < dss->feat->num_ports; i++) {
|
||||
port = of_graph_get_port_by_id(parent, i);
|
||||
if (!port)
|
||||
continue;
|
||||
|
||||
switch (dss->feat->ports[i]) {
|
||||
case OMAP_DISPLAY_TYPE_DPI:
|
||||
dpi_uninit_port(port);
|
||||
break;
|
||||
case OMAP_DISPLAY_TYPE_SDI:
|
||||
sdi_uninit_port(port);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
__dss_uninit_ports(dss, dss->feat->num_ports);
|
||||
}
|
||||
|
||||
static int dss_video_pll_probe(struct dss_device *dss)
|
||||
|
Loading…
x
Reference in New Issue
Block a user