From: "Kory Maincent (TI.com)" kory.maincent@bootlin.com
The drm_kms_helper_poll_fini() and drm_atomic_helper_shutdown() helpers should only be called when the device has been successfully registered. Currently, these functions are called unconditionally in tilcdc_fini(), which causes warnings during probe deferral scenarios.
[ 7.972317] WARNING: CPU: 0 PID: 23 at drivers/gpu/drm/drm_atomic_state_helper.c:175 drm_atomic_helper_crtc_duplicate_state+0x60/0x68 ... [ 8.005820] drm_atomic_helper_crtc_duplicate_state from drm_atomic_get_crtc_state+0x68/0x108 [ 8.005858] drm_atomic_get_crtc_state from drm_atomic_helper_disable_all+0x90/0x1c8 [ 8.005885] drm_atomic_helper_disable_all from drm_atomic_helper_shutdown+0x90/0x144 [ 8.005911] drm_atomic_helper_shutdown from tilcdc_fini+0x68/0xf8 [tilcdc] [ 8.005957] tilcdc_fini [tilcdc] from tilcdc_pdev_probe+0xb0/0x6d4 [tilcdc]
Fix this by rewriting the failed probe cleanup path using the standard goto error handling pattern, which ensures that cleanup functions are only called on successfully initialized resources. Additionally, remove the now-unnecessary is_registered flag.
Cc: stable@vger.kernel.org Fixes: 3c4babae3c4a ("drm: Call drm_atomic_helper_shutdown() at shutdown/remove time for misc drivers") Signed-off-by: Kory Maincent (TI.com) kory.maincent@bootlin.com ---
I'm working on removing the usage of deprecated functions as well as general improvements to this driver, but it will take some time so for now this is a simple fix to a functional bug.
Change in v3: - Rewrite the failed probe clean up path using goto - Remove the is_registered flag
Change in v2: - Add missing cc: stable tag - Add Swamil reviewed-by --- drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 2 +- drivers/gpu/drm/tilcdc/tilcdc_drv.c | 53 ++++++++++++++++++---------- drivers/gpu/drm/tilcdc/tilcdc_drv.h | 2 +- 3 files changed, 37 insertions(+), 20 deletions(-)
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c index 5718d9d83a49f..52c95131af5af 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c @@ -586,7 +586,7 @@ static void tilcdc_crtc_recover_work(struct work_struct *work) drm_modeset_unlock(&crtc->mutex); }
-static void tilcdc_crtc_destroy(struct drm_crtc *crtc) +void tilcdc_crtc_destroy(struct drm_crtc *crtc) { struct tilcdc_drm_private *priv = crtc->dev->dev_private;
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c index 7caec4d38ddf0..2a88cce445b8f 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c @@ -172,8 +172,7 @@ static void tilcdc_fini(struct drm_device *dev) if (priv->crtc) tilcdc_crtc_shutdown(priv->crtc);
- if (priv->is_registered) - drm_dev_unregister(dev); + drm_dev_unregister(dev);
drm_kms_helper_poll_fini(dev); drm_atomic_helper_shutdown(dev); @@ -220,21 +219,21 @@ static int tilcdc_init(const struct drm_driver *ddrv, struct device *dev) priv->wq = alloc_ordered_workqueue("tilcdc", 0); if (!priv->wq) { ret = -ENOMEM; - goto init_failed; + goto put_drm; }
priv->mmio = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(priv->mmio)) { dev_err(dev, "failed to request / ioremap\n"); ret = PTR_ERR(priv->mmio); - goto init_failed; + goto free_wq; }
priv->clk = clk_get(dev, "fck"); if (IS_ERR(priv->clk)) { dev_err(dev, "failed to get functional clock\n"); ret = -ENODEV; - goto init_failed; + goto free_wq; }
pm_runtime_enable(dev); @@ -313,7 +312,7 @@ static int tilcdc_init(const struct drm_driver *ddrv, struct device *dev) ret = tilcdc_crtc_create(ddev); if (ret < 0) { dev_err(dev, "failed to create crtc\n"); - goto init_failed; + goto disable_pm; } modeset_init(ddev);
@@ -324,46 +323,46 @@ static int tilcdc_init(const struct drm_driver *ddrv, struct device *dev) if (ret) { dev_err(dev, "failed to register cpufreq notifier\n"); priv->freq_transition.notifier_call = NULL; - goto init_failed; + goto destroy_crtc; } #endif
if (priv->is_componentized) { ret = component_bind_all(dev, ddev); if (ret < 0) - goto init_failed; + goto unregister_cpufreq_notif;
ret = tilcdc_add_component_encoder(ddev); if (ret < 0) - goto init_failed; + goto unbind_component; } else { ret = tilcdc_attach_external_device(ddev); if (ret) - goto init_failed; + goto unregister_cpufreq_notif; }
if (!priv->external_connector && ((priv->num_encoders == 0) || (priv->num_connectors == 0))) { dev_err(dev, "no encoders/connectors found\n"); ret = -EPROBE_DEFER; - goto init_failed; + goto unbind_component; }
ret = drm_vblank_init(ddev, 1); if (ret < 0) { dev_err(dev, "failed to initialize vblank\n"); - goto init_failed; + goto unbind_component; }
ret = platform_get_irq(pdev, 0); if (ret < 0) - goto init_failed; + goto unbind_component; priv->irq = ret;
ret = tilcdc_irq_install(ddev, priv->irq); if (ret < 0) { dev_err(dev, "failed to install IRQ handler\n"); - goto init_failed; + goto unbind_component; }
drm_mode_config_reset(ddev); @@ -372,16 +371,34 @@ static int tilcdc_init(const struct drm_driver *ddrv, struct device *dev)
ret = drm_dev_register(ddev, 0); if (ret) - goto init_failed; - priv->is_registered = true; + goto stop_poll;
drm_client_setup_with_color_mode(ddev, bpp);
return 0;
-init_failed: - tilcdc_fini(ddev); +stop_poll: + drm_kms_helper_poll_fini(ddev); + tilcdc_irq_uninstall(ddev); +unbind_component: + if (priv->is_componentized) + component_unbind_all(dev, ddev); +unregister_cpufreq_notif: +#ifdef CONFIG_CPU_FREQ + cpufreq_unregister_notifier(&priv->freq_transition, + CPUFREQ_TRANSITION_NOTIFIER); +#endif +destroy_crtc: + tilcdc_crtc_destroy(priv->crtc); +disable_pm: + pm_runtime_disable(dev); + clk_put(priv->clk); +free_wq: + destroy_workqueue(priv->wq); +put_drm: platform_set_drvdata(pdev, NULL); + ddev->dev_private = NULL; + drm_dev_put(ddev);
return ret; } diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.h b/drivers/gpu/drm/tilcdc/tilcdc_drv.h index b818448c83f61..58b276f82a669 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.h +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.h @@ -82,7 +82,6 @@ struct tilcdc_drm_private { struct drm_encoder *external_encoder; struct drm_connector *external_connector;
- bool is_registered; bool is_componentized; bool irq_enabled; }; @@ -164,6 +163,7 @@ void tilcdc_crtc_set_panel_info(struct drm_crtc *crtc, void tilcdc_crtc_set_simulate_vesa_sync(struct drm_crtc *crtc, bool simulate_vesa_sync); void tilcdc_crtc_shutdown(struct drm_crtc *crtc); +void tilcdc_crtc_destroy(struct drm_crtc *crtc); int tilcdc_crtc_update_fb(struct drm_crtc *crtc, struct drm_framebuffer *fb, struct drm_pending_vblank_event *event);
Hi Kory,
kernel test robot noticed the following build warnings:
[auto build test WARNING on linus/master] [also build test WARNING on v6.18-rc6 next-20251118] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Kory-Maincent/drm-tilcdc-Fix-... base: linus/master patch link: https://lore.kernel.org/r/20251118133850.125561-1-kory.maincent%40bootlin.co... patch subject: [PATCH v3] drm/tilcdc: Fix removal actions in case of failed probe config: arm-randconfig-003-20251119 (https://download.01.org/0day-ci/archive/20251119/202511191009.muedhmup-lkp@i...) compiler: clang version 22.0.0git (https://github.com/llvm/llvm-project 0bba1e76581bad04e7d7f09f5115ae5e2989e0d9) reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251119/202511191009.muedhmup-lkp@i...)
If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot lkp@intel.com | Closes: https://lore.kernel.org/oe-kbuild-all/202511191009.muedhmup-lkp@intel.com/
All warnings (new ones prefixed by >>):
drivers/gpu/drm/tilcdc/tilcdc_drv.c:391:1: warning: unused label 'destroy_crtc' [-Wunused-label]
391 | destroy_crtc: | ^~~~~~~~~~~~~ 1 warning generated.
vim +/destroy_crtc +391 drivers/gpu/drm/tilcdc/tilcdc_drv.c
329 330 if (priv->is_componentized) { 331 ret = component_bind_all(dev, ddev); 332 if (ret < 0) 333 goto unregister_cpufreq_notif; 334 335 ret = tilcdc_add_component_encoder(ddev); 336 if (ret < 0) 337 goto unbind_component; 338 } else { 339 ret = tilcdc_attach_external_device(ddev); 340 if (ret) 341 goto unregister_cpufreq_notif; 342 } 343 344 if (!priv->external_connector && 345 ((priv->num_encoders == 0) || (priv->num_connectors == 0))) { 346 dev_err(dev, "no encoders/connectors found\n"); 347 ret = -EPROBE_DEFER; 348 goto unbind_component; 349 } 350 351 ret = drm_vblank_init(ddev, 1); 352 if (ret < 0) { 353 dev_err(dev, "failed to initialize vblank\n"); 354 goto unbind_component; 355 } 356 357 ret = platform_get_irq(pdev, 0); 358 if (ret < 0) 359 goto unbind_component; 360 priv->irq = ret; 361 362 ret = tilcdc_irq_install(ddev, priv->irq); 363 if (ret < 0) { 364 dev_err(dev, "failed to install IRQ handler\n"); 365 goto unbind_component; 366 } 367 368 drm_mode_config_reset(ddev); 369 370 drm_kms_helper_poll_init(ddev); 371 372 ret = drm_dev_register(ddev, 0); 373 if (ret) 374 goto stop_poll; 375 376 drm_client_setup_with_color_mode(ddev, bpp); 377 378 return 0; 379 380 stop_poll: 381 drm_kms_helper_poll_fini(ddev); 382 tilcdc_irq_uninstall(ddev); 383 unbind_component: 384 if (priv->is_componentized) 385 component_unbind_all(dev, ddev); 386 unregister_cpufreq_notif: 387 #ifdef CONFIG_CPU_FREQ 388 cpufreq_unregister_notifier(&priv->freq_transition, 389 CPUFREQ_TRANSITION_NOTIFIER); 390 #endif
391 destroy_crtc:
392 tilcdc_crtc_destroy(priv->crtc); 393 disable_pm: 394 pm_runtime_disable(dev); 395 clk_put(priv->clk); 396 free_wq: 397 destroy_workqueue(priv->wq); 398 put_drm: 399 platform_set_drvdata(pdev, NULL); 400 ddev->dev_private = NULL; 401 drm_dev_put(ddev); 402 403 return ret; 404 } 405
Hi Kory,
kernel test robot noticed the following build warnings:
[auto build test WARNING on linus/master] [also build test WARNING on v6.18-rc6 next-20251118] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Kory-Maincent/drm-tilcdc-Fix-... base: linus/master patch link: https://lore.kernel.org/r/20251118133850.125561-1-kory.maincent%40bootlin.co... patch subject: [PATCH v3] drm/tilcdc: Fix removal actions in case of failed probe config: arm-randconfig-004-20251119 (https://download.01.org/0day-ci/archive/20251119/202511191045.bW4DdgHX-lkp@i...) compiler: arm-linux-gnueabi-gcc (GCC) 13.4.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251119/202511191045.bW4DdgHX-lkp@i...)
If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot lkp@intel.com | Closes: https://lore.kernel.org/oe-kbuild-all/202511191045.bW4DdgHX-lkp@intel.com/
All warnings (new ones prefixed by >>):
drivers/gpu/drm/tilcdc/tilcdc_drv.c: In function 'tilcdc_init':
drivers/gpu/drm/tilcdc/tilcdc_drv.c:391:1: warning: label 'destroy_crtc' defined but not used [-Wunused-label]
391 | destroy_crtc: | ^~~~~~~~~~~~
vim +/destroy_crtc +391 drivers/gpu/drm/tilcdc/tilcdc_drv.c
329 330 if (priv->is_componentized) { 331 ret = component_bind_all(dev, ddev); 332 if (ret < 0) 333 goto unregister_cpufreq_notif; 334 335 ret = tilcdc_add_component_encoder(ddev); 336 if (ret < 0) 337 goto unbind_component; 338 } else { 339 ret = tilcdc_attach_external_device(ddev); 340 if (ret) 341 goto unregister_cpufreq_notif; 342 } 343 344 if (!priv->external_connector && 345 ((priv->num_encoders == 0) || (priv->num_connectors == 0))) { 346 dev_err(dev, "no encoders/connectors found\n"); 347 ret = -EPROBE_DEFER; 348 goto unbind_component; 349 } 350 351 ret = drm_vblank_init(ddev, 1); 352 if (ret < 0) { 353 dev_err(dev, "failed to initialize vblank\n"); 354 goto unbind_component; 355 } 356 357 ret = platform_get_irq(pdev, 0); 358 if (ret < 0) 359 goto unbind_component; 360 priv->irq = ret; 361 362 ret = tilcdc_irq_install(ddev, priv->irq); 363 if (ret < 0) { 364 dev_err(dev, "failed to install IRQ handler\n"); 365 goto unbind_component; 366 } 367 368 drm_mode_config_reset(ddev); 369 370 drm_kms_helper_poll_init(ddev); 371 372 ret = drm_dev_register(ddev, 0); 373 if (ret) 374 goto stop_poll; 375 376 drm_client_setup_with_color_mode(ddev, bpp); 377 378 return 0; 379 380 stop_poll: 381 drm_kms_helper_poll_fini(ddev); 382 tilcdc_irq_uninstall(ddev); 383 unbind_component: 384 if (priv->is_componentized) 385 component_unbind_all(dev, ddev); 386 unregister_cpufreq_notif: 387 #ifdef CONFIG_CPU_FREQ 388 cpufreq_unregister_notifier(&priv->freq_transition, 389 CPUFREQ_TRANSITION_NOTIFIER); 390 #endif
391 destroy_crtc:
392 tilcdc_crtc_destroy(priv->crtc); 393 disable_pm: 394 pm_runtime_disable(dev); 395 clk_put(priv->clk); 396 free_wq: 397 destroy_workqueue(priv->wq); 398 put_drm: 399 platform_set_drvdata(pdev, NULL); 400 ddev->dev_private = NULL; 401 drm_dev_put(ddev); 402 403 return ret; 404 } 405
linux-stable-mirror@lists.linaro.org