[PATCH v3 16/22] drm/tilcdc: Modernize driver initialization and cleanup paths
From: "Kory Maincent (TI.com)" <kory.maincent@bootlin.com>
Date: 2026-01-06 17:44:22
Also in:
dri-devel, linux-arm-kernel, linux-omap, lkml
Subsystem:
drm drivers, drm drivers and misc gpu patches, drm drivers for ti lcdc, the rest · Maintainers:
David Airlie, Simona Vetter, Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Jyri Sarha, Tomi Valkeinen, Linus Torvalds
Refactor the driver initialization to use modern DRM managed resource APIs, simplifying the code. The tilcdc_init and tilcdc_fini wrapper functions are removed since they served no purpose after the component framework was eliminated. Their logic is integrated directly into probe and remove. Key changes: - Use devm_drm_dev_alloc() instead of drm_dev_alloc(). - Use drmm_mode_config_init() instead of drm_mode_config_init(). - Align the remove path with the probe error path to ensure consistent cleanup ordering in both success and failure cases. - Adjust platform_set_drvdata() to store the private structure instead of the drm_device, matching the new allocation pattern. These changes reduce error-prone code while maintaining the same functional behavior. Signed-off-by: Kory Maincent (TI.com) <kory.maincent@bootlin.com> --- Change in v3: - Split the patch between code move and cleanup for better diff readibility. --- drivers/gpu/drm/tilcdc/tilcdc_drv.c | 111 ++++++++++++------------------------ drivers/gpu/drm/tilcdc/tilcdc_drv.h | 2 + 2 files changed, 40 insertions(+), 73 deletions(-)
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
index c306fc3ae2784..64b6aea5fd1c6 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c@@ -80,7 +80,7 @@ static const struct drm_mode_config_funcs mode_config_funcs = { static void modeset_init(struct drm_device *dev) { - struct tilcdc_drm_private *priv = dev->dev_private; + struct tilcdc_drm_private *priv = ddev_to_tilcdc_priv(dev); dev->mode_config.min_width = 0; dev->mode_config.min_height = 0;
@@ -106,14 +106,14 @@ static int cpufreq_transition(struct notifier_block *nb, static irqreturn_t tilcdc_irq(int irq, void *arg) { struct drm_device *dev = arg; - struct tilcdc_drm_private *priv = dev->dev_private; + struct tilcdc_drm_private *priv = ddev_to_tilcdc_priv(dev); return tilcdc_crtc_irq(priv->crtc); } static int tilcdc_irq_install(struct drm_device *dev, unsigned int irq) { - struct tilcdc_drm_private *priv = dev->dev_private; + struct tilcdc_drm_private *priv = ddev_to_tilcdc_priv(dev); int ret; ret = request_irq(irq, tilcdc_irq, 0, dev->driver->name, dev);
@@ -127,7 +127,7 @@ static int tilcdc_irq_install(struct drm_device *dev, unsigned int irq) static void tilcdc_irq_uninstall(struct drm_device *dev) { - struct tilcdc_drm_private *priv = dev->dev_private; + struct tilcdc_drm_private *priv = ddev_to_tilcdc_priv(dev); if (!priv->irq_enabled) return;
@@ -175,7 +175,7 @@ static int tilcdc_regs_show(struct seq_file *m, void *arg) { struct drm_info_node *node = (struct drm_info_node *) m->private; struct drm_device *dev = node->minor->dev; - struct tilcdc_drm_private *priv = dev->dev_private; + struct tilcdc_drm_private *priv = ddev_to_tilcdc_priv(dev); unsigned i; pm_runtime_get_sync(dev->dev);
@@ -259,39 +259,6 @@ static int tilcdc_pm_resume(struct device *dev) static DEFINE_SIMPLE_DEV_PM_OPS(tilcdc_pm_ops, tilcdc_pm_suspend, tilcdc_pm_resume); -static void tilcdc_fini(struct drm_device *dev) -{ - struct tilcdc_drm_private *priv = dev->dev_private; - -#ifdef CONFIG_CPU_FREQ - if (priv->freq_transition.notifier_call) - cpufreq_unregister_notifier(&priv->freq_transition, - CPUFREQ_TRANSITION_NOTIFIER); -#endif - - if (priv->crtc) - tilcdc_crtc_shutdown(priv->crtc); - - drm_dev_unregister(dev); - - drm_kms_helper_poll_fini(dev); - drm_atomic_helper_shutdown(dev); - tilcdc_irq_uninstall(dev); - drm_mode_config_cleanup(dev); - - if (priv->clk) - clk_put(priv->clk); - - if (priv->wq) - destroy_workqueue(priv->wq); - - dev->dev_private = NULL; - - pm_runtime_disable(dev->dev); - - drm_dev_put(dev); -} - static const struct of_device_id tilcdc_of_match[] = { { .compatible = "ti,am33xx-tilcdc", .data = (void *)AM33XX_TILCDC}, { .compatible = "ti,da850-tilcdc", .data = (void *)DA850_TILCDC},
@@ -299,37 +266,34 @@ static const struct of_device_id tilcdc_of_match[] = { }; MODULE_DEVICE_TABLE(of, tilcdc_of_match); -static int tilcdc_init(const struct drm_driver *ddrv, struct device *dev) +static int tilcdc_pdev_probe(struct platform_device *pdev) { - struct drm_device *ddev; - struct platform_device *pdev = to_platform_device(dev); - struct device_node *node = dev->of_node; + struct device_node *node = pdev->dev.of_node; const struct of_device_id *of_id; struct tilcdc_drm_private *priv; + struct device *dev = &pdev->dev; + struct drm_device *ddev; u32 bpp = 0; int ret; - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - - ddev = drm_dev_alloc(ddrv, dev); - if (IS_ERR(ddev)) - return PTR_ERR(ddev); + priv = devm_drm_dev_alloc(dev, &tilcdc_driver, + struct tilcdc_drm_private, ddev); + if (IS_ERR(priv)) + return PTR_ERR(priv); of_id = of_match_node(tilcdc_of_match, node); if (!of_id) return -ENODEV; - ddev->dev_private = priv; - platform_set_drvdata(pdev, ddev); - drm_mode_config_init(ddev); + platform_set_drvdata(pdev, priv); + ddev = &priv->ddev; + ret = drmm_mode_config_init(ddev); + if (ret) + return ret; priv->wq = alloc_ordered_workqueue("tilcdc", 0); - if (!priv->wq) { - ret = -ENOMEM; - goto put_drm; - } + if (!priv->wq) + return -ENOMEM; priv->mmio = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(priv->mmio)) {
@@ -495,33 +459,34 @@ static int tilcdc_init(const struct drm_driver *ddrv, struct device *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; } -static int tilcdc_pdev_probe(struct platform_device *pdev) -{ - /* bail out early if no DT data: */ - if (!pdev->dev.of_node) { - dev_err(&pdev->dev, "device-tree data is missing\n"); - return -ENXIO; - } - - return tilcdc_init(&tilcdc_driver, &pdev->dev); -} - static void tilcdc_pdev_remove(struct platform_device *pdev) { - tilcdc_fini(platform_get_drvdata(pdev)); + struct tilcdc_drm_private *priv = platform_get_drvdata(pdev); + struct drm_device *ddev = &priv->ddev; + + drm_dev_unregister(ddev); + drm_kms_helper_poll_fini(ddev); + tilcdc_irq_uninstall(ddev); +#ifdef CONFIG_CPU_FREQ + cpufreq_unregister_notifier(&priv->freq_transition, + CPUFREQ_TRANSITION_NOTIFIER); +#endif + tilcdc_crtc_destroy(priv->crtc); + pm_runtime_disable(&pdev->dev); + clk_put(priv->clk); + destroy_workqueue(priv->wq); } static void tilcdc_pdev_shutdown(struct platform_device *pdev) { - drm_atomic_helper_shutdown(platform_get_drvdata(pdev)); + struct tilcdc_drm_private *priv = platform_get_drvdata(pdev); + struct drm_device *ddev = &priv->ddev; + + drm_atomic_helper_shutdown(ddev); } static struct platform_driver tilcdc_platform_driver = {
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.h b/drivers/gpu/drm/tilcdc/tilcdc_drv.h
index 60e85e29b1063..e3d04a3eb25b4 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.h
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.h@@ -48,6 +48,8 @@ struct tilcdc_drm_private { unsigned int irq; + struct drm_device ddev; + /* don't attempt resolutions w/ higher W * H * Hz: */ uint32_t max_bandwidth; /*
--
2.43.0