Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/meson: Fix error handling when afbcd.ops->init fails

When afbcd.ops->init fails we need to free the struct drm_device. Also
all errors which come after afbcd.ops->init was successful need to exit
the AFBCD, just like meson_drv_unbind() does.

Fixes: d1b5e41e13a7e9 ("drm/meson: Add AFBCD module driver")
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Acked-by: Neil Armstrong <narmstrong@baylibre.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20211230235515.1627522-3-martin.blumenstingl@googlemail.com

authored by

Martin Blumenstingl and committed by
Neil Armstrong
fa747d75 04b8a5d9

+11 -8
+11 -8
drivers/gpu/drm/meson/meson_drv.c
··· 302 302 if (priv->afbcd.ops) { 303 303 ret = priv->afbcd.ops->init(priv); 304 304 if (ret) 305 - return ret; 305 + goto free_drm; 306 306 } 307 307 308 308 /* Encoder Initialization */ 309 309 310 310 ret = meson_encoder_cvbs_init(priv); 311 311 if (ret) 312 - goto free_drm; 312 + goto exit_afbcd; 313 313 314 314 if (has_components) { 315 315 ret = component_bind_all(drm->dev, drm); 316 316 if (ret) { 317 317 dev_err(drm->dev, "Couldn't bind all components\n"); 318 - goto free_drm; 318 + goto exit_afbcd; 319 319 } 320 320 } 321 321 322 322 ret = meson_encoder_hdmi_init(priv); 323 323 if (ret) 324 - goto free_drm; 324 + goto exit_afbcd; 325 325 326 326 ret = meson_plane_create(priv); 327 327 if (ret) 328 - goto free_drm; 328 + goto exit_afbcd; 329 329 330 330 ret = meson_overlay_create(priv); 331 331 if (ret) 332 - goto free_drm; 332 + goto exit_afbcd; 333 333 334 334 ret = meson_crtc_create(priv); 335 335 if (ret) 336 - goto free_drm; 336 + goto exit_afbcd; 337 337 338 338 ret = request_irq(priv->vsync_irq, meson_irq, 0, drm->driver->name, drm); 339 339 if (ret) 340 - goto free_drm; 340 + goto exit_afbcd; 341 341 342 342 drm_mode_config_reset(drm); 343 343 ··· 355 355 356 356 uninstall_irq: 357 357 free_irq(priv->vsync_irq, drm); 358 + exit_afbcd: 359 + if (priv->afbcd.ops) 360 + priv->afbcd.ops->exit(priv); 358 361 free_drm: 359 362 drm_dev_put(drm); 360 363