diff options
Diffstat (limited to 'drivers/media/platform/aspeed-video.c')
-rw-r--r-- | drivers/media/platform/aspeed-video.c | 58 |
1 files changed, 35 insertions, 23 deletions
diff --git a/drivers/media/platform/aspeed-video.c b/drivers/media/platform/aspeed-video.c index eb12f3793062..d8593cb2ae84 100644 --- a/drivers/media/platform/aspeed-video.c +++ b/drivers/media/platform/aspeed-video.c @@ -606,6 +606,16 @@ static irqreturn_t aspeed_video_irq(int irq, void *arg) aspeed_video_start_frame(video); } + /* + * CAPTURE_COMPLETE and FRAME_COMPLETE interrupts come even when these + * are disabled in the VE_INTERRUPT_CTRL register so clear them to + * prevent unnecessary interrupt calls. + */ + if (sts & VE_INTERRUPT_CAPTURE_COMPLETE) + sts &= ~VE_INTERRUPT_CAPTURE_COMPLETE; + if (sts & VE_INTERRUPT_FRAME_COMPLETE) + sts &= ~VE_INTERRUPT_FRAME_COMPLETE; + return sts ? IRQ_NONE : IRQ_HANDLED; } @@ -614,7 +624,7 @@ static void aspeed_video_check_and_set_polarity(struct aspeed_video *video) int i; int hsync_counter = 0; int vsync_counter = 0; - u32 sts; + u32 sts, ctrl; for (i = 0; i < NUM_POLARITY_CHECKS; ++i) { sts = aspeed_video_read(video, VE_MODE_DETECT_STATUS); @@ -629,30 +639,29 @@ static void aspeed_video_check_and_set_polarity(struct aspeed_video *video) hsync_counter++; } - if (hsync_counter < 0 || vsync_counter < 0) { - u32 ctrl = 0; + ctrl = aspeed_video_read(video, VE_CTRL); - if (hsync_counter < 0) { - ctrl = VE_CTRL_HSYNC_POL; - video->detected_timings.polarities &= - ~V4L2_DV_HSYNC_POS_POL; - } else { - video->detected_timings.polarities |= - V4L2_DV_HSYNC_POS_POL; - } - - if (vsync_counter < 0) { - ctrl = VE_CTRL_VSYNC_POL; - video->detected_timings.polarities &= - ~V4L2_DV_VSYNC_POS_POL; - } else { - video->detected_timings.polarities |= - V4L2_DV_VSYNC_POS_POL; - } + if (hsync_counter < 0) { + ctrl |= VE_CTRL_HSYNC_POL; + video->detected_timings.polarities &= + ~V4L2_DV_HSYNC_POS_POL; + } else { + ctrl &= ~VE_CTRL_HSYNC_POL; + video->detected_timings.polarities |= + V4L2_DV_HSYNC_POS_POL; + } - if (ctrl) - aspeed_video_update(video, VE_CTRL, 0, ctrl); + if (vsync_counter < 0) { + ctrl |= VE_CTRL_VSYNC_POL; + video->detected_timings.polarities &= + ~V4L2_DV_VSYNC_POS_POL; + } else { + ctrl &= ~VE_CTRL_VSYNC_POL; + video->detected_timings.polarities |= + V4L2_DV_VSYNC_POS_POL; } + + aspeed_video_write(video, VE_CTRL, ctrl); } static bool aspeed_video_alloc_buf(struct aspeed_video *video, @@ -741,6 +750,8 @@ static void aspeed_video_get_resolution(struct aspeed_video *video) } set_bit(VIDEO_RES_DETECT, &video->flags); + aspeed_video_update(video, VE_CTRL, + VE_CTRL_VSYNC_POL | VE_CTRL_HSYNC_POL, 0); aspeed_video_enable_mode_detect(video); rc = wait_event_interruptible_timeout(video->wait, @@ -1646,7 +1657,8 @@ static int aspeed_video_probe(struct platform_device *pdev) { int rc; struct resource *res; - struct aspeed_video *video = kzalloc(sizeof(*video), GFP_KERNEL); + struct aspeed_video *video = + devm_kzalloc(&pdev->dev, sizeof(*video), GFP_KERNEL); if (!video) return -ENOMEM; |