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

Commit c5939a73 authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'topic/core-stuff-2014-09-29' of git://anongit.freedesktop.org/drm-intel into drm-next

Ok, here's the update core-stuff pull request with the locking fixup patch
fixed up with another patch.

* tag 'topic/core-stuff-2014-09-29' of git://anongit.freedesktop.org/drm-intel:
  drm: Drop grab fpriv->fbs_lock in drm_fb_release
  drm/udl: use container_of to resolve udl_fbdev from drm_fb_helper
  drm/ast: use container_of to resolve ast_fbdev from drm_fb_helper
  drm/gma500: use container_of to resolve psb_fbdev from drm_fb_helper
  drm/qxl: use container_of to resolve qxl_fbdev from drm_fb_helper
  drm/nouveau: use container_of to resolve nouveau_plane from drm_plane
  drm/nouveau: use container_of to resolve nouveau_fbdev from drm_fb_helper
  drm/radeon: use container_of to resolve radeon_fbdev from drm_fb_helper
  drm/mgag200: use container_of to resolve mga_fbdev from drm_fb_helper
  drm/cirrus: use container_of to resolve cirrus_fbdev from drm_fb_helper
  drm: Improve debug output for drm_wait_one_vblank
  drm: Fixup locking for universal cursor planes
  drm: Don't update vblank timestamp when the counter didn't change
