media: rockchip: rkisp1: allow separate interrupts
authorHeiko Stuebner <heiko.stuebner@theobroma-systems.com>
Fri, 23 Jul 2021 07:32:15 +0000 (09:32 +0200)
committerMauro Carvalho Chehab <mchehab+huawei@kernel.org>
Thu, 30 Sep 2021 08:07:36 +0000 (10:07 +0200)
Depending on the per-soc implementation there can be one interrupt
for isp, mipi and capture events or separate per-event interrupts.

So simply check for the presence of a named "mi" interrupt
to differentiate between the two cases.

Signed-off-by: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>
Reviewed-by: Dafna Hirschfeld <dafna.hirschfeld@collabora.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c
drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c

index 41988eb..768987d 100644 (file)
@@ -685,12 +685,17 @@ static void rkisp1_handle_buffer(struct rkisp1_capture *cap)
        spin_unlock(&cap->buf.lock);
 }
 
-void rkisp1_capture_isr(struct rkisp1_device *rkisp1)
+irqreturn_t rkisp1_capture_isr(int irq, void *ctx)
 {
+       struct device *dev = ctx;
+       struct rkisp1_device *rkisp1 = dev_get_drvdata(dev);
        unsigned int i;
        u32 status;
 
        status = rkisp1_read(rkisp1, RKISP1_CIF_MI_MIS);
+       if (!status)
+               return IRQ_NONE;
+
        rkisp1_write(rkisp1, status, RKISP1_CIF_MI_ICR);
 
        for (i = 0; i < ARRAY_SIZE(rkisp1->capture_devs); ++i) {
@@ -718,6 +723,8 @@ void rkisp1_capture_isr(struct rkisp1_device *rkisp1)
                cap->is_streaming = false;
                wake_up(&cap->done);
        }
+
+       return IRQ_HANDLED;
 }
 
 /* ----------------------------------------------------------------------------
index 785e916..36ce4a0 100644 (file)
@@ -12,6 +12,7 @@
 #define _RKISP1_COMMON_H
 
 #include <linux/clk.h>
+#include <linux/interrupt.h>
 #include <linux/mutex.h>
 #include <linux/rkisp1-config.h>
 #include <media/media-device.h>
@@ -455,9 +456,9 @@ void rkisp1_params_configure(struct rkisp1_params *params,
 void rkisp1_params_disable(struct rkisp1_params *params);
 
 /* irq handlers */
-void rkisp1_isp_isr(struct rkisp1_device *rkisp1);
-void rkisp1_mipi_isr(struct rkisp1_device *rkisp1);
-void rkisp1_capture_isr(struct rkisp1_device *rkisp1);
+irqreturn_t rkisp1_isp_isr(int irq, void *ctx);
+irqreturn_t rkisp1_mipi_isr(int irq, void *ctx);
+irqreturn_t rkisp1_capture_isr(int irq, void *ctx);
 void rkisp1_stats_isr(struct rkisp1_stats *stats, u32 isp_ris);
 void rkisp1_params_isr(struct rkisp1_device *rkisp1);
 
index 5d96417..b5e35b1 100644 (file)
  *  +-----------+    +-----------+
  */
 
+struct rkisp1_isr_data {
+       const char *name;
+       irqreturn_t (*isr)(int irq, void *ctx);
+};
+
 struct rkisp1_match_data {
        const char * const *clks;
-       unsigned int size;
+       unsigned int clk_size;
+       const struct rkisp1_isr_data *isrs;
+       unsigned int isr_size;
        enum rkisp1_cif_isp_version isp_ver;
 };
 
@@ -386,18 +393,15 @@ err_unreg_isp_subdev:
 
 static irqreturn_t rkisp1_isr(int irq, void *ctx)
 {
-       struct device *dev = ctx;
-       struct rkisp1_device *rkisp1 = dev_get_drvdata(dev);
-
        /*
         * Call rkisp1_capture_isr() first to handle the frame that
         * potentially completed using the current frame_sequence number before
         * it is potentially incremented by rkisp1_isp_isr() in the vertical
         * sync.
         */
-       rkisp1_capture_isr(rkisp1);
-       rkisp1_isp_isr(rkisp1);
-       rkisp1_mipi_isr(rkisp1);
+       rkisp1_capture_isr(irq, ctx);
+       rkisp1_isp_isr(irq, ctx);
+       rkisp1_mipi_isr(irq, ctx);
 
        return IRQ_HANDLED;
 }
