mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 20:07:46 +09:00
drm/omap: dss: Cleanup DSS ports on initialisation failure
[ Upstream commit 2a0a3ae17d ]
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
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
b4bca7b2a6
commit
0d5984ba93
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user