Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
[safe/jmp/linux-2.6] / drivers / media / video / zoran_driver.c
index fac97cb..5394d7a 100644 (file)
@@ -52,7 +52,6 @@
 #include <linux/pci.h>
 #include <linux/vmalloc.h>
 #include <linux/wait.h>
-#include <linux/byteorder/generic.h>
 
 #include <linux/interrupt.h>
 #include <linux/i2c.h>
@@ -60,7 +59,6 @@
 
 #include <linux/spinlock.h>
 #define     MAP_NR(x)       virt_to_page(x)
-#define     ZORAN_HARDWARE  VID_HARDWARE_ZR36067
 #define     ZORAN_VID_TYPE  ( \
                                VID_TYPE_CAPTURE | \
                                VID_TYPE_OVERLAY | \
@@ -75,6 +73,7 @@
 #include <media/v4l2-common.h>
 #include "videocodec.h"
 
+#include <asm/byteorder.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
 #include <linux/proc_fs.h>
@@ -86,7 +85,6 @@
 #include "zoran_device.h"
 #include "zoran_card.h"
 
-#ifdef CONFIG_VIDEO_V4L2
        /* we declare some card type definitions here, they mean
         * the same as the v4l1 ZORAN_VID_TYPE above, except it's v4l2 */
 #define ZORAN_V4L2_VID_FLAGS ( \
                                V4L2_CAP_VIDEO_OUTPUT |\
                                V4L2_CAP_VIDEO_OVERLAY \
                              )
-#endif
 
 #include <asm/byteorder.h>
 
