提交 2a0a3ae1 编写于 作者: L Laurent Pinchart 提交者: Tomi Valkeinen

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: NHans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: NLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: NTomi Valkeinen <tomi.valkeinen@ti.com>
Acked-by: NSam Ravnborg <sam@ravnborg.org>
Tested-by: NSebastian Reichel <sebastian.reichel@collabora.com>
Reviewed-by: NSebastian Reichel <sebastian.reichel@collabora.com>
Signed-off-by: NTomi Valkeinen <tomi.valkeinen@ti.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200226112514.12455-22-laurent.pinchart@ideasonboard.com
上级 5e20bdf3
...@@ -1151,46 +1151,38 @@ static const struct dss_features dra7xx_dss_feats = { ...@@ -1151,46 +1151,38 @@ static const struct dss_features dra7xx_dss_feats = {
.has_lcd_clk_src = true, .has_lcd_clk_src = true,
}; };
static int dss_init_ports(struct dss_device *dss) static void __dss_uninit_ports(struct dss_device *dss, unsigned int num_ports)
{ {
struct platform_device *pdev = dss->pdev; struct platform_device *pdev = dss->pdev;
struct device_node *parent = pdev->dev.of_node; struct device_node *parent = pdev->dev.of_node;
struct device_node *port; struct device_node *port;
unsigned int i; unsigned int i;
int r;
for (i = 0; i < dss->feat->num_ports; i++) { for (i = 0; i < num_ports; i++) {
port = of_graph_get_port_by_id(parent, i); port = of_graph_get_port_by_id(parent, i);
if (!port) if (!port)
continue; continue;
switch (dss->feat->ports[i]) { switch (dss->feat->ports[i]) {
case OMAP_DISPLAY_TYPE_DPI: case OMAP_DISPLAY_TYPE_DPI:
r = dpi_init_port(dss, pdev, port, dss->feat->model); dpi_uninit_port(port);
if (r)
return r;
break; break;
case OMAP_DISPLAY_TYPE_SDI: case OMAP_DISPLAY_TYPE_SDI:
r = sdi_init_port(dss, pdev, port); sdi_uninit_port(port);
if (r)
return r;
break; break;
default: default:
break; break;
} }
} }
return 0;
} }
static void dss_uninit_ports(struct dss_device *dss) static int dss_init_ports(struct dss_device *dss)
{ {
struct platform_device *pdev = dss->pdev; struct platform_device *pdev = dss->pdev;
struct device_node *parent = pdev->dev.of_node; struct device_node *parent = pdev->dev.of_node;
struct device_node *port; struct device_node *port;
int i; unsigned int i;
int r;
for (i = 0; i < dss->feat->num_ports; i++) { for (i = 0; i < dss->feat->num_ports; i++) {
port = of_graph_get_port_by_id(parent, i); port = of_graph_get_port_by_id(parent, i);
...@@ -1199,15 +1191,32 @@ static void dss_uninit_ports(struct dss_device *dss) ...@@ -1199,15 +1191,32 @@ static void dss_uninit_ports(struct dss_device *dss)
switch (dss->feat->ports[i]) { switch (dss->feat->ports[i]) {
case OMAP_DISPLAY_TYPE_DPI: case OMAP_DISPLAY_TYPE_DPI:
dpi_uninit_port(port); r = dpi_init_port(dss, pdev, port, dss->feat->model);
if (r)
goto error;
break; break;
case OMAP_DISPLAY_TYPE_SDI: case OMAP_DISPLAY_TYPE_SDI:
sdi_uninit_port(port); r = sdi_init_port(dss, pdev, port);
if (r)
goto error;
break; break;
default: default:
break; break;
} }
} }
return 0;
error:
__dss_uninit_ports(dss, i);
return r;
}
static void dss_uninit_ports(struct dss_device *dss)
{
__dss_uninit_ports(dss, dss->feat->num_ports);
} }
static int dss_video_pll_probe(struct dss_device *dss) static int dss_video_pll_probe(struct dss_device *dss)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册