Skip to content

Commit 3fb1f62

Browse files
author
Thomas Zimmermann
committed
drm/fb-helper: Remove drm_fb_helper_unprepare() from drm_fb_helper_fini()
Move drm_fb_helper_unprepare() from drm_fb_helper_fini() into the calling fbdev implementation. Avoids a possible stale mutex with generic fbdev code. As indicated by its name, drm_fb_helper_prepare() prepares struct drm_fb_helper before setting up the fbdev support with a call to drm_fb_helper_init(). In legacy fbdev emulation, this happens next to each other. If successful, drm_fb_helper_fini() later tear down the fbdev device and also unprepare via drm_fb_helper_unprepare(). Generic fbdev emulation prepares struct drm_fb_helper immediately after allocating the instance. It only calls drm_fb_helper_init() as part of processing a hotplug event. If the hotplug-handling fails, it runs drm_fb_helper_fini(). This unprepares the fb-helper instance and the next hotplug event runs on stale data. Solve this by moving drm_fb_helper_unprepare() from drm_fb_helper_fini() into the fbdev implementations. Call it right before freeing the fb-helper instance. Fixes: 643231b ("drm/fbdev-generic: Minimize hotplug error handling") Cc: Thomas Zimmermann <[email protected]> Cc: Javier Martinez Canillas <[email protected]> Cc: Maarten Lankhorst <[email protected]> Cc: Maxime Ripard <[email protected]> Cc: David Airlie <[email protected]> Cc: Daniel Vetter <[email protected]> Cc: [email protected] Signed-off-by: Thomas Zimmermann <[email protected]> Reviewed-by: Daniel Vetter <[email protected]> Reviewed-by: Javier Martinez Canillas <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent fb073aa commit 3fb1f62

File tree

10 files changed

+17
-3
lines changed

10 files changed

+17
-3
lines changed

drivers/gpu/drm/armada/armada_fbdev.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ int armada_fbdev_init(struct drm_device *dev)
147147
err_fb_setup:
148148
drm_fb_helper_fini(fbh);
149149
err_fb_helper:
150+
drm_fb_helper_unprepare(fbh);
150151
priv->fbdev = NULL;
151152
return ret;
152153
}
@@ -164,6 +165,8 @@ void armada_fbdev_fini(struct drm_device *dev)
164165
if (fbh->fb)
165166
fbh->fb->funcs->destroy(fbh->fb);
166167

168+
drm_fb_helper_unprepare(fbh);
169+
167170
priv->fbdev = NULL;
168171
}
169172
}

drivers/gpu/drm/drm_fb_helper.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -590,8 +590,6 @@ void drm_fb_helper_fini(struct drm_fb_helper *fb_helper)
590590
}
591591
mutex_unlock(&kernel_fb_helper_lock);
592592

593-
drm_fb_helper_unprepare(fb_helper);
594-
595593
if (!fb_helper->client.funcs)
596594
drm_client_release(&fb_helper->client);
597595
}

drivers/gpu/drm/drm_fbdev_generic.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ static void drm_fbdev_fb_destroy(struct fb_info *info)
6565

6666
drm_client_framebuffer_delete(fb_helper->buffer);
6767
drm_client_release(&fb_helper->client);
68+
69+
drm_fb_helper_unprepare(fb_helper);
6870
kfree(fb_helper);
6971
}
7072

drivers/gpu/drm/exynos/exynos_drm_fbdev.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,8 +183,8 @@ int exynos_drm_fbdev_init(struct drm_device *dev)
183183

184184
err_setup:
185185
drm_fb_helper_fini(helper);
186-
187186
err_init:
187+
drm_fb_helper_unprepare(helper);
188188
private->fb_helper = NULL;
189189
kfree(fbdev);
190190

@@ -219,6 +219,7 @@ void exynos_drm_fbdev_fini(struct drm_device *dev)
219219
fbdev = to_exynos_fbdev(private->fb_helper);
220220

