|
@@ -9,6 +9,7 @@
|
|
|
#include <linux/platform_device.h>
|
|
|
#include <linux/highmem.h>
|
|
|
#include <linux/types.h>
|
|
|
+#include <linux/rwsem.h>
|
|
|
|
|
|
#include <mm/slab.h>
|
|
|
|
|
@@ -36,6 +37,8 @@ static struct cam_req_mgr_device g_dev;
|
|
|
struct kmem_cache *g_cam_req_mgr_timer_cachep;
|
|
|
static struct list_head cam_req_mgr_ordered_sd_list;
|
|
|
|
|
|
+DECLARE_RWSEM(rwsem_lock);
|
|
|
+
|
|
|
static struct device_attribute camera_debug_sysfs_attr =
|
|
|
__ATTR(debug_node, 0600, NULL, cam_debug_sysfs_node_store);
|
|
|
|
|
@@ -104,10 +107,28 @@ static void cam_v4l2_device_cleanup(void)
|
|
|
g_dev.v4l2_dev = NULL;
|
|
|
}
|
|
|
|
|
|
+void cam_req_mgr_rwsem_read_op(enum cam_subdev_rwsem lock)
|
|
|
+{
|
|
|
+ if (lock == CAM_SUBDEV_LOCK)
|
|
|
+ down_read(&rwsem_lock);
|
|
|
+ else if (lock == CAM_SUBDEV_UNLOCK)
|
|
|
+ up_read(&rwsem_lock);
|
|
|
+}
|
|
|
+
|
|
|
+static void cam_req_mgr_rwsem_write_op(enum cam_subdev_rwsem lock)
|
|
|
+{
|
|
|
+ if (lock == CAM_SUBDEV_LOCK)
|
|
|
+ down_write(&rwsem_lock);
|
|
|
+ else if (lock == CAM_SUBDEV_UNLOCK)
|
|
|
+ up_write(&rwsem_lock);
|
|
|
+}
|
|
|
+
|
|
|
static int cam_req_mgr_open(struct file *filep)
|
|
|
{
|
|
|
int rc;
|
|
|
|
|
|
+ cam_req_mgr_rwsem_write_op(CAM_SUBDEV_LOCK);
|
|
|
+
|
|
|
mutex_lock(&g_dev.cam_lock);
|
|
|
if (g_dev.open_cnt >= 1) {
|
|
|
rc = -EALREADY;
|
|
@@ -133,12 +154,14 @@ static int cam_req_mgr_open(struct file *filep)
|
|
|
}
|
|
|
|
|
|
mutex_unlock(&g_dev.cam_lock);
|
|
|
+ cam_req_mgr_rwsem_write_op(CAM_SUBDEV_UNLOCK);
|
|
|
return rc;
|
|
|
|
|
|
mem_mgr_init_fail:
|
|
|
v4l2_fh_release(filep);
|
|
|
end:
|
|
|
mutex_unlock(&g_dev.cam_lock);
|
|
|
+ cam_req_mgr_rwsem_write_op(CAM_SUBDEV_UNLOCK);
|
|
|
return rc;
|
|
|
}
|
|
|
|
|
@@ -168,10 +191,14 @@ static int cam_req_mgr_close(struct file *filep)
|
|
|
CAM_WARN(CAM_CRM,
|
|
|
"release invoked associated userspace process has died, open_cnt: %d",
|
|
|
g_dev.open_cnt);
|
|
|
+
|
|
|
+ cam_req_mgr_rwsem_write_op(CAM_SUBDEV_LOCK);
|
|
|
+
|
|
|
mutex_lock(&g_dev.cam_lock);
|
|
|
|
|
|
if (g_dev.open_cnt <= 0) {
|
|
|
mutex_unlock(&g_dev.cam_lock);
|
|
|
+ cam_req_mgr_rwsem_write_op(CAM_SUBDEV_UNLOCK);
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
|
|
@@ -202,6 +229,8 @@ static int cam_req_mgr_close(struct file *filep)
|
|
|
cam_mem_mgr_deinit();
|
|
|
mutex_unlock(&g_dev.cam_lock);
|
|
|
|
|
|
+ cam_req_mgr_rwsem_write_op(CAM_SUBDEV_UNLOCK);
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
|