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

drm/tilcdc: Convert to Linux IRQ interfaces

Drop the DRM IRQ midlayer in favor of Linux IRQ interfaces. DRM's
IRQ helpers are mostly useful for UMS drivers. Modern KMS drivers
don't benefit from using it.

DRM IRQ callbacks are now being called directly or inlined.

Calls to platform_get_irq() can fail with a negative errno code.
Abort initialization in this case. The DRM IRQ midlayer does not
handle this case correctly.

For most drivers, only the DRM IRQ helpers use irq_enabled from
struct drm_device. Tilcdc also uses irq_enabled to make its error
rollback work correctly. As the field will become legacy, duplicated
the state in the driver's local private structure.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Acked-by: Sam Ravnborg <sam@ravnborg.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20210803090704.32152-12-tzimmermann@suse.de

+43 -11
+40 -11
drivers/gpu/drm/tilcdc/tilcdc_drv.c
··· 20 20 #include <drm/drm_fourcc.h> 21 21 #include <drm/drm_gem_cma_helper.h> 22 22 #include <drm/drm_gem_framebuffer_helper.h> 23 - #include <drm/drm_irq.h> 24 23 #include <drm/drm_mm.h> 25 24 #include <drm/drm_probe_helper.h> 26 25 #include <drm/drm_vblank.h> ··· 123 124 } 124 125 #endif 125 126 127 + static irqreturn_t tilcdc_irq(int irq, void *arg) 128 + { 129 + struct drm_device *dev = arg; 130 + struct tilcdc_drm_private *priv = dev->dev_private; 131 + 132 + return tilcdc_crtc_irq(priv->crtc); 133 + } 134 + 135 + static int tilcdc_irq_install(struct drm_device *dev, unsigned int irq) 136 + { 137 + struct tilcdc_drm_private *priv = dev->dev_private; 138 + int ret; 139 + 140 + ret = request_irq(irq, tilcdc_irq, 0, dev->driver->name, dev); 141 + if (ret) 142 + return ret; 143 + 144 + priv->irq_enabled = false; 145 + 146 + return 0; 147 + } 148 + 149 + static void tilcdc_irq_uninstall(struct drm_device *dev) 150 + { 151 + struct tilcdc_drm_private *priv = dev->dev_private; 152 + 153 + if (!priv->irq_enabled) 154 + return; 155 + 156 + free_irq(priv->irq, dev); 157 + priv->irq_enabled = false; 158 + } 159 + 126 160 /* 127 161 * DRM operations: 128 162 */ ··· 177 145 drm_dev_unregister(dev); 178 146 179 147 drm_kms_helper_poll_fini(dev); 180 - drm_irq_uninstall(dev); 148 + tilcdc_irq_uninstall(dev); 181 149 drm_mode_config_cleanup(dev); 182 150 183 151 if (priv->clk) ··· 368 336 goto init_failed; 369 337 } 370 338 371 - ret = drm_irq_install(ddev, platform_get_irq(pdev, 0)); 339 + ret = platform_get_irq(pdev, 0); 340 + if (ret < 0) 341 + goto init_failed; 342 + priv->irq = ret; 343 + 344 + ret = tilcdc_irq_install(ddev, priv->irq); 372 345 if (ret < 0) { 373 346 dev_err(dev, "failed to install IRQ handler\n"); 374 347 goto init_failed; ··· 395 358 tilcdc_fini(ddev); 396 359 397 360 return ret; 398 - } 399 - 400 - static irqreturn_t tilcdc_irq(int irq, void *arg) 401 - { 402 - struct drm_device *dev = arg; 403 - struct tilcdc_drm_private *priv = dev->dev_private; 404 - return tilcdc_crtc_irq(priv->crtc); 405 361 } 406 362 407 363 #if defined(CONFIG_DEBUG_FS) ··· 484 454 485 455 static const struct drm_driver tilcdc_driver = { 486 456 .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, 487 - .irq_handler = tilcdc_irq, 488 457 DRM_GEM_CMA_DRIVER_OPS, 489 458 #ifdef CONFIG_DEBUG_FS 490 459 .debugfs_init = tilcdc_debugfs_init,
+3
drivers/gpu/drm/tilcdc/tilcdc_drv.h
··· 46 46 struct clk *clk; /* functional clock */ 47 47 int rev; /* IP revision */ 48 48 49 + unsigned int irq; 50 + 49 51 /* don't attempt resolutions w/ higher W * H * Hz: */ 50 52 uint32_t max_bandwidth; 51 53 /* ··· 84 82 85 83 bool is_registered; 86 84 bool is_componentized; 85 + bool irq_enabled; 87 86 }; 88 87 89 88 /* Sub-module for display. Since we don't know at compile time what panels