gfx: drv: Reference count cursor BOs
authorVille Syrjälä <ville.syrjala@linux.intel.com>
Wed, 15 Feb 2012 13:02:50 +0000 (15:02 +0200)
committerMarkus Lehtonen <markus.lehtonen@linux.intel.com>
Tue, 3 Jul 2012 09:30:06 +0000 (12:30 +0300)
Refrence count cursor BOs the same way as FB BOs.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Imre Deak <imre.deak@intel.com>
Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
drivers/staging/mrst/drv/psb_fb.c
drivers/staging/mrst/drv/psb_intel_display.c
drivers/staging/mrst/drv/psb_intel_drv.h

index 02fb056..c501a80 100644 (file)
@@ -722,7 +722,17 @@ static void *psb_bo_from_handle(struct drm_device *dev,
        IMG_HANDLE hKernelMemInfo = (IMG_HANDLE)handle;
        int ret;
 
+       mutex_lock(&gPVRSRVLock);
+
        ret = psb_get_meminfo_by_handle(hKernelMemInfo, &psKernelMemInfo);
+
+       if (!ret) {
+               psKernelMemInfo = PVRSRVGetSrcMemInfo(psKernelMemInfo);
+               ret = psb_fb_ref_locked(psKernelMemInfo);
+       }
+
+       mutex_unlock(&gPVRSRVLock);
+
        if (ret) {
                DRM_ERROR("Cannot get meminfo for handle 0x%x\n",
                          (IMG_UINT32)hKernelMemInfo);
@@ -732,6 +742,13 @@ static void *psb_bo_from_handle(struct drm_device *dev,
        return (void *)psKernelMemInfo;
 }
 
+static void psb_bo_unref(struct drm_device *dev, void *bof)
+{
+       PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo = (PVRSRV_KERNEL_MEM_INFO *)bof;
+
+       psb_fb_unref(psKernelMemInfo, psb_get_tgid());
+}
+
 static size_t psb_bo_size(struct drm_device *dev, void *bof)
 {
        PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo = (PVRSRV_KERNEL_MEM_INFO *)bof;
@@ -766,6 +783,7 @@ void psb_modeset_init(struct drm_device *dev)
        PSB_DEBUG_ENTRY("\n");
        /* Init mm functions */
        mode_dev->bo_from_handle = psb_bo_from_handle;
+       mode_dev->bo_unref = psb_bo_unref;
        mode_dev->bo_size = psb_bo_size;
        mode_dev->bo_offset = psb_bo_offset;
        mode_dev->bo_pin_for_scanout = psb_bo_pin_for_scanout;
index 88717bd..3424f7a 100644 (file)
@@ -709,6 +709,7 @@ static int mdfld_intel_crtc_cursor_set(struct drm_crtc *crtc,
                        mode_dev->bo_unpin_for_scanout(dev,
                                                       psb_intel_crtc->
                                                       cursor_bo);
+                       mode_dev->bo_unref(dev, psb_intel_crtc->cursor_bo);
                        psb_intel_crtc->cursor_bo = NULL;
                }
                return 0;
@@ -726,11 +727,12 @@ static int mdfld_intel_crtc_cursor_set(struct drm_crtc *crtc,
 
        ret = mode_dev->bo_pin_for_scanout(dev, bo);
        if (ret)
-               return ret;
+               goto unref_bo;
        size = mode_dev->bo_size(dev, bo);
        if (size < width * height * 4) {
                DRM_ERROR("buffer is to small\n");
-               return -ENOMEM;
+               ret = -ENOMEM;
+               goto unpin_bo;
        }
 
         /*insert this bo into gtt*/
@@ -739,7 +741,7 @@ static int mdfld_intel_crtc_cursor_set(struct drm_crtc *crtc,
        ret = psb_gtt_map_meminfo(dev, bo, &page_offset);
         if(ret) {
                 DRM_ERROR("Can not map meminfo to GTT. handle 0x%x\n", handle);
-                return ret;
+               goto unpin_bo;
         }
 
        addr = page_offset << PAGE_SHIFT;
@@ -760,10 +762,18 @@ static int mdfld_intel_crtc_cursor_set(struct drm_crtc *crtc,
        /* unpin the old bo */
        if (psb_intel_crtc->cursor_bo && psb_intel_crtc->cursor_bo != bo) {
                mode_dev->bo_unpin_for_scanout(dev, psb_intel_crtc->cursor_bo);
+               mode_dev->bo_unref(dev, psb_intel_crtc->cursor_bo);
                psb_intel_crtc->cursor_bo = bo;
        }
 
        return 0;
+
+ unpin_bo:
+       mode_dev->bo_unpin_for_scanout(dev, bo);
+ unref_bo:
+       mode_dev->bo_unref(dev, bo);
+ out:
+       return ret;
 }
 
 static int mdfld_intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
index 306fc67..6bbb914 100644 (file)
@@ -106,6 +106,7 @@ struct psb_intel_mode_device {
        void *(*bo_from_handle) (struct drm_device *dev,
                                 struct drm_file *file_priv,
                                 unsigned int handle);
+       void (*bo_unref) (struct drm_device *dev, void *bo);
         size_t(*bo_size) (struct drm_device *dev, void *bo);
         size_t(*bo_offset) (struct drm_device *dev, void *bo);
        int (*bo_pin_for_scanout) (struct drm_device *dev, void *bo);