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]