parents 1dadba87 1b116297
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -186,7 +186,8 @@ static int astfb_create_object(struct ast_fbdev *afbdev,
static int astfb_create(struct drm_fb_helper *helper,
			struct drm_fb_helper_surface_size *sizes)
{
	struct ast_fbdev *afbdev = (struct ast_fbdev *)helper;
	struct ast_fbdev *afbdev =
		container_of(helper, struct ast_fbdev, helper);
	struct drm_device *dev = afbdev->helper.dev;
	struct drm_mode_fb_cmd2 mode_cmd;
	struct drm_framebuffer *fb;
+2 −1
Original line number Diff line number Diff line
@@ -160,7 +160,8 @@ static int cirrusfb_create_object(struct cirrus_fbdev *afbdev,
static int cirrusfb_create(struct drm_fb_helper *helper,
			   struct drm_fb_helper_surface_size *sizes)
{
	struct cirrus_fbdev *gfbdev = (struct cirrus_fbdev *)helper;
	struct cirrus_fbdev *gfbdev =
		container_of(helper, struct cirrus_fbdev, helper);
	struct drm_device *dev = gfbdev->helper.dev;
	struct cirrus_device *cdev = gfbdev->helper.dev->dev_private;
	struct fb_info *info;
+44 −19
Original line number Diff line number Diff line
@@ -2263,7 +2263,7 @@ int drm_mode_getplane(struct drm_device *dev, void *data,
 *
 * src_{x,y,w,h} are provided in 16.16 fixed point format
 */
static int setplane_internal(struct drm_plane *plane,
static int __setplane_internal(struct drm_plane *plane,
			       struct drm_crtc *crtc,
			       struct drm_framebuffer *fb,
			       int32_t crtc_x, int32_t crtc_y,
@@ -2272,12 +2272,10 @@ static int setplane_internal(struct drm_plane *plane,
			       uint32_t src_x, uint32_t src_y,
			       uint32_t src_w, uint32_t src_h)
{
	struct drm_device *dev = plane->dev;
	int ret = 0;
	unsigned int fb_width, fb_height;
	int i;

	drm_modeset_lock_all(dev);
	/* No fb means shut it down */
	if (!fb) {
		plane->old_fb = plane->fb;
@@ -2345,10 +2343,28 @@ static int setplane_internal(struct drm_plane *plane,
	if (plane->old_fb)
		drm_framebuffer_unreference(plane->old_fb);
	plane->old_fb = NULL;
	drm_modeset_unlock_all(dev);

	return ret;
}

static int setplane_internal(struct drm_plane *plane,
			     struct drm_crtc *crtc,
			     struct drm_framebuffer *fb,
			     int32_t crtc_x, int32_t crtc_y,
			     uint32_t crtc_w, uint32_t crtc_h,
			     /* src_{x,y,w,h} values are 16.16 fixed point */
			     uint32_t src_x, uint32_t src_y,
			     uint32_t src_w, uint32_t src_h)
{
	int ret;

	drm_modeset_lock_all(plane->dev);
	ret = __setplane_internal(plane, crtc, fb,
				  crtc_x, crtc_y, crtc_w, crtc_h,
				  src_x, src_y, src_w, src_h);
	drm_modeset_unlock_all(plane->dev);

	return ret;
}

/**
@@ -2714,6 +2730,7 @@ static int drm_mode_cursor_universal(struct drm_crtc *crtc,
	int ret = 0;

	BUG_ON(!crtc->cursor);
	WARN_ON(crtc->cursor->crtc != crtc && crtc->cursor->crtc != NULL);

	/*
	 * Obtain fb we'll be using (either new or existing) and take an extra
@@ -2733,11 +2750,9 @@ static int drm_mode_cursor_universal(struct drm_crtc *crtc,
			fb = NULL;
		}
	} else {
		mutex_lock(&dev->mode_config.mutex);
		fb = crtc->cursor->fb;
		if (fb)
			drm_framebuffer_reference(fb);
		mutex_unlock(&dev->mode_config.mutex);
	}

	if (req->flags & DRM_MODE_CURSOR_MOVE) {
@@ -2759,7 +2774,7 @@ static int drm_mode_cursor_universal(struct drm_crtc *crtc,
	 * setplane_internal will take care of deref'ing either the old or new
	 * framebuffer depending on success.
	 */
	ret = setplane_internal(crtc->cursor, crtc, fb,
	ret = __setplane_internal(crtc->cursor, crtc, fb,
				crtc_x, crtc_y, crtc_w, crtc_h,
				0, 0, src_w, src_h);

@@ -2795,10 +2810,12 @@ static int drm_mode_cursor_common(struct drm_device *dev,
	 * If this crtc has a universal cursor plane, call that plane's update
	 * handler rather than using legacy cursor handlers.
	 */
	if (crtc->cursor)
		return drm_mode_cursor_universal(crtc, req, file_priv);

	drm_modeset_lock_crtc(crtc);
	if (crtc->cursor) {
		ret = drm_mode_cursor_universal(crtc, req, file_priv);
		goto out;
	}

	if (req->flags & DRM_MODE_CURSOR_BO) {
		if (!crtc->funcs->cursor_set && !crtc->funcs->cursor_set2) {
			ret = -ENXIO;
@@ -3383,7 +3400,16 @@ void drm_fb_release(struct drm_file *priv)
	struct drm_device *dev = priv->minor->dev;
	struct drm_framebuffer *fb, *tfb;

	mutex_lock(&priv->fbs_lock);
	/*
	 * When the file gets released that means no one else can access the fb
	 * list any more, so no need to grab fpriv->fbs_lock. And we need to to
	 * avoid upsetting lockdep since the universal cursor code adds a
	 * framebuffer while holding mutex locks.
	 *
	 * Note that a real deadlock between fpriv->fbs_lock and the modeset
	 * locks is impossible here since no one else but this function can get
	 * at it any more.
	 */
	list_for_each_entry_safe(fb, tfb, &priv->fbs, filp_head) {

		mutex_lock(&dev->mode_config.fb_lock);
@@ -3396,7 +3422,6 @@ void drm_fb_release(struct drm_file *priv)
		/* This will also drop the fpriv->fbs reference. */
		drm_framebuffer_remove(fb);
	}
	mutex_unlock(&priv->fbs_lock);
}

/**
+5 −2
Original line number Diff line number Diff line
@@ -126,6 +126,9 @@ static void drm_update_vblank_count(struct drm_device *dev, int crtc)
	DRM_DEBUG("updating vblank count on crtc %d, missed %d\n",
		  crtc, diff);

	if (diff == 0)
		return;

	/* Reinitialize corresponding vblank timestamp if high-precision query
	 * available. Skip this step if query unsupported or failed. Will
	 * reinitialize delayed at next vblank interrupt in that case.
@@ -1074,7 +1077,7 @@ void drm_wait_one_vblank(struct drm_device *dev, int crtc)
	u32 last;

	ret = drm_vblank_get(dev, crtc);
	if (WARN_ON(ret))
	if (WARN(ret, "vblank not available on crtc %i, ret=%i\n", crtc, ret))
		return;

	last = drm_vblank_count(dev, crtc);
@@ -1083,7 +1086,7 @@ void drm_wait_one_vblank(struct drm_device *dev, int crtc)
				 last != drm_vblank_count(dev, crtc),
				 msecs_to_jiffies(100));

	WARN_ON(ret == 0);
	WARN(ret == 0, "vblank wait timed out on crtc %i\n", crtc);

	drm_vblank_put(dev, crtc);
}
+2 −1
Original line number Diff line number Diff line
@@ -540,7 +540,8 @@ static void psbfb_gamma_get(struct drm_crtc *crtc, u16 *red,
static int psbfb_probe(struct drm_fb_helper *helper,
				struct drm_fb_helper_surface_size *sizes)
{
	struct psb_fbdev *psb_fbdev = (struct psb_fbdev *)helper;
	struct psb_fbdev *psb_fbdev =
		container_of(helper, struct psb_fbdev, psb_fb_helper);
	struct drm_device *dev = psb_fbdev->psb_fb_helper.dev;
	struct drm_psb_private *dev_priv = dev->dev_private;
	int bytespp;
Loading