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

drm/imx: ipuv3-plane: use drm managed resources

Use drmm_universal_plane_alloc() to align plane memory lifetime with
the drm device. drm_plane_cleanup() is called automatically before the
memory is freed.
Also move the call to ipu_plane_get_resources() into ipu_plane_init()
and use drm managed resources to put IPU resources automatically when
required. Handle error return values of the plane property creation
functions.

Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>

+36 -63
+2 -25
drivers/gpu/drm/imx/ipuv3-crtc.c
··· 384 384 drm_crtc_init_with_planes(drm, crtc, &ipu_crtc->plane[0]->base, NULL, 385 385 &ipu_crtc_funcs, NULL); 386 386 387 - ret = ipu_plane_get_resources(ipu_crtc->plane[0]); 388 - if (ret) { 389 - dev_err(ipu_crtc->dev, "getting plane 0 resources failed with %d.\n", 390 - ret); 391 - goto err_put_resources; 392 - } 393 - 394 387 /* If this crtc is using the DP, add an overlay plane */ 395 388 if (pdata->dp >= 0 && pdata->dma[1] > 0) { 396 389 ipu_crtc->plane[1] = ipu_plane_init(drm, ipu, pdata->dma[1], 397 390 IPU_DP_FLOW_SYNC_FG, 398 391 drm_crtc_mask(&ipu_crtc->base), 399 392 DRM_PLANE_TYPE_OVERLAY); 400 - if (IS_ERR(ipu_crtc->plane[1])) { 393 + if (IS_ERR(ipu_crtc->plane[1])) 401 394 ipu_crtc->plane[1] = NULL; 402 - } else { 403 - ret = ipu_plane_get_resources(ipu_crtc->plane[1]); 404 - if (ret) { 405 - dev_err(ipu_crtc->dev, "getting plane 1 " 406 - "resources failed with %d.\n", ret); 407 - goto err_put_plane0_res; 408 - } 409 - } 410 395 } 411 396 412 397 ipu_crtc->irq = ipu_plane_irq(ipu_crtc->plane[0]); ··· 399 414 "imx_drm", ipu_crtc); 400 415 if (ret < 0) { 401 416 dev_err(ipu_crtc->dev, "irq request failed with %d.\n", ret); 402 - goto err_put_plane1_res; 417 + goto err_put_resources; 403 418 } 404 419 /* Only enable IRQ when we actually need it to trigger work. */ 405 420 disable_irq(ipu_crtc->irq); 406 421 407 422 return 0; 408 423 409 - err_put_plane1_res: 410 - if (ipu_crtc->plane[1]) 411 - ipu_plane_put_resources(ipu_crtc->plane[1]); 412 - err_put_plane0_res: 413 - ipu_plane_put_resources(ipu_crtc->plane[0]); 414 424 err_put_resources: 415 425 ipu_put_resources(ipu_crtc); 416 426 ··· 432 452 struct ipu_crtc *ipu_crtc = dev_get_drvdata(dev); 433 453 434 454 ipu_put_resources(ipu_crtc); 435 - if (ipu_crtc->plane[1]) 436 - ipu_plane_put_resources(ipu_crtc->plane[1]); 437 - ipu_plane_put_resources(ipu_crtc->plane[0]); 438 455 } 439 456 440 457 static const struct component_ops ipu_crtc_ops = {
+34 -35
drivers/gpu/drm/imx/ipuv3-plane.c
··· 11 11 #include <drm/drm_fourcc.h> 12 12 #include <drm/drm_gem_cma_helper.h> 13 13 #include <drm/drm_gem_framebuffer_helper.h> 14 + #include <drm/drm_managed.h> 14 15 #include <drm/drm_plane_helper.h> 15 16 16 17 #include <video/imx-ipu-v3.h> ··· 143 142 fb->format->cpp[2] * x - eba; 144 143 } 145 144 146 - void ipu_plane_put_resources(struct ipu_plane *ipu_plane) 145 + static void ipu_plane_put_resources(struct drm_device *dev, void *ptr) 147 146 { 147 + struct ipu_plane *ipu_plane = ptr; 148 + 148 149 if (!IS_ERR_OR_NULL(ipu_plane->dp)) 149 150 ipu_dp_put(ipu_plane->dp); 150 151 if (!IS_ERR_OR_NULL(ipu_plane->dmfc)) ··· 157 154 ipu_idmac_put(ipu_plane->alpha_ch); 158 155 } 159 156 160 - int ipu_plane_get_resources(struct ipu_plane *ipu_plane) 157 + static int ipu_plane_get_resources(struct drm_device *dev, 158 + struct ipu_plane *ipu_plane) 161 159 { 162 160 int ret; 163 161 int alpha_ch; ··· 169 165 DRM_ERROR("failed to get idmac channel: %d\n", ret); 170 166 return ret; 171 167 } 168 + 169 + ret = drmm_add_action_or_reset(dev, ipu_plane_put_resources, ipu_plane); 170 + if (ret) 171 + return ret; 172 172 173 173 alpha_ch = ipu_channel_alpha_channel(ipu_plane->dma); 174 174 if (alpha_ch >= 0) { ··· 189 181 if (IS_ERR(ipu_plane->dmfc)) { 190 182 ret = PTR_ERR(ipu_plane->dmfc); 191 183 DRM_ERROR("failed to get dmfc: ret %d\n", ret); 192 - goto err_out; 184 + return ret; 193 185 } 194 186 195 187 if (ipu_plane->dp_flow >= 0) { ··· 197 189 if (IS_ERR(ipu_plane->dp)) { 198 190 ret = PTR_ERR(ipu_plane->dp); 199 191 DRM_ERROR("failed to get dp flow: %d\n", ret); 200 - goto err_out; 192 + return ret; 201 193 } 202 194 } 203 195 204 196 return 0; 205 - err_out: 206 - ipu_plane_put_resources(ipu_plane); 207 - 208 - return ret; 209 197 } 210 198 211 199 static bool ipu_plane_separate_alpha(struct ipu_plane *ipu_plane) ··· 265 261 } 266 262 } 267 263 EXPORT_SYMBOL_GPL(ipu_plane_disable_deferred); 268 - 269 - static void ipu_plane_destroy(struct drm_plane *plane) 270 - { 271 - struct ipu_plane *ipu_plane = to_ipu_plane(plane); 272 - 273 - DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); 274 - 275 - drm_plane_cleanup(plane); 276 - kfree(ipu_plane); 277 - } 278 264 279 265 static void ipu_plane_state_reset(struct drm_plane *plane) 280 266 { ··· 330 336 static const struct drm_plane_funcs ipu_plane_funcs = { 331 337 .update_plane = drm_atomic_helper_update_plane, 332 338 .disable_plane = drm_atomic_helper_disable_plane, 333 - .destroy = ipu_plane_destroy, 334 339 .reset = ipu_plane_state_reset, 335 340 .atomic_duplicate_state = ipu_plane_duplicate_state, 336 341 .atomic_destroy_state = ipu_plane_destroy_state, ··· 827 834 DRM_DEBUG_KMS("channel %d, dp flow %d, possible_crtcs=0x%x\n", 828 835 dma, dp, possible_crtcs); 829 836 830 - ipu_plane = kzalloc(sizeof(*ipu_plane), GFP_KERNEL); 831 - if (!ipu_plane) { 832 - DRM_ERROR("failed to allocate plane\n"); 833 - return ERR_PTR(-ENOMEM); 837 + ipu_plane = drmm_universal_plane_alloc(dev, struct ipu_plane, base, 838 + possible_crtcs, &ipu_plane_funcs, 839 + ipu_plane_formats, 840 + ARRAY_SIZE(ipu_plane_formats), 841 + modifiers, type, NULL); 842 + if (IS_ERR(ipu_plane)) { 843 + DRM_ERROR("failed to allocate and initialize %s plane\n", 844 + zpos ? "overlay" : "primary"); 845 + return ipu_plane; 834 846 } 835 847 836 848 ipu_plane->ipu = ipu; ··· 845 847 if (ipu_prg_present(ipu)) 846 848 modifiers = pre_format_modifiers; 847 849 848 - ret = drm_universal_plane_init(dev, &ipu_plane->base, possible_crtcs, 849 - &ipu_plane_funcs, ipu_plane_formats, 850 - ARRAY_SIZE(ipu_plane_formats), 851 - modifiers, type, NULL); 852 - if (ret) { 853 - DRM_ERROR("failed to initialize plane\n"); 854 - kfree(ipu_plane); 855 - return ERR_PTR(ret); 856 - } 857 - 858 850 drm_plane_helper_add(&ipu_plane->base, &ipu_plane_helper_funcs); 859 851 860 852 if (dp == IPU_DP_FLOW_SYNC_BG || dp == IPU_DP_FLOW_SYNC_FG) 861 - drm_plane_create_zpos_property(&ipu_plane->base, zpos, 0, 1); 853 + ret = drm_plane_create_zpos_property(&ipu_plane->base, zpos, 0, 854 + 1); 862 855 else 863 - drm_plane_create_zpos_immutable_property(&ipu_plane->base, 0); 856 + ret = drm_plane_create_zpos_immutable_property(&ipu_plane->base, 857 + 0); 858 + if (ret) 859 + return ERR_PTR(ret); 860 + 861 + ret = ipu_plane_get_resources(dev, ipu_plane); 862 + if (ret) { 863 + DRM_ERROR("failed to get %s plane resources: %pe\n", 864 + zpos ? "overlay" : "primary", &ret); 865 + return ERR_PTR(ret); 866 + } 864 867 865 868 return ipu_plane; 866 869 }
-3
drivers/gpu/drm/imx/ipuv3-plane.h
··· 41 41 uint32_t src_x, uint32_t src_y, uint32_t src_w, 42 42 uint32_t src_h, bool interlaced); 43 43 44 - int ipu_plane_get_resources(struct ipu_plane *plane); 45 - void ipu_plane_put_resources(struct ipu_plane *plane); 46 - 47 44 int ipu_plane_irq(struct ipu_plane *plane); 48 45 49 46 void ipu_plane_disable(struct ipu_plane *ipu_plane, bool disable_dp_channel);