/*
* TODO:
* - remove "mark pages reserved-hacks" from memory allocation code
- * and implement nopage()
+ * and implement fault()
* - check decimation, calculating and reporting image size when
* using decimation
* - implement read(), user mode buffers and overlay (?)
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/mm.h>
-#include <linux/moduleparam.h>
#include <linux/time.h>
#include <linux/version.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-sgi.h>
-#include <linux/videodev.h>
#include <linux/videodev2.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-common.h>
#include <linux/video_decoder.h>
+#include <linux/mutex.h>
#include <asm/paccess.h>
#include <asm/io.h>
struct vino_framebuffer *buffer[VINO_FRAMEBUFFER_COUNT_MAX];
spinlock_t queue_lock;
- struct semaphore queue_sem;
+ struct mutex queue_mutex;
wait_queue_head_t frame_wait_queue;
};
/* the driver is currently processing the queue */
int capturing;
- struct semaphore sem;
+ struct mutex mutex;
spinlock_t capture_lock;
unsigned int users;
*
* Use non-zero value to enable conversion.
*/
-static int vino_pixel_conversion = 0;
+static int vino_pixel_conversion;
module_param_named(pixelconv, vino_pixel_conversion, int, 0);
static int vino_i2c_del_bus(void)
{
- return i2c_sgi_del_bus(&vino_i2c_adapter);
+ return i2c_del_adapter(&vino_i2c_adapter);
}
static int i2c_camera_command(unsigned int cmd, void *arg)
if (q->type != VINO_MEMORY_MMAP)
return;
- down(&q->queue_sem);
+ mutex_lock(&q->queue_mutex);
vino_queue_free_with_count(q, q->length);
- up(&q->queue_sem);
+ mutex_unlock(&q->queue_mutex);
}
static int vino_queue_init(struct vino_framebuffer_queue *q,
if (*length < 1)
return -EINVAL;
- down(&q->queue_sem);
+ mutex_lock(&q->queue_mutex);
if (*length > VINO_FRAMEBUFFER_COUNT_MAX)
*length = VINO_FRAMEBUFFER_COUNT_MAX;
q->magic = VINO_QUEUE_MAGIC;
}
- up(&q->queue_sem);
+ mutex_unlock(&q->queue_mutex);
return ret;
}
unsigned int w = vcs->clipping.right - vcs->clipping.left;
unsigned int d = vcs->decimation;
unsigned int bpp = vino_data_formats[vcs->data_format].bpp;
- unsigned int lsize;
+ unsigned int lsize;
dprintk("update_line_size(): before: w = %d, d = %d, "
"line_size = %d\n", w, d, vcs->line_size);
- /* line size must be multiple of 8 bytes */
+ /* line size must be multiple of 8 bytes */
lsize = (bpp * (w / d)) & ~7;
w = (lsize / bpp) * d;
init_waitqueue_entry(&wait, current);
/* add ourselves into wait queue */
add_wait_queue(&vcs->fb_queue.frame_wait_queue, &wait);
- /* and set current state */
- set_current_state(TASK_INTERRUPTIBLE);
/* to ensure that schedule_timeout will return immediately
- * if VINO interrupt was triggred meanwhile */
- schedule_timeout(HZ / 10);
+ * if VINO interrupt was triggered meanwhile */
+ schedule_timeout_interruptible(msecs_to_jiffies(100));
if (signal_pending(current))
err = -EINTR;
}
}
-static irqreturn_t vino_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t vino_interrupt(int irq, void *dev_id)
{
u32 ctrl, intr;
unsigned int fc_a, fc_b;
/* First try D1 and then SAA7191 */
if (vino_drvdata->camera.driver
&& (vino_drvdata->camera.owner == VINO_NO_CHANNEL)) {
- if (i2c_use_client(vino_drvdata->camera.driver)) {
- ret = -ENODEV;
- goto out;
- }
-
+ i2c_use_client(vino_drvdata->camera.driver);
vino_drvdata->camera.owner = vcs->channel;
vcs->input = VINO_INPUT_D1;
vcs->data_norm = VINO_DATA_NORM_D1;
int input, data_norm;
int saa7191_input;
- if (i2c_use_client(vino_drvdata->decoder.driver)) {
- ret = -ENODEV;
- goto out;
- }
-
+ i2c_use_client(vino_drvdata->decoder.driver);
input = VINO_INPUT_COMPOSITE;
saa7191_input = vino_get_saa7191_input(input);
}
if (vino_drvdata->decoder.owner == VINO_NO_CHANNEL) {
- if (i2c_use_client(vino_drvdata->decoder.driver)) {
- ret = -ENODEV;
- goto out;
- }
+ i2c_use_client(vino_drvdata->decoder.driver);
vino_drvdata->decoder.owner = vcs->channel;
}
}
if (vino_drvdata->camera.owner == VINO_NO_CHANNEL) {
- if (i2c_use_client(vino_drvdata->camera.driver)) {
- ret = -ENODEV;
- goto out;
- }
+ i2c_use_client(vino_drvdata->camera.driver);
vino_drvdata->camera.owner = vcs->channel;
}
dprintk("open(): channel = %c\n",
(vcs->channel == VINO_CHANNEL_A) ? 'A' : 'B');
- down(&vcs->sem);
+ mutex_lock(&vcs->mutex);
if (vcs->users) {
dprintk("open(): driver busy\n");
vcs->users++;
out:
- up(&vcs->sem);
+ mutex_unlock(&vcs->mutex);
dprintk("open(): %s!\n", ret ? "failed" : "complete");
struct vino_channel_settings *vcs = video_get_drvdata(dev);
dprintk("close():\n");
- down(&vcs->sem);
+ mutex_lock(&vcs->mutex);
vcs->users--;
vino_queue_free(&vcs->fb_queue);
}
- up(&vcs->sem);
+ mutex_unlock(&vcs->mutex);
return 0;
}
// TODO: reject mmap if already mapped
- if (down_interruptible(&vcs->sem))
+ if (mutex_lock_interruptible(&vcs->mutex))
return -EINTR;
if (vcs->reading) {
vma->vm_ops = &vino_vm_ops;
out:
- up(&vcs->sem);
+ mutex_unlock(&vcs->mutex);
return ret;
}
struct vino_channel_settings *vcs = video_get_drvdata(dev);
int ret;
- if (down_interruptible(&vcs->sem))
+ if (mutex_lock_interruptible(&vcs->mutex))
return -EINTR;
ret = video_usercopy(inode, file, cmd, arg, vino_do_ioctl);
- up(&vcs->sem);
+ mutex_unlock(&vcs->mutex);
return ret;
}
/* Initialization and cleanup */
-// __initdata
-static int vino_init_stage = 0;
+/* __initdata */
+static int vino_init_stage;
-static struct file_operations vino_fops = {
+static const struct file_operations vino_fops = {
.owner = THIS_MODULE,
.open = vino_open,
.release = vino_close,
static struct video_device v4l_device_template = {
.name = "NOT SET",
- //.type = VID_TYPE_CAPTURE | VID_TYPE_SUBCAPTURE |
- // VID_TYPE_CLIPPING | VID_TYPE_SCALES, VID_TYPE_OVERLAY
- .hardware = VID_HARDWARE_VINO,
.fops = &vino_fops,
.minor = -1,
};
vcs->capturing = 0;
- init_MUTEX(&vcs->sem);
+ mutex_init(&vcs->mutex);
spin_lock_init(&vcs->capture_lock);
- init_MUTEX(&vcs->fb_queue.queue_sem);
+ mutex_init(&vcs->fb_queue.queue_mutex);
spin_lock_init(&vcs->fb_queue.queue_lock);
init_waitqueue_head(&vcs->fb_queue.frame_wait_queue);