Merge tag 'topic/core-stuff-2014-08-15' of git://anongit.freedesktop.org/drm-intel into drm-next
So small drm stuff all over for 3.18. Biggest one is the cmdline parsing from Chris with a few fixes from me to make it work for stupid kernel configs. Plus the atomic prep series. Tested for more than a week in -nightly and Ville/Imre indeed discovered some fun which is now fixed (and i915 vblank patches postponed since the fixups need this branch plus drm-intel-next merged together). * tag 'topic/core-stuff-2014-08-15' of git://anongit.freedesktop.org/drm-intel: drm: Use the type of the array element when reallocating drm: Don't return 0 for a value used as a denominator drm: Docbook fixes drm/irq: Implement a generic vblank_wait function drm: Add a plane->reset hook drm: trylock modest locking for fbdev panics drm: Move ->old_fb from crtc to plane drm: Handle legacy per-crtc locking with full acquire ctx drm: Move modeset_lock_all helpers to drm_modeset_lock.[hc] drm: Add drm_plane/connector_index drm: idiot-proof vblank drm: Warn when leaking flip events on close drm: Perform cmdline mode parsing during connector initialisation video/fbdev: Always built-in video= cmdline parsing drm: Don't grab an fb reference for the idr
This commit is contained in:
@@ -720,6 +720,8 @@ EXPORT_SYMBOL(drm_get_last_vbltimestamp);
|
||||
*/
|
||||
u32 drm_vblank_count(struct drm_device *dev, int crtc)
|
||||
{
|
||||
if (WARN_ON(crtc >= dev->num_crtcs))
|
||||
return 0;
|
||||
return atomic_read(&dev->vblank[crtc].count);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_vblank_count);
|
||||
@@ -742,6 +744,9 @@ u32 drm_vblank_count_and_time(struct drm_device *dev, int crtc,
|
||||
{
|
||||
u32 cur_vblank;
|
||||
|
||||
if (WARN_ON(crtc >= dev->num_crtcs))
|
||||
return 0;
|
||||
|
||||
/* Read timestamp from slot of _vblank_time ringbuffer
|
||||
* that corresponds to current vblank count. Retry if
|
||||
* count has incremented during readout. This works like
|
||||
@@ -917,6 +922,9 @@ int drm_vblank_get(struct drm_device *dev, int crtc)
|
||||
unsigned long irqflags;
|
||||
int ret = 0;
|
||||
|
||||
if (WARN_ON(crtc >= dev->num_crtcs))
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock_irqsave(&dev->vbl_lock, irqflags);
|
||||
/* Going from 0->1 means we have to enable interrupts again */
|
||||
if (atomic_add_return(1, &dev->vblank[crtc].refcount) == 1) {
|
||||
@@ -965,6 +973,9 @@ void drm_vblank_put(struct drm_device *dev, int crtc)
|
||||
{
|
||||
BUG_ON(atomic_read(&dev->vblank[crtc].refcount) == 0);
|
||||
|
||||
if (WARN_ON(crtc >= dev->num_crtcs))
|
||||
return;
|
||||
|
||||
/* Last user schedules interrupt disable */
|
||||
if (atomic_dec_and_test(&dev->vblank[crtc].refcount) &&
|
||||
(drm_vblank_offdelay > 0))
|
||||
@@ -988,6 +999,50 @@ void drm_crtc_vblank_put(struct drm_crtc *crtc)
|
||||
}
|
||||
EXPORT_SYMBOL(drm_crtc_vblank_put);
|
||||
|
||||
/**
|
||||
* drm_wait_one_vblank - wait for one vblank
|
||||
* @dev: DRM device
|
||||
* @crtc: crtc index
|
||||
*
|
||||
* This waits for one vblank to pass on @crtc, using the irq driver interfaces.
|
||||
* It is a failure to call this when the vblank irq for @crtc is disabled, e.g.
|
||||
* due to lack of driver support or because the crtc is off.
|
||||
*/
|
||||
void drm_wait_one_vblank(struct drm_device *dev, int crtc)
|
||||
{
|
||||
int ret;
|
||||
u32 last;
|
||||
|
||||
ret = drm_vblank_get(dev, crtc);
|
||||
if (WARN_ON(ret))
|
||||
return;
|
||||
|
||||
last = drm_vblank_count(dev, crtc);
|
||||
|
||||
ret = wait_event_timeout(dev->vblank[crtc].queue,
|
||||
last != drm_vblank_count(dev, crtc),
|
||||
msecs_to_jiffies(100));
|
||||
|
||||
WARN_ON(ret == 0);
|
||||
|
||||
drm_vblank_put(dev, crtc);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_wait_one_vblank);
|
||||
|
||||
/**
|
||||
* drm_crtc_wait_one_vblank - wait for one vblank
|
||||
* @crtc: DRM crtc
|
||||
*
|
||||
* This waits for one vblank to pass on @crtc, using the irq driver interfaces.
|
||||
* It is a failure to call this when the vblank irq for @crtc is disabled, e.g.
|
||||
* due to lack of driver support or because the crtc is off.
|
||||
*/
|
||||
void drm_crtc_wait_one_vblank(struct drm_crtc *crtc)
|
||||
{
|
||||
drm_wait_one_vblank(crtc->dev, drm_crtc_index(crtc));
|
||||
}
|
||||
EXPORT_SYMBOL(drm_crtc_wait_one_vblank);
|
||||
|
||||
/**
|
||||
* drm_vblank_off - disable vblank events on a CRTC
|
||||
* @dev: DRM device
|
||||
@@ -1009,6 +1064,9 @@ void drm_vblank_off(struct drm_device *dev, int crtc)
|
||||
unsigned long irqflags;
|
||||
unsigned int seq;
|
||||
|
||||
if (WARN_ON(crtc >= dev->num_crtcs))
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&dev->vbl_lock, irqflags);
|
||||
vblank_disable_and_save(dev, crtc);
|
||||
wake_up(&dev->vblank[crtc].queue);
|
||||
@@ -1068,6 +1126,9 @@ void drm_vblank_on(struct drm_device *dev, int crtc)
|
||||
{
|
||||
unsigned long irqflags;
|
||||
|
||||
if (WARN_ON(crtc >= dev->num_crtcs))
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&dev->vbl_lock, irqflags);
|
||||
/* re-enable interrupts if there's are users left */
|
||||
if (atomic_read(&dev->vblank[crtc].refcount) != 0)
|
||||
@@ -1121,6 +1182,10 @@ void drm_vblank_pre_modeset(struct drm_device *dev, int crtc)
|
||||
/* vblank is not initialized (IRQ not installed ?), or has been freed */
|
||||
if (!dev->num_crtcs)
|
||||
return;
|
||||
|
||||
if (WARN_ON(crtc >= dev->num_crtcs))
|
||||
return;
|
||||
|
||||
/*
|
||||
* To avoid all the problems that might happen if interrupts
|
||||
* were enabled/disabled around or between these calls, we just
|
||||
@@ -1429,6 +1494,9 @@ bool drm_handle_vblank(struct drm_device *dev, int crtc)
|
||||
if (!dev->num_crtcs)
|
||||
return false;
|
||||
|
||||
if (WARN_ON(crtc >= dev->num_crtcs))
|
||||
return false;
|
||||
|
||||
/* Need timestamp lock to prevent concurrent execution with
|
||||
* vblank enable/disable, as this would cause inconsistent
|
||||
* or corrupted timestamps and vblank counts.
|
||||
|
Reference in New Issue
Block a user