Hi, Julien: On Thu, 2024-11-21 at 09:53 +0100, Julien Stephan wrote: > External email : Please do not click links or open attachments until you have verified the sender or the content. > > > From: Phi-bang Nguyen <pnguyen@xxxxxxxxxxxx> > > This driver provides a path to bypass the SoC ISP so that image data > coming from the SENINF can go directly into memory without any image > processing. This allows the use of an external ISP. > > Signed-off-by: Phi-bang Nguyen <pnguyen@xxxxxxxxxxxx> > Signed-off-by: Florian Sylvestre <fsylvestre@xxxxxxxxxxxx> > [Paul Elder fix irq locking] > Signed-off-by: Paul Elder <paul.elder@xxxxxxxxxxxxxxxx> > Co-developed-by: Laurent Pinchart <laurent.pinchart@xxxxxxxxxxxxxxxx> > Signed-off-by: Laurent Pinchart <laurent.pinchart@xxxxxxxxxxxxxxxx> > Co-developed-by: Julien Stephan <jstephan@xxxxxxxxxxxx> > Signed-off-by: Julien Stephan <jstephan@xxxxxxxxxxxx> > --- [snip] > +static irqreturn_t isp_irq_camsv30(int irq, void *data) > +{ > + struct mtk_cam_dev *cam_dev = (struct mtk_cam_dev *)data; > + struct mtk_cam_dev_buffer *buf; > + unsigned int irq_status; > + > + spin_lock(&cam_dev->buf_list_lock); spin_lock region should be as small as possible. Move to where you start to access buf_list. > + > + irq_status = mtk_camsv30_read(cam_dev, CAMSV_INT_STATUS); > + > + if (irq_status & INT_ST_MASK_CAMSV_ERR) > + dev_err(cam_dev->dev, "irq error 0x%lx\n", > + irq_status & INT_ST_MASK_CAMSV_ERR); > + > + /* De-queue frame */ > + if (irq_status & CAMSV_IRQ_PASS1_DON) { > + cam_dev->sequence++; > + > + buf = list_first_entry_or_null(&cam_dev->buf_list, > + struct mtk_cam_dev_buffer, > + list); > + if (buf) { > + buf->v4l2_buf.sequence = cam_dev->sequence; > + buf->v4l2_buf.vb2_buf.timestamp = > + ktime_get_ns(); > + vb2_buffer_done(&buf->v4l2_buf.vb2_buf, > + VB2_BUF_STATE_DONE); These jobs could be done after buffer is deleted from list, and move these jobs out of this spin_lock region. vb2_buffer_done() looks like does many things. So it's worth to move vb2_buffer_done() out of this spin_lock region. spin_lock(); processed_buf = list_first_entry_or_null(); if (processed_buf) list_del(&processed_buf->list); spin_unlock(); if (processed_buf) { ... vb2_buffer_done(); } Regards, CK > + list_del(&buf->list); > + } > + > + buf = list_first_entry_or_null(&cam_dev->buf_list, > + struct mtk_cam_dev_buffer, > + list); > + if (buf) > + mtk_camsv30_update_buffers_add(cam_dev, buf); > + } > + > + spin_unlock(&cam_dev->buf_list_lock); > + > + return IRQ_HANDLED; > +} > + >