diff --git a/drivers/media/platform/nxp/dw100/dw100.c b/drivers/media/platform/nxp/dw100/dw100.c index a0a9a3f0dc1e..42748d0f0483 100644 --- a/drivers/media/platform/nxp/dw100/dw100.c +++ b/drivers/media/platform/nxp/dw100/dw100.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -74,6 +75,7 @@ struct dw100_device { struct clk_bulk_data *clks; int num_clks; struct dentry *debugfs_root; + bool frame_failed; }; struct dw100_q_data { @@ -1404,7 +1406,8 @@ static irqreturn_t dw100_irq_handler(int irq, void *dev_id) { struct dw100_device *dw_dev = dev_id; u32 pending_irqs, err_irqs, frame_done_irq; - bool with_error = true; + + dw_dev->frame_failed = true; pending_irqs = dw_hw_get_pending_irqs(dw_dev); frame_done_irq = pending_irqs & DW100_INTERRUPT_STATUS_INT_FRAME_DONE; @@ -1412,7 +1415,7 @@ static irqreturn_t dw100_irq_handler(int irq, void *dev_id) if (frame_done_irq) { dev_dbg(&dw_dev->pdev->dev, "Frame done interrupt\n"); - with_error = false; + dw_dev->frame_failed = false; err_irqs &= ~DW100_INTERRUPT_STATUS_INT_ERR_STATUS (DW100_INTERRUPT_STATUS_INT_ERR_FRAME_DONE); } @@ -1425,7 +1428,14 @@ static irqreturn_t dw100_irq_handler(int irq, void *dev_id) dw100_hw_clear_irq(dw_dev, pending_irqs | DW100_INTERRUPT_STATUS_INT_ERR_TIME_OUT); - dw100_job_finish(dw_dev, with_error); + return IRQ_WAKE_THREAD; +} + +static irqreturn_t dw100_irq_thread_fn(int irq, void *dev_id) +{ + struct dw100_device *dw_dev = dev_id; + + dw100_job_finish(dw_dev, dw_dev->frame_failed); return IRQ_HANDLED; } @@ -1594,8 +1604,9 @@ static int dw100_probe(struct platform_device *pdev) pm_runtime_put_sync(&pdev->dev); - ret = devm_request_irq(&pdev->dev, irq, dw100_irq_handler, IRQF_ONESHOT, - dev_name(&pdev->dev), dw_dev); + ret = devm_request_threaded_irq(&pdev->dev, irq, dw100_irq_handler, + dw100_irq_thread_fn, 0, + dev_name(&pdev->dev), dw_dev); if (ret < 0) { dev_err(&pdev->dev, "Failed to request irq: %d\n", ret); goto err_pm;