I've tested a few dual-DSI panel drivers which choke if they PROBE_DEFER at the wrong time, so I patched those up in patch 1 and 2. Patch 3 fixes the other drivers that I couldn't test, but seem to have all the same problem.
Brian Norris (3): drm/panel: kingdisplay-kd097d04: Delete panel on attach() failure drm/panel: innolux-p079zca: Delete panel on attach() failure drm/panel: Delete panel on mipi_dsi_attach() failure
drivers/gpu/drm/panel/panel-feiyang-fy07024di26a30d.c | 8 +++++++- drivers/gpu/drm/panel/panel-innolux-p079zca.c | 10 +++++++++- drivers/gpu/drm/panel/panel-jdi-lt070me05000.c | 8 +++++++- drivers/gpu/drm/panel/panel-kingdisplay-kd097d04.c | 8 +++++++- drivers/gpu/drm/panel/panel-novatek-nt36672a.c | 8 +++++++- drivers/gpu/drm/panel/panel-panasonic-vvx10f034n00.c | 8 +++++++- drivers/gpu/drm/panel/panel-ronbo-rb070d30.c | 8 +++++++- .../gpu/drm/panel/panel-samsung-s6e88a0-ams452ef01.c | 1 + drivers/gpu/drm/panel/panel-samsung-sofef00.c | 1 + drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c | 8 +++++++- 10 files changed, 60 insertions(+), 8 deletions(-)
If we fail to attach (e.g., because 1 of 2 dual-DSI controllers aren't ready), we leave a dangling drm_panel reference to freed memory. Clean that up on failure.
Fixes: 2a994cbed6b2 ("drm/panel: Add Kingdisplay KD097D04 panel driver") Signed-off-by: Brian Norris briannorris@chromium.org ---
drivers/gpu/drm/panel/panel-kingdisplay-kd097d04.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/panel/panel-kingdisplay-kd097d04.c b/drivers/gpu/drm/panel/panel-kingdisplay-kd097d04.c index 86e4213e8bb1..daccb1fd5fda 100644 --- a/drivers/gpu/drm/panel/panel-kingdisplay-kd097d04.c +++ b/drivers/gpu/drm/panel/panel-kingdisplay-kd097d04.c @@ -406,7 +406,13 @@ static int kingdisplay_panel_probe(struct mipi_dsi_device *dsi) if (err < 0) return err;
- return mipi_dsi_attach(dsi); + err = mipi_dsi_attach(dsi); + if (err < 0) { + kingdisplay_panel_del(kingdisplay); + return err; + } + + return 0; }
static int kingdisplay_panel_remove(struct mipi_dsi_device *dsi)
If we fail to attach (e.g., because 1 of 2 dual-DSI controllers aren't ready), we leave a dangling drm_panel reference to freed memory. Clean that up on failure.
This problem exists since the driver's introduction, but is especially relevant after refactored for dual-DSI variants.
Fixes: 14c8f2e9f8ea ("drm/panel: add Innolux P079ZCA panel driver") Fixes: 7ad4e4636c54 ("drm/panel: p079zca: Refactor panel driver to support multiple panels") Signed-off-by: Brian Norris briannorris@chromium.org ---
drivers/gpu/drm/panel/panel-innolux-p079zca.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/panel/panel-innolux-p079zca.c b/drivers/gpu/drm/panel/panel-innolux-p079zca.c index aea316225391..f194b62e290c 100644 --- a/drivers/gpu/drm/panel/panel-innolux-p079zca.c +++ b/drivers/gpu/drm/panel/panel-innolux-p079zca.c @@ -484,6 +484,7 @@ static void innolux_panel_del(struct innolux_panel *innolux) static int innolux_panel_probe(struct mipi_dsi_device *dsi) { const struct panel_desc *desc; + struct innolux_panel *innolux; int err;
desc = of_device_get_match_data(&dsi->dev); @@ -495,7 +496,14 @@ static int innolux_panel_probe(struct mipi_dsi_device *dsi) if (err < 0) return err;
- return mipi_dsi_attach(dsi); + err = mipi_dsi_attach(dsi); + if (err < 0) { + innolux = mipi_dsi_get_drvdata(dsi); + innolux_panel_del(innolux); + return err; + } + + return 0; }
static int innolux_panel_remove(struct mipi_dsi_device *dsi)
Many DSI panel drivers fail to clean up their panel references on mipi_dsi_attach() failure, so we're leaving a dangling drm_panel reference to freed memory. Clean that up on failure.
Noticed by inspection, after seeing similar problems on other drivers. Therefore, I'm not marking Fixes/stable.
Signed-off-by: Brian Norris briannorris@chromium.org ---
drivers/gpu/drm/panel/panel-feiyang-fy07024di26a30d.c | 8 +++++++- drivers/gpu/drm/panel/panel-jdi-lt070me05000.c | 8 +++++++- drivers/gpu/drm/panel/panel-novatek-nt36672a.c | 8 +++++++- drivers/gpu/drm/panel/panel-panasonic-vvx10f034n00.c | 8 +++++++- drivers/gpu/drm/panel/panel-ronbo-rb070d30.c | 8 +++++++- drivers/gpu/drm/panel/panel-samsung-s6e88a0-ams452ef01.c | 1 + drivers/gpu/drm/panel/panel-samsung-sofef00.c | 1 + drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c | 8 +++++++- 8 files changed, 44 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/panel/panel-feiyang-fy07024di26a30d.c b/drivers/gpu/drm/panel/panel-feiyang-fy07024di26a30d.c index 581661b506f8..f9c1f7bc8218 100644 --- a/drivers/gpu/drm/panel/panel-feiyang-fy07024di26a30d.c +++ b/drivers/gpu/drm/panel/panel-feiyang-fy07024di26a30d.c @@ -227,7 +227,13 @@ static int feiyang_dsi_probe(struct mipi_dsi_device *dsi) dsi->format = MIPI_DSI_FMT_RGB888; dsi->lanes = 4;
- return mipi_dsi_attach(dsi); + ret = mipi_dsi_attach(dsi); + if (ret < 0) { + drm_panel_remove(&ctx->panel); + return ret; + } + + return 0; }
static int feiyang_dsi_remove(struct mipi_dsi_device *dsi) diff --git a/drivers/gpu/drm/panel/panel-jdi-lt070me05000.c b/drivers/gpu/drm/panel/panel-jdi-lt070me05000.c index 733010b5e4f5..3c86ad262d5e 100644 --- a/drivers/gpu/drm/panel/panel-jdi-lt070me05000.c +++ b/drivers/gpu/drm/panel/panel-jdi-lt070me05000.c @@ -473,7 +473,13 @@ static int jdi_panel_probe(struct mipi_dsi_device *dsi) if (ret < 0) return ret;
- return mipi_dsi_attach(dsi); + ret = mipi_dsi_attach(dsi); + if (ret < 0) { + jdi_panel_del(jdi); + return ret; + } + + return 0; }
static int jdi_panel_remove(struct mipi_dsi_device *dsi) diff --git a/drivers/gpu/drm/panel/panel-novatek-nt36672a.c b/drivers/gpu/drm/panel/panel-novatek-nt36672a.c index 533cd3934b8b..839b263fb3c0 100644 --- a/drivers/gpu/drm/panel/panel-novatek-nt36672a.c +++ b/drivers/gpu/drm/panel/panel-novatek-nt36672a.c @@ -656,7 +656,13 @@ static int nt36672a_panel_probe(struct mipi_dsi_device *dsi) if (err < 0) return err;
- return mipi_dsi_attach(dsi); + err = mipi_dsi_attach(dsi); + if (err < 0) { + drm_panel_remove(&pinfo->base); + return err; + } + + return 0; }
static int nt36672a_panel_remove(struct mipi_dsi_device *dsi) diff --git a/drivers/gpu/drm/panel/panel-panasonic-vvx10f034n00.c b/drivers/gpu/drm/panel/panel-panasonic-vvx10f034n00.c index 3c20beeb1781..3991f5d950af 100644 --- a/drivers/gpu/drm/panel/panel-panasonic-vvx10f034n00.c +++ b/drivers/gpu/drm/panel/panel-panasonic-vvx10f034n00.c @@ -241,7 +241,13 @@ static int wuxga_nt_panel_probe(struct mipi_dsi_device *dsi) if (ret < 0) return ret;
- return mipi_dsi_attach(dsi); + ret = mipi_dsi_attach(dsi); + if (ret < 0) { + wuxga_nt_panel_del(wuxga_nt); + return ret; + } + + return 0; }
static int wuxga_nt_panel_remove(struct mipi_dsi_device *dsi) diff --git a/drivers/gpu/drm/panel/panel-ronbo-rb070d30.c b/drivers/gpu/drm/panel/panel-ronbo-rb070d30.c index a3782830ae3c..1fb579a574d9 100644 --- a/drivers/gpu/drm/panel/panel-ronbo-rb070d30.c +++ b/drivers/gpu/drm/panel/panel-ronbo-rb070d30.c @@ -199,7 +199,13 @@ static int rb070d30_panel_dsi_probe(struct mipi_dsi_device *dsi) dsi->format = MIPI_DSI_FMT_RGB888; dsi->lanes = 4;
- return mipi_dsi_attach(dsi); + ret = mipi_dsi_attach(dsi); + if (ret < 0) { + drm_panel_remove(&ctx->panel); + return ret; + } + + return 0; }
static int rb070d30_panel_dsi_remove(struct mipi_dsi_device *dsi) diff --git a/drivers/gpu/drm/panel/panel-samsung-s6e88a0-ams452ef01.c b/drivers/gpu/drm/panel/panel-samsung-s6e88a0-ams452ef01.c index ea63799ff2a1..29fde3823212 100644 --- a/drivers/gpu/drm/panel/panel-samsung-s6e88a0-ams452ef01.c +++ b/drivers/gpu/drm/panel/panel-samsung-s6e88a0-ams452ef01.c @@ -247,6 +247,7 @@ static int s6e88a0_ams452ef01_probe(struct mipi_dsi_device *dsi) ret = mipi_dsi_attach(dsi); if (ret < 0) { dev_err(dev, "Failed to attach to DSI host: %d\n", ret); + drm_panel_remove(&ctx->panel); return ret; }
diff --git a/drivers/gpu/drm/panel/panel-samsung-sofef00.c b/drivers/gpu/drm/panel/panel-samsung-sofef00.c index 8cb1853574bb..6d107e14fcc5 100644 --- a/drivers/gpu/drm/panel/panel-samsung-sofef00.c +++ b/drivers/gpu/drm/panel/panel-samsung-sofef00.c @@ -302,6 +302,7 @@ static int sofef00_panel_probe(struct mipi_dsi_device *dsi) ret = mipi_dsi_attach(dsi); if (ret < 0) { dev_err(dev, "Failed to attach to DSI host: %d\n", ret); + drm_panel_remove(&ctx->panel); return ret; }
diff --git a/drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c b/drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c index b937e24dac8e..25829a0a8e80 100644 --- a/drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c +++ b/drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c @@ -296,7 +296,13 @@ static int sharp_nt_panel_probe(struct mipi_dsi_device *dsi) if (ret < 0) return ret;
- return mipi_dsi_attach(dsi); + ret = mipi_dsi_attach(dsi); + if (ret < 0) { + sharp_nt_panel_del(sharp_nt); + return ret; + } + + return 0; }
static int sharp_nt_panel_remove(struct mipi_dsi_device *dsi)
Hi Brian,
On Thu, Sep 23, 2021 at 05:33:52PM -0700, Brian Norris wrote:
I've tested a few dual-DSI panel drivers which choke if they PROBE_DEFER at the wrong time, so I patched those up in patch 1 and 2. Patch 3 fixes the other drivers that I couldn't test, but seem to have all the same problem.
Brian Norris (3): drm/panel: kingdisplay-kd097d04: Delete panel on attach() failure drm/panel: innolux-p079zca: Delete panel on attach() failure drm/panel: Delete panel on mipi_dsi_attach() failure
Thanks for fixing these up, and especially for the fix of the remaining panel drivers.
I have applied all three patches to drm-misc-next as I did not consider the fixes urgent.
They will show up in -next in 1-2 weeks.
Sam
dri-devel@lists.freedesktop.org