@@ -408,9 +412,15 @@ static const char * const rk3399_isp_clks[] = {
        "hclk",
 };
 
+static const struct rkisp1_isr_data rk3399_isp_isrs[] = {
+       { NULL, rkisp1_isr },
+};
+
 static const struct rkisp1_match_data rk3399_isp_match_data = {
        .clks = rk3399_isp_clks,
-       .size = ARRAY_SIZE(rk3399_isp_clks),
+       .clk_size = ARRAY_SIZE(rk3399_isp_clks),
+       .isrs = rk3399_isp_isrs,
+       .isr_size = ARRAY_SIZE(rk3399_isp_isrs),
        .isp_ver = RKISP1_V10,
 };
 
@@ -479,23 +489,27 @@ static int rkisp1_probe(struct platform_device *pdev)
        if (IS_ERR(rkisp1->base_addr))
                return PTR_ERR(rkisp1->base_addr);
 
-       irq = platform_get_irq(pdev, 0);
-       if (irq < 0)
-               return irq;
-
-       ret = devm_request_irq(dev, irq, rkisp1_isr, IRQF_SHARED,
-                              dev_driver_string(dev), dev);
-       if (ret) {
-               dev_err(dev, "request irq failed: %d\n", ret);
-               return ret;
+       for (i = 0; i < match_data->isr_size; i++) {
+               irq = (match_data->isrs[i].name) ?
+                               platform_get_irq_byname(pdev, match_data->isrs[i].name) :
+                               platform_get_irq(pdev, i);
+               if (irq < 0)
+                       return irq;
+
+               ret = devm_request_irq(dev, irq, match_data->isrs[i].isr, IRQF_SHARED,
+                                      dev_driver_string(dev), dev);
+               if (ret) {
+                       dev_err(dev, "request irq failed: %d\n", ret);
+                       return ret;
+               }
        }
 
-       for (i = 0; i < match_data->size; i++)
+       for (i = 0; i < match_data->clk_size; i++)
                rkisp1->clks[i].id = match_data->clks[i];
-       ret = devm_clk_bulk_get(dev, match_data->size, rkisp1->clks);
+       ret = devm_clk_bulk_get(dev, match_data->clk_size, rkisp1->clks);
        if (ret)
                return ret;
-       rkisp1->clk_size = match_data->size;
+       rkisp1->clk_size = match_data->clk_size;
 
        pm_runtime_enable(&pdev->dev);
 
index d596bc0..d7c422c 100644 (file)
@@ -1106,13 +1106,15 @@ void rkisp1_isp_unregister(struct rkisp1_device *rkisp1)
  * Interrupt handlers
  */
 
-void rkisp1_mipi_isr(struct rkisp1_device *rkisp1)
+irqreturn_t rkisp1_mipi_isr(int irq, void *ctx)
 {
+       struct device *dev = ctx;
+       struct rkisp1_device *rkisp1 = dev_get_drvdata(dev);
        u32 val, status;
 
        status = rkisp1_read(rkisp1, RKISP1_CIF_MIPI_MIS);
        if (!status)
-               return;
+               return IRQ_NONE;
 
        rkisp1_write(rkisp1, status, RKISP1_CIF_MIPI_ICR);
 
@@ -1147,6 +1149,8 @@ void rkisp1_mipi_isr(struct rkisp1_device *rkisp1)
        } else {
                rkisp1->debug.mipi_error++;
        }
+
+       return IRQ_HANDLED;
 }
 
 static void rkisp1_isp_queue_event_sof(struct rkisp1_isp *isp)
@@ -1159,13 +1163,15 @@ static void rkisp1_isp_queue_event_sof(struct rkisp1_isp *isp)
        v4l2_event_queue(isp->sd.devnode, &event);
 }
 
-void rkisp1_isp_isr(struct rkisp1_device *rkisp1)
+irqreturn_t rkisp1_isp_isr(int irq, void *ctx)
 {
+       struct device *dev = ctx;
+       struct rkisp1_device *rkisp1 = dev_get_drvdata(dev);
        u32 status, isp_err;
 
        status = rkisp1_read(rkisp1, RKISP1_CIF_ISP_MIS);
        if (!status)
-               return;
+               return IRQ_NONE;
 
        rkisp1_write(rkisp1, status, RKISP1_CIF_ISP_ICR);
 
@@ -1207,4 +1213,6 @@ void rkisp1_isp_isr(struct rkisp1_device *rkisp1)
                 */
                rkisp1_params_isr(rkisp1);
        }
+
+       return IRQ_HANDLED;
 }