Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2ec77fc9 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 'drm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6: (26 commits)
  drm/radeon: update sarea copies of last_ variables on resume.
  drm/i915: Keep refs on the object over the lifetime of vmas for GTT mmap.
  drm/i915: take struct mutex around fb unref
  drm: Use spread spectrum when the bios tells us it's ok.
  drm: Collapse identical i8xx_clock() and i9xx_clock().
  drm: Bring PLL limits in sync with DDX values.
  drm: Add locking around cursor gem operations.
  drm: Propagate failure from setting crtc base.
  drm: Check for a NULL encoder when reverting on error path
  drm/i915: Cleanup the hws on ringbuffer constrution failure.
  drm/i915: Don't add panel_fixed_mode to the probed modes list at LVDS init.
  drm: Release user fbs in drm_release
  drm/i915: Unpin the fb on error during construction.
  drm/i915: Unpin the hws if we fail to kmap.
  drm/i915: Unpin the ringbuffer if we fail to ioremap it.
  drm/i915: unpin for an invalid memory domain.
  drm/i915: Release and unlock on mmap_gtt error path.
  drm/i915: Set framebuffer alignment based upon the fence constraints.
  drm: Do not leak a new reference for flink() on an existing name
  drm/i915: Fix potential AB-BA deadlock in i915_gem_execbuffer()
  ...
