summaryrefslogtreecommitdiff
path: root/drivers/staging/media/ipu3
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/media/ipu3')
-rw-r--r--drivers/staging/media/ipu3/ipu3-css-params.c2
-rw-r--r--drivers/staging/media/ipu3/ipu3-mmu.c10
-rw-r--r--drivers/staging/media/ipu3/ipu3-v4l2.c10
-rw-r--r--drivers/staging/media/ipu3/ipu3.c5
-rw-r--r--drivers/staging/media/ipu3/ipu3.h4
5 files changed, 25 insertions, 6 deletions
diff --git a/drivers/staging/media/ipu3/ipu3-css-params.c b/drivers/staging/media/ipu3/ipu3-css-params.c
index 4533dacad4be..ef3b5d07137a 100644
--- a/drivers/staging/media/ipu3/ipu3-css-params.c
+++ b/drivers/staging/media/ipu3/ipu3-css-params.c
@@ -161,7 +161,7 @@ imgu_css_scaler_calc(u32 input_width, u32 input_height, u32 target_width,
memset(&cfg->scaler_coeffs_chroma, 0,
sizeof(cfg->scaler_coeffs_chroma));
- memset(&cfg->scaler_coeffs_luma, 0, sizeof(*cfg->scaler_coeffs_luma));
+ memset(&cfg->scaler_coeffs_luma, 0, sizeof(cfg->scaler_coeffs_luma));
do {
phase_step_correction++;
diff --git a/drivers/staging/media/ipu3/ipu3-mmu.c b/drivers/staging/media/ipu3/ipu3-mmu.c
index 3d969b0522ab..abcf1f3e5f63 100644
--- a/drivers/staging/media/ipu3/ipu3-mmu.c
+++ b/drivers/staging/media/ipu3/ipu3-mmu.c
@@ -174,8 +174,10 @@ static u32 *imgu_mmu_get_l2pt(struct imgu_mmu *mmu, u32 l1pt_idx)
spin_lock_irqsave(&mmu->lock, flags);
l2pt = mmu->l2pts[l1pt_idx];
- if (l2pt)
- goto done;
+ if (l2pt) {
+ spin_unlock_irqrestore(&mmu->lock, flags);
+ return l2pt;
+ }
spin_unlock_irqrestore(&mmu->lock, flags);
@@ -190,8 +192,9 @@ static u32 *imgu_mmu_get_l2pt(struct imgu_mmu *mmu, u32 l1pt_idx)
l2pt = mmu->l2pts[l1pt_idx];
if (l2pt) {
+ spin_unlock_irqrestore(&mmu->lock, flags);
imgu_mmu_free_page_table(new_l2pt);
- goto done;
+ return l2pt;
}
l2pt = new_l2pt;
@@ -200,7 +203,6 @@ static u32 *imgu_mmu_get_l2pt(struct imgu_mmu *mmu, u32 l1pt_idx)
pteval = IPU3_ADDR2PTE(virt_to_phys(new_l2pt));
mmu->l1pt[l1pt_idx] = pteval;
-done:
spin_unlock_irqrestore(&mmu->lock, flags);
return l2pt;
}
diff --git a/drivers/staging/media/ipu3/ipu3-v4l2.c b/drivers/staging/media/ipu3/ipu3-v4l2.c
index 3c7ad1eed434..c764cb55dc8d 100644
--- a/drivers/staging/media/ipu3/ipu3-v4l2.c
+++ b/drivers/staging/media/ipu3/ipu3-v4l2.c
@@ -367,8 +367,10 @@ static void imgu_vb2_buf_queue(struct vb2_buffer *vb)
vb2_set_plane_payload(vb, 0, need_bytes);
+ mutex_lock(&imgu->streaming_lock);
if (imgu->streaming)
imgu_queue_buffers(imgu, false, node->pipe);
+ mutex_unlock(&imgu->streaming_lock);
dev_dbg(&imgu->pci_dev->dev, "%s for pipe %u node %u", __func__,
node->pipe, node->id);
@@ -468,10 +470,13 @@ static int imgu_vb2_start_streaming(struct vb2_queue *vq, unsigned int count)
dev_dbg(dev, "%s node name %s pipe %u id %u", __func__,
node->name, node->pipe, node->id);
+ mutex_lock(&imgu->streaming_lock);
if (imgu->streaming) {
r = -EBUSY;
+ mutex_unlock(&imgu->streaming_lock);
goto fail_return_bufs;
}
+ mutex_unlock(&imgu->streaming_lock);
if (!node->enabled) {
dev_err(dev, "IMGU node is not enabled");
@@ -498,9 +503,11 @@ static int imgu_vb2_start_streaming(struct vb2_queue *vq, unsigned int count)
/* Start streaming of the whole pipeline now */
dev_dbg(dev, "IMGU streaming is ready to start");
+ mutex_lock(&imgu->streaming_lock);
r = imgu_s_stream(imgu, true);
if (!r)
imgu->streaming = true;
+ mutex_unlock(&imgu->streaming_lock);
return 0;
@@ -532,6 +539,7 @@ static void imgu_vb2_stop_streaming(struct vb2_queue *vq)
dev_err(&imgu->pci_dev->dev,
"failed to stop subdev streaming\n");
+ mutex_lock(&imgu->streaming_lock);
/* Was this the first node with streaming disabled? */
if (imgu->streaming && imgu_all_nodes_streaming(imgu, node)) {
/* Yes, really stop streaming now */
@@ -542,6 +550,8 @@ static void imgu_vb2_stop_streaming(struct vb2_queue *vq)
}
imgu_return_all_buffers(imgu, node, VB2_BUF_STATE_ERROR);
+ mutex_unlock(&imgu->streaming_lock);
+
media_pipeline_stop(&node->vdev.entity);
}
diff --git a/drivers/staging/media/ipu3/ipu3.c b/drivers/staging/media/ipu3/ipu3.c
index 06a61f31ca50..08eb6791918b 100644
--- a/drivers/staging/media/ipu3/ipu3.c
+++ b/drivers/staging/media/ipu3/ipu3.c
@@ -261,6 +261,7 @@ int imgu_queue_buffers(struct imgu_device *imgu, bool initial, unsigned int pipe
ivb = list_first_entry(&imgu_pipe->nodes[node].buffers,
struct imgu_vb2_buffer, list);
+ list_del(&ivb->list);
vb = &ivb->vbb.vb2_buf;
r = imgu_css_set_parameters(&imgu->css, pipe,
vb2_plane_vaddr(vb, 0));
@@ -274,7 +275,6 @@ int imgu_queue_buffers(struct imgu_device *imgu, bool initial, unsigned int pipe
vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
dev_dbg(&imgu->pci_dev->dev,
"queue user parameters %d to css.", vb->index);
- list_del(&ivb->list);
} else if (imgu_pipe->queue_enabled[node]) {
struct imgu_css_buffer *buf =
imgu_queue_getbuf(imgu, node, pipe);
@@ -663,6 +663,7 @@ static int imgu_pci_probe(struct pci_dev *pci_dev,
return r;
mutex_init(&imgu->lock);
+ mutex_init(&imgu->streaming_lock);
atomic_set(&imgu->qbuf_barrier, 0);
init_waitqueue_head(&imgu->buf_drain_wq);
@@ -726,6 +727,7 @@ out_mmu_exit:
out_css_powerdown:
imgu_css_set_powerdown(&pci_dev->dev, imgu->base);
out_mutex_destroy:
+ mutex_destroy(&imgu->streaming_lock);
mutex_destroy(&imgu->lock);
return r;
@@ -743,6 +745,7 @@ static void imgu_pci_remove(struct pci_dev *pci_dev)
imgu_css_set_powerdown(&pci_dev->dev, imgu->base);
imgu_dmamap_exit(imgu);
imgu_mmu_exit(imgu->mmu);
+ mutex_destroy(&imgu->streaming_lock);
mutex_destroy(&imgu->lock);
}
diff --git a/drivers/staging/media/ipu3/ipu3.h b/drivers/staging/media/ipu3/ipu3.h
index 73b123b2b8a2..8cd6a0077d99 100644
--- a/drivers/staging/media/ipu3/ipu3.h
+++ b/drivers/staging/media/ipu3/ipu3.h
@@ -146,6 +146,10 @@ struct imgu_device {
* vid_buf.list and css->queue
*/
struct mutex lock;
+
+ /* Lock to protect writes to streaming flag in this struct */
+ struct mutex streaming_lock;
+
/* Forbid streaming and buffer queuing during system suspend. */
atomic_t qbuf_barrier;
/* Indicate if system suspend take place while imgu is streaming. */