221221
exynos_drm_fbdev_destroy(dev, private->fb_helper);
222+
drm_fb_helper_unprepare(private->fb_helper);
222223
kfree(fbdev);
223224
private->fb_helper = NULL;
224225
}

drivers/gpu/drm/gma500/framebuffer.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,7 @@ int psb_fbdev_init(struct drm_device *dev)
427427
fini:
428428
drm_fb_helper_fini(fb_helper);
429429
free:
430+
drm_fb_helper_unprepare(fb_helper);
430431
kfree(fb_helper);
431432
return ret;
432433
}
@@ -439,6 +440,7 @@ static void psb_fbdev_fini(struct drm_device *dev)
439440
return;
440441

441442
psb_fbdev_destroy(dev, dev_priv->fb_helper);
443+
drm_fb_helper_unprepare(dev_priv->fb_helper);
442444
kfree(dev_priv->fb_helper);
443445
dev_priv->fb_helper = NULL;
444446
}

drivers/gpu/drm/i915/display/intel_fbdev.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,7 @@ static void intel_fbdev_destroy(struct intel_fbdev *ifbdev)
340340
if (ifbdev->fb)
341341
drm_framebuffer_remove(&ifbdev->fb->base);
342342

343+
drm_fb_helper_unprepare(&ifbdev->helper);
343344
kfree(ifbdev);
344345
}
345346

drivers/gpu/drm/msm/msm_fbdev.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ struct drm_fb_helper *msm_fbdev_init(struct drm_device *dev)
170170
fini:
171171
drm_fb_helper_fini(helper);
172172
fail:
173+
drm_fb_helper_unprepare(helper);
173174
kfree(fbdev);
174175
return NULL;
175176
}
@@ -196,6 +197,7 @@ void msm_fbdev_free(struct drm_device *dev)
196197
drm_framebuffer_remove(fbdev->fb);
197198
}
198199

200+
drm_fb_helper_unprepare(helper);
199201
kfree(fbdev);
200202

201203
priv->fbdev = NULL;

drivers/gpu/drm/omapdrm/omap_fbdev.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,7 @@ void omap_fbdev_init(struct drm_device *dev)
256256
fini:
257257
drm_fb_helper_fini(helper);
258258
fail:
259+
drm_fb_helper_unprepare(helper);
259260
kfree(fbdev);
260261

261262
dev_warn(dev->dev, "omap_fbdev_init failed\n");
@@ -286,6 +287,7 @@ void omap_fbdev_fini(struct drm_device *dev)
286287
if (fbdev->fb)
287288
drm_framebuffer_remove(fbdev->fb);
288289

290+
drm_fb_helper_unprepare(helper);
289291
kfree(fbdev);
290292

291293
priv->fbdev = NULL;

drivers/gpu/drm/radeon/radeon_fb.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,7 @@ int radeon_fbdev_init(struct radeon_device *rdev)
367367
fini:
368368
drm_fb_helper_fini(&rfbdev->helper);
369369
free:
370+
drm_fb_helper_unprepare(&rfbdev->helper);
370371
kfree(rfbdev);
371372
return ret;
372373
}
@@ -377,6 +378,7 @@ void radeon_fbdev_fini(struct radeon_device *rdev)
377378
return;
378379

379380
radeon_fbdev_destroy(rdev->ddev, rdev->mode_info.rfbdev);
381+
drm_fb_helper_unprepare(&rdev->mode_info.rfbdev->helper);
380382
kfree(rdev->mode_info.rfbdev);
381383
rdev->mode_info.rfbdev = NULL;
382384
}

drivers/gpu/drm/tegra/fb.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,7 @@ static struct tegra_fbdev *tegra_fbdev_create(struct drm_device *drm)
315315

316316
static void tegra_fbdev_free(struct tegra_fbdev *fbdev)
317317
{
318+
drm_fb_helper_unprepare(&fbdev->base);
318319
kfree(fbdev);
319320
}
320321

0 commit comments

Comments
 (0)