aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video
diff options
context:
space:
mode:
authorJonathan Corbet <corbet@lwn.net>2012-03-16 18:14:53 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-03-19 21:16:19 -0400
commit121bbe254a46e075673e6b9eec5613ea16400ccc (patch)
treee263df14121003ed7e78eeec82ac3eaa61643fba /drivers/media/video
parent482d35c41f2efb0408624e222bbc9efc0b3518eb (diff)
[media] marvell-cam: fix the green screen of death
I had learned through hard experience that dinking around with the DMA descriptors while the C1_DESC_ENA enable bit was set is a recipe for all kinds of truly malicious behavior on the hardware's part, regardless of whether the DMA engine is actually operating at the time. That notwithstanding, the driver did so dink, resulting in "green frame" captures and the death of the system in random, spectacular ways. Move the tweaking of C1_DESC_ENA to the same function that sets the descriptor so we know that we'll never try to set a descriptor while that bit is set. Signed-off-by: Jonathan Corbet <corbet@lwn.net> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video')
-rw-r--r--drivers/media/video/marvell-ccic/mcam-core.c13
1 files changed, 6 insertions, 7 deletions
diff --git a/drivers/media/video/marvell-ccic/mcam-core.c b/drivers/media/video/marvell-ccic/mcam-core.c
index 050724f8d3e6..e46a72af63c4 100644
--- a/drivers/media/video/marvell-ccic/mcam-core.c
+++ b/drivers/media/video/marvell-ccic/mcam-core.c
@@ -509,11 +509,17 @@ static void mcam_sg_next_buffer(struct mcam_camera *cam)
509 509
510 buf = list_first_entry(&cam->buffers, struct mcam_vb_buffer, queue); 510 buf = list_first_entry(&cam->buffers, struct mcam_vb_buffer, queue);
511 list_del_init(&buf->queue); 511 list_del_init(&buf->queue);
512 /*
513 * Very Bad Not Good Things happen if you don't clear
514 * C1_DESC_ENA before making any descriptor changes.
515 */
516 mcam_reg_clear_bit(cam, REG_CTRL1, C1_DESC_ENA);
512 mcam_reg_write(cam, REG_DMA_DESC_Y, buf->dma_desc_pa); 517 mcam_reg_write(cam, REG_DMA_DESC_Y, buf->dma_desc_pa);
513 mcam_reg_write(cam, REG_DESC_LEN_Y, 518 mcam_reg_write(cam, REG_DESC_LEN_Y,
514 buf->dma_desc_nent*sizeof(struct mcam_dma_desc)); 519 buf->dma_desc_nent*sizeof(struct mcam_dma_desc));
515 mcam_reg_write(cam, REG_DESC_LEN_U, 0); 520 mcam_reg_write(cam, REG_DESC_LEN_U, 0);
516 mcam_reg_write(cam, REG_DESC_LEN_V, 0); 521 mcam_reg_write(cam, REG_DESC_LEN_V, 0);
522 mcam_reg_set_bit(cam, REG_CTRL1, C1_DESC_ENA);
517 cam->vb_bufs[0] = buf; 523 cam->vb_bufs[0] = buf;
518} 524}
519 525
@@ -533,7 +539,6 @@ static void mcam_ctlr_dma_sg(struct mcam_camera *cam)
533 539
534 mcam_reg_clear_bit(cam, REG_CTRL1, C1_DESC_3WORD); 540 mcam_reg_clear_bit(cam, REG_CTRL1, C1_DESC_3WORD);
535 mcam_sg_next_buffer(cam); 541 mcam_sg_next_buffer(cam);
536 mcam_reg_set_bit(cam, REG_CTRL1, C1_DESC_ENA);
537 cam->nbufs = 3; 542 cam->nbufs = 3;
538} 543}
539 544
@@ -561,17 +566,11 @@ static void mcam_dma_sg_done(struct mcam_camera *cam, int frame)
561 if (cam->state != S_STREAMING) 566 if (cam->state != S_STREAMING)
562 return; 567 return;
563 /* 568 /*
564 * Very Bad Not Good Things happen if you don't clear
565 * C1_DESC_ENA before making any descriptor changes.
566 */
567 mcam_reg_clear_bit(cam, REG_CTRL1, C1_DESC_ENA);
568 /*
569 * If we have another buffer available, put it in and 569 * If we have another buffer available, put it in and
570 * restart the engine. 570 * restart the engine.
571 */ 571 */
572 if (!list_empty(&cam->buffers)) { 572 if (!list_empty(&cam->buffers)) {
573 mcam_sg_next_buffer(cam); 573 mcam_sg_next_buffer(cam);
574 mcam_reg_set_bit(cam, REG_CTRL1, C1_DESC_ENA);
575 mcam_ctlr_start(cam); 574 mcam_ctlr_start(cam);
576 /* 575 /*
577 * Otherwise set CF_SG_RESTART and the controller will 576 * Otherwise set CF_SG_RESTART and the controller will