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>
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);
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;
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;
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;
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*/
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;
/* 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)
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);