Browse Source

msm: camera: common: Detach pinctrl state operation

Currently pinctrl state update operation is integrated
with platform resource operation. This can create unwanted
transition of pinctrl which can stay in suspend state.
This change detach and separate out the pinctrl entries
with index passed from devicetree. Pinctrl select
state operation is detach from platform enable/disable
operation to operate from device directly only for better
control with respect to operation.

CRs-Fixed: 2907475, 2954556
Change-Id: I918568f96e8888df6882f165458f5c4ab32d6348
Signed-off-by: Jigarkumar Zala <[email protected]>
Jigarkumar Zala 4 years ago
parent
commit
78f6e5bd2d

+ 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]++;
 	cci_dev->master_active_slave[master]++;
 	if (!cci_dev->cci_master_info[master].is_initilized) {
 	if (!cci_dev->cci_master_info[master].is_initilized) {
 		/* Re-initialize the completion */
 		/* 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(
 		reinit_completion(
 		&cci_dev->cci_master_info[master].reset_complete);
 		&cci_dev->cci_master_info[master].reset_complete);
 		reinit_completion(&cci_dev->cci_master_info[master].rd_done);
 		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",
 				"Failed: reset complete timeout for master: %d",
 				master);
 				master);
 			rc = -ETIMEDOUT;
 			rc = -ETIMEDOUT;
-			cci_dev->master_active_slave[master]--;
-			return rc;
+			goto MASTER_INIT_ERR;
 		}
 		}
 
 
 		flush_workqueue(cci_dev->write_wq[master]);
 		flush_workqueue(cci_dev->write_wq[master]);
@@ -79,6 +86,11 @@ static int cam_cci_init_master(struct cci_device *cci_dev,
 	}
 	}
 
 
 	return 0;
 	return 0;
+
+MASTER_INIT_ERR:
+	cci_dev->master_active_slave[master]--;
+
+	return rc;
 }
 }
 
 
 int cam_cci_init(struct v4l2_subdev *sd,
 int cam_cci_init(struct v4l2_subdev *sd,
@@ -197,7 +209,7 @@ int cam_cci_init(struct v4l2_subdev *sd,
 	return 0;
 	return 0;
 
 
 reset_complete_failed:
 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:
 platform_enable_failed:
 	cci_dev->ref_count--;
 	cci_dev->ref_count--;
 	cam_cpas_stop(cci_dev->cpas_handle);
 	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 (!(--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;
 		cci_dev->cci_master_info[master].is_initilized = false;
 		CAM_DBG(CAM_CCI,
 		CAM_DBG(CAM_CCI,
 			"All submodules are released for master: %d", master);
 			"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;
 	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(
 static int cam_soc_util_request_pinctrl(
 	struct cam_hw_soc_info *soc_info)
 	struct cam_hw_soc_info *soc_info)
 {
 {
-
 	struct cam_soc_pinctrl_info *device_pctrl = &soc_info->pinctrl_info;
 	struct cam_soc_pinctrl_info *device_pctrl = &soc_info->pinctrl_info;
 	struct device *dev = soc_info->dev;
 	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);
 	device_pctrl->pinctrl = devm_pinctrl_get(dev);
 	if (IS_ERR_OR_NULL(device_pctrl->pinctrl)) {
 	if (IS_ERR_OR_NULL(device_pctrl->pinctrl)) {
@@ -2200,27 +2256,99 @@ static int cam_soc_util_request_pinctrl(
 		device_pctrl->pinctrl = NULL;
 		device_pctrl->pinctrl = NULL;
 		return 0;
 		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,
 		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;
 		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,
 		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;
 		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;
 	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(
 static void cam_soc_util_regulator_disable_default(
 	struct cam_hw_soc_info *soc_info)
 	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);
 	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);
 	rc = cam_soc_util_request_gpio_table(soc_info, true);
 	if (rc) {
 	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);
 			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 */
 	/* release for gpio */
 	cam_soc_util_request_gpio_table(soc_info, false);
 	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;
 			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;
 	return rc;
 
 
-disable_irq:
-	if (enable_irq)
-		cam_soc_util_irq_disable(soc_info);
-
 disable_clk:
 disable_clk:
 	if (enable_clocks)
 	if (enable_clocks)
 		cam_soc_util_clk_disable_default(soc_info);
 		cam_soc_util_clk_disable_default(soc_info);
@@ -2574,7 +2689,6 @@ disable_clk:
 disable_regulator:
 disable_regulator:
 	cam_soc_util_regulator_disable_default(soc_info);
 	cam_soc_util_regulator_disable_default(soc_info);
 
 
-
 	return rc;
 	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);
 	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;
 	return rc;
 }
 }
 
 

+ 32 - 4
drivers/cam_utils/cam_soc_util.h

@@ -44,6 +44,9 @@
 /* maximum number of optional device clock */
 /* maximum number of optional device clock */
 #define CAM_SOC_MAX_OPT_CLK    2
 #define CAM_SOC_MAX_OPT_CLK    2
 
 
+/* maximum number of pinctrl mapping */
+#define CAM_SOC_MAX_PINCTRL_MAP     2
+
 /* DDR device types */
 /* DDR device types */
 #define DDR_TYPE_LPDDR4        6
 #define DDR_TYPE_LPDDR4        6
 #define DDR_TYPE_LPDDR4X       7
 #define DDR_TYPE_LPDDR4X       7
@@ -96,17 +99,29 @@ struct cam_soc_reg_map {
 	resource_size_t                 size;
 	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
  * struct cam_soc_pinctrl_info:   Information about pinctrl data
  *
  *
  * @pinctrl:               pintrl object
  * @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 cam_soc_pinctrl_info {
 	struct pinctrl *pinctrl;
 	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);
 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_ */
 #endif /* _CAM_SOC_UTIL_H_ */