Re: [bug report] drm/meson: fix unbind path if HDMI fails to bind

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

On 08/06/2024 16:20, Dan Carpenter wrote:
Hello Neil Armstrong,

Commit 6a044642988b ("drm/meson: fix unbind path if HDMI fails to
bind") from May 30, 2023 (linux-next), leads to the following Smatch
static checker warning:

	drivers/gpu/drm/meson/meson_drv.c:377 meson_drv_bind_master()
	error: we previously assumed 'priv' could be null (see line 205)

Thanks, I'll look into this.

Neil


drivers/gpu/drm/meson/meson_drv.c
     180 static int meson_drv_bind_master(struct device *dev, bool has_components)
     181 {
     182         struct platform_device *pdev = to_platform_device(dev);
     183         const struct meson_drm_match_data *match;
     184         struct meson_drm *priv;
     185         struct drm_device *drm;
     186         struct resource *res;
     187         void __iomem *regs;
     188         int ret, i;
     189
     190         /* Checks if an output connector is available */
     191         if (!meson_vpu_has_available_connectors(dev)) {
     192                 dev_err(dev, "No output connector available\n");
     193                 return -ENODEV;
     194         }
     195
     196         match = of_device_get_match_data(dev);
     197         if (!match)
     198                 return -ENODEV;
     199
     200         drm = drm_dev_alloc(&meson_driver, dev);
     201         if (IS_ERR(drm))
     202                 return PTR_ERR(drm);
     203
     204         priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
     205         if (!priv) {
     206                 ret = -ENOMEM;
     207                 goto free_drm;

priv is NULL so the calls to meson_encoder_*_remove() will Oops.

     208         }
     209         drm->dev_private = priv;
     210         priv->drm = drm;
     211         priv->dev = dev;
     212         priv->compat = match->compat;
     213         priv->afbcd.ops = match->afbcd_ops;
     214
     215         regs = devm_platform_ioremap_resource_byname(pdev, "vpu");
     216         if (IS_ERR(regs)) {
     217                 ret = PTR_ERR(regs);
     218                 goto free_drm;
     219         }
     220
     221         priv->io_base = regs;
     222
     223         res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hhi");
     224         if (!res) {
     225                 ret = -EINVAL;
     226                 goto free_drm;
     227         }
     228         /* Simply ioremap since it may be a shared register zone */
     229         regs = devm_ioremap(dev, res->start, resource_size(res));
     230         if (!regs) {
     231                 ret = -EADDRNOTAVAIL;
     232                 goto free_drm;
     233         }
     234
     235         priv->hhi = devm_regmap_init_mmio(dev, regs,
     236                                           &meson_regmap_config);
     237         if (IS_ERR(priv->hhi)) {
     238                 dev_err(&pdev->dev, "Couldn't create the HHI regmap\n");
     239                 ret = PTR_ERR(priv->hhi);
     240                 goto free_drm;
     241         }
     242
     243         priv->canvas = meson_canvas_get(dev);
     244         if (IS_ERR(priv->canvas)) {
     245                 ret = PTR_ERR(priv->canvas);
     246                 goto free_drm;
     247         }
     248
     249         ret = meson_canvas_alloc(priv->canvas, &priv->canvas_id_osd1);
     250         if (ret)
     251                 goto free_drm;
     252         ret = meson_canvas_alloc(priv->canvas, &priv->canvas_id_vd1_0);
     253         if (ret) {
     254                 meson_canvas_free(priv->canvas, priv->canvas_id_osd1);
     255                 goto free_drm;
     256         }
     257         ret = meson_canvas_alloc(priv->canvas, &priv->canvas_id_vd1_1);
     258         if (ret) {
     259                 meson_canvas_free(priv->canvas, priv->canvas_id_osd1);
     260                 meson_canvas_free(priv->canvas, priv->canvas_id_vd1_0);
     261                 goto free_drm;
     262         }
     263         ret = meson_canvas_alloc(priv->canvas, &priv->canvas_id_vd1_2);
     264         if (ret) {
     265                 meson_canvas_free(priv->canvas, priv->canvas_id_osd1);
     266                 meson_canvas_free(priv->canvas, priv->canvas_id_vd1_0);
     267                 meson_canvas_free(priv->canvas, priv->canvas_id_vd1_1);

What about this clean up?

     268                 goto free_drm;
     269         }
     270
     271         priv->vsync_irq = platform_get_irq(pdev, 0);
     272
     273         ret = drm_vblank_init(drm, 1);
     274         if (ret)
     275                 goto free_drm;

Do we not need to do it here as well?

     276
     277         /* Assign limits per soc revision/package */
     278         for (i = 0 ; i < ARRAY_SIZE(meson_drm_soc_attrs) ; ++i) {
     279                 if (soc_device_match(meson_drm_soc_attrs[i].attrs)) {
     280                         priv->limits = &meson_drm_soc_attrs[i].limits;
     281                         break;
     282                 }
     283         }
     284
     285         /*
     286          * Remove early framebuffers (ie. simplefb). The framebuffer can be
     287          * located anywhere in RAM
     288          */
     289         ret = drm_aperture_remove_framebuffers(&meson_driver);
     290         if (ret)
     291                 goto free_drm;
     292
     293         ret = drmm_mode_config_init(drm);
     294         if (ret)
     295                 goto free_drm;
     296         drm->mode_config.max_width = 3840;
     297         drm->mode_config.max_height = 2160;
     298         drm->mode_config.funcs = &meson_mode_config_funcs;
     299         drm->mode_config.helper_private        = &meson_mode_config_helpers;
     300
     301         /* Hardware Initialization */
     302
     303         meson_vpu_init(priv);
     304         meson_venc_init(priv);
     305         meson_vpp_init(priv);
     306         meson_viu_init(priv);
     307         if (priv->afbcd.ops) {
     308                 ret = priv->afbcd.ops->init(priv);
     309                 if (ret)
     310                         goto free_drm;
     311         }
     312
     313         /* Encoder Initialization */
     314
     315         ret = meson_encoder_cvbs_probe(priv);
     316         if (ret)
     317                 goto exit_afbcd;
     318
     319         if (has_components) {
     320                 ret = component_bind_all(dev, drm);
     321                 if (ret) {
     322                         dev_err(drm->dev, "Couldn't bind all components\n");
     323                         /* Do not try to unbind */
     324                         has_components = false;
     325                         goto exit_afbcd;
     326                 }
     327         }
     328
     329         ret = meson_encoder_hdmi_probe(priv);
     330         if (ret)
     331                 goto exit_afbcd;
     332
     333         if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) {
     334                 ret = meson_encoder_dsi_probe(priv);
     335                 if (ret)
     336                         goto exit_afbcd;
     337         }
     338
     339         ret = meson_plane_create(priv);
     340         if (ret)
     341                 goto exit_afbcd;
     342
     343         ret = meson_overlay_create(priv);
     344         if (ret)
     345                 goto exit_afbcd;
     346
     347         ret = meson_crtc_create(priv);
     348         if (ret)
     349                 goto exit_afbcd;
     350
     351         ret = request_irq(priv->vsync_irq, meson_irq, 0, drm->driver->name, drm);
     352         if (ret)
     353                 goto exit_afbcd;
     354
     355         drm_mode_config_reset(drm);
     356
     357         drm_kms_helper_poll_init(drm);
     358
     359         platform_set_drvdata(pdev, priv);
     360
     361         ret = drm_dev_register(drm, 0);
     362         if (ret)
     363                 goto uninstall_irq;
     364
     365         drm_fbdev_dma_setup(drm, 32);
     366
     367         return 0;
     368
     369 uninstall_irq:
     370         free_irq(priv->vsync_irq, drm);
     371 exit_afbcd:
     372         if (priv->afbcd.ops)
     373                 priv->afbcd.ops->exit(priv);
     374 free_drm:
     375         drm_dev_put(drm);
     376
--> 377         meson_encoder_dsi_remove(priv);
     378         meson_encoder_hdmi_remove(priv);
     379         meson_encoder_cvbs_remove(priv);
     380
     381         if (has_components)
     382                 component_unbind_all(dev, drm);
     383
     384         return ret;
     385 }

regards,
dan carpenter




[Index of Archives]     [Linux DRI Users]     [Linux Intel Graphics]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux