aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2009-02-11 09:52:44 -0500
committerDave Airlie <airlied@redhat.com>2009-02-19 21:21:12 -0500
commit85a7bb98582b60b7e9130159d2464eb0bbac13f7 (patch)
tree74b0e5ec3ea7d6993b2db11b522932c379e185af /drivers/gpu
parent67eabc0553a32c491fdb392ff2358a0384562050 (diff)
drm/i915: Cleanup the hws on ringbuffer constrution failure.
If we fail to create the ringbuffer, then we need to cleanup the allocated hws. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Eric Anholt <eric@anholt.net> Signed-off-by: Dave Airlie <airlied@linux.ie>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c39
1 files changed, 25 insertions, 14 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index fd4b4e268a22..078858178832 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -3119,6 +3119,27 @@ i915_gem_init_hws(struct drm_device *dev)
3119 return 0; 3119 return 0;
3120} 3120}
3121 3121
3122static void
3123i915_gem_cleanup_hws(struct drm_device *dev)
3124{
3125 drm_i915_private_t *dev_priv = dev->dev_private;
3126 struct drm_gem_object *obj = dev_priv->hws_obj;
3127 struct drm_i915_gem_object *obj_priv = obj->driver_private;
3128
3129 if (dev_priv->hws_obj == NULL)
3130 return;
3131
3132 kunmap(obj_priv->page_list[0]);
3133 i915_gem_object_unpin(obj);
3134 drm_gem_object_unreference(obj);
3135 dev_priv->hws_obj = NULL;
3136 memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map));
3137 dev_priv->hw_status_page = NULL;
3138
3139 /* Write high address into HWS_PGA when disabling. */
3140 I915_WRITE(HWS_PGA, 0x1ffff000);
3141}
3142
3122int 3143int
3123i915_gem_init_ringbuffer(struct drm_device *dev) 3144i915_gem_init_ringbuffer(struct drm_device *dev)
3124{ 3145{
@@ -3136,6 +3157,7 @@ i915_gem_init_ringbuffer(struct drm_device *dev)
3136 obj = drm_gem_object_alloc(dev, 128 * 1024); 3157 obj = drm_gem_object_alloc(dev, 128 * 1024);
3137 if (obj == NULL) { 3158 if (obj == NULL) {
3138 DRM_ERROR("Failed to allocate ringbuffer\n"); 3159 DRM_ERROR("Failed to allocate ringbuffer\n");
3160 i915_gem_cleanup_hws(dev);
3139 return -ENOMEM; 3161 return -ENOMEM;
3140 } 3162 }
3141 obj_priv = obj->driver_private; 3163 obj_priv = obj->driver_private;
@@ -3143,6 +3165,7 @@ i915_gem_init_ringbuffer(struct drm_device *dev)
3143 ret = i915_gem_object_pin(obj, 4096); 3165 ret = i915_gem_object_pin(obj, 4096);
3144 if (ret != 0) { 3166 if (ret != 0) {
3145 drm_gem_object_unreference(obj); 3167 drm_gem_object_unreference(obj);
3168 i915_gem_cleanup_hws(dev);
3146 return ret; 3169 return ret;
3147 } 3170 }
3148 3171
@@ -3162,6 +3185,7 @@ i915_gem_init_ringbuffer(struct drm_device *dev)
3162 memset(&dev_priv->ring, 0, sizeof(dev_priv->ring)); 3185 memset(&dev_priv->ring, 0, sizeof(dev_priv->ring));
3163 i915_gem_object_unpin(obj); 3186 i915_gem_object_unpin(obj);
3164 drm_gem_object_unreference(obj); 3187 drm_gem_object_unreference(obj);
3188 i915_gem_cleanup_hws(dev);
3165 return -EINVAL; 3189 return -EINVAL;
3166 } 3190 }
3167 ring->ring_obj = obj; 3191 ring->ring_obj = obj;
@@ -3241,20 +3265,7 @@ i915_gem_cleanup_ringbuffer(struct drm_device *dev)
3241 dev_priv->ring.ring_obj = NULL; 3265 dev_priv->ring.ring_obj = NULL;
3242 memset(&dev_priv->ring, 0, sizeof(dev_priv->ring)); 3266 memset(&dev_priv->ring, 0, sizeof(dev_priv->ring));
3243 3267
3244 if (dev_priv->hws_obj != NULL) { 3268 i915_gem_cleanup_hws(dev);
3245 struct drm_gem_object *obj = dev_priv->hws_obj;
3246 struct drm_i915_gem_object *obj_priv = obj->driver_private;
3247
3248 kunmap(obj_priv->page_list[0]);
3249 i915_gem_object_unpin(obj);
3250 drm_gem_object_unreference(obj);
3251 dev_priv->hws_obj = NULL;
3252 memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map));
3253 dev_priv->hw_status_page = NULL;
3254
3255 /* Write high address into HWS_PGA when disabling. */
3256 I915_WRITE(HWS_PGA, 0x1ffff000);
3257 }
3258} 3269}
3259 3270
3260int 3271int