-const struct zoran_format zoran_formats[] = {
-       {
-               .name = "15-bit RGB",
-               .palette = VIDEO_PALETTE_RGB555,
-#ifdef CONFIG_VIDEO_V4L2
-#ifdef __LITTLE_ENDIAN
-               .fourcc = V4L2_PIX_FMT_RGB555,
+#if defined(CONFIG_VIDEO_V4L1_COMPAT)
+#define ZFMT(pal, fcc, cs) \
+       .palette = (pal), .fourcc = (fcc), .colorspace = (cs)
 #else
-               .fourcc = V4L2_PIX_FMT_RGB555X,
-#endif
-               .colorspace = V4L2_COLORSPACE_SRGB,
+#define ZFMT(pal, fcc, cs) \
+       .fourcc = (fcc), .colorspace = (cs)
 #endif
+
+const struct zoran_format zoran_formats[] = {
+       {
+               .name = "15-bit RGB LE",
+               ZFMT(VIDEO_PALETTE_RGB555,
+                    V4L2_PIX_FMT_RGB555, V4L2_COLORSPACE_SRGB),
                .depth = 15,
                .flags = ZORAN_FORMAT_CAPTURE |
                         ZORAN_FORMAT_OVERLAY,
+               .vfespfr = ZR36057_VFESPFR_RGB555|ZR36057_VFESPFR_ErrDif|
+                          ZR36057_VFESPFR_LittleEndian,
        }, {
-               .name = "16-bit RGB",
-               .palette = VIDEO_PALETTE_RGB565,
-#ifdef CONFIG_VIDEO_V4L2
-#ifdef __LITTLE_ENDIAN
-               .fourcc = V4L2_PIX_FMT_RGB565,
-#else
-               .fourcc = V4L2_PIX_FMT_RGB565X,
-#endif
-               .colorspace = V4L2_COLORSPACE_SRGB,
-#endif
+               .name = "15-bit RGB BE",
+               ZFMT(-1,
+                    V4L2_PIX_FMT_RGB555X, V4L2_COLORSPACE_SRGB),
+               .depth = 15,
+               .flags = ZORAN_FORMAT_CAPTURE |
+                        ZORAN_FORMAT_OVERLAY,
+               .vfespfr = ZR36057_VFESPFR_RGB555|ZR36057_VFESPFR_ErrDif,
+       }, {
+               .name = "16-bit RGB LE",
+               ZFMT(VIDEO_PALETTE_RGB565,
+                    V4L2_PIX_FMT_RGB565, V4L2_COLORSPACE_SRGB),
+               .depth = 16,
+               .flags = ZORAN_FORMAT_CAPTURE |
+                        ZORAN_FORMAT_OVERLAY,
+               .vfespfr = ZR36057_VFESPFR_RGB565|ZR36057_VFESPFR_ErrDif|
+                          ZR36057_VFESPFR_LittleEndian,
+       }, {
+               .name = "16-bit RGB BE",
+               ZFMT(-1,
+                    V4L2_PIX_FMT_RGB565, V4L2_COLORSPACE_SRGB),
                .depth = 16,
                .flags = ZORAN_FORMAT_CAPTURE |
                         ZORAN_FORMAT_OVERLAY,
+               .vfespfr = ZR36057_VFESPFR_RGB565|ZR36057_VFESPFR_ErrDif,
        }, {
                .name = "24-bit RGB",
-               .palette = VIDEO_PALETTE_RGB24,
-#ifdef CONFIG_VIDEO_V4L2
-#ifdef __LITTLE_ENDIAN
-               .fourcc = V4L2_PIX_FMT_BGR24,
-#else
-               .fourcc = V4L2_PIX_FMT_RGB24,
-#endif
-               .colorspace = V4L2_COLORSPACE_SRGB,
-#endif
+               ZFMT(VIDEO_PALETTE_RGB24,
+                    V4L2_PIX_FMT_BGR24, V4L2_COLORSPACE_SRGB),
                .depth = 24,
                .flags = ZORAN_FORMAT_CAPTURE |
                         ZORAN_FORMAT_OVERLAY,
+               .vfespfr = ZR36057_VFESPFR_RGB888|ZR36057_VFESPFR_Pack24,
        }, {
-               .name = "32-bit RGB",
-               .palette = VIDEO_PALETTE_RGB32,
-#ifdef CONFIG_VIDEO_V4L2
-#ifdef __LITTLE_ENDIAN
-               .fourcc = V4L2_PIX_FMT_BGR32,
-#else
-               .fourcc = V4L2_PIX_FMT_RGB32,
-#endif
-               .colorspace = V4L2_COLORSPACE_SRGB,
-#endif
+               .name = "32-bit RGB LE",
+               ZFMT(VIDEO_PALETTE_RGB32,
+                    V4L2_PIX_FMT_BGR32, V4L2_COLORSPACE_SRGB),
+               .depth = 32,
+               .flags = ZORAN_FORMAT_CAPTURE |
+                        ZORAN_FORMAT_OVERLAY,
+               .vfespfr = ZR36057_VFESPFR_RGB888|ZR36057_VFESPFR_LittleEndian,
+       }, {
+               .name = "32-bit RGB BE",
+               ZFMT(-1,
+                    V4L2_PIX_FMT_RGB32, V4L2_COLORSPACE_SRGB),
                .depth = 32,
                .flags = ZORAN_FORMAT_CAPTURE |
                         ZORAN_FORMAT_OVERLAY,
+               .vfespfr = ZR36057_VFESPFR_RGB888,
        }, {
                .name = "4:2:2, packed, YUYV",
-               .palette = VIDEO_PALETTE_YUV422,
-#ifdef CONFIG_VIDEO_V4L2
-               .fourcc = V4L2_PIX_FMT_YUYV,
-               .colorspace = V4L2_COLORSPACE_SMPTE170M,
-#endif
+               ZFMT(VIDEO_PALETTE_YUV422,
+                    V4L2_PIX_FMT_YUYV, V4L2_COLORSPACE_SMPTE170M),
                .depth = 16,
                .flags = ZORAN_FORMAT_CAPTURE |
                         ZORAN_FORMAT_OVERLAY,
+               .vfespfr = ZR36057_VFESPFR_YUV422,
+       }, {
+               .name = "4:2:2, packed, UYVY",
+               ZFMT(VIDEO_PALETTE_UYVY,
+                    V4L2_PIX_FMT_UYVY, V4L2_COLORSPACE_SMPTE170M),
+               .depth = 16,
+               .flags = ZORAN_FORMAT_CAPTURE |
+                        ZORAN_FORMAT_OVERLAY,
+               .vfespfr = ZR36057_VFESPFR_YUV422|ZR36057_VFESPFR_LittleEndian,
        }, {
                .name = "Hardware-encoded Motion-JPEG",
-               .palette = -1,
-#ifdef CONFIG_VIDEO_V4L2
-               .fourcc = V4L2_PIX_FMT_MJPEG,
-               .colorspace = V4L2_COLORSPACE_SMPTE170M,
-#endif
+               ZFMT(-1,
+                    V4L2_PIX_FMT_MJPEG, V4L2_COLORSPACE_SMPTE170M),
                .depth = 0,
                .flags = ZORAN_FORMAT_CAPTURE |
                         ZORAN_FORMAT_PLAYBACK |
                         ZORAN_FORMAT_COMPRESSED,
        }
 };
-static const int zoran_num_formats =
-    (sizeof(zoran_formats) / sizeof(struct zoran_format));
+#define NUM_FORMATS ARRAY_SIZE(zoran_formats)
 
 // RJ: Test only - want to test BUZ_USE_HIMEM even when CONFIG_BIGPHYS_AREA is defined
 
 
-extern int *zr_debug;
-
-#define dprintk(num, format, args...) \
-       do { \
-               if (*zr_debug >= num) \
-                       printk(format, ##args); \
-       } while (0)
-
 extern int v4l_nbufs;
 extern int v4l_bufsize;
 extern int jpg_nbufs;
 extern int jpg_bufsize;
 extern int pass_through;
 
-static int lock_norm = 0;      /* 1=Don't change TV standard (norm) */
-module_param(lock_norm, int, 0);
-MODULE_PARM_DESC(lock_norm, "Users can't change norm");
+static int lock_norm;  /* 0 = default 1 = Don't change TV standard (norm) */
+module_param(lock_norm, int, 0644);
+MODULE_PARM_DESC(lock_norm, "Prevent norm changes (1 = ignore, >1 = fail)");
 
-#ifdef CONFIG_VIDEO_V4L2
        /* small helper function for calculating buffersizes for v4l2
         * we calculate the nearest higher power-of-two, which
         * will be the recommended buffersize */
@@ -226,7 +226,6 @@ zoran_v4l2_calc_bufsize (struct zoran_jpg_settings *settings)
                return 8192;
        return result;
 }
-#endif
 
 /* forward references */
 static void v4l_fbuffer_free(struct file *file);
@@ -332,11 +331,8 @@ v4l_fbuffer_alloc (struct file *file)
                if (fh->v4l_buffers.buffer_size <= MAX_KMALLOC_MEM) {
                        /* Use kmalloc */
 
-                       mem =
-                           (unsigned char *) kmalloc(fh->v4l_buffers.
-                                                     buffer_size,
-                                                     GFP_KERNEL);
-                       if (mem == 0) {
+                       mem = kmalloc(fh->v4l_buffers.buffer_size, GFP_KERNEL);
+                       if (!mem) {
                                dprintk(1,
                                        KERN_ERR
                                        "%s: v4l_fbuffer_alloc() - kmalloc for V4L buf %d failed\n",
@@ -499,7 +495,7 @@ jpg_fbuffer_alloc (struct file *file)
                        jpg_fbuffer_free(file);
                        return -ENOBUFS;
                }
-               fh->jpg_buffers.buffer[i].frag_tab = (u32 *) mem;
+               fh->jpg_buffers.buffer[i].frag_tab = (__le32 *) mem;
                fh->jpg_buffers.buffer[i].frag_tab_bus =
                    virt_to_bus((void *) mem);
 
@@ -768,13 +764,13 @@ v4l_grab (struct file       *file,
        struct zoran *zr = fh->zr;
        int res = 0, i;
 
-       for (i = 0; i < zoran_num_formats; i++) {
+       for (i = 0; i < NUM_FORMATS; i++) {
                if (zoran_formats[i].palette == mp->format &&
                    zoran_formats[i].flags & ZORAN_FORMAT_CAPTURE &&
                    !(zoran_formats[i].flags & ZORAN_FORMAT_COMPRESSED))
                        break;
        }
-       if (i == zoran_num_formats || zoran_formats[i].depth == 0) {
+       if (i == NUM_FORMATS || zoran_formats[i].depth == 0) {
                dprintk(1,
                        KERN_ERR
                        "%s: v4l_grab() - wrong bytes-per-pixel format\n",
@@ -1091,12 +1087,10 @@ jpg_sync (struct file       *file,
                frame = zr->jpg_pend[zr->jpg_que_tail & BUZ_MASK_FRAME];
 
        /* buffer should now be in BUZ_STATE_DONE */
-       if (*zr_debug > 0)
-               if (zr->jpg_buffers.buffer[frame].state != BUZ_STATE_DONE)
-                       dprintk(2,
-                               KERN_ERR
-                               "%s: jpg_sync() - internal state error\n",
-                               ZR_DEVNAME(zr));
+       if (zr->jpg_buffers.buffer[frame].state != BUZ_STATE_DONE)
+               dprintk(2,
+                       KERN_ERR "%s: jpg_sync() - internal state error\n",
+                       ZR_DEVNAME(zr));
 
        *bs = zr->jpg_buffers.buffer[frame].bs;
        bs->frame = frame;
@@ -1173,10 +1167,14 @@ zoran_close_end_session (struct file *file)
 
        /* v4l capture */
        if (fh->v4l_buffers.active != ZORAN_FREE) {
+               unsigned long flags;
+
+               spin_lock_irqsave(&zr->spinlock, flags);
                zr36057_set_memgrab(zr, 0);
                zr->v4l_buffers.allocated = 0;
                zr->v4l_buffers.active = fh->v4l_buffers.active =
                    ZORAN_FREE;
+               spin_unlock_irqrestore(&zr->spinlock, flags);
        }
 
        /* v4l buffers */
@@ -1279,7 +1277,7 @@ zoran_open (struct inode *inode,
        }
 
        dprintk(1, KERN_INFO "%s: zoran_open(%s, pid=[%d]), users(-)=%d\n",
-               ZR_DEVNAME(zr), current->comm, current->pid, zr->user);
+               ZR_DEVNAME(zr), current->comm, task_pid_nr(current), zr->user);
 
        /* now, create the open()-specific file_ops struct */
        fh = kzalloc(sizeof(struct zoran_fh), GFP_KERNEL);
@@ -1352,7 +1350,7 @@ zoran_close (struct inode *inode,
        struct zoran *zr = fh->zr;
 
        dprintk(1, KERN_INFO "%s: zoran_close(%s, pid=[%d]), users(+)=%d\n",
-               ZR_DEVNAME(zr), current->comm, current->pid, zr->user);
+               ZR_DEVNAME(zr), current->comm, task_pid_nr(current), zr->user);
 
        /* kernel locks (fs/device.c), so don't do that ourselves
         * (prevents deadlocks) */
@@ -1370,7 +1368,7 @@ zoran_close (struct inode *inode,
                /* disable interrupts */
                btand(~ZR36057_ICR_IntPinEn, ZR36057_ICR);
 
-               if (*zr_debug > 1)
+               if (zr36067_debug > 1)
                        print_interrupts(zr);
 
                /* Overlay off */
@@ -1704,7 +1702,6 @@ setup_overlay (struct file *file,
        return wait_grab_pending(zr);
 }
 
-#ifdef CONFIG_VIDEO_V4L2
        /* get the status of a buffer in the clients buffer queue */
 static int
 zoran_v4l2_buffer_status (struct file        *file,
@@ -1810,7 +1807,6 @@ zoran_v4l2_buffer_status (struct file        *file,
 
        return 0;
 }
-#endif
 
 static int
 zoran_set_norm (struct zoran *zr,
@@ -2107,7 +2103,7 @@ zoran_do_ioctl (struct inode *inode,
                        vpict->colour, vpict->contrast, vpict->depth,
                        vpict->palette);
 
-               for (i = 0; i < zoran_num_formats; i++) {
+               for (i = 0; i < NUM_FORMATS; i++) {
                        const struct zoran_format *fmt = &zoran_formats[i];
 
                        if (fmt->palette != -1 &&
@@ -2116,7 +2112,7 @@ zoran_do_ioctl (struct inode *inode,
                            fmt->depth == vpict->depth)
                                break;
                }
-               if (i == zoran_num_formats) {
+               if (i == NUM_FORMATS) {
                        dprintk(1,
                                KERN_ERR
                                "%s: VIDIOCSPICT - Invalid palette %d\n",
@@ -2220,10 +2216,10 @@ zoran_do_ioctl (struct inode *inode,
                        ZR_DEVNAME(zr), vbuf->base, vbuf->width,
                        vbuf->height, vbuf->depth, vbuf->bytesperline);
 
-               for (i = 0; i < zoran_num_formats; i++)
+               for (i = 0; i < NUM_FORMATS; i++)
                        if (zoran_formats[i].depth == vbuf->depth)
                                break;
-               if (i == zoran_num_formats) {
+               if (i == NUM_FORMATS) {
                        dprintk(1,
                                KERN_ERR
                                "%s: VIDIOCSFBUF - invalid fbuf depth %d\n",
@@ -2619,8 +2615,6 @@ zoran_do_ioctl (struct inode *inode,
        }
                break;
 
-#ifdef CONFIG_VIDEO_V4L2
-
                /* The new video4linux2 capture interface - much nicer than video4linux1, since
                 * it allows for integrating the JPEG capturing calls inside standard v4l2
                 */
@@ -2672,14 +2666,14 @@ zoran_do_ioctl (struct inode *inode,
                        return -EINVAL;
                }
 
-               for (i = 0; i < zoran_num_formats; i++) {
+               for (i = 0; i < NUM_FORMATS; i++) {
                        if (zoran_formats[i].flags & flag)
                                num++;
                        if (num == fmt->index)
                                break;
                }
                if (fmt->index < 0 /* late, but not too late */  ||
-                   i == zoran_num_formats)
+                   i == NUM_FORMATS)
                        return -EINVAL;
 
                memset(fmt, 0, sizeof(*fmt));
@@ -2737,7 +2731,8 @@ zoran_do_ioctl (struct inode *inode,
                                fmt->fmt.pix.height =
                                    fh->v4l_settings.height;
                                fmt->fmt.pix.sizeimage =
-                                   fh->v4l_buffers.buffer_size;
+                                   fh->v4l_settings.bytesperline *
+                                   fh->v4l_settings.height;
                                fmt->fmt.pix.pixelformat =
                                    fh->v4l_settings.format->fourcc;
                                fmt->fmt.pix.colorspace =
@@ -2941,11 +2936,11 @@ zoran_do_ioctl (struct inode *inode,
                        sfmtjpg_unlock_and_return:
                                mutex_unlock(&zr->resource_lock);
                        } else {
-                               for (i = 0; i < zoran_num_formats; i++)
+                               for (i = 0; i < NUM_FORMATS; i++)
                                        if (fmt->fmt.pix.pixelformat ==
                                            zoran_formats[i].fourcc)
                                                break;
-                               if (i == zoran_num_formats) {
+                               if (i == NUM_FORMATS) {
                                        dprintk(1,
                                                KERN_ERR
                                                "%s: VIDIOC_S_FMT - unknown/unsupported format 0x%x (%4.4s)\n",
@@ -2984,8 +2979,9 @@ zoran_do_ioctl (struct inode *inode,
 
                                /* tell the user the
                                 * results/missing stuff */
-                               fmt->fmt.pix.sizeimage = fh->v4l_buffers.buffer_size    /*zr->gbpl * zr->gheight */
-                                   ;
+                               fmt->fmt.pix.sizeimage =
+                                       fh->v4l_settings.height *
+                                       fh->v4l_settings.bytesperline;
                                if (BUZ_MAX_HEIGHT <
                                    (fh->v4l_settings.height * 2))
                                        fmt->fmt.pix.field =
@@ -3053,10 +3049,10 @@ zoran_do_ioctl (struct inode *inode,
                        fb->fmt.bytesperline, fb->fmt.pixelformat,
                        (char *) &printformat);
 
-               for (i = 0; i < zoran_num_formats; i++)
+               for (i = 0; i < NUM_FORMATS; i++)
                        if (zoran_formats[i].fourcc == fb->fmt.pixelformat)
                                break;
-               if (i == zoran_num_formats) {
+               if (i == NUM_FORMATS) {
                        dprintk(1,
                                KERN_ERR
                                "%s: VIDIOC_S_FBUF - format=0x%x (%4.4s) not allowed\n",
@@ -3185,7 +3181,7 @@ zoran_do_ioctl (struct inode *inode,
                        "%s: VIDIOC_QUERYBUF - index=%d, type=%d\n",
                        ZR_DEVNAME(zr), buf->index, buf->type);
 
-               memset(buf, 0, sizeof(buf));
+               memset(buf, 0, sizeof(*buf));
                buf->type = type;
                buf->index = index;
 
@@ -3439,8 +3435,13 @@ zoran_do_ioctl (struct inode *inode,
                                goto strmoff_unlock_and_return;
 
                        /* unload capture */
-                       if (zr->v4l_memgrab_active)
+                       if (zr->v4l_memgrab_active) {
+                               unsigned long flags;
+
+                               spin_lock_irqsave(&zr->spinlock, flags);
                                zr36057_set_memgrab(zr, 0);
+                               spin_unlock_irqrestore(&zr->spinlock, flags);
+                       }
 
                        for (i = 0; i < fh->v4l_buffers.num_buffers; i++)
                                zr->v4l_buffers.buffer[i].state =
@@ -4149,11 +4150,11 @@ zoran_do_ioctl (struct inode *inode,
                                   V4L2_BUF_TYPE_VIDEO_CAPTURE) {
                                int i;
 
-                               for (i = 0; i < zoran_num_formats; i++)
+                               for (i = 0; i < NUM_FORMATS; i++)
                                        if (zoran_formats[i].fourcc ==
                                            fmt->fmt.pix.pixelformat)
                                                break;
-                               if (i == zoran_num_formats) {
+                               if (i == NUM_FORMATS) {
                                        res = -EINVAL;
                                        goto tryfmt_unlock_and_return;
                                }
@@ -4185,7 +4186,6 @@ zoran_do_ioctl (struct inode *inode,
                return 0;
        }
                break;
-#endif
 
        default:
                dprintk(1, KERN_DEBUG "%s: UNKNOWN ioctl cmd: 0x%x\n",
@@ -4213,8 +4213,8 @@ zoran_poll (struct file *file,
 {
        struct zoran_fh *fh = file->private_data;
        struct zoran *zr = fh->zr;
-       wait_queue_head_t *queue = NULL;
        int res = 0, frame;
+       unsigned long flags;
 
        /* we should check whether buffers are ready to be synced on
         * (w/o waits - O_NONBLOCK) here
@@ -4228,51 +4228,58 @@ zoran_poll (struct file *file,
 
        switch (fh->map_mode) {
        case ZORAN_MAP_MODE_RAW:
-               if (fh->v4l_buffers.active == ZORAN_FREE ||
-                   zr->v4l_pend_head == zr->v4l_pend_tail) {
-                       dprintk(1,
-                               "%s: zoran_poll() - no buffers queued\n",
-                               ZR_DEVNAME(zr));
-                       res = POLLNVAL;
-                       goto poll_unlock_and_return;
-               }
-               queue = &zr->v4l_capq;
-               frame = zr->v4l_pend[zr->v4l_pend_tail & V4L_MASK_FRAME];
-               poll_wait(file, queue, wait);
-               if (fh->v4l_buffers.buffer[frame].state == BUZ_STATE_DONE)
+               poll_wait(file, &zr->v4l_capq, wait);
+               frame = zr->v4l_pend[zr->v4l_sync_tail & V4L_MASK_FRAME];
+
+               spin_lock_irqsave(&zr->spinlock, flags);
+               dprintk(3,
+                       KERN_DEBUG
+                       "%s: %s() raw - active=%c, sync_tail=%lu/%c, pend_tail=%lu, pend_head=%lu\n",
+                       ZR_DEVNAME(zr), __func__,
+                       "FAL"[fh->v4l_buffers.active], zr->v4l_sync_tail,
+                       "UPMD"[zr->v4l_buffers.buffer[frame].state],
+                       zr->v4l_pend_tail, zr->v4l_pend_head);
+               /* Process is the one capturing? */
+               if (fh->v4l_buffers.active != ZORAN_FREE &&
+                   /* Buffer ready to DQBUF? */
+                   zr->v4l_buffers.buffer[frame].state == BUZ_STATE_DONE)
                        res = POLLIN | POLLRDNORM;
+               spin_unlock_irqrestore(&zr->spinlock, flags);
+
                break;
 
        case ZORAN_MAP_MODE_JPG_REC:
        case ZORAN_MAP_MODE_JPG_PLAY:
-               if (fh->jpg_buffers.active == ZORAN_FREE ||
-                   zr->jpg_que_head == zr->jpg_que_tail) {
-                       dprintk(1,
-                               "%s: zoran_poll() - no buffers queued\n",
-                               ZR_DEVNAME(zr));
-                       res = POLLNVAL;
-                       goto poll_unlock_and_return;
-               }
-               queue = &zr->jpg_capq;
+               poll_wait(file, &zr->jpg_capq, wait);
                frame = zr->jpg_pend[zr->jpg_que_tail & BUZ_MASK_FRAME];
-               poll_wait(file, queue, wait);
-               if (fh->jpg_buffers.buffer[frame].state == BUZ_STATE_DONE) {
+
+               spin_lock_irqsave(&zr->spinlock, flags);
+               dprintk(3,
+                       KERN_DEBUG
+                       "%s: %s() jpg - active=%c, que_tail=%lu/%c, que_head=%lu, dma=%lu/%lu\n",
+                       ZR_DEVNAME(zr), __func__,
+                       "FAL"[fh->jpg_buffers.active], zr->jpg_que_tail,
+                       "UPMD"[zr->jpg_buffers.buffer[frame].state],
+                       zr->jpg_que_head, zr->jpg_dma_tail, zr->jpg_dma_head);
+               if (fh->jpg_buffers.active != ZORAN_FREE &&
+                   zr->jpg_buffers.buffer[frame].state == BUZ_STATE_DONE) {
                        if (fh->map_mode == ZORAN_MAP_MODE_JPG_REC)
                                res = POLLIN | POLLRDNORM;
                        else
                                res = POLLOUT | POLLWRNORM;
                }
+               spin_unlock_irqrestore(&zr->spinlock, flags);
+
                break;
 
        default:
                dprintk(1,
+                       KERN_ERR
                        "%s: zoran_poll() - internal error, unknown map_mode=%d\n",
                        ZR_DEVNAME(zr), fh->map_mode);
                res = POLLNVAL;
-               goto poll_unlock_and_return;
        }
 
-poll_unlock_and_return:
        mutex_unlock(&zr->resource_lock);
 
        return res;
@@ -4368,11 +4375,15 @@ zoran_vm_close (struct vm_area_struct *vma)
                                mutex_lock(&zr->resource_lock);
 
                                if (fh->v4l_buffers.active != ZORAN_FREE) {
+                                       unsigned long flags;
+
+                                       spin_lock_irqsave(&zr->spinlock, flags);
                                        zr36057_set_memgrab(zr, 0);
                                        zr->v4l_buffers.allocated = 0;
                                        zr->v4l_buffers.active =
                                            fh->v4l_buffers.active =
                                            ZORAN_FREE;
+                                       spin_unlock_irqrestore(&zr->spinlock, flags);
                                }
                                //v4l_fbuffer_free(file);
                                fh->v4l_buffers.allocated = 0;
@@ -4495,7 +4506,7 @@ zoran_mmap (struct file           *file,
                                if (todo > fraglen)
                                        todo = fraglen;
                                pos =
-                                   le32_to_cpu((unsigned long) fh->jpg_buffers.
+                                   le32_to_cpu(fh->jpg_buffers.
                                    buffer[i].frag_tab[2 * j]);
                                /* should just be pos on i386 */
                                page = virt_to_phys(bus_to_virt(pos))
@@ -4621,7 +4632,9 @@ static const struct file_operations zoran_fops = {
        .open = zoran_open,
        .release = zoran_close,
        .ioctl = zoran_ioctl,
+#ifdef CONFIG_COMPAT
        .compat_ioctl   = v4l_compat_ioctl32,
+#endif
        .llseek = no_llseek,
        .read = zoran_read,
        .write = zoran_write,
@@ -4632,10 +4645,7 @@ static const struct file_operations zoran_fops = {
 struct video_device zoran_template __devinitdata = {
        .name = ZORAN_NAME,
        .type = ZORAN_VID_TYPE,
-#ifdef CONFIG_VIDEO_V4L2
        .type2 = ZORAN_V4L2_VID_FLAGS,
-#endif
-       .hardware = ZORAN_HARDWARE,
        .fops = &zoran_fops,
        .release = &zoran_vdev_release,
        .minor = -1