فهرست منبع

Merge "msm: camera: common: Detach pinctrl state operation" into camera-kernel.lnx.5.0

Savita Patted 4 سال پیش
والد
کامیت
2946eb9c57
3فایلهای تغییر یافته به همراه197 افزوده شده و 44 حذف شده
  1. 19 3
      drivers/cam_sensor_module/cam_cci/cam_cci_soc.c
  2. 146 37
      drivers/cam_utils/cam_soc_util.c
  3. 32 4
      drivers/cam_utils/cam_soc_util.h

+ 19 - 3
drivers/cam_sensor_module/cam_cci/cam_cci_soc.c

@@ -28,6 +28,14 @@ static int cam_cci_init_master(struct cci_device *cci_dev,
 	cci_dev->master_active_slave[master]++;
 	if (!cci_dev->cci_master_info[master].is_initilized) {
 		/* Re-initialize the completion */
+		rc = cam_soc_util_select_pinctrl_state(soc_info, master, true);
+		if (rc) {
+			CAM_ERR(CAM_CCI,
+				"Pinctrl active state x'sition failed, rc: %d",
+				rc);
+			goto MASTER_INIT_ERR;
+		}
+
 		reinit_completion(
 		&cci_dev->cci_master_info[master].reset_complete);
 		reinit_completion(&cci_dev->cci_master_info[master].rd_done);
@@ -56,8 +64,7 @@ static int cam_cci_init_master(struct cci_device *cci_dev,
 				"Failed: reset complete timeout for master: %d",
 				master);
 			rc = -ETIMEDOUT;
-			cci_dev->master_active_slave[master]--;
-			return rc;
+			goto MASTER_INIT_ERR;
 		}
 
 		flush_workqueue(cci_dev->write_wq[master]);
@@ -79,6 +86,11 @@ static int cam_cci_init_master(struct cci_device *cci_dev,
 	}
 
 	return 0;
+
+MASTER_INIT_ERR:
+	cci_dev->master_active_slave[master]--;
+
+	return rc;
 }
 
 int cam_cci_init(struct v4l2_subdev *sd,
@@ -197,7 +209,7 @@ int cam_cci_init(struct v4l2_subdev *sd,
 	return 0;
 
 reset_complete_failed:
-	cam_soc_util_disable_platform_resource(soc_info, 1, 1);
+	cam_soc_util_disable_platform_resource(soc_info, true, true);
 platform_enable_failed:
 	cci_dev->ref_count--;
 	cam_cpas_stop(cci_dev->cpas_handle);
@@ -411,6 +423,10 @@ int cam_cci_soc_release(struct cci_device *cci_dev,
 	}
 
 	if (!(--cci_dev->master_active_slave[master])) {
+		if (cam_soc_util_select_pinctrl_state(soc_info, master, false))
+			CAM_WARN(CAM_CCI,
+				"Pinctrl suspend state x'sition failed");
+
 		cci_dev->cci_master_info[master].is_initilized = false;
 		CAM_DBG(CAM_CCI,
 			"All submodules are released for master: %d", master);

+ 146 - 37
drivers/cam_utils/cam_soc_util.c

@@ -2187,12 +2187,68 @@ int cam_soc_util_regulator_enable(struct regulator *rgltr,
 	return rc;
 }
 
+int cam_soc_util_select_pinctrl_state(struct cam_hw_soc_info *soc_info,
+	int pctrl_idx, bool active)
+{
+	int rc = 0;
+
+	struct cam_soc_pinctrl_info *pctrl_info = &soc_info->pinctrl_info;
+
+	if (pctrl_idx >= CAM_SOC_MAX_PINCTRL_MAP) {
+		CAM_ERR(CAM_UTIL, "Invalid Map idx: %d max supported: %d",
+			pctrl_idx, CAM_SOC_MAX_PINCTRL_MAP);
+		return -EINVAL;
+	}
+
+	if (pctrl_info->pctrl_state[pctrl_idx].gpio_state_active &&
+		active &&
+		!pctrl_info->pctrl_state[pctrl_idx].is_active) {
+		rc = pinctrl_select_state(pctrl_info->pinctrl,
+			pctrl_info->pctrl_state[pctrl_idx].gpio_state_active);
+		if (rc)
+			CAM_ERR(CAM_UTIL,
+				"Pinctrl active state transition failed: rc: %d",
+				rc);
+		else {
+			pctrl_info->pctrl_state[pctrl_idx].is_active = true;
+			CAM_DBG(CAM_UTIL, "Pctrl_idx: %d is in active state",
+				pctrl_idx);
+		}
+	}
+
+	if (pctrl_info->pctrl_state[pctrl_idx].gpio_state_suspend &&
+		!active &&
+		pctrl_info->pctrl_state[pctrl_idx].is_active) {
+		rc = pinctrl_select_state(pctrl_info->pinctrl,
+			pctrl_info->pctrl_state[pctrl_idx].gpio_state_suspend);
+		if (rc)
+			CAM_ERR(CAM_UTIL,
+				"Pinctrl suspend state transition failed: rc: %d",
+				rc);
+		else {
+			pctrl_info->pctrl_state[pctrl_idx].is_active = false;
+			CAM_DBG(CAM_UTIL, "Pctrl_idx: %d is in suspend state",
+				pctrl_idx);
+		}
+	}
+
+	return rc;
+}
+
 static int cam_soc_util_request_pinctrl(
 	struct cam_hw_soc_info *soc_info)
 {
-
 	struct cam_soc_pinctrl_info *device_pctrl = &soc_info->pinctrl_info;
 	struct device *dev = soc_info->dev;
+	struct device_node *of_node = dev->of_node;
+	uint32_t i = 0;
+	int rc = 0;
+	const char *name;
+	uint32_t idx;
+	char pctrl_active[50];
+	char pctrl_suspend[50];
+	int32_t num_of_map_idx = 0;
+	int32_t num_of_string = 0;
 
 	device_pctrl->pinctrl = devm_pinctrl_get(dev);
 	if (IS_ERR_OR_NULL(device_pctrl->pinctrl)) {
@@ -2200,27 +2256,99 @@ static int cam_soc_util_request_pinctrl(
 		device_pctrl->pinctrl = NULL;
 		return 0;
 	}
-	device_pctrl->gpio_state_active =
-		pinctrl_lookup_state(device_pctrl->pinctrl,
-				CAM_SOC_PINCTRL_STATE_DEFAULT);
-	if (IS_ERR_OR_NULL(device_pctrl->gpio_state_active)) {
+
+	num_of_map_idx = of_property_count_u32_elems(
+		of_node, "pctrl-idx-mapping");
+	if (num_of_map_idx <= 0) {
 		CAM_ERR(CAM_UTIL,
-			"Failed to get the active state pinctrl handle");
-		device_pctrl->gpio_state_active = NULL;
+			"Reading pctrl-idx-mapping failed");
 		return -EINVAL;
 	}
-	device_pctrl->gpio_state_suspend
-		= pinctrl_lookup_state(device_pctrl->pinctrl,
-				CAM_SOC_PINCTRL_STATE_SLEEP);
-	if (IS_ERR_OR_NULL(device_pctrl->gpio_state_suspend)) {
+
+	num_of_string = of_property_count_strings(
+		of_node, "pctrl-map-names");
+	if (num_of_string <= 0) {
+		CAM_ERR(CAM_UTIL, "no pinctrl-mapping found for: %s",
+			soc_info->dev_name);
+		device_pctrl->pinctrl = NULL;
+		return -EINVAL;
+	}
+
+	if (num_of_map_idx != num_of_string) {
 		CAM_ERR(CAM_UTIL,
-			"Failed to get the suspend state pinctrl handle");
-		device_pctrl->gpio_state_suspend = NULL;
+			"Incorrect inputs mapping-idx count: %d mapping-names: %d",
+			num_of_map_idx, num_of_string);
+		device_pctrl->pinctrl = NULL;
+		return -EINVAL;
+	}
+
+	if (num_of_map_idx > CAM_SOC_MAX_PINCTRL_MAP) {
+		CAM_ERR(CAM_UTIL, "Invalid mapping %u max supported: %d",
+			num_of_map_idx, CAM_SOC_MAX_PINCTRL_MAP);
 		return -EINVAL;
 	}
+
+	for (i = 0; i < num_of_map_idx; i++) {
+		memset(pctrl_active, '\0', sizeof(pctrl_active));
+		memset(pctrl_suspend, '\0', sizeof(pctrl_suspend));
+		of_property_read_u32_index(of_node,
+			"pctrl-idx-mapping", i, &idx);
+
+		if (idx >= CAM_SOC_MAX_PINCTRL_MAP) {
+			CAM_ERR(CAM_UTIL, "Invalid Index: %d max supported: %d",
+				idx, CAM_SOC_MAX_PINCTRL_MAP);
+			return -EINVAL;
+		}
+
+		rc = of_property_read_string_index(
+			of_node, "pctrl-map-names", i, &name);
+		if (rc) {
+			CAM_ERR(CAM_UTIL,
+				"failed to read pinctrl-mapping at %d", i);
+			return rc;
+		}
+
+		snprintf(pctrl_active, sizeof(pctrl_active),
+			"%s%s",	name, "_active");
+		CAM_DBG(CAM_UTIL, "pctrl_active at index: %d name: %s",
+			i, pctrl_active);
+		snprintf(pctrl_suspend, sizeof(pctrl_suspend),
+			"%s%s", name, "_suspend");
+		CAM_DBG(CAM_UTIL, "pctrl_suspend at index: %d name: %s",
+			i, pctrl_suspend);
+
+		device_pctrl->pctrl_state[idx].gpio_state_active =
+			pinctrl_lookup_state(device_pctrl->pinctrl,
+			pctrl_active);
+		if (IS_ERR_OR_NULL(
+			device_pctrl->pctrl_state[idx].gpio_state_active)) {
+			CAM_ERR(CAM_UTIL,
+				"Failed to get the active state pinctrl handle");
+			device_pctrl->pctrl_state[idx].gpio_state_active =
+				NULL;
+			return -EINVAL;
+		}
+		device_pctrl->pctrl_state[idx].gpio_state_suspend =
+			pinctrl_lookup_state(device_pctrl->pinctrl,
+			pctrl_suspend);
+		if (IS_ERR_OR_NULL(
+			device_pctrl->pctrl_state[idx].gpio_state_suspend)) {
+			CAM_ERR(CAM_UTIL,
+				"Failed to get the active state pinctrl handle");
+			device_pctrl->pctrl_state[idx].gpio_state_suspend = NULL;
+			return -EINVAL;
+		}
+	}
+
 	return 0;
 }
 
+static void cam_soc_util_release_pinctrl(struct cam_hw_soc_info *soc_info)
+{
+	if (soc_info->pinctrl_info.pinctrl)
+		devm_pinctrl_put(soc_info->pinctrl_info.pinctrl);
+}
+
 static void cam_soc_util_regulator_disable_default(
 	struct cam_hw_soc_info *soc_info)
 {
@@ -2405,8 +2533,10 @@ int cam_soc_util_request_platform_resource(
 	}
 
 	rc = cam_soc_util_request_pinctrl(soc_info);
-	if (rc)
-		CAM_DBG(CAM_UTIL, "Failed in request pinctrl, rc=%d", rc);
+	if (rc) {
+		CAM_ERR(CAM_UTIL, "Failed in requesting Pinctrl, rc: %d", rc);
+		goto put_clk;
+	}
 
 	rc = cam_soc_util_request_gpio_table(soc_info, true);
 	if (rc) {
@@ -2513,9 +2643,7 @@ int cam_soc_util_release_platform_resource(struct cam_hw_soc_info *soc_info)
 			soc_info->irq_line->start, soc_info->irq_data);
 	}
 
-	if (soc_info->pinctrl_info.pinctrl)
-		devm_pinctrl_put(soc_info->pinctrl_info.pinctrl);
-
+	cam_soc_util_release_pinctrl(soc_info);
 
 	/* release for gpio */
 	cam_soc_util_request_gpio_table(soc_info, false);
@@ -2552,21 +2680,8 @@ int cam_soc_util_enable_platform_resource(struct cam_hw_soc_info *soc_info,
 			goto disable_clk;
 	}
 
-	if (soc_info->pinctrl_info.pinctrl &&
-		soc_info->pinctrl_info.gpio_state_active) {
-		rc = pinctrl_select_state(soc_info->pinctrl_info.pinctrl,
-			soc_info->pinctrl_info.gpio_state_active);
-
-		if (rc)
-			goto disable_irq;
-	}
-
 	return rc;
 
-disable_irq:
-	if (enable_irq)
-		cam_soc_util_irq_disable(soc_info);
-
 disable_clk:
 	if (enable_clocks)
 		cam_soc_util_clk_disable_default(soc_info);
@@ -2574,7 +2689,6 @@ disable_clk:
 disable_regulator:
 	cam_soc_util_regulator_disable_default(soc_info);
 
-
 	return rc;
 }
 
@@ -2594,11 +2708,6 @@ int cam_soc_util_disable_platform_resource(struct cam_hw_soc_info *soc_info,
 
 	cam_soc_util_regulator_disable_default(soc_info);
 
-	if (soc_info->pinctrl_info.pinctrl &&
-		soc_info->pinctrl_info.gpio_state_suspend)
-		rc = pinctrl_select_state(soc_info->pinctrl_info.pinctrl,
-			soc_info->pinctrl_info.gpio_state_suspend);
-
 	return rc;
 }
 

+ 32 - 4
drivers/cam_utils/cam_soc_util.h

@@ -44,6 +44,9 @@
 /* maximum number of optional device clock */
 #define CAM_SOC_MAX_OPT_CLK    2
 
+/* maximum number of pinctrl mapping */
+#define CAM_SOC_MAX_PINCTRL_MAP     2
+
 /* DDR device types */
 #define DDR_TYPE_LPDDR4        6
 #define DDR_TYPE_LPDDR4X       7
@@ -96,17 +99,29 @@ struct cam_soc_reg_map {
 	resource_size_t                 size;
 };
 
+/**
+ * struct cam_soc_pinctrl_state:   Information about pinctrl state
+ *
+ * @gpio_state_active:     default pinctrl state
+ * @gpio_state_suspend:    suspend state of pinctrl
+ * @is_active:             to identify if pinctrl is in use.
+ **/
+struct cam_soc_pinctrl_state {
+	struct pinctrl_state *gpio_state_active;
+	struct pinctrl_state *gpio_state_suspend;
+	bool is_active;
+};
+
 /**
  * struct cam_soc_pinctrl_info:   Information about pinctrl data
  *
  * @pinctrl:               pintrl object
- * @gpio_state_active:     default pinctrl state
- * @gpio_state_suspend     suspend state of pinctrl
+ * @pctrl_state:           pinctrl state montior map
  **/
 struct cam_soc_pinctrl_info {
 	struct pinctrl *pinctrl;
-	struct pinctrl_state *gpio_state_active;
-	struct pinctrl_state *gpio_state_suspend;
+	struct cam_soc_pinctrl_state pctrl_state[
+		CAM_SOC_MAX_PINCTRL_MAP];
 };
 
 /**
@@ -745,4 +760,17 @@ int cam_soc_util_reg_dump_to_cmd_buf(void *ctx,
  */
 int cam_soc_util_print_clk_freq(struct cam_hw_soc_info *soc_info);
 
+/**
+ * cam_soc_util_select_pinctrl_state()
+ *
+ * @brief:              This function gets the pinctrl handle
+ *
+ * @soc_info:           Device soc struct to be populated
+ * @active:             True for active and false for suspend state
+ *
+ * @return:             success or failure
+ */
+int cam_soc_util_select_pinctrl_state(
+	struct cam_hw_soc_info *soc_info, int idx, bool active);
+
 #endif /* _CAM_SOC_UTIL_H_ */