#include <linux/debugfs.h>
#include <linux/interrupt.h>
#include <linux/io.h>
+#include <linux/irqreturn.h>
#include <linux/minmax.h>
#include <linux/module.h>
#include <linux/of.h>
struct clk_bulk_data *clks;
int num_clks;
struct dentry *debugfs_root;
+ bool frame_failed;
};
struct dw100_q_data {
{
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;
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);
}
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;
}
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;