]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
media: rzg2l-cru: Add IRQ handler to OF data
authorLad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Fri, 11 Apr 2025 17:05:42 +0000 (19:05 +0200)
committerHans Verkuil <hverkuil@xs4all.nl>
Wed, 23 Apr 2025 08:55:53 +0000 (10:55 +0200)
Add `irq_handler` to the `rzg2l_cru_info` structure and pass it as part of
the OF data. This prepares for supporting RZ/G3E and RZ/V2H(P) SoCs, which
require a different IRQ handler. Update the IRQ request code to use the
handler from the OF data.

Add `enable_interrupts` and `disable_interrupts` function pointers to the
`rzg2l_cru_info` structure and pass them as part of the OF data. This
prepares for supporting RZ/G3E and RZ/V2H(P) SoCs, which require different
interrupt configurations.

Implement `rzg2l_cru_enable_interrupts()` and
`rzg2l_cru_disable_interrupts()` functions and update the code to use them
instead of directly writing to interrupt registers.

Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
Link: https://lore.kernel.org/r/20250411170624.472257-15-tommaso.merciai.xr@bp.renesas.com
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
drivers/media/platform/renesas/rzg2l-cru/rzg2l-core.c
drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h
drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c

index e7fef7f3f8223cf8063579ba5312b321f5093b68..ae989fa2768b3544ac6d2a3868f98aa282c2d6e4 100644 (file)
@@ -275,7 +275,7 @@ static int rzg2l_cru_probe(struct platform_device *pdev)
        if (irq < 0)
                return irq;
 
-       ret = devm_request_irq(dev, irq, rzg2l_cru_irq, 0,
+       ret = devm_request_irq(dev, irq, cru->info->irq_handler, 0,
                               KBUILD_MODNAME, cru);
        if (ret)
                return dev_err_probe(dev, ret, "failed to request irq\n");
@@ -356,6 +356,9 @@ static const struct rzg2l_cru_info rzgl2_cru_info = {
        .max_height = 4095,
        .image_conv = ICnMC,
        .regs = rzg2l_cru_regs,
+       .irq_handler = rzg2l_cru_irq,
+       .enable_interrupts = rzg2l_cru_enable_interrupts,
+       .disable_interrupts = rzg2l_cru_disable_interrupts,
 };
 
 static const struct of_device_id rzg2l_cru_of_id_table[] = {
index ca156772b949b0eb544e5919e4965a0b5409fb7b..3f694044d8cd10d25eb5a67db3995f39c65b8c67 100644 (file)
@@ -34,6 +34,8 @@ enum rzg2l_csi2_pads {
        RZG2L_CRU_IP_SOURCE,
 };
 
+struct rzg2l_cru_dev;
+
 /**
  * enum rzg2l_cru_dma_state - DMA states
  * @RZG2L_CRU_DMA_STOPPED:   No operation in progress
@@ -83,6 +85,9 @@ struct rzg2l_cru_info {
        unsigned int max_height;
        u16 image_conv;
        const u16 *regs;
+       irqreturn_t (*irq_handler)(int irq, void *data);
+       void (*enable_interrupts)(struct rzg2l_cru_dev *cru);
+       void (*disable_interrupts)(struct rzg2l_cru_dev *cru);
 };
 
 /**
@@ -177,4 +182,7 @@ const struct rzg2l_cru_ip_format *rzg2l_cru_ip_code_to_fmt(unsigned int code);
 const struct rzg2l_cru_ip_format *rzg2l_cru_ip_format_to_fmt(u32 format);
 const struct rzg2l_cru_ip_format *rzg2l_cru_ip_index_to_fmt(u32 index);
 
+void rzg2l_cru_enable_interrupts(struct rzg2l_cru_dev *cru);
+void rzg2l_cru_disable_interrupts(struct rzg2l_cru_dev *cru);
+
 #endif
index 95cce250b3272021cb3f4f9504f6a60eeae145fd..a104821d823f9123e6e5fb6e94522792861b6c38 100644 (file)
@@ -300,8 +300,7 @@ void rzg2l_cru_stop_image_processing(struct rzg2l_cru_dev *cru)
        spin_lock_irqsave(&cru->qlock, flags);
 
        /* Disable and clear the interrupt */
-       rzg2l_cru_write(cru, CRUnIE, 0);
-       rzg2l_cru_write(cru, CRUnINTS, 0x001F0F0F);
+       cru->info->disable_interrupts(cru);
 
        /* Stop the operation of image conversion */
        rzg2l_cru_write(cru, ICnEN, 0);
@@ -393,6 +392,17 @@ static int rzg2l_cru_get_virtual_channel(struct rzg2l_cru_dev *cru)
        return fd.entry[0].bus.csi2.vc;
 }
 
+void rzg2l_cru_enable_interrupts(struct rzg2l_cru_dev *cru)
+{
+       rzg2l_cru_write(cru, CRUnIE, CRUnIE_EFE);
+}
+
+void rzg2l_cru_disable_interrupts(struct rzg2l_cru_dev *cru)
+{
+       rzg2l_cru_write(cru, CRUnIE, 0);
+       rzg2l_cru_write(cru, CRUnINTS, 0x001f000f);
+}
+
 int rzg2l_cru_start_image_processing(struct rzg2l_cru_dev *cru)
 {
        struct v4l2_mbus_framefmt *fmt = rzg2l_cru_ip_get_src_fmt(cru);
@@ -414,8 +424,7 @@ int rzg2l_cru_start_image_processing(struct rzg2l_cru_dev *cru)
        rzg2l_cru_write(cru, CRUnRST, CRUnRST_VRESETN);
 
        /* Disable and clear the interrupt before using */
-       rzg2l_cru_write(cru, CRUnIE, 0);
-       rzg2l_cru_write(cru, CRUnINTS, 0x001f000f);
+       cru->info->disable_interrupts(cru);
 
        /* Initialize the AXI master */
        rzg2l_cru_initialize_axi(cru);
@@ -428,7 +437,7 @@ int rzg2l_cru_start_image_processing(struct rzg2l_cru_dev *cru)
        }
 
        /* Enable interrupt */
-       rzg2l_cru_write(cru, CRUnIE, CRUnIE_EFE);
+       cru->info->enable_interrupts(cru);
 
        /* Enable image processing reception */
        rzg2l_cru_write(cru, ICnEN, ICnEN_ICEN);