Skip to content

Commit

Permalink
Merge branch 'drm-fixes' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/airlied/drm-2.6

* '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()
  ...
  • Loading branch information
torvalds committed Feb 21, 2009
2 parents be71cb5 + 3d16118 commit 2ec77fc
Show file tree
Hide file tree
Showing 18 changed files with 279 additions and 173 deletions.
3 changes: 1 addition & 2 deletions drivers/gpu/drm/drm_crtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
21 changes: 16 additions & 5 deletions drivers/gpu/drm/drm_crtc_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -512,8 +512,8 @@ 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,
old_fb);
ret = !crtc_funcs->mode_set_base(crtc, crtc->x, crtc->y,
old_fb);
goto done;
}
}
Expand Down Expand Up @@ -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) {

Expand Down Expand Up @@ -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;
}
Expand All @@ -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);
Expand All @@ -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;
Expand Down
3 changes: 3 additions & 0 deletions drivers/gpu/drm/drm_fops.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
79 changes: 55 additions & 24 deletions drivers/gpu/drm/drm_gem.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down Expand Up @@ -295,35 +295,37 @@ 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;
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);
return 0;
}
ret = idr_get_new_above(&dev->object_name_idr, obj, 1,
&obj->name);
spin_unlock(&dev->object_name_lock);
if (ret == -EAGAIN)
goto again;

if (ret != 0) {
mutex_lock(&dev->struct_mutex);
drm_gem_object_unreference(obj);
mutex_unlock(&dev->struct_mutex);
return ret;
}
if (ret == -EAGAIN)
goto again;

/*
* Leave the reference from the lookup around as the
* name table now holds one
*/
args->name = (uint64_t) obj->name;
if (ret != 0)
goto err;

return 0;
/* 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;
}

/**
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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);

Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/i915/i915_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/i915/i915_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,8 @@ typedef struct drm_i915_private {
unsigned int lvds_dither:1;
unsigned int lvds_vbt:1;
unsigned int int_crt_support:1;
unsigned int lvds_use_ssc:1;
int lvds_ssc_freq;

struct drm_i915_fence_reg fence_regs[16]; /* assume 965 */
int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */
Expand Down
Loading

0 comments on commit 2ec77fc

Please sign in to comment.