parents be71cb5b 3d16118d
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -1741,9 +1741,8 @@ int drm_mode_getfb(struct drm_device *dev,
 * RETURNS:
 * Zero on success, errno on failure.
 */
void drm_fb_release(struct file *filp)
void drm_fb_release(struct drm_file *priv)
{
	struct drm_file *priv = filp->private_data;
	struct drm_device *dev = priv->minor->dev;
	struct drm_framebuffer *fb, *tfb;

+16 −5
Original line number Diff line number Diff line
@@ -512,7 +512,7 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
	if (drm_mode_equal(&saved_mode, &crtc->mode)) {
		if (saved_x != crtc->x || saved_y != crtc->y ||
		    depth_changed || bpp_changed) {
			crtc_funcs->mode_set_base(crtc, crtc->x, crtc->y,
			ret = !crtc_funcs->mode_set_base(crtc, crtc->x, crtc->y,
							 old_fb);
			goto done;
		}
@@ -552,7 +552,9 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
	/* Set up the DPLL and any encoders state that needs to adjust or depend
	 * on the DPLL.
	 */
	crtc_funcs->mode_set(crtc, mode, adjusted_mode, x, y, old_fb);
	ret = !crtc_funcs->mode_set(crtc, mode, adjusted_mode, x, y, old_fb);
	if (!ret)
	    goto done;

	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {

@@ -752,6 +754,8 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
			if (!drm_crtc_helper_set_mode(set->crtc, set->mode,
						      set->x, set->y,
						      old_fb)) {
				DRM_ERROR("failed to set mode on crtc %p\n",
					  set->crtc);
				ret = -EINVAL;
				goto fail_set_mode;
			}
@@ -765,7 +769,10 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
		old_fb = set->crtc->fb;
		if (set->crtc->fb != set->fb)
			set->crtc->fb = set->fb;
		crtc_funcs->mode_set_base(set->crtc, set->x, set->y, old_fb);
		ret = crtc_funcs->mode_set_base(set->crtc,
						set->x, set->y, old_fb);
		if (ret != 0)
		    goto fail_set_mode;
	}

	kfree(save_encoders);
@@ -775,8 +782,12 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
fail_set_mode:
	set->crtc->enabled = save_enabled;
	count = 0;
	list_for_each_entry(connector, &dev->mode_config.connector_list, head)
	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
		if (!connector->encoder)
			continue;

		connector->encoder->crtc = save_crtcs[count++];
	}
fail_no_encoder:
	kfree(save_crtcs);
	count = 0;
+3 −0
Original line number Diff line number Diff line
@@ -457,6 +457,9 @@ int drm_release(struct inode *inode, struct file *filp)
	if (dev->driver->driver_features & DRIVER_GEM)
		drm_gem_release(dev, file_priv);

	if (dev->driver->driver_features & DRIVER_MODESET)
		drm_fb_release(file_priv);

	mutex_lock(&dev->ctxlist_mutex);
	if (!list_empty(&dev->ctxlist)) {
		struct drm_ctx_list *pos, *n;
+55 −24
Original line number Diff line number Diff line
@@ -104,8 +104,8 @@ drm_gem_init(struct drm_device *dev)

	if (drm_mm_init(&mm->offset_manager, DRM_FILE_PAGE_OFFSET_START,
			DRM_FILE_PAGE_OFFSET_SIZE)) {
		drm_free(mm, sizeof(struct drm_gem_mm), DRM_MEM_MM);
		drm_ht_remove(&mm->offset_hash);
		drm_free(mm, sizeof(struct drm_gem_mm), DRM_MEM_MM);
		return -ENOMEM;
	}

@@ -295,37 +295,39 @@ drm_gem_flink_ioctl(struct drm_device *dev, void *data,
		return -EBADF;

again:
	if (idr_pre_get(&dev->object_name_idr, GFP_KERNEL) == 0)
		return -ENOMEM;
	if (idr_pre_get(&dev->object_name_idr, GFP_KERNEL) == 0) {
		ret = -ENOMEM;
		goto err;
	}

	spin_lock(&dev->object_name_lock);
	if (obj->name) {
		args->name = obj->name;
		spin_unlock(&dev->object_name_lock);
		return 0;
	}
	if (!obj->name) {
		ret = idr_get_new_above(&dev->object_name_idr, obj, 1,
					&obj->name);
		args->name = (uint64_t) obj->name;
		spin_unlock(&dev->object_name_lock);

		if (ret == -EAGAIN)
			goto again;

	if (ret != 0) {
		if (ret != 0)
			goto err;

		/* Allocate a reference for the name table.  */
		drm_gem_object_reference(obj);
	} else {
		args->name = (uint64_t) obj->name;
		spin_unlock(&dev->object_name_lock);
		ret = 0;
	}

err:
	mutex_lock(&dev->struct_mutex);
	drm_gem_object_unreference(obj);
	mutex_unlock(&dev->struct_mutex);
	return ret;
}

	/*
	 * Leave the reference from the lookup around as the
	 * name table now holds one
	 */
	args->name = (uint64_t) obj->name;

	return 0;
}

/**
 * Open an object using the global name, returning a handle and the size.
 *
@@ -448,6 +450,7 @@ drm_gem_object_handle_free(struct kref *kref)
	spin_lock(&dev->object_name_lock);
	if (obj->name) {
		idr_remove(&dev->object_name_idr, obj->name);
		obj->name = 0;
		spin_unlock(&dev->object_name_lock);
		/*
		 * The object name held a reference to this object, drop
@@ -460,6 +463,26 @@ drm_gem_object_handle_free(struct kref *kref)
}
EXPORT_SYMBOL(drm_gem_object_handle_free);

void drm_gem_vm_open(struct vm_area_struct *vma)
{
	struct drm_gem_object *obj = vma->vm_private_data;

	drm_gem_object_reference(obj);
}
EXPORT_SYMBOL(drm_gem_vm_open);

void drm_gem_vm_close(struct vm_area_struct *vma)
{
	struct drm_gem_object *obj = vma->vm_private_data;
	struct drm_device *dev = obj->dev;

	mutex_lock(&dev->struct_mutex);
	drm_gem_object_unreference(obj);
	mutex_unlock(&dev->struct_mutex);
}
EXPORT_SYMBOL(drm_gem_vm_close);


/**
 * drm_gem_mmap - memory map routine for GEM objects
 * @filp: DRM file pointer
@@ -521,6 +544,14 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
#endif
	vma->vm_page_prot = __pgprot(prot);

	/* Take a ref for this mapping of the object, so that the fault
	 * handler can dereference the mmap offset's pointer to the object.
	 * This reference is cleaned up by the corresponding vm_close
	 * (which should happen whether the vma was created by this call, or
	 * by a vm_open due to mremap or partial unmap or whatever).
	 */
	drm_gem_object_reference(obj);

	vma->vm_file = filp;	/* Needed for drm_vm_open() */
	drm_vm_open_locked(vma);

+2 −0
Original line number Diff line number Diff line
@@ -94,6 +94,8 @@ static int i915_resume(struct drm_device *dev)

static struct vm_operations_struct i915_gem_vm_ops = {
	.fault = i915_gem_fault,
	.open = drm_gem_vm_open,
	.close = drm_gem_vm_close,
};

static struct drm_driver driver = {
Loading