Просмотр исходного кода

Merge "msm: camera: sensor: Handle tpg shutdown properly" into camera-kernel.lnx.5.0

Camera Software Integration 3 лет назад
Родитель
Сommit
624ee237ea

+ 40 - 17
drivers/cam_sensor_module/cam_tpg/cam_tpg_dev.c

@@ -9,6 +9,36 @@
 #include "tpg_hw/tpg_hw_v_1_0/tpg_hw_v_1_0_data.h"
 #include "tpg_hw/tpg_hw_v_1_3/tpg_hw_v_1_3_data.h"
 
+static int cam_tpg_subdev_close(struct v4l2_subdev *sd,
+	struct v4l2_subdev_fh *fh)
+{
+	struct cam_tpg_device *tpg_dev =
+		v4l2_get_subdevdata(sd);
+
+	bool crm_active = cam_req_mgr_is_open();
+
+	if (!tpg_dev) {
+		CAM_ERR(CAM_TPG, "tpg_dev ptr is NULL");
+		return -EINVAL;
+	}
+
+	if (crm_active) {
+		CAM_DBG(CAM_TPG, "CRM is ACTIVE, close should be from CRM");
+		return 0;
+	}
+
+	mutex_lock(&tpg_dev->mutex);
+	if (tpg_dev->state == CAM_TPG_STATE_INIT) {
+		CAM_DBG(CAM_TPG, "TPG node %d is succesfully closed", tpg_dev->soc_info.index);
+		mutex_unlock(&tpg_dev->mutex);
+		return 0;
+	}
+	cam_tpg_shutdown(tpg_dev);
+	mutex_unlock(&tpg_dev->mutex);
+
+	return 0;
+}
+
 static long cam_tpg_subdev_ioctl(struct v4l2_subdev *sd,
 	unsigned int cmd, void *arg)
 {
@@ -19,6 +49,15 @@ static long cam_tpg_subdev_ioctl(struct v4l2_subdev *sd,
 	case VIDIOC_CAM_CONTROL:
 		rc = cam_tpg_core_cfg(tpg_dev, arg);
 		break;
+	case CAM_SD_SHUTDOWN:
+		if (!cam_req_mgr_is_shutdown()) {
+			CAM_ERR(CAM_CORE, "SD shouldn't come from user space");
+			return 0;
+		}
+		mutex_lock(&tpg_dev->mutex);
+		cam_tpg_shutdown(tpg_dev);
+		mutex_unlock(&tpg_dev->mutex);
+		break;
 	default:
 		CAM_ERR(CAM_TPG, "Wrong ioctl : %d", cmd);
 		rc = -ENOIOCTLCMD;
@@ -81,23 +120,6 @@ static struct v4l2_subdev_core_ops tpg_subdev_core_ops = {
 #endif
 };
 
-static int cam_tpg_subdev_close(struct v4l2_subdev *sd,
-	struct v4l2_subdev_fh *fh)
-{
-	struct cam_tpg_device *tpg_dev =
-		v4l2_get_subdevdata(sd);
-
-	if (!tpg_dev) {
-		CAM_ERR(CAM_TPG, "tpg_dev ptr is NULL");
-		return -EINVAL;
-	}
-
-	mutex_lock(&tpg_dev->mutex);
-	cam_tpg_shutdown(tpg_dev);
-	mutex_unlock(&tpg_dev->mutex);
-
-	return 0;
-}
 
 static const struct v4l2_subdev_ops tpg_subdev_ops = {
 	.core = &tpg_subdev_core_ops,
@@ -225,6 +247,7 @@ static int cam_tpg_hw_layer_init(struct cam_tpg_device *tpg_dev,
 	tpg_dev->tpg_hw.hw_info  = (struct tpg_hw_info *)match_dev->data;
 	tpg_dev->tpg_hw.soc_info = &tpg_dev->soc_info;
 	tpg_dev->tpg_hw.cpas_handle = tpg_dev->cpas_handle;
+	tpg_dev->tpg_hw.state    = TPG_HW_STATE_HW_DISABLED;
 	mutex_init(&tpg_dev->tpg_hw.mutex);
 
 	tpg_dev->tpg_hw.vc_slots = devm_kzalloc(&pdev->dev,

+ 11 - 2
drivers/cam_sensor_module/cam_tpg/tpg_hw/tpg_hw.c

@@ -240,9 +240,11 @@ static int tpg_hw_soc_disable(struct tpg_hw *hw)
 		CAM_ERR(CAM_TPG, "TPG[%d] Disable platform failed %d",
 				hw->hw_idx, rc);
 
-	if (cam_cpas_stop(hw->cpas_handle)) {
+	if ((rc = cam_cpas_stop(hw->cpas_handle))) {
 		CAM_ERR(CAM_TPG, "TPG[%d] CPAS stop failed",
 				hw->hw_idx);
+	} else {
+		hw->state = TPG_HW_STATE_HW_DISABLED;
 	}
 
 	return rc;
@@ -287,6 +289,7 @@ static int tpg_hw_soc_enable(
 				hw->hw_idx);
 		goto stop_cpas;
 	}
+	hw->state = TPG_HW_STATE_HW_ENABLED;
 
 	return rc;
 stop_cpas:
@@ -634,10 +637,16 @@ int tpg_hw_reset(struct tpg_hw *hw)
 		CAM_ERR(CAM_TPG, "TPG[%d] Unable to free up the streams", hw->hw_idx);
 
 	/* disable the hw */
-	if (cam_cpas_stop(hw->cpas_handle)) {
+	mutex_lock(&hw->mutex);
+	if ((hw->state != TPG_HW_STATE_HW_DISABLED) &&
+			cam_cpas_stop(hw->cpas_handle)) {
 		CAM_ERR(CAM_TPG, "TPG[%d] CPAS stop failed",
 				hw->hw_idx);
+		rc = -EINVAL;
+	} else {
+		hw->state = TPG_HW_STATE_HW_DISABLED;
 	}
+	mutex_unlock(&hw->mutex);
 
 	return rc;
 }

+ 11 - 0
drivers/cam_sensor_module/cam_tpg/tpg_hw/tpg_hw.h

@@ -42,6 +42,17 @@ struct tpg_hw_ops {
 	int (*dump_status)(struct tpg_hw *hw, void *data);
 };
 
+/**
+ * tpg_hw_state : tpg hw states
+ *
+ * TPG_HW_STATE_HW_DISABLED: tpg hw is not enabled yet
+ * TPG_HW_STATE_HW_ENABLED : tpg hw is enabled
+ */
+enum tpg_hw_state {
+	TPG_HW_STATE_HW_DISABLED,
+	TPG_HW_STATE_HW_ENABLED,
+};
+
 /**
  * @brief tpg_vc_slot_info
  * @slot_id      : slot id of this vc slot