On Mon Aug 17 12:22:01 2026 +0530, Balakrishnan Sambath wrote:
> isc_stop_streaming() and the isc_start_streaming() error path dropped the
> runtime PM reference with the histogram still enabled. A HISDONE firing
> just before the stop, or a failed isc_update_profile() on the start path,
> can queue isc_awb_work(), which reads the histogram registers before
> taking its own PM reference and faults on the unclocked device.
> 
> Disable the histogram, synchronize the IRQ and flush the work before the
> device is left unclocked. isc_configure() is the one enabling the
> histogram and then calling isc_update_profile(), so do the cleanup in its
> own failure path; isc_stop_streaming() does the same on teardown.
> synchronize_irq() must come before cancel_work_sync(), so an in-flight
> handler cannot re-queue awb_work after it is cancelled.
> 
> Fixes: 93d4a26c3dab ("[media] atmel-isc: add the isc pipeline function")
> Cc: [email protected]
> Signed-off-by: Balakrishnan Sambath <[email protected]>
> Reviewed-by: Eugen Hristev <[email protected]>
> Signed-off-by: Hans Verkuil <[email protected]>

Patch committed.

Thanks,
Hans Verkuil

 drivers/media/platform/microchip/microchip-isc-base.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

---

diff --git a/drivers/media/platform/microchip/microchip-isc-base.c 
b/drivers/media/platform/microchip/microchip-isc-base.c
index debbc38717de..0f486dd5bd82 100644
--- a/drivers/media/platform/microchip/microchip-isc-base.c
+++ b/drivers/media/platform/microchip/microchip-isc-base.c
@@ -289,6 +289,7 @@ static int isc_configure(struct isc_device *isc)
        struct regmap *regmap = isc->regmap;
        u32 pfe_cfg0, dcfg, mask, pipeline;
        struct isc_subdev_entity *subdev = isc->current_subdev;
+       int ret;
 
        pfe_cfg0 = isc->config.sd_format->pfe_cfg0_bps;
        pipeline = isc->config.bits_pipeline;
@@ -321,7 +322,15 @@ static int isc_configure(struct isc_device *isc)
                isc_set_histogram(isc, false);
 
        /* Update profile */
-       return isc_update_profile(isc);
+       ret = isc_update_profile(isc);
+       if (ret) {
+               /* flush the histogram work before the clocks are gated */
+               isc_set_histogram(isc, false);
+               synchronize_irq(isc->irq);
+               cancel_work_sync(&isc->awb_work);
+       }
+
+       return ret;
 }
 
 static int isc_prepare_streaming(struct vb2_queue *vq)
@@ -425,9 +434,13 @@ static void isc_stop_streaming(struct vb2_queue *vq)
        /* Disable DMA interrupt */
        regmap_write(isc->regmap, ISC_INTDIS, ISC_INT_DDONE);
 
+       isc_set_histogram(isc, false);
+
        /* let a running IRQ handler finish before the clock is disabled */
        synchronize_irq(isc->irq);
 
+       cancel_work_sync(&isc->awb_work);
+
        pm_runtime_put_sync(isc->dev);
 
        /* Disable stream on the sub device */
_______________________________________________
linuxtv-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to