Add dry-coded DRM drawable private information storage for FreeBSD.
With this, all modules build again.main
parent
3f04fe7890
commit
33a50412c2
|
@ -59,6 +59,8 @@ typedef struct drm_file drm_file_t;
|
|||
#include <sys/bus.h>
|
||||
#include <sys/signalvar.h>
|
||||
#include <sys/poll.h>
|
||||
#include <sys/tree.h>
|
||||
#include <sys/taskqueue.h>
|
||||
#include <vm/vm.h>
|
||||
#include <vm/pmap.h>
|
||||
#include <vm/vm_extern.h>
|
||||
|
@ -152,6 +154,7 @@ typedef struct drm_file drm_file_t;
|
|||
#define DRM_MEM_CTXBITMAP 17
|
||||
#define DRM_MEM_STUB 18
|
||||
#define DRM_MEM_SGLISTS 19
|
||||
#define DRM_MEM_DRAWABLE 20
|
||||
|
||||
#define DRM_MAX_CTXBITMAP (PAGE_SIZE * 8)
|
||||
|
||||
|
@ -184,10 +187,15 @@ MALLOC_DECLARE(M_DRM);
|
|||
#define DRM_CURPROC curthread
|
||||
#define DRM_STRUCTPROC struct thread
|
||||
#define DRM_SPINTYPE struct mtx
|
||||
#define DRM_SPININIT(l,name) mtx_init(&l, name, NULL, MTX_DEF)
|
||||
#define DRM_SPINUNINIT(l) mtx_destroy(&l)
|
||||
#define DRM_SPININIT(l,name) mtx_init(l, name, NULL, MTX_DEF)
|
||||
#define DRM_SPINUNINIT(l) mtx_destroy(l)
|
||||
#define DRM_SPINLOCK(l) mtx_lock(l)
|
||||
#define DRM_SPINUNLOCK(u) mtx_unlock(u);
|
||||
#define DRM_SPINUNLOCK(u) mtx_unlock(u)
|
||||
#define DRM_SPINLOCK_IRQSAVE(l, irqflags) do { \
|
||||
mtx_lock(l); \
|
||||
(void)irqflags; \
|
||||
} while (0)
|
||||
#define DRM_SPINUNLOCK_IRQRESTORE(u, irqflags) mtx_unlock(u)
|
||||
#define DRM_SPINLOCK_ASSERT(l) mtx_assert(l, MA_OWNED)
|
||||
#define DRM_CURRENTPID curthread->td_proc->p_pid
|
||||
#define DRM_LOCK() mtx_lock(&dev->dev_lock)
|
||||
|
@ -732,6 +740,8 @@ struct drm_device {
|
|||
struct mtx irq_lock; /* protects irq condition checks */
|
||||
struct mtx dev_lock; /* protects everything else */
|
||||
#endif
|
||||
DRM_SPINTYPE drw_lock;
|
||||
|
||||
/* Usage Counters */
|
||||
int open_count; /* Outstanding files open */
|
||||
int buf_use; /* Buffers in use -- cannot alloc */
|
||||
|
@ -797,6 +807,13 @@ struct drm_device {
|
|||
void *dev_private;
|
||||
unsigned int agp_buffer_token;
|
||||
drm_local_map_t *agp_buffer_map;
|
||||
|
||||
struct unrhdr *drw_unrhdr;
|
||||
/* RB tree of drawable infos */
|
||||
RB_HEAD(drawable_tree, bsd_drm_drawable_info) drw_head;
|
||||
|
||||
struct task locked_task;
|
||||
void (*locked_task_call)(drm_device_t *dev);
|
||||
};
|
||||
|
||||
extern int drm_debug_flag;
|
||||
|
@ -959,6 +976,8 @@ int drm_getsareactx(DRM_IOCTL_ARGS);
|
|||
/* Drawable IOCTL support (drm_drawable.c) */
|
||||
int drm_adddraw(DRM_IOCTL_ARGS);
|
||||
int drm_rmdraw(DRM_IOCTL_ARGS);
|
||||
int drm_update_draw(DRM_IOCTL_ARGS);
|
||||
struct drm_drawable_info *drm_get_drawable_info(drm_device_t *dev, int handle);
|
||||
|
||||
/* Authentication IOCTL support (drm_auth.c) */
|
||||
int drm_getmagic(DRM_IOCTL_ARGS);
|
||||
|
|
|
@ -40,7 +40,7 @@ int drm_dma_setup(drm_device_t *dev)
|
|||
if (dev->dma == NULL)
|
||||
return DRM_ERR(ENOMEM);
|
||||
|
||||
DRM_SPININIT(dev->dma_lock, "drmdma");
|
||||
DRM_SPININIT(&dev->dma_lock, "drmdma");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -80,7 +80,7 @@ void drm_dma_takedown(drm_device_t *dev)
|
|||
free(dma->pagelist, M_DRM);
|
||||
free(dev->dma, M_DRM);
|
||||
dev->dma = NULL;
|
||||
DRM_SPINUNINIT(dev->dma_lock);
|
||||
DRM_SPINUNINIT(&dev->dma_lock);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -33,11 +33,67 @@
|
|||
|
||||
#include "drmP.h"
|
||||
|
||||
struct bsd_drm_drawable_info {
|
||||
struct drm_drawable_info info;
|
||||
int handle;
|
||||
RB_ENTRY(bsd_drm_drawable_info) tree;
|
||||
};
|
||||
|
||||
static int
|
||||
drm_drawable_compare(struct bsd_drm_drawable_info *a,
|
||||
struct bsd_drm_drawable_info *b)
|
||||
{
|
||||
if (a->handle > b->handle)
|
||||
return 1;
|
||||
if (a->handle > b->handle)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
RB_GENERATE_STATIC(drawable_tree, bsd_drm_drawable_info, tree,
|
||||
drm_drawable_compare);
|
||||
|
||||
struct drm_drawable_info *
|
||||
drm_get_drawable_info(drm_device_t *dev, int handle)
|
||||
{
|
||||
struct bsd_drm_drawable_info find, *result;
|
||||
|
||||
find.handle = handle;
|
||||
result = RB_FIND(drawable_tree, &dev->drw_head, &find);
|
||||
|
||||
return &result->info;
|
||||
}
|
||||
|
||||
static struct drm_drawable_info *
|
||||
drm_drawable_info_alloc(drm_device_t *dev, int handle)
|
||||
{
|
||||
struct bsd_drm_drawable_info *info;
|
||||
|
||||
info = drm_calloc(1, sizeof(struct bsd_drm_drawable_info),
|
||||
DRM_MEM_DRAWABLE);
|
||||
if (info == NULL)
|
||||
return NULL;
|
||||
|
||||
info->handle = handle;
|
||||
RB_INSERT(drawable_tree, &dev->drw_head, info);
|
||||
|
||||
return &info->info;
|
||||
}
|
||||
|
||||
static void
|
||||
drm_drawable_info_free(drm_device_t *dev, struct drm_drawable_info *info)
|
||||
{
|
||||
RB_REMOVE(drawable_tree, &dev->drw_head,
|
||||
(struct bsd_drm_drawable_info *)info);
|
||||
drm_free(info, sizeof(struct bsd_drm_drawable_info), DRM_MEM_DRAWABLE);
|
||||
}
|
||||
|
||||
int drm_adddraw(DRM_IOCTL_ARGS)
|
||||
{
|
||||
DRM_DEVICE;
|
||||
drm_draw_t draw;
|
||||
|
||||
draw.handle = 0; /* NOOP */
|
||||
draw.handle = alloc_unr(dev->drw_unrhdr);
|
||||
DRM_DEBUG("%d\n", draw.handle);
|
||||
|
||||
DRM_COPY_TO_USER_IOCTL((drm_draw_t *)data, draw, sizeof(draw));
|
||||
|
@ -47,5 +103,60 @@ int drm_adddraw(DRM_IOCTL_ARGS)
|
|||
|
||||
int drm_rmdraw(DRM_IOCTL_ARGS)
|
||||
{
|
||||
return 0; /* NOOP */
|
||||
DRM_DEVICE;
|
||||
drm_draw_t *draw = (drm_draw_t *)data;
|
||||
struct drm_drawable_info *info;
|
||||
|
||||
free_unr(dev->drw_unrhdr, draw->handle);
|
||||
|
||||
info = drm_get_drawable_info(dev, draw->handle);
|
||||
if (info != NULL) {
|
||||
drm_drawable_info_free(dev, info);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int drm_update_draw(DRM_IOCTL_ARGS)
|
||||
{
|
||||
DRM_DEVICE;
|
||||
struct drm_drawable_info *info;
|
||||
struct drm_update_draw *update = (struct drm_update_draw *)data;
|
||||
|
||||
info = drm_get_drawable_info(dev, update->handle);
|
||||
if (info == NULL) {
|
||||
info = drm_drawable_info_alloc(dev, update->handle);
|
||||
if (info == NULL)
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
switch (update->type) {
|
||||
case DRM_DRAWABLE_CLIPRECTS:
|
||||
DRM_SPINLOCK(&dev->drw_lock);
|
||||
if (update->num != info->num_rects) {
|
||||
drm_free(info->rects,
|
||||
sizeof(*info->rects) * info->num_rects,
|
||||
DRM_MEM_DRAWABLE);
|
||||
info->rects = NULL;
|
||||
info->num_rects = 0;
|
||||
}
|
||||
if (update->num == 0) {
|
||||
DRM_SPINUNLOCK(&dev->drw_lock);
|
||||
return 0;
|
||||
}
|
||||
if (info->rects == NULL) {
|
||||
info->rects = drm_alloc(sizeof(*info->rects) *
|
||||
update->num, DRM_MEM_DRAWABLE);
|
||||
if (info->rects == NULL)
|
||||
return ENOMEM;
|
||||
info->num_rects = update->num;
|
||||
}
|
||||
/* For some reason the pointer arg is unsigned long long. */
|
||||
copyin((void *)(intptr_t)update->data, info->rects,
|
||||
sizeof(*info->rects) * info->num_rects);
|
||||
DRM_SPINUNLOCK(&dev->drw_lock);
|
||||
return 0;
|
||||
default:
|
||||
return EINVAL;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include <sys/limits.h>
|
||||
#include "drmP.h"
|
||||
#include "drm.h"
|
||||
#include "drm_sarea.h"
|
||||
|
@ -121,6 +122,7 @@ static drm_ioctl_desc_t drm_ioctls[256] = {
|
|||
[DRM_IOCTL_NR(DRM_IOCTL_SG_FREE)] = { drm_sg_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK)] = { drm_wait_vblank, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_UPDATE_DRAW)] = { drm_update_draw, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
|
||||
};
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
|
@ -557,6 +559,12 @@ static int drm_load(drm_device_t *dev)
|
|||
goto error;
|
||||
}
|
||||
|
||||
dev->drw_unrhdr = new_unrhdr(1, INT_MAX, NULL);
|
||||
if (dev->drw_unrhdr == NULL) {
|
||||
DRM_ERROR("Couldn't allocate drawable number allocator\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
DRM_INFO("Initialized %s %d.%d.%d %s\n",
|
||||
dev->driver.name,
|
||||
dev->driver.major,
|
||||
|
@ -628,6 +636,8 @@ static void drm_unload(drm_device_t *dev)
|
|||
if (dev->driver.unload != NULL)
|
||||
dev->driver.unload(dev);
|
||||
|
||||
delete_unrhdr(dev->drw_unrhdr);
|
||||
|
||||
drm_mem_uninit();
|
||||
#if defined(__FreeBSD__) && __FreeBSD_version >= 500000
|
||||
mtx_destroy(&dev->dev_lock);
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
#include "drmP.h"
|
||||
#include "drm.h"
|
||||
|
||||
static void drm_locked_task(void *context, int pending __unused);
|
||||
|
||||
int drm_irq_by_busid(DRM_IOCTL_ARGS)
|
||||
{
|
||||
DRM_DEVICE;
|
||||
|
@ -87,7 +89,7 @@ int drm_irq_install(drm_device_t *dev)
|
|||
|
||||
dev->context_flag = 0;
|
||||
|
||||
DRM_SPININIT(dev->irq_lock, "DRM IRQ lock");
|
||||
DRM_SPININIT(&dev->irq_lock, "DRM IRQ lock");
|
||||
|
||||
/* Before installing handler */
|
||||
dev->driver.irq_preinstall(dev);
|
||||
|
@ -131,6 +133,7 @@ int drm_irq_install(drm_device_t *dev)
|
|||
dev->driver.irq_postinstall(dev);
|
||||
DRM_UNLOCK();
|
||||
|
||||
TASK_INIT(&dev->locked_task, 0, drm_locked_task, dev);
|
||||
return 0;
|
||||
err:
|
||||
DRM_LOCK();
|
||||
|
@ -142,7 +145,7 @@ err:
|
|||
dev->irqrid = 0;
|
||||
}
|
||||
#endif
|
||||
DRM_SPINUNINIT(dev->irq_lock);
|
||||
DRM_SPINUNINIT(&dev->irq_lock);
|
||||
DRM_UNLOCK();
|
||||
return retcode;
|
||||
}
|
||||
|
@ -174,7 +177,7 @@ int drm_irq_uninstall(drm_device_t *dev)
|
|||
#elif defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
pci_intr_disestablish(&dev->pa.pa_pc, dev->irqh);
|
||||
#endif
|
||||
DRM_SPINUNINIT(dev->irq_lock);
|
||||
DRM_SPINUNINIT(&dev->irq_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -291,3 +294,45 @@ void drm_vbl_send_signals( drm_device_t *dev )
|
|||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void drm_locked_task(void *context, int pending __unused)
|
||||
{
|
||||
drm_device_t *dev = context;
|
||||
|
||||
DRM_LOCK();
|
||||
for (;;) {
|
||||
int ret;
|
||||
|
||||
if (drm_lock_take(&dev->lock.hw_lock->lock,
|
||||
DRM_KERNEL_CONTEXT))
|
||||
{
|
||||
dev->lock.filp = (void *)(uintptr_t)DRM_CURRENTPID;
|
||||
dev->lock.lock_time = jiffies;
|
||||
atomic_inc(&dev->counts[_DRM_STAT_LOCKS]);
|
||||
break; /* Got lock */
|
||||
}
|
||||
|
||||
/* Contention */
|
||||
#if defined(__FreeBSD__) && __FreeBSD_version > 500000
|
||||
ret = msleep((void *)&dev->lock.lock_queue, &dev->dev_lock,
|
||||
PZERO | PCATCH, "drmlk2", 0);
|
||||
#else
|
||||
ret = tsleep((void *)&dev->lock.lock_queue, PZERO | PCATCH,
|
||||
"drmlk2", 0);
|
||||
#endif
|
||||
if (ret != 0)
|
||||
return;
|
||||
}
|
||||
DRM_UNLOCK();
|
||||
|
||||
dev->locked_task_call(dev);
|
||||
|
||||
drm_lock_free(dev, &dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT);
|
||||
}
|
||||
|
||||
void
|
||||
drm_locked_tasklet(drm_device_t *dev, void (*tasklet)(drm_device_t *dev))
|
||||
{
|
||||
dev->locked_task_call = tasklet;
|
||||
taskqueue_enqueue(taskqueue_swi, &dev->locked_task);
|
||||
}
|
||||
|
|
|
@ -90,6 +90,7 @@ int drm_sg_alloc(drm_device_t * dev, drm_scatter_gather_t * request)
|
|||
dev->sg = entry;
|
||||
DRM_UNLOCK();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int drm_sg_alloc_ioctl(DRM_IOCTL_ARGS)
|
||||
|
|
|
@ -1264,5 +1264,19 @@ static inline void drm_ctl_free(void *pt, size_t size, int area)
|
|||
|
||||
/*@}*/
|
||||
|
||||
/** Type for the OS's non-sleepable mutex lock */
|
||||
#define DRM_SPINTYPE spinlock_t
|
||||
/**
|
||||
* Initialize the lock for use. name is an optional string describing the
|
||||
* lock
|
||||
*/
|
||||
#define DRM_SPININIT(l,name) spin_lock_init(l);
|
||||
#define DRM_SPINUNINIT(l)
|
||||
#define DRM_SPINLOCK(l) spin_lock(l);
|
||||
#define DRM_SPINUNLOCK(u) spin_unlock(l);
|
||||
#define DRM_SPINLOCK_IRQSAVE(l, flags) spin_lock_irqflags(l, _flags);
|
||||
#define DRM_SPINUNLOCK_IRQRESTORE(u, flags) spin_unlock_irqrestore(l, _flags);
|
||||
#define DRM_SPINLOCK_ASSERT(l) do {} while (0)
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
#endif
|
||||
|
|
|
@ -118,7 +118,7 @@ typedef struct drm_i915_private {
|
|||
struct mem_block *agp_heap;
|
||||
unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds;
|
||||
int vblank_pipe;
|
||||
spinlock_t user_irq_lock;
|
||||
DRM_SPINTYPE user_irq_lock;
|
||||
int user_irq_refcount;
|
||||
int fence_irq_on;
|
||||
uint32_t irq_enable_reg;
|
||||
|
@ -133,7 +133,7 @@ typedef struct drm_i915_private {
|
|||
#ifdef I915_HAVE_BUFFER
|
||||
void *agp_iomap;
|
||||
#endif
|
||||
spinlock_t swaps_lock;
|
||||
DRM_SPINTYPE swaps_lock;
|
||||
drm_i915_vbl_swap_t vbl_swaps;
|
||||
unsigned int swaps_pending;
|
||||
} drm_i915_private_t;
|
||||
|
|
|
@ -50,6 +50,8 @@ i915_dispatch_vsync_flip(drm_device_t *dev, drm_drawable_info_t *drw, int pipe)
|
|||
u16 x1, y1, x2, y2;
|
||||
int pf_pipes = 1 << pipe;
|
||||
|
||||
DRM_SPINLOCK_ASSERT(&dev->drw_lock);
|
||||
|
||||
/* If the window is visible on the other pipe, we have to flip on that
|
||||
* pipe as well.
|
||||
*/
|
||||
|
@ -89,7 +91,6 @@ i915_dispatch_vsync_flip(drm_device_t *dev, drm_drawable_info_t *drw, int pipe)
|
|||
static void i915_vblank_tasklet(drm_device_t *dev)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||
unsigned long irqflags;
|
||||
struct list_head *list, *tmp, hits, *hit;
|
||||
int nhits, nrects, slice[2], upper[2], lower[2], i, num_pages;
|
||||
unsigned counter[2] = { atomic_read(&dev->vbl_received),
|
||||
|
@ -111,7 +112,12 @@ static void i915_vblank_tasklet(drm_device_t *dev)
|
|||
|
||||
nhits = nrects = 0;
|
||||
|
||||
spin_lock_irqsave(&dev_priv->swaps_lock, irqflags);
|
||||
/* No irqsave/restore necessary. This tasklet may be run in an
|
||||
* interrupt context or normal context, but we don't have to worry
|
||||
* about getting interrupted by something acquiring the lock, because
|
||||
* we are the interrupt context thing that acquires the lock.
|
||||
*/
|
||||
DRM_SPINLOCK(&dev_priv->swaps_lock);
|
||||
|
||||
/* Find buffer swaps scheduled for this vertical blank */
|
||||
list_for_each_safe(list, tmp, &dev_priv->vbl_swaps.head) {
|
||||
|
@ -124,15 +130,15 @@ static void i915_vblank_tasklet(drm_device_t *dev)
|
|||
list_del(list);
|
||||
dev_priv->swaps_pending--;
|
||||
|
||||
spin_unlock(&dev_priv->swaps_lock);
|
||||
spin_lock(&dev->drw_lock);
|
||||
DRM_SPINUNLOCK(&dev_priv->swaps_lock);
|
||||
DRM_SPINLOCK(&dev->drw_lock);
|
||||
|
||||
drw = drm_get_drawable_info(dev, vbl_swap->drw_id);
|
||||
|
||||
if (!drw) {
|
||||
spin_unlock(&dev->drw_lock);
|
||||
DRM_SPINUNLOCK(&dev->drw_lock);
|
||||
drm_free(vbl_swap, sizeof(*vbl_swap), DRM_MEM_DRIVER);
|
||||
spin_lock(&dev_priv->swaps_lock);
|
||||
DRM_SPINLOCK(&dev_priv->swaps_lock);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -149,7 +155,7 @@ static void i915_vblank_tasklet(drm_device_t *dev)
|
|||
}
|
||||
}
|
||||
|
||||
spin_unlock(&dev->drw_lock);
|
||||
DRM_SPINUNLOCK(&dev->drw_lock);
|
||||
|
||||
/* List of hits was empty, or we reached the end of it */
|
||||
if (hit == &hits)
|
||||
|
@ -157,16 +163,15 @@ static void i915_vblank_tasklet(drm_device_t *dev)
|
|||
|
||||
nhits++;
|
||||
|
||||
spin_lock(&dev_priv->swaps_lock);
|
||||
DRM_SPINLOCK(&dev_priv->swaps_lock);
|
||||
}
|
||||
|
||||
DRM_SPINUNLOCK(&dev->drw_lock);
|
||||
|
||||
if (nhits == 0) {
|
||||
spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags);
|
||||
return;
|
||||
}
|
||||
|
||||
spin_unlock(&dev_priv->swaps_lock);
|
||||
|
||||
i915_kernel_lost_context(dev);
|
||||
|
||||
upper[0] = upper[1] = 0;
|
||||
|
@ -180,7 +185,7 @@ static void i915_vblank_tasklet(drm_device_t *dev)
|
|||
offsets[2] = sarea_priv->third_offset;
|
||||
num_pages = sarea_priv->third_handle ? 3 : 2;
|
||||
|
||||
spin_lock(&dev->drw_lock);
|
||||
DRM_SPINLOCK(&dev->drw_lock);
|
||||
|
||||
/* Emit blits for buffer swaps, partitioning both outputs into as many
|
||||
* slices as there are buffer swaps scheduled in order to avoid tearing
|
||||
|
@ -262,7 +267,7 @@ static void i915_vblank_tasklet(drm_device_t *dev)
|
|||
}
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&dev->drw_lock, irqflags);
|
||||
DRM_SPINUNLOCK(&dev->drw_lock);
|
||||
|
||||
list_for_each_safe(hit, tmp, &hits) {
|
||||
drm_i915_vbl_swap_t *swap_hit =
|
||||
|
@ -362,23 +367,23 @@ int i915_emit_irq(drm_device_t * dev)
|
|||
|
||||
void i915_user_irq_on(drm_i915_private_t *dev_priv)
|
||||
{
|
||||
spin_lock(&dev_priv->user_irq_lock);
|
||||
DRM_SPINLOCK(&dev_priv->user_irq_lock);
|
||||
if (dev_priv->irq_enabled && (++dev_priv->user_irq_refcount == 1)){
|
||||
dev_priv->irq_enable_reg |= USER_INT_FLAG;
|
||||
I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg);
|
||||
}
|
||||
spin_unlock(&dev_priv->user_irq_lock);
|
||||
DRM_SPINUNLOCK(&dev_priv->user_irq_lock);
|
||||
|
||||
}
|
||||
|
||||
void i915_user_irq_off(drm_i915_private_t *dev_priv)
|
||||
{
|
||||
spin_lock(&dev_priv->user_irq_lock);
|
||||
DRM_SPINLOCK(&dev_priv->user_irq_lock);
|
||||
if (dev_priv->irq_enabled && (--dev_priv->user_irq_refcount == 0)) {
|
||||
// dev_priv->irq_enable_reg &= ~USER_INT_FLAG;
|
||||
// I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg);
|
||||
}
|
||||
spin_unlock(&dev_priv->user_irq_lock);
|
||||
DRM_SPINUNLOCK(&dev_priv->user_irq_lock);
|
||||
}
|
||||
|
||||
|
||||
|
@ -597,16 +602,6 @@ int i915_vblank_swap(DRM_IOCTL_ARGS)
|
|||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&dev->drw_lock, irqflags);
|
||||
|
||||
if (!drm_get_drawable_info(dev, swap.drawable)) {
|
||||
spin_unlock_irqrestore(&dev->drw_lock, irqflags);
|
||||
DRM_DEBUG("Invalid drawable ID %d\n", swap.drawable);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&dev->drw_lock, irqflags);
|
||||
|
||||
curseq = atomic_read(pipe ? &dev->vbl_received2 : &dev->vbl_received);
|
||||
|
||||
if (seqtype == _DRM_VBLANK_RELATIVE)
|
||||
|
@ -629,12 +624,13 @@ int i915_vblank_swap(DRM_IOCTL_ARGS)
|
|||
|
||||
LOCK_TEST_WITH_RETURN(dev, filp);
|
||||
|
||||
spin_lock_irqsave(&dev->drw_lock, irqflags);
|
||||
DRM_SPINLOCK_IRQSAVE(&dev->drw_lock, irqflags);
|
||||
|
||||
drw = drm_get_drawable_info(dev, swap.drawable);
|
||||
|
||||
if (!drw) {
|
||||
spin_unlock_irqrestore(&dev->drw_lock, irqflags);
|
||||
DRM_SPINUNLOCK_IRQRESTORE(&dev->drw_lock,
|
||||
irqflags);
|
||||
DRM_DEBUG("Invalid drawable ID %d\n",
|
||||
swap.drawable);
|
||||
return DRM_ERR(EINVAL);
|
||||
|
@ -642,13 +638,13 @@ int i915_vblank_swap(DRM_IOCTL_ARGS)
|
|||
|
||||
i915_dispatch_vsync_flip(dev, drw, pipe);
|
||||
|
||||
spin_unlock_irqrestore(&dev->drw_lock, irqflags);
|
||||
DRM_SPINUNLOCK_IRQRESTORE(&dev->drw_lock, irqflags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&dev_priv->swaps_lock, irqflags);
|
||||
DRM_SPINLOCK_IRQSAVE(&dev_priv->swaps_lock, irqflags);
|
||||
|
||||
list_for_each(list, &dev_priv->vbl_swaps.head) {
|
||||
vbl_swap = list_entry(list, drm_i915_vbl_swap_t, head);
|
||||
|
@ -657,13 +653,13 @@ int i915_vblank_swap(DRM_IOCTL_ARGS)
|
|||
vbl_swap->pipe == pipe &&
|
||||
vbl_swap->sequence == swap.sequence) {
|
||||
vbl_swap->flip = (swap.seqtype & _DRM_VBLANK_FLIP);
|
||||
spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags);
|
||||
DRM_SPINUNLOCK_IRQRESTORE(&dev_priv->swaps_lock, irqflags);
|
||||
DRM_DEBUG("Already scheduled\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags);
|
||||
DRM_SPINUNLOCK_IRQRESTORE(&dev_priv->swaps_lock, irqflags);
|
||||
|
||||
if (dev_priv->swaps_pending >= 100) {
|
||||
DRM_DEBUG("Too many swaps queued\n");
|
||||
|
@ -687,12 +683,12 @@ int i915_vblank_swap(DRM_IOCTL_ARGS)
|
|||
if (vbl_swap->flip)
|
||||
swap.sequence++;
|
||||
|
||||
spin_lock_irqsave(&dev_priv->swaps_lock, irqflags);
|
||||
DRM_SPINLOCK_IRQSAVE(&dev_priv->swaps_lock, irqflags);
|
||||
|
||||
list_add_tail((struct list_head *)vbl_swap, &dev_priv->vbl_swaps.head);
|
||||
dev_priv->swaps_pending++;
|
||||
|
||||
spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags);
|
||||
DRM_SPINUNLOCK_IRQRESTORE(&dev_priv->swaps_lock, irqflags);
|
||||
|
||||
DRM_COPY_TO_USER_IOCTL((drm_i915_vblank_swap_t __user *) data, swap,
|
||||
sizeof(swap));
|
||||
|
@ -715,11 +711,11 @@ void i915_driver_irq_postinstall(drm_device_t * dev)
|
|||
{
|
||||
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||
|
||||
spin_lock_init(&dev_priv->swaps_lock);
|
||||
DRM_SPININIT(&dev_priv->swaps_lock, "swap");
|
||||
INIT_LIST_HEAD(&dev_priv->vbl_swaps.head);
|
||||
dev_priv->swaps_pending = 0;
|
||||
|
||||
spin_lock_init(&dev_priv->user_irq_lock);
|
||||
DRM_SPININIT(&dev_priv->user_irq_lock, "userirq");
|
||||
dev_priv->user_irq_refcount = 0;
|
||||
|
||||
i915_enable_interrupt(dev);
|
||||
|
|
Loading…
Reference in New Issue