From f491cb1513203c1d45813e81eb944bfe1a57fbb6 Mon Sep 17 00:00:00 2001 From: lizhirong Date: Thu, 22 May 2025 09:31:57 +0800 Subject: [PATCH] k1:camera: fix the issue where udev scans nodes to release subdev node resource when the camera in use Change-Id: Ia1a058965c379875e3f0ff91d5a4a87774dcd34e Signed-off-by: lizhirong --- .../platform/spacemit/camera/vi/subdev.c | 30 ++++++++++++------- .../platform/spacemit/camera/vi/subdev.h | 1 + 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/drivers/media/platform/spacemit/camera/vi/subdev.c b/drivers/media/platform/spacemit/camera/vi/subdev.c index 2280bd21ebe3..e3c90de0cc9b 100644 --- a/drivers/media/platform/spacemit/camera/vi/subdev.c +++ b/drivers/media/platform/spacemit/camera/vi/subdev.c @@ -16,7 +16,11 @@ static int spm_subdev_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { struct spm_camera_subdev *sc_subdev = v4l2_subdev_to_sc_subdev(sd); - cam_dbg("%s(%s) enter.", __func__, sc_subdev->name); + cam_dbg("%s(%s) enter. cnt:%d", __func__, sc_subdev->name, atomic_read(&sc_subdev->ref_cnt)); + + if (atomic_inc_return(&sc_subdev->ref_cnt) != 1) + cam_warn("subdev(%s) was already openned.", sc_subdev->name); + return 0; } @@ -28,18 +32,22 @@ static int spm_subdev_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) struct spm_camera_subdev *sc_subdev = v4l2_subdev_to_sc_subdev(sd); struct media_pipeline *pipe = media_entity_pipeline(me); - cam_dbg("%s(%s) enter.", __func__, sc_subdev->name); - mutex_lock(&mdev->graph_mutex); - if (pipe) { - sc_pipeline = media_pipeline_to_sc_pipeline(pipe); - if (sc_pipeline->state >= PIPELINE_ST_STARTED) { - __spm_mlink_stop_pipeline(me); - } - while (sc_pipeline->state >= PIPELINE_ST_GET) { - __spm_mlink_put_pipeline(me, 1); + cam_dbg("%s(%s) enter. cnt:%d", __func__, sc_subdev->name, atomic_read(&sc_subdev->ref_cnt)); + + if (atomic_dec_and_test(&sc_subdev->ref_cnt)) { + mutex_lock(&mdev->graph_mutex); + if (pipe) { + sc_pipeline = media_pipeline_to_sc_pipeline(pipe); + if (sc_pipeline->state >= PIPELINE_ST_STARTED) { + __spm_mlink_stop_pipeline(me); + } + while (sc_pipeline->state >= PIPELINE_ST_GET) { + __spm_mlink_put_pipeline(me, 1); + } } + mutex_unlock(&mdev->graph_mutex); } - mutex_unlock(&mdev->graph_mutex); + return 0; } diff --git a/drivers/media/platform/spacemit/camera/vi/subdev.h b/drivers/media/platform/spacemit/camera/vi/subdev.h index 9e5d4208b71c..797fc9e16024 100644 --- a/drivers/media/platform/spacemit/camera/vi/subdev.h +++ b/drivers/media/platform/spacemit/camera/vi/subdev.h @@ -36,6 +36,7 @@ struct spm_camera_subdev { struct notifier_block vnode_nb; uint32_t pads_stream_enable; int is_resetting; + atomic_t ref_cnt; long (*ioctl)(struct v4l2_subdev *sd, unsigned int cmd, void *arg); void (*release)(struct spm_camera_subdev *sc_subdev); void (*notify)(struct spm_camera_subdev *sc_subdev, unsigned int notification,