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

Commit a034d1b7 authored by Magnus Damm's avatar Magnus Damm Committed by Mauro Carvalho Chehab
Browse files

V4L/DVB (8338): soc_camera: Move spinlocks



This patch moves the spinlock handling from soc_camera.c to the actual
camera host driver. The spinlock_alloc/free callbacks are replaced with
code in init_videobuf(). So far all camera host drivers implement their
own spinlock_alloc/free methods anyway, and videobuf_queue_core_init()
BUGs on a NULL spinlock argument, so, new camera host drivers will not
forget to provide a spinlock when initialising their videobuf queues.

Signed-off-by: default avatarMagnus Damm <damm@igel.co.jp>
Signed-off-by: default avatarGuennadi Liakhovetski <g.liakhovetski@pengutronix.de>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@infradead.org>
parent 092d3921
Loading
Loading
Loading
Loading
+5 −12
Original line number Original line Diff line number Diff line
@@ -583,12 +583,15 @@ static struct videobuf_queue_ops pxa_videobuf_ops = {
	.buf_release    = pxa_videobuf_release,
	.buf_release    = pxa_videobuf_release,
};
};


static void pxa_camera_init_videobuf(struct videobuf_queue *q, spinlock_t *lock,
static void pxa_camera_init_videobuf(struct videobuf_queue *q,
			      struct soc_camera_device *icd)
			      struct soc_camera_device *icd)
{
{
	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
	struct pxa_camera_dev *pcdev = ici->priv;

	/* We must pass NULL as dev pointer, then all pci_* dma operations
	/* We must pass NULL as dev pointer, then all pci_* dma operations
	 * transform to normal dma_* ones. */
	 * transform to normal dma_* ones. */
	videobuf_queue_sg_init(q, &pxa_videobuf_ops, NULL, lock,
	videobuf_queue_sg_init(q, &pxa_videobuf_ops, NULL, &pcdev->lock,
				V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE,
				V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE,
				sizeof(struct pxa_buffer), icd);
				sizeof(struct pxa_buffer), icd);
}
}
@@ -994,15 +997,6 @@ static int pxa_camera_querycap(struct soc_camera_host *ici,
	return 0;
	return 0;
}
}


static spinlock_t *pxa_camera_spinlock_alloc(struct soc_camera_file *icf)
{
	struct soc_camera_host *ici =
		to_soc_camera_host(icf->icd->dev.parent);
	struct pxa_camera_dev *pcdev = ici->priv;

	return &pcdev->lock;
}

static struct soc_camera_host_ops pxa_soc_camera_host_ops = {
static struct soc_camera_host_ops pxa_soc_camera_host_ops = {
	.owner		= THIS_MODULE,
	.owner		= THIS_MODULE,
	.add		= pxa_camera_add_device,
	.add		= pxa_camera_add_device,
@@ -1015,7 +1009,6 @@ static struct soc_camera_host_ops pxa_soc_camera_host_ops = {
	.querycap	= pxa_camera_querycap,
	.querycap	= pxa_camera_querycap,
	.try_bus_param	= pxa_camera_try_bus_param,
	.try_bus_param	= pxa_camera_try_bus_param,
	.set_bus_param	= pxa_camera_set_bus_param,
	.set_bus_param	= pxa_camera_set_bus_param,
	.spinlock_alloc	= pxa_camera_spinlock_alloc,
};
};


/* Should be allocated dynamically too, but we have only one. */
/* Should be allocated dynamically too, but we have only one. */
+1 −38
Original line number Original line Diff line number Diff line
@@ -183,7 +183,6 @@ static int soc_camera_open(struct inode *inode, struct file *file)
	struct soc_camera_device *icd;
	struct soc_camera_device *icd;
	struct soc_camera_host *ici;
	struct soc_camera_host *ici;
	struct soc_camera_file *icf;
	struct soc_camera_file *icf;
	spinlock_t *lock;
	int ret;
	int ret;


	icf = vmalloc(sizeof(*icf));
	icf = vmalloc(sizeof(*icf));
@@ -210,13 +209,6 @@ static int soc_camera_open(struct inode *inode, struct file *file)
	}
	}


	icf->icd = icd;
	icf->icd = icd;

	icf->lock = ici->ops->spinlock_alloc(icf);
	if (!icf->lock) {
		ret = -ENOMEM;
		goto esla;
	}

	icd->use_count++;
	icd->use_count++;


	/* Now we really have to activate the camera */
	/* Now we really have to activate the camera */
@@ -234,17 +226,12 @@ static int soc_camera_open(struct inode *inode, struct file *file)
	file->private_data = icf;
	file->private_data = icf;
	dev_dbg(&icd->dev, "camera device open\n");
	dev_dbg(&icd->dev, "camera device open\n");


	ici->ops->init_videobuf(&icf->vb_vidq, icf->lock, icd);
	ici->ops->init_videobuf(&icf->vb_vidq, icd);


	return 0;
	return 0;


	/* All errors are entered with the video_lock held */
	/* All errors are entered with the video_lock held */
eiciadd:
eiciadd:
	lock = icf->lock;
	icf->lock = NULL;
	if (ici->ops->spinlock_free)
		ici->ops->spinlock_free(lock);
esla:
	module_put(ici->ops->owner);
	module_put(ici->ops->owner);
emgi:
emgi:
	module_put(icd->ops->owner);
	module_put(icd->ops->owner);
@@ -260,15 +247,11 @@ static int soc_camera_close(struct inode *inode, struct file *file)
	struct soc_camera_device *icd = icf->icd;
	struct soc_camera_device *icd = icf->icd;
	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
	struct video_device *vdev = icd->vdev;
	struct video_device *vdev = icd->vdev;
	spinlock_t *lock = icf->lock;


	mutex_lock(&video_lock);
	mutex_lock(&video_lock);
	icd->use_count--;
	icd->use_count--;
	if (!icd->use_count)
	if (!icd->use_count)
		ici->ops->remove(icd);
		ici->ops->remove(icd);
	icf->lock = NULL;
	if (ici->ops->spinlock_free)
		ici->ops->spinlock_free(lock);
	module_put(icd->ops->owner);
	module_put(icd->ops->owner);
	module_put(ici->ops->owner);
	module_put(ici->ops->owner);
	mutex_unlock(&video_lock);
	mutex_unlock(&video_lock);
@@ -764,21 +747,6 @@ static void dummy_release(struct device *dev)
{
{
}
}


static spinlock_t *spinlock_alloc(struct soc_camera_file *icf)
{
	spinlock_t *lock = kmalloc(sizeof(spinlock_t), GFP_KERNEL);

	if (lock)
		spin_lock_init(lock);

	return lock;
}

static void spinlock_free(spinlock_t *lock)
{
	kfree(lock);
}

int soc_camera_host_register(struct soc_camera_host *ici)
int soc_camera_host_register(struct soc_camera_host *ici)
{
{
	int ret;
	int ret;
@@ -808,11 +776,6 @@ int soc_camera_host_register(struct soc_camera_host *ici)
	if (ret)
	if (ret)
		goto edevr;
		goto edevr;


	if (!ici->ops->spinlock_alloc) {
		ici->ops->spinlock_alloc = spinlock_alloc;
		ici->ops->spinlock_free = spinlock_free;
	}

	scan_add_host(ici);
	scan_add_host(ici);


	return 0;
	return 0;
+1 −4
Original line number Original line Diff line number Diff line
@@ -48,7 +48,6 @@ struct soc_camera_device {
struct soc_camera_file {
struct soc_camera_file {
	struct soc_camera_device *icd;
	struct soc_camera_device *icd;
	struct videobuf_queue vb_vidq;
	struct videobuf_queue vb_vidq;
	spinlock_t *lock;
};
};


struct soc_camera_host {
struct soc_camera_host {
@@ -67,15 +66,13 @@ struct soc_camera_host_ops {
	int (*set_fmt_cap)(struct soc_camera_device *, __u32,
	int (*set_fmt_cap)(struct soc_camera_device *, __u32,
			   struct v4l2_rect *);
			   struct v4l2_rect *);
	int (*try_fmt_cap)(struct soc_camera_device *, struct v4l2_format *);
	int (*try_fmt_cap)(struct soc_camera_device *, struct v4l2_format *);
	void (*init_videobuf)(struct videobuf_queue*, spinlock_t *,
	void (*init_videobuf)(struct videobuf_queue *,
			      struct soc_camera_device *);
			      struct soc_camera_device *);
	int (*reqbufs)(struct soc_camera_file *, struct v4l2_requestbuffers *);
	int (*reqbufs)(struct soc_camera_file *, struct v4l2_requestbuffers *);
	int (*querycap)(struct soc_camera_host *, struct v4l2_capability *);
	int (*querycap)(struct soc_camera_host *, struct v4l2_capability *);
	int (*try_bus_param)(struct soc_camera_device *, __u32);
	int (*try_bus_param)(struct soc_camera_device *, __u32);
	int (*set_bus_param)(struct soc_camera_device *, __u32);
	int (*set_bus_param)(struct soc_camera_device *, __u32);
	unsigned int (*poll)(struct file *, poll_table *);
	unsigned int (*poll)(struct file *, poll_table *);
	spinlock_t* (*spinlock_alloc)(struct soc_camera_file *);
	void (*spinlock_free)(spinlock_t *);
};
};


struct soc_camera_link {
struct soc_camera_link {