aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorPatrik Jakobsson <patrik.r.jakobsson@gmail.com>2013-05-26 11:56:19 -0400
committerPatrik Jakobsson <patrik.r.jakobsson@gmail.com>2013-06-09 12:03:32 -0400
commit3463cf1aad48ef43dd0b4cbd7fed15dcc8d2ca53 (patch)
tree32073abf1d0aac112c3d730e9d44e78fe430929f /drivers/gpu
parent22e7c385a80d771aaf3a15ae7ccea3b0686bbe10 (diff)
drm/gma500/psb: Fix cursor gem obj referencing on psb
The internal crtc cursor gem object pointer was never set/updated since it was required to be set in the first place. Fixing this will make the pin/unpin count match and prevent cursor objects from leaking when userspace drops all references to it. Also make sure we drop the gem obj reference on failure. This patch only affects Poulsbo chips. Signed-off-by: Patrik Jakobsson <patrik.r.jakobsson@gmail.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/gma500/psb_intel_display.c19
1 files changed, 13 insertions, 6 deletions
diff --git a/drivers/gpu/drm/gma500/psb_intel_display.c b/drivers/gpu/drm/gma500/psb_intel_display.c
index 12d129ef21a9..6666493789d1 100644
--- a/drivers/gpu/drm/gma500/psb_intel_display.c
+++ b/drivers/gpu/drm/gma500/psb_intel_display.c
@@ -843,7 +843,7 @@ static int psb_intel_crtc_cursor_set(struct drm_crtc *crtc,
843 struct gtt_range *cursor_gt = psb_intel_crtc->cursor_gt; 843 struct gtt_range *cursor_gt = psb_intel_crtc->cursor_gt;
844 struct drm_gem_object *obj; 844 struct drm_gem_object *obj;
845 void *tmp_dst, *tmp_src; 845 void *tmp_dst, *tmp_src;
846 int ret, i, cursor_pages; 846 int ret = 0, i, cursor_pages;
847 847
848 /* if we want to turn of the cursor ignore width and height */ 848 /* if we want to turn of the cursor ignore width and height */
849 if (!handle) { 849 if (!handle) {
@@ -880,7 +880,8 @@ static int psb_intel_crtc_cursor_set(struct drm_crtc *crtc,
880 880
881 if (obj->size < width * height * 4) { 881 if (obj->size < width * height * 4) {
882 dev_dbg(dev->dev, "buffer is to small\n"); 882 dev_dbg(dev->dev, "buffer is to small\n");
883 return -ENOMEM; 883 ret = -ENOMEM;
884 goto unref_cursor;
884 } 885 }
885 886
886 gt = container_of(obj, struct gtt_range, gem); 887 gt = container_of(obj, struct gtt_range, gem);
@@ -889,13 +890,14 @@ static int psb_intel_crtc_cursor_set(struct drm_crtc *crtc,
889 ret = psb_gtt_pin(gt); 890 ret = psb_gtt_pin(gt);
890 if (ret) { 891 if (ret) {
891 dev_err(dev->dev, "Can not pin down handle 0x%x\n", handle); 892 dev_err(dev->dev, "Can not pin down handle 0x%x\n", handle);
892 return ret; 893 goto unref_cursor;
893 } 894 }
894 895
895 if (dev_priv->ops->cursor_needs_phys) { 896 if (dev_priv->ops->cursor_needs_phys) {
896 if (cursor_gt == NULL) { 897 if (cursor_gt == NULL) {
897 dev_err(dev->dev, "No hardware cursor mem available"); 898 dev_err(dev->dev, "No hardware cursor mem available");
898 return -ENOMEM; 899 ret = -ENOMEM;
900 goto unref_cursor;
899 } 901 }
900 902
901 /* Prevent overflow */ 903 /* Prevent overflow */
@@ -936,9 +938,14 @@ static int psb_intel_crtc_cursor_set(struct drm_crtc *crtc,
936 struct gtt_range, gem); 938 struct gtt_range, gem);
937 psb_gtt_unpin(gt); 939 psb_gtt_unpin(gt);
938 drm_gem_object_unreference(psb_intel_crtc->cursor_obj); 940 drm_gem_object_unreference(psb_intel_crtc->cursor_obj);
939 psb_intel_crtc->cursor_obj = obj;
940 } 941 }
941 return 0; 942
943 psb_intel_crtc->cursor_obj = obj;
944 return ret;
945
946unref_cursor:
947 drm_gem_object_unreference(obj);
948 return ret;
942} 949}
943 950
944static int psb_intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) 951static int psb_intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)