struct v4l2_control ctrl;
        bool reset_wdt_timer = false;
 
+       lockdep_assert_held(&isp->mutex);
+
        if (
            buf_type != IA_CSS_BUFFER_TYPE_METADATA &&
            buf_type != IA_CSS_BUFFER_TYPE_3A_STATISTICS &&
        bool stream_restart[MAX_STREAM_NUM] = {0};
        bool depth_mode = false;
        int i, ret, depth_cnt = 0;
+       unsigned long flags;
+
+       lockdep_assert_held(&isp->mutex);
 
        atomisp_css_irq_enable(isp, IA_CSS_IRQ_INFO_CSS_RECEIVER_SOF, false);
 
 
                stream_restart[asd->index] = true;
 
+               spin_lock_irqsave(&isp->lock, flags);
                asd->streaming = ATOMISP_DEVICE_STREAMING_STOPPING;
+               spin_unlock_irqrestore(&isp->lock, flags);
 
                /* stream off sensor */
                ret = v4l2_subdev_call(
                css_pipe_id = atomisp_get_css_pipe_id(asd);
                atomisp_css_stop(asd, css_pipe_id, true);
 
+               spin_lock_irqsave(&isp->lock, flags);
                asd->streaming = ATOMISP_DEVICE_STREAMING_DISABLED;
+               spin_unlock_irqrestore(&isp->lock, flags);
 
                asd->preview_exp_id = 1;
                asd->postview_exp_id = 1;
                                                   IA_CSS_INPUT_MODE_BUFFERED_SENSOR);
 
                css_pipe_id = atomisp_get_css_pipe_id(asd);
-               if (atomisp_css_start(asd, css_pipe_id, true))
+               if (atomisp_css_start(asd, css_pipe_id, true)) {
                        dev_warn(isp->dev,
                                 "start SP failed, so do not set streaming to be enable!\n");
-               else
+               } else {
+                       spin_lock_irqsave(&isp->lock, flags);
                        asd->streaming = ATOMISP_DEVICE_STREAMING_ENABLED;
+                       spin_unlock_irqrestore(&isp->lock, flags);
+               }
 
                atomisp_csi2_configure(asd);
        }
 {
        int i;
 
+       lockdep_assert_held(&isp->mutex);
+
        if (!atomisp_streaming_count(isp))
                return;
 
        unsigned long irqflags;
        bool need_to_enqueue_buffer = false;
 
+       lockdep_assert_held(&asd->isp->mutex);
+
        if (!asd) {
                dev_err(pipe->isp->dev, "%s(): asd is NULL, device is %s\n",
                        __func__, pipe->vdev.name);
        struct atomisp_css_params *css_param = &asd->params.css_param;
        int ret;
 
+       lockdep_assert_held(&asd->isp->mutex);
+
        if (!asd) {
                dev_err(pipe->isp->dev, "%s(): asd is NULL, device is %s\n",
                        __func__, vdev->name);
        struct v4l2_subdev_fh fh;
        int ret;
 
+       lockdep_assert_held(&isp->mutex);
+
        if (!asd) {
                dev_err(isp->dev, "%s(): asd is NULL, device is %s\n",
                        __func__, vdev->name);
 {
        struct v4l2_ctrl *c;
 
+       lockdep_assert_held(&asd->isp->mutex);
+
        /*
        * In case of M10MO ZSL capture case, we need to issue a separate
        * capture request to M10MO which will output captured jpeg image
        int value = *exp_id;
        int ret;
 
+       lockdep_assert_held(&isp->mutex);
+
        ret = __is_raw_buffer_locked(asd, value);
        if (ret) {
                dev_err(isp->dev, "%s exp_id %d invalid %d.\n", __func__, value, ret);
        int value = *exp_id;
        int ret;
 
+       lockdep_assert_held(&isp->mutex);
+
        ret = __clear_raw_buffer_bitmap(asd, value);
        if (ret) {
                dev_err(isp->dev, "%s exp_id %d invalid %d.\n", __func__, value, ret);
        if (!event || asd->streaming != ATOMISP_DEVICE_STREAMING_ENABLED)
                return -EINVAL;
 
+       lockdep_assert_held(&asd->isp->mutex);
+
        dev_dbg(asd->isp->dev, "%s: trying to inject a fake event 0x%x\n",
                __func__, *event);
 
 
        struct atomisp_dis_buf *dis_buf;
        unsigned long flags;
 
+       lockdep_assert_held(&isp->mutex);
+
        if (!asd->params.dvs_stat->hor_prod.odd_real ||
            !asd->params.dvs_stat->hor_prod.odd_imag ||
            !asd->params.dvs_stat->hor_prod.even_real ||
                return -EINVAL;
 
        /* isp needs to be streaming to get DIS statistics */
-       spin_lock_irqsave(&isp->lock, flags);
-       if (asd->streaming != ATOMISP_DEVICE_STREAMING_ENABLED) {
-               spin_unlock_irqrestore(&isp->lock, flags);
+       if (asd->streaming != ATOMISP_DEVICE_STREAMING_ENABLED)
                return -EINVAL;
-       }
-       spin_unlock_irqrestore(&isp->lock, flags);
 
        if (atomisp_compare_dvs_grid(asd, &stats->dvs2_stat.grid_info) != 0)
                /* If the grid info in the argument differs from the current
        bool reset_wdt_timer[MAX_STREAM_NUM] = {false};
        int i;
 
+       lockdep_assert_held(&isp->mutex);
+
        while (!ia_css_dequeue_psys_event(¤t_event.event)) {
                if (current_event.event.type ==
                    IA_CSS_EVENT_TYPE_FW_ASSERT) {
 
 {
        struct atomisp_sub_device *asd = container_of(
                                             ctrl->handler, struct atomisp_sub_device, ctrl_handler);
+       unsigned int streaming;
+       unsigned long flags;
 
        switch (ctrl->id) {
        case V4L2_CID_RUN_MODE:
                return __atomisp_update_run_mode(asd);
        case V4L2_CID_DEPTH_MODE:
-               if (asd->streaming != ATOMISP_DEVICE_STREAMING_DISABLED) {
+               /* Use spinlock instead of mutex to avoid possible locking issues */
+               spin_lock_irqsave(&asd->isp->lock, flags);
+               streaming = asd->streaming;
+               spin_unlock_irqrestore(&asd->isp->lock, flags);
+               if (streaming != ATOMISP_DEVICE_STREAMING_DISABLED) {
                        dev_err(asd->isp->dev,
                                "ISP is streaming, it is not supported to change the depth mode\n");
                        return -EINVAL;