Эх сурвалжийг харах

msm: camera: sensor: Add pinctrl specific handling in res_mgr

Currently pinctrl is handled together regardless of pinctrl
is requested for the active/suspend state. This change adds
the per pinctrl handling when pinctrl gpio is shared among
multiple slaves. Also remove mclk specific logic as this
change will handle it at gpio/pinctrl level.

CRs-Fixed: 2758167
Change-Id: I4fa028d3eee80e056a74324a420c08967cbf6c5f
Signed-off-by: Jigarkumar Zala <[email protected]>
Jigarkumar Zala 4 жил өмнө
parent
commit
5a37a310f7

+ 462 - 221
drivers/cam_sensor_module/cam_res_mgr/cam_res_mgr.c

@@ -45,10 +45,6 @@ static void cam_res_mgr_free_res(void)
 		kfree(flash_res);
 	}
 	mutex_unlock(&cam_res->flash_res_lock);
-
-	mutex_lock(&cam_res->clk_res_lock);
-	cam_res->shared_clk_ref_count = 0;
-	mutex_unlock(&cam_res->clk_res_lock);
 }
 
 void cam_res_mgr_led_trigger_register(const char *name, struct led_trigger **tp)
@@ -158,77 +154,117 @@ void cam_res_mgr_led_trigger_event(struct led_trigger *trig,
 }
 EXPORT_SYMBOL(cam_res_mgr_led_trigger_event);
 
-int cam_res_mgr_shared_pinctrl_init(void)
+int cam_res_mgr_util_get_idx_from_shared_pctrl_gpio(
+	uint gpio)
 {
-	struct cam_soc_pinctrl_info *pinctrl_info;
+	int index = 0;
+	struct cam_res_mgr_dt *dt = &cam_res->dt;
 
-	/*
-	 * We allow the cam_res is NULL or shared_gpio_enabled
-	 * is false, it means this driver no probed or doesn't
-	 * have shared gpio in this device.
-	 */
-	if (!cam_res || !cam_res->shared_gpio_enabled) {
-		CAM_DBG(CAM_RES, "Not support shared gpio.");
-		return 0;
+	for (index = 0; index < dt->num_shared_pctrl_gpio; index++) {
+		if (gpio == dt->shared_pctrl_gpio[index])
+			break;
 	}
 
-	mutex_lock(&cam_res->gpio_res_lock);
-	if (cam_res->pstatus != PINCTRL_STATUS_PUT) {
-		CAM_DBG(CAM_RES, "The shared pinctrl already been got.");
-		mutex_unlock(&cam_res->gpio_res_lock);
-		return 0;
-	}
+	if (index == dt->num_shared_pctrl_gpio)
+		return -EINVAL;
 
-	pinctrl_info = &cam_res->dt.pinctrl_info;
+	return index;
+}
+EXPORT_SYMBOL(cam_res_mgr_util_get_idx_from_shared_pctrl_gpio);
 
-	pinctrl_info->pinctrl =
-		devm_pinctrl_get(cam_res->dev);
-	if (IS_ERR_OR_NULL(pinctrl_info->pinctrl)) {
-		CAM_ERR(CAM_RES, "Pinctrl not available");
-		cam_res->shared_gpio_enabled = false;
-		mutex_unlock(&cam_res->gpio_res_lock);
-		return -EINVAL;
-	}
+int cam_res_mgr_util_get_idx_from_shared_gpio(
+	uint gpio)
+{
+	int index = 0;
+	struct cam_res_mgr_dt *dt = &cam_res->dt;
 
-	pinctrl_info->gpio_state_active =
-		pinctrl_lookup_state(pinctrl_info->pinctrl,
-			CAM_RES_MGR_DEFAULT);
-	if (IS_ERR_OR_NULL(pinctrl_info->gpio_state_active)) {
-		CAM_ERR(CAM_RES,
-			"Failed to get the active state pinctrl handle");
-		cam_res->shared_gpio_enabled = false;
-		mutex_unlock(&cam_res->gpio_res_lock);
-		return -EINVAL;
+	for (index = 0; index < dt->num_shared_gpio; index++) {
+		if (gpio == dt->shared_gpio[index])
+			break;
 	}
 
-	pinctrl_info->gpio_state_suspend =
-		pinctrl_lookup_state(pinctrl_info->pinctrl,
-			CAM_RES_MGR_SLEEP);
-	if (IS_ERR_OR_NULL(pinctrl_info->gpio_state_suspend)) {
-		CAM_ERR(CAM_RES,
-			"Failed to get the active state pinctrl handle");
-		cam_res->shared_gpio_enabled = false;
-		mutex_unlock(&cam_res->gpio_res_lock);
+	if (index == dt->num_shared_gpio)
 		return -EINVAL;
+
+	return index;
+}
+EXPORT_SYMBOL(cam_res_mgr_util_get_idx_from_shared_gpio);
+
+static bool cam_res_mgr_gpio_is_in_shared_pctrl_gpio(
+	uint gpio)
+{
+	int index = 0;
+	bool found = false;
+	struct cam_res_mgr_dt *dt = &cam_res->dt;
+
+	for (index = 0; index < dt->num_shared_pctrl_gpio; index++) {
+		if (gpio == dt->shared_pctrl_gpio[index]) {
+			found = true;
+			break;
+		}
 	}
 
-	cam_res->pstatus = PINCTRL_STATUS_GOT;
-	mutex_unlock(&cam_res->gpio_res_lock);
+	return found;
+}
 
-	return 0;
+static bool cam_res_mgr_gpio_is_in_shared_gpio(
+	uint gpio)
+{
+	int index = 0;
+	bool found = false;
+	struct cam_res_mgr_dt *dt = &cam_res->dt;
+
+	for (; index < dt->num_shared_gpio; index++) {
+		if (gpio == dt->shared_gpio[index]) {
+			found = true;
+			break;
+		}
+	}
+
+	return found;
 }
-EXPORT_SYMBOL(cam_res_mgr_shared_pinctrl_init);
 
-static bool cam_res_mgr_shared_pinctrl_check_hold(void)
+int cam_res_mgr_util_shared_gpio_check_hold(uint gpio)
 {
 	int index = 0;
 	int dev_num = 0;
-	bool hold = false;
 	struct list_head *list;
-	struct cam_gpio_res *gpio_res;
-	struct cam_res_mgr_dt *dt = &cam_res->dt;
+	struct cam_gpio_res *gpio_res = NULL;
+	struct cam_res_mgr_dt *dt =  NULL;
+	bool is_shared_gpio = false;
+	bool is_shared_pctrl_gpio = false;
+
+	if (!cam_res) {
+		CAM_DBG(CAM_RES, "res mgr is not initilized");
+		return 0;
+	}
+
+	if (!cam_res->shared_gpio_enabled) {
+		CAM_DBG(CAM_RES, "Res_mgr is not sharing any gpios");
+		return 0;
+	}
+
+	dt = &cam_res->dt;
+
+	is_shared_gpio =
+		cam_res_mgr_gpio_is_in_shared_gpio(gpio);
+	is_shared_pctrl_gpio =
+		cam_res_mgr_gpio_is_in_shared_pctrl_gpio(gpio);
+
+	if (is_shared_gpio && is_shared_pctrl_gpio) {
+		CAM_ERR(CAM_RES,
+			"gpio %u cannot be shared between pinctrl and gpio");
+		return -EINVAL;
+	}
+
+	if (is_shared_gpio) {
+		index = cam_res_mgr_util_get_idx_from_shared_gpio(gpio);
+		if (index < 0) {
+			CAM_ERR(CAM_RES, "Gpio%u not found in shared gpio list",
+				gpio);
+			return -EINVAL;
+		}
 
-	for (; index < dt->num_shared_gpio; index++) {
 		list_for_each_entry(gpio_res,
 			&cam_res->gpio_res_list, list) {
 
@@ -238,85 +274,113 @@ static bool cam_res_mgr_shared_pinctrl_check_hold(void)
 					dev_num++;
 
 				if (dev_num >= 2) {
-					hold = true;
-					break;
+					return RES_MGR_GPIO_NEED_HOLD;
 				}
 			}
 		}
 	}
 
-	if (cam_res->shared_clk_ref_count > 1)
-		hold = true;
-
-	return hold;
-}
+	if (is_shared_pctrl_gpio) {
+		index = cam_res_mgr_util_get_idx_from_shared_pctrl_gpio(gpio);
+		if (index < 0) {
+			CAM_ERR(CAM_RES,
+				"gpio%u not found in shared pctrl gpio list",
+				gpio);
+			return -EINVAL;
+		}
 
-void cam_res_mgr_shared_pinctrl_put(void)
-{
-	struct cam_soc_pinctrl_info *pinctrl_info;
+		list_for_each_entry(gpio_res,
+			&cam_res->gpio_res_list, list) {
+			if (gpio_res->gpio ==
+				dt->shared_pctrl_gpio[index]) {
+				list_for_each(list, &gpio_res->dev_list)
+					dev_num++;
 
-	if (!cam_res || !cam_res->shared_gpio_enabled) {
-		CAM_DBG(CAM_RES, "Not support shared gpio.");
-		return;
+				if (dev_num >= 2) {
+					CAM_DBG(CAM_RES,
+						"gpio: %u needs to hold", gpio);
+					return RES_MGR_GPIO_NEED_HOLD;
+				}
+			}
+		}
 	}
 
-	mutex_lock(&cam_res->gpio_res_lock);
-	if (cam_res->pstatus == PINCTRL_STATUS_PUT) {
-		CAM_DBG(CAM_RES, "The shared pinctrl already been put");
-		mutex_unlock(&cam_res->gpio_res_lock);
-		return;
-	}
+	for (index = 0; index < dt->num_shared_gpio; index++) {
+		list_for_each_entry(gpio_res,
+			&cam_res->gpio_res_list, list) {
 
-	if (cam_res_mgr_shared_pinctrl_check_hold()) {
-		CAM_INFO(CAM_RES, "Need hold put this pinctrl");
-		mutex_unlock(&cam_res->gpio_res_lock);
-		return;
+			if (gpio_res->gpio ==
+				dt->shared_gpio[index]) {
+				list_for_each(list, &gpio_res->dev_list)
+					dev_num++;
+
+				if (dev_num >= 2) {
+					CAM_DBG(CAM_RES,
+						"gpio: %u needs to hold", gpio);
+					return RES_MGR_GPIO_NEED_HOLD;
+				}
+			}
+		}
 	}
 
-	pinctrl_info = &cam_res->dt.pinctrl_info;
+	for (index = 0; index < dt->num_shared_pctrl_gpio; index++) {
+		list_for_each_entry(gpio_res,
+			&cam_res->gpio_res_list, list) {
 
-	devm_pinctrl_put(pinctrl_info->pinctrl);
+			if (gpio_res->gpio ==
+				dt->shared_pctrl_gpio[index]) {
+				list_for_each(list, &gpio_res->dev_list)
+					dev_num++;
 
-	cam_res->pstatus = PINCTRL_STATUS_PUT;
-	mutex_unlock(&cam_res->gpio_res_lock);
+				if (dev_num >= 2) {
+					CAM_DBG(CAM_RES,
+						"gpio: %u needs to hold", gpio);
+					return RES_MGR_GPIO_NEED_HOLD;
+				}
+			}
+		}
+	}
+
+	CAM_DBG(CAM_RES, "gpio: %u can free the resource", gpio);
+	return RES_MGR_GPIO_CAN_FREE;
 }
-EXPORT_SYMBOL(cam_res_mgr_shared_pinctrl_put);
+EXPORT_SYMBOL(cam_res_mgr_util_shared_gpio_check_hold);
 
-int cam_res_mgr_shared_pinctrl_select_state(bool active)
+static int cam_res_mgr_shared_pinctrl_select_state(
+	int idx, bool active)
 {
 	int rc = 0;
-	struct cam_soc_pinctrl_info *pinctrl_info;
 
 	if (!cam_res || !cam_res->shared_gpio_enabled) {
 		CAM_DBG(CAM_RES, "Not support shared gpio.");
 		return 0;
 	}
 
-	mutex_lock(&cam_res->gpio_res_lock);
-	if (cam_res->pstatus == PINCTRL_STATUS_PUT) {
+	if (cam_res->pctrl_res[idx].pstatus == PINCTRL_STATUS_PUT) {
 		CAM_DBG(CAM_RES, "The shared pinctrl alerady been put.!");
-		mutex_unlock(&cam_res->gpio_res_lock);
 		return 0;
 	}
 
-	pinctrl_info = &cam_res->dt.pinctrl_info;
-
-	if (active && (cam_res->pstatus != PINCTRL_STATUS_ACTIVE)) {
-		rc = pinctrl_select_state(pinctrl_info->pinctrl,
-			pinctrl_info->gpio_state_active);
-		cam_res->pstatus = PINCTRL_STATUS_ACTIVE;
+	if (active &&
+		(cam_res->pctrl_res[idx].pstatus != PINCTRL_STATUS_ACTIVE)) {
+		CAM_DBG(CAM_RES,
+			"pinctrl select state to active for the shared_pctrl_gpio idx: %d",
+			idx);
+		rc = pinctrl_select_state(cam_res->pinctrl,
+			cam_res->pctrl_res[idx].active);
+		cam_res->pctrl_res[idx].pstatus = PINCTRL_STATUS_ACTIVE;
 	} else if (!active &&
-		!cam_res_mgr_shared_pinctrl_check_hold()) {
-		rc = pinctrl_select_state(pinctrl_info->pinctrl,
-			pinctrl_info->gpio_state_suspend);
-		cam_res->pstatus = PINCTRL_STATUS_SUSPEND;
+		(cam_res->pctrl_res[idx].pstatus == PINCTRL_STATUS_ACTIVE)) {
+		CAM_DBG(CAM_RES,
+			"pinctrl select state to suspend for the shared_pctrl_gpio idx: %d",
+			idx);
+		rc = pinctrl_select_state(cam_res->pinctrl,
+			cam_res->pctrl_res[idx].suspend);
+		cam_res->pctrl_res[idx].pstatus = PINCTRL_STATUS_SUSPEND;
 	}
 
-	mutex_unlock(&cam_res->gpio_res_lock);
-
-	return rc;
+	return 0;
 }
-EXPORT_SYMBOL(cam_res_mgr_shared_pinctrl_select_state);
 
 static int cam_res_mgr_add_device(struct device *dev,
 	struct cam_gpio_res *gpio_res)
@@ -329,61 +393,78 @@ static int cam_res_mgr_add_device(struct device *dev,
 
 	dev_res->dev = dev;
 	INIT_LIST_HEAD(&dev_res->list);
-
 	list_add_tail(&dev_res->list, &gpio_res->dev_list);
 
 	return 0;
 }
 
-static bool cam_res_mgr_gpio_is_shared(uint gpio)
+static struct cam_gpio_res *cam_res_mgr_find_if_gpio_in_list(uint gpio)
 {
-	int index = 0;
-	bool found = false;
-	struct cam_res_mgr_dt *dt = &cam_res->dt;
+	struct cam_gpio_res *gpio_res = NULL;
 
-	mutex_lock(&cam_res->gpio_res_lock);
-	for (; index < dt->num_shared_gpio; index++) {
-		if (gpio == dt->shared_gpio[index]) {
-			found = true;
-			break;
-		}
+	list_for_each_entry(gpio_res, &cam_res->gpio_res_list, list) {
+		if (gpio == gpio_res->gpio)
+			return gpio_res;
 	}
-	mutex_unlock(&cam_res->gpio_res_lock);
 
-	return found;
+	return NULL;
+}
+
+static bool __cam_res_mgr_find_if_gpio_is_shared(uint gpio)
+{
+	bool found_in_shared_gpio = false;
+	bool found_in_shared_pctrl_gpio = false;
+
+	found_in_shared_gpio = cam_res_mgr_gpio_is_in_shared_gpio(gpio);
+
+	found_in_shared_pctrl_gpio =
+		cam_res_mgr_gpio_is_in_shared_pctrl_gpio(gpio);
+
+	if (found_in_shared_pctrl_gpio && found_in_shared_gpio) {
+		CAM_WARN(CAM_RES, "gpio: %u cannot be shared in both list",
+			gpio);
+		return false;
+	}
+
+	if (found_in_shared_pctrl_gpio || found_in_shared_gpio)
+		return true;
+
+	return false;
 }
 
+
 int cam_res_mgr_gpio_request(struct device *dev, uint gpio,
 		unsigned long flags, const char *label)
 {
-	int rc = 0;
-	bool found = false;
-	struct cam_gpio_res *gpio_res = NULL;
+	int                          rc = 0;
+	bool                         dev_found = false;
+	bool                         gpio_found = false;
+	int                          pctrl_idx = -1;
+	struct cam_gpio_res         *gpio_res = NULL;
 
+	mutex_lock(&cam_res->gpio_res_lock);
 	if (cam_res && cam_res->shared_gpio_enabled) {
-		mutex_lock(&cam_res->gpio_res_lock);
-		list_for_each_entry(gpio_res, &cam_res->gpio_res_list, list) {
-			if (gpio == gpio_res->gpio) {
-				found = true;
-				break;
-			}
-		}
-		mutex_unlock(&cam_res->gpio_res_lock);
+		gpio_res = cam_res_mgr_find_if_gpio_in_list(gpio);
+		if (gpio_res == NULL)
+			gpio_found = false;
+		else
+			gpio_found = true;
 	}
 
 	/*
-	 * found equal to false has two situation:
-	 * 1. shared gpio not enabled
-	 * 2. shared gpio enabled, but not find this gpio
+	 * gpio_found equal to false has two situation:
+	 * 1. shared gpio/pinctrl_gpio not enabled
+	 * 2. shared gpio/pinctrl_gpio enabled, but not find this gpio
 	 *    from the gpio_res_list
-	 * These two situation both need request gpio.
+	 * These two situations both need request gpio.
 	 */
-	if (!found) {
+	if (!gpio_found) {
+		CAM_DBG(CAM_RES, "gpio: %u not found in gpio_res list", gpio);
 		rc = gpio_request_one(gpio, flags, label);
 		if (rc) {
 			CAM_ERR(CAM_RES, "gpio %d:%s request fails",
 				gpio, label);
-			return rc;
+			goto end;
 		}
 	}
 
@@ -392,59 +473,83 @@ int cam_res_mgr_gpio_request(struct device *dev, uint gpio,
 	 * from gpio_res_list, then insert a cam_gpio_res
 	 * to gpio_res_list.
 	 */
-	if (!found && cam_res
-		&& cam_res->shared_gpio_enabled &&
-		cam_res_mgr_gpio_is_shared(gpio)) {
+	if ((!gpio_found && cam_res
+		&& cam_res->shared_gpio_enabled) &&
+		(cam_res_mgr_gpio_is_in_shared_gpio(gpio) ||
+		(cam_res_mgr_gpio_is_in_shared_pctrl_gpio(gpio)))) {
+		CAM_DBG(CAM_RES, "gpio: %u is shared", gpio);
 
 		gpio_res = kzalloc(sizeof(struct cam_gpio_res), GFP_KERNEL);
-		if (!gpio_res)
-			return -ENOMEM;
-
+		if (!gpio_res) {
+			rc = -ENOMEM;
+			goto end;
+		}
 		gpio_res->gpio = gpio;
 		gpio_res->power_on_count = 0;
 		INIT_LIST_HEAD(&gpio_res->list);
 		INIT_LIST_HEAD(&gpio_res->dev_list);
 
-		mutex_lock(&cam_res->gpio_res_lock);
 		rc = cam_res_mgr_add_device(dev, gpio_res);
 		if (rc) {
 			kfree(gpio_res);
-			mutex_unlock(&cam_res->gpio_res_lock);
-			return rc;
+			goto end;
 		}
 
 		list_add_tail(&gpio_res->list, &cam_res->gpio_res_list);
-		mutex_unlock(&cam_res->gpio_res_lock);
 	}
 
-	if (found && cam_res
+	/* if shared gpio is in pinctrl gpio list */
+	if (!gpio_found && cam_res
+		&& cam_res->shared_gpio_enabled &&
+		cam_res_mgr_gpio_is_in_shared_pctrl_gpio(gpio)) {
+		pctrl_idx =
+			cam_res_mgr_util_get_idx_from_shared_pctrl_gpio(gpio);
+		CAM_DBG(CAM_RES,
+			"shared_pctrl_gpio is at idx: %d", pctrl_idx);
+		if (pctrl_idx < 0) {
+			CAM_ERR(CAM_RES,
+				"pctrl_gpio: %u not found", gpio);
+			rc = -EINVAL;
+			goto end;
+		}
+
+		/* Update Pinctrl state to active */
+		cam_res_mgr_shared_pinctrl_select_state(pctrl_idx, true);
+	}
+
+	if (gpio_found && cam_res
 		&& cam_res->shared_gpio_enabled) {
 		struct cam_dev_res *dev_res = NULL;
 
-		found = 0;
-		mutex_lock(&cam_res->gpio_res_lock);
 		list_for_each_entry(dev_res, &gpio_res->dev_list, list) {
 			if (dev_res->dev == dev) {
-				found = 1;
+				dev_found = true;
 				break;
 			}
 		}
 
-		if (!found)
+		if (!dev_found) {
 			rc = cam_res_mgr_add_device(dev, gpio_res);
-
-		mutex_unlock(&cam_res->gpio_res_lock);
+			if (rc) {
+				CAM_ERR(CAM_RES,
+					"add device to gpio res list failed rc: %d",
+					rc);
+				goto end;
+			}
+		}
 	}
 
+end:
+	mutex_unlock(&cam_res->gpio_res_lock);
 	return rc;
 }
 EXPORT_SYMBOL(cam_res_mgr_gpio_request);
 
-bool cam_res_mgr_check_if_gpio_is_shared(
+bool cam_res_mgr_util_check_if_gpio_is_shared(
 	struct gpio *gpio_tbl, uint8_t size)
 {
-	bool found = false;
 	int i = 0;
+	bool found = false;
 
 	if (!cam_res) {
 		CAM_DBG(CAM_RES, "cam_res data is not avaialbe");
@@ -457,42 +562,44 @@ bool cam_res_mgr_check_if_gpio_is_shared(
 	}
 
 	for (i = 0; i < size; i++) {
-		found = cam_res_mgr_gpio_is_shared(gpio_tbl[i].gpio);
-		if (found) {
-			CAM_DBG(CAM_RES, "gpio: %d is shared gpio",
-				gpio_tbl[i].gpio);
-			break;
-		}
+		found = __cam_res_mgr_find_if_gpio_is_shared(gpio_tbl[i].gpio);
+		if (found)
+			return found;
 	}
 
-	return found;
+	return false;
 }
-EXPORT_SYMBOL(cam_res_mgr_check_if_gpio_is_shared);
+EXPORT_SYMBOL(cam_res_mgr_util_check_if_gpio_is_shared);
 
 static void cam_res_mgr_gpio_free(struct device *dev, uint gpio)
 {
-	bool found = false;
-	bool need_free = true;
-	int dev_num =  0;
-	struct cam_gpio_res *gpio_res = NULL;
+	bool                   gpio_found = false;
+	bool                   need_free = true;
+	int                    dev_num = 0;
+	struct cam_gpio_res   *gpio_res = NULL;
+	bool                   is_shared_gpio = false;
+	bool                   is_shared_pctrl_gpio = false;
+	int                    pctrl_idx = -1;
+
+	is_shared_gpio = cam_res_mgr_gpio_is_in_shared_gpio(gpio);
+	is_shared_pctrl_gpio =
+			cam_res_mgr_gpio_is_in_shared_pctrl_gpio(gpio);
 
+	mutex_lock(&cam_res->gpio_res_lock);
 	if (cam_res && cam_res->shared_gpio_enabled) {
-		mutex_lock(&cam_res->gpio_res_lock);
 		list_for_each_entry(gpio_res, &cam_res->gpio_res_list, list) {
 			if (gpio == gpio_res->gpio) {
-				found = true;
+				gpio_found = true;
 				break;
 			}
 		}
-		mutex_unlock(&cam_res->gpio_res_lock);
 	}
 
-	if (found && cam_res
+	if (gpio_found && cam_res
 		&& cam_res->shared_gpio_enabled) {
 		struct list_head *list;
 		struct cam_dev_res *dev_res = NULL;
 
-		mutex_lock(&cam_res->gpio_res_lock);
 		/* Count the dev number in the dev_list */
 		list_for_each(list, &gpio_res->dev_list)
 			dev_num++;
@@ -507,7 +614,6 @@ static void cam_res_mgr_gpio_free(struct device *dev, uint gpio)
 				struct cam_dev_res, list);
 			list_del_init(&dev_res->list);
 			kfree(dev_res);
-
 			list_del_init(&gpio_res->list);
 			kfree(gpio_res);
 		} else {
@@ -521,11 +627,22 @@ static void cam_res_mgr_gpio_free(struct device *dev, uint gpio)
 				}
 			}
 		}
-		mutex_unlock(&cam_res->gpio_res_lock);
 	}
 
-	if (need_free)
+	if (need_free) {
+		if (is_shared_pctrl_gpio) {
+			pctrl_idx =
+				cam_res_mgr_util_get_idx_from_shared_pctrl_gpio(
+					gpio);
+			cam_res_mgr_shared_pinctrl_select_state(
+				pctrl_idx, false);
+		}
+
+		CAM_DBG(CAM_RES, "freeing gpio: %u", gpio);
 		gpio_free(gpio);
+	}
+
+	mutex_unlock(&cam_res->gpio_res_lock);
 }
 
 void cam_res_mgr_gpio_free_arry(struct device *dev,
@@ -542,15 +659,14 @@ int cam_res_mgr_gpio_set_value(unsigned int gpio, int value)
 	bool found = false;
 	struct cam_gpio_res *gpio_res = NULL;
 
+	mutex_lock(&cam_res->gpio_res_lock);
 	if (cam_res && cam_res->shared_gpio_enabled) {
-		mutex_lock(&cam_res->gpio_res_lock);
 		list_for_each_entry(gpio_res, &cam_res->gpio_res_list, list) {
 			if (gpio == gpio_res->gpio) {
 				found = true;
 				break;
 			}
 		}
-		mutex_unlock(&cam_res->gpio_res_lock);
 	}
 
 	/*
@@ -577,42 +693,85 @@ int cam_res_mgr_gpio_set_value(unsigned int gpio, int value)
 		}
 	}
 
+	mutex_unlock(&cam_res->gpio_res_lock);
 	return rc;
 }
 EXPORT_SYMBOL(cam_res_mgr_gpio_set_value);
 
-void cam_res_mgr_shared_clk_config(bool value)
+static int cam_res_mgr_shared_pinctrl_init(
+	struct device *dev)
 {
-	if (!cam_res)
-		return;
+	int i = 0;
+	char pctrl_active[50];
+	char pctrl_suspend[50];
+	struct cam_res_mgr_dt *dt = &cam_res->dt;
+
+	cam_res->pinctrl = devm_pinctrl_get(dev);
+	if (IS_ERR_OR_NULL(cam_res->pinctrl)) {
+		CAM_ERR(CAM_RES, "Pinctrl not available");
+		return -EINVAL;
+	}
 
-	mutex_lock(&cam_res->clk_res_lock);
-	if (value)
-		cam_res->shared_clk_ref_count++;
-	else
-		cam_res->shared_clk_ref_count--;
-	mutex_unlock(&cam_res->clk_res_lock);
+	for (i = 0; i < dt->num_shared_pctrl_gpio; i++) {
+		memset(pctrl_active, '\0', sizeof(pctrl_active));
+		memset(pctrl_suspend, '\0', sizeof(pctrl_suspend));
+		snprintf(pctrl_active, sizeof(pctrl_active),
+			"%s%s",
+			cam_res->dt.pctrl_name[i],
+			"_active");
+		CAM_DBG(CAM_RES, "pctrl_active at index: %d name: %s",
+			i, pctrl_active);
+		snprintf(pctrl_suspend, sizeof(pctrl_suspend),
+			"%s%s",
+			cam_res->dt.pctrl_name[i],
+			"_suspend");
+		CAM_DBG(CAM_RES, "pctrl_suspend at index: %d name: %s",
+			i, pctrl_suspend);
+		cam_res->pctrl_res[i].active =
+			pinctrl_lookup_state(cam_res->pinctrl,
+			pctrl_active);
+		if (IS_ERR_OR_NULL(cam_res->pctrl_res[i].active)) {
+			CAM_ERR(CAM_RES,
+				"Failed to get the active state pinctrl handle");
+			return -EINVAL;
+		}
+		cam_res->pctrl_res[i].suspend =
+			pinctrl_lookup_state(cam_res->pinctrl,
+			pctrl_suspend);
+		if (IS_ERR_OR_NULL(cam_res->pctrl_res[i].active)) {
+			CAM_ERR(CAM_RES,
+				"Failed to get the active state pinctrl handle");
+			return -EINVAL;
+		}
+		cam_res->pctrl_res[i].pstatus = PINCTRL_STATUS_GOT;
+	}
+
+	cam_res->pstatus = PINCTRL_STATUS_GOT;
+
+	return 0;
 }
-EXPORT_SYMBOL(cam_res_mgr_shared_clk_config);
 
-static int cam_res_mgr_parse_dt(struct device *dev)
+static int cam_res_mgr_parse_dt_shared_gpio(
+	struct device *dev)
 {
 	int rc = 0;
 	struct device_node *of_node = NULL;
 	struct cam_res_mgr_dt *dt = &cam_res->dt;
 
 	of_node = dev->of_node;
-
 	dt->num_shared_gpio = of_property_count_u32_elems(of_node,
 		"shared-gpios");
 
-	if (dt->num_shared_gpio > MAX_SHARED_GPIO_SIZE ||
-		dt->num_shared_gpio <= 0) {
-		/*
-		 * Not really an error, it means dtsi not configure
-		 * the shared gpio.
-		 */
-		CAM_DBG(CAM_RES, "Invalid GPIO number %d. No shared gpio.",
+	if (dt->num_shared_gpio <= 0) {
+		CAM_DBG(CAM_RES,
+			"Not found any shared gpio");
+		return -ENODEV;
+	}
+
+	if (dt->num_shared_gpio >= MAX_SHARED_GPIO_SIZE) {
+		CAM_ERR(CAM_RES,
+			"shared_gpio: %d max supported: %d",
+			MAX_SHARED_GPIO_SIZE,
 			dt->num_shared_gpio);
 		return -EINVAL;
 	}
@@ -624,39 +783,110 @@ static int cam_res_mgr_parse_dt(struct device *dev)
 		return -EINVAL;
 	}
 
-	dt->pinctrl_info.pinctrl = devm_pinctrl_get(dev);
-	if (IS_ERR_OR_NULL(dt->pinctrl_info.pinctrl)) {
-		CAM_ERR(CAM_RES, "Pinctrl not available");
-		return -EINVAL;
+	return rc;
+}
+
+static int cam_res_mgr_parse_dt_shared_pinctrl_gpio(
+	struct device *dev)
+{
+	int rc = 0, i = 0;
+	int pinctrl_name_nodes = 0;
+	struct device_node *of_node = NULL;
+	struct cam_res_mgr_dt *dt = &cam_res->dt;
+
+	of_node = dev->of_node;
+	dt->num_shared_pctrl_gpio = of_property_count_u32_elems(of_node,
+		"shared-pinctrl-gpios");
+
+	if (dt->num_shared_pctrl_gpio <= 0) {
+		CAM_DBG(CAM_RES,
+			"Not found any shared pinctrl res");
+		return -ENODEV;
 	}
 
-	/*
-	 * Check the pinctrl state to make sure the gpio
-	 * shared enabled.
-	 */
-	dt->pinctrl_info.gpio_state_active =
-		pinctrl_lookup_state(dt->pinctrl_info.pinctrl,
-			CAM_RES_MGR_DEFAULT);
-	if (IS_ERR_OR_NULL(dt->pinctrl_info.gpio_state_active)) {
+	if (dt->num_shared_pctrl_gpio >= MAX_SHARED_PCTRL_GPIO_SIZE) {
 		CAM_ERR(CAM_RES,
-			"Failed to get the active state pinctrl handle");
+			"Invalid Pinctrl GPIO number %d. No shared gpio.",
+			dt->num_shared_pctrl_gpio);
 		return -EINVAL;
 	}
 
-	dt->pinctrl_info.gpio_state_suspend =
-		pinctrl_lookup_state(dt->pinctrl_info.pinctrl,
-			CAM_RES_MGR_SLEEP);
-	if (IS_ERR_OR_NULL(dt->pinctrl_info.gpio_state_suspend)) {
+	pinctrl_name_nodes = of_property_count_strings(of_node,
+		"shared-pctrl-gpio-names");
+
+	if (pinctrl_name_nodes != dt->num_shared_pctrl_gpio) {
 		CAM_ERR(CAM_RES,
-			"Failed to get the active state pinctrl handle");
+			"Mismatch between entries:: pctrl_gpio: %d and pctrl_name: %d",
+			dt->num_shared_pctrl_gpio,
+			pinctrl_name_nodes);
 		return -EINVAL;
 	}
 
-	devm_pinctrl_put(dt->pinctrl_info.pinctrl);
+	CAM_INFO(CAM_RES,
+		"number of pctrl_gpio: %d", dt->num_shared_pctrl_gpio);
+
+	rc = of_property_read_u32_array(of_node, "shared-pinctrl-gpios",
+		dt->shared_pctrl_gpio, dt->num_shared_pctrl_gpio);
+	if (rc) {
+		CAM_ERR(CAM_RES, "Get shared pinctrl gpio array failed.");
+		return -EINVAL;
+	}
+
+	for (i = 0; i < pinctrl_name_nodes; i++) {
+		rc = of_property_read_string_index(of_node,
+			"shared-pctrl-gpio-names",
+			i, &(dt->pctrl_name[i]));
+		CAM_INFO(CAM_RES, "shared-pctrl-gpio-names[%d] = %s",
+			i, dt->pctrl_name[i]);
+		if (rc) {
+			CAM_ERR(CAM_RES,
+				"i= %d pinctrl_name_nodes= %d reading clock-names failed",
+				i, pinctrl_name_nodes);
+			return rc;
+		}
+	}
 
 	return rc;
 }
 
+static int cam_res_mgr_parse_dt(struct device *dev)
+{
+	int rc = 0;
+
+	rc = cam_res_mgr_parse_dt_shared_gpio(dev);
+	if (rc) {
+		if (rc == -ENODEV) {
+			CAM_DBG(CAM_RES,
+				"Shared GPIO resources not available");
+		} else {
+			CAM_ERR(CAM_RES,
+				"Shared gpio parsing failed: rc: %d", rc);
+			return rc;
+		}
+	}
+
+	rc = cam_res_mgr_parse_dt_shared_pinctrl_gpio(dev);
+	if (rc) {
+		if (rc == -ENODEV) {
+			CAM_DBG(CAM_RES,
+				"Pinctrl shared resources not available");
+		} else {
+			CAM_ERR(CAM_RES,  "Pinctrl parsing failed: rc: %d",
+				rc);
+			return rc;
+		}
+	} else {
+		/* When shared pinctrl is detected do the init */
+		rc = cam_res_mgr_shared_pinctrl_init(dev);
+		if (rc) {
+			CAM_ERR(CAM_RES, "Pinctrl init failed rc: %d", rc);
+			return rc;
+		}
+	}
+
+	return 0;
+}
+
 static int cam_res_mgr_component_bind(struct device *dev,
 	struct device *master_dev, void *data)
 {
@@ -664,25 +894,31 @@ static int cam_res_mgr_component_bind(struct device *dev,
 	struct platform_device *pdev = to_platform_device(dev);
 
 	cam_res = kzalloc(sizeof(*cam_res), GFP_KERNEL);
-	if (!cam_res)
+	if (!cam_res) {
+		CAM_ERR(CAM_RES, "Not Enough Mem");
 		return -ENOMEM;
-
+	}
 	cam_res->dev = &pdev->dev;
-	mutex_init(&cam_res->flash_res_lock);
-	mutex_init(&cam_res->gpio_res_lock);
-	mutex_init(&cam_res->clk_res_lock);
 
+	CAM_DBG(CAM_RES, "ENTER");
 	rc = cam_res_mgr_parse_dt(&pdev->dev);
 	if (rc) {
-		CAM_DBG(CAM_RES, "Disable shared gpio support.");
-		cam_res->shared_gpio_enabled = false;
-	} else {
+		CAM_ERR(CAM_RES,
+			"Error in parsing device tree, rc: %d", rc);
+		kfree(cam_res);
+		return rc;
+	}
+
+	if (cam_res->dt.num_shared_gpio || cam_res->dt.num_shared_pctrl_gpio) {
 		CAM_DBG(CAM_RES, "Enable shared gpio support.");
 		cam_res->shared_gpio_enabled = true;
+	} else {
+		CAM_DBG(CAM_RES, "Disable shared gpio support.");
+		cam_res->shared_gpio_enabled = false;
 	}
 
-	cam_res->shared_clk_ref_count = 0;
-	cam_res->pstatus = PINCTRL_STATUS_PUT;
+	mutex_init(&cam_res->flash_res_lock);
+	mutex_init(&cam_res->gpio_res_lock);
 
 	INIT_LIST_HEAD(&cam_res->gpio_res_list);
 	INIT_LIST_HEAD(&cam_res->flash_res_list);
@@ -696,9 +932,14 @@ static void cam_res_mgr_component_unbind(struct device *dev,
 {
 	if (cam_res) {
 		cam_res_mgr_free_res();
+		devm_pinctrl_put(cam_res->pinctrl);
+		cam_res->pinctrl = NULL;
+		cam_res->pstatus = PINCTRL_STATUS_PUT;
 		kfree(cam_res);
 		cam_res = NULL;
 	}
+
+	CAM_DBG(CAM_RES, "Component unbound successfully");
 }
 
 const static struct component_ops cam_res_mgr_component_ops = {

+ 22 - 42
drivers/cam_sensor_module/cam_res_mgr/cam_res_mgr_api.h

@@ -43,37 +43,6 @@ void cam_res_mgr_led_trigger_unregister(struct led_trigger *tp);
 void cam_res_mgr_led_trigger_event(struct led_trigger *trig,
 	enum led_brightness brightness);
 
-/**
- * @brief: Get the corresponding pinctrl of dev
- *
- *  Init the shared pinctrl if shared pinctrl enabled.
- *
- * @return None
- */
-int cam_res_mgr_shared_pinctrl_init(void);
-
-/**
- * @brief: Put the pinctrl
- *
- *  Put the shared pinctrl.
- *
- * @return Status of operation. Negative in case of error. Zero otherwise.
- */
-void cam_res_mgr_shared_pinctrl_put(void);
-
-/**
- * @brief: Select the corresponding state
- *
- *  Active state can be selected directly, but need hold to suspend the
- *  pinctrl if the gpios in this pinctrl also held by other pinctrl.
- *
- * @active   : The flag to indicate whether active or suspend
- * the shared pinctrl.
- *
- * @return Status of operation. Negative in case of error. Zero otherwise.
- */
-int cam_res_mgr_shared_pinctrl_select_state(bool active);
-
 /**
  * @brief: Check for shared gpio
  *
@@ -85,7 +54,7 @@ int cam_res_mgr_shared_pinctrl_select_state(bool active);
  * @size      : GPIO table size
  * @return Status of operation. False if not shared, true otherwise.
  */
-bool cam_res_mgr_check_if_gpio_is_shared(
+bool cam_res_mgr_util_check_if_gpio_is_shared(
 	struct gpio *gpio_tbl, uint8_t size);
 
 /**
@@ -131,16 +100,6 @@ void cam_res_mgr_gpio_free_arry(struct device *dev,
  */
 int cam_res_mgr_gpio_set_value(unsigned int gpio, int value);
 
-/**
- * @brief: Config the shared clk ref count
- *
- *  Config the shared clk ref count..
- *
- * @value   : get or put the shared clk.
- *
- * @return None
- */
-void cam_res_mgr_shared_clk_config(bool value);
 
 /**
  * @brief : API to register RES_MGR to platform framework.
@@ -152,4 +111,25 @@ int cam_res_mgr_init(void);
  * @brief : API to remove RES_MGR from platform framework.
  */
 void cam_res_mgr_exit(void);
+
+/**
+ * @brief : API to get gpio idx from shared gpio list.
+ * @return idx for Success and error if gpio not found or invalid.
+ */
+int cam_res_mgr_util_get_idx_from_shared_gpio(uint gpio);
+
+/**
+ * @brief : API to get gpio idx from shared pinctrl gpio list.
+ * @return idx for Success and error if gpio not found or invalid.
+ */
+int cam_res_mgr_util_get_idx_from_shared_pctrl_gpio(uint gpio);
+
+/**
+ * @brief : API to check whether gpio is in use or can be free.
+ * @return NEED_HOLD macro if gpio is in use CAN_FREE if gpio can be free,
+ *	error if operation is not valid, 0 in case of res_mgr is not
+ *	available.
+ */
+int cam_res_mgr_util_shared_gpio_check_hold(uint gpio);
+
 #endif /* __CAM_RES_MGR_API_H__ */

+ 40 - 25
drivers/cam_sensor_module/cam_res_mgr/cam_res_mgr_private.h

@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2018, 2020 The Linux Foundation. All rights reserved.
  */
 
 #ifndef __CAM_RES_MGR_PRIVATE_H__
@@ -9,12 +9,10 @@
 #include <linux/list.h>
 #include <linux/leds.h>
 #include "cam_soc_util.h"
+#include "cam_sensor_util.h"
 
-#define MAX_SHARED_GPIO_SIZE 16
-
-/* pinctrl states name */
-#define CAM_RES_MGR_SLEEP	"cam_res_mgr_suspend"
-#define CAM_RES_MGR_DEFAULT	"cam_res_mgr_default"
+#define MAX_SHARED_GPIO_SIZE         16
+#define MAX_SHARED_PCTRL_GPIO_SIZE   10
 
 /**
  * enum pinctrl_status - Enum for pinctrl status
@@ -65,17 +63,34 @@ struct cam_flash_res {
 	struct led_trigger *trigger;
 };
 
+/**
+ * struct cam_pinctrl_res
+ *
+ * @active         : Pinctrl state pointer for active state
+ * @suspend        : Pinctrl state pointer for suspend state
+ * @pstatus        : Pinctrl status holder
+ */
+struct cam_pinctrl_res {
+	struct pinctrl_state  *active;
+	struct pinctrl_state  *suspend;
+	enum pinctrl_status   pstatus;
+};
+
 /**
  * struct cam_res_mgr_dt
  *
- * @shared_gpio     : Shared gpios list in the device tree
- * @num_shared_gpio : The number of shared gpio
- * @pinctrl_info    : Pinctrl information
+ * @shared_gpio            : Shared gpios list
+ * @shared_pctrl_gpio      : Shared pinctrl gpio list
+ * @num_shared_gpio        : Number of shared gpio
+ * @num_shared_pctrl_gpio  : Number of shared pinctrl gpio
+ * @pctrl_name             : Pinctrl name from shared pinctrl gpio list
  */
 struct cam_res_mgr_dt {
-	uint                        shared_gpio[MAX_SHARED_GPIO_SIZE];
-	int                         num_shared_gpio;
-	struct cam_soc_pinctrl_info pinctrl_info;
+	uint                shared_gpio[MAX_SHARED_GPIO_SIZE];
+	uint                shared_pctrl_gpio[MAX_SHARED_PCTRL_GPIO_SIZE];
+	int                 num_shared_gpio;
+	int                 num_shared_pctrl_gpio;
+	const char         *pctrl_name[MAX_SHARED_PCTRL_GPIO_SIZE];
 };
 
 /**
@@ -84,27 +99,27 @@ struct cam_res_mgr_dt {
  * @dev                 : Pointer to the device
  * @dt                  : Device tree resource
  * @shared_gpio_enabled : The flag to indicate if support shared gpio
- * @pstatus             : Shared pinctrl status
+ * @pstatus             : Top level device pinctrl status
+ * @pinctrl             : Device pinctrl pointer
+ * @pctrl_res           : Pinctrl resource array
  * @gpio_res_list       : List head of the gpio resource
  * @flash_res_list      : List head of the flash resource
  * @gpio_res_lock       : GPIO resource lock
  * @flash_res_lock      : Flash resource lock
- * @clk_res_lock        : Clk resource lock
  */
 struct cam_res_mgr {
-	struct device         *dev;
-	struct cam_res_mgr_dt dt;
-
-	bool                  shared_gpio_enabled;
-	enum pinctrl_status   pstatus;
+	struct device          *dev;
+	struct cam_res_mgr_dt   dt;
+	bool                    shared_gpio_enabled;
 
-	uint                  shared_clk_ref_count;
+	enum pinctrl_status     pstatus;
+	struct pinctrl         *pinctrl;
+	struct cam_pinctrl_res  pctrl_res[MAX_SHARED_PCTRL_GPIO_SIZE];
 
-	struct list_head      gpio_res_list;
-	struct list_head      flash_res_list;
-	struct mutex          gpio_res_lock;
-	struct mutex          flash_res_lock;
-	struct mutex          clk_res_lock;
+	struct list_head        gpio_res_list;
+	struct list_head        flash_res_list;
+	struct mutex            gpio_res_lock;
+	struct mutex            flash_res_lock;
 };
 
 #endif /* __CAM_RES_MGR_PRIVATE_H__ */

+ 5 - 42
drivers/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c

@@ -1201,7 +1201,8 @@ int cam_sensor_util_request_gpio_table(
 	}
 
 	for (i = 0; i < size; i++) {
-		CAM_DBG(CAM_SENSOR, "i: %d, gpio %d dir %ld",  i,
+		CAM_DBG(CAM_SENSOR, "%s%d, i: %d, gpio %d dir %lld",
+			soc_info->dev_name, soc_info->index, i,
 			gpio_tbl[i].gpio, gpio_tbl[i].flags);
 	}
 
@@ -1227,7 +1228,7 @@ int cam_sensor_util_request_gpio_table(
 	return rc;
 }
 
-static bool cam_sensor_util_check_gpio_is_shared(
+bool cam_sensor_util_check_gpio_is_shared(
 	struct cam_hw_soc_info *soc_info)
 {
 	int rc = 0;
@@ -1255,7 +1256,7 @@ static bool cam_sensor_util_check_gpio_is_shared(
 		return false;
 	}
 
-	rc = cam_res_mgr_check_if_gpio_is_shared(
+	rc = cam_res_mgr_util_check_if_gpio_is_shared(
 		gpio_tbl, size);
 	if (!rc) {
 		CAM_DBG(CAM_SENSOR,
@@ -1988,7 +1989,6 @@ int cam_sensor_core_power_up(struct cam_sensor_power_ctrl_t *ctrl,
 		struct cam_hw_soc_info *soc_info)
 {
 	int rc = 0, index = 0, no_gpio = 0, ret = 0, num_vreg, j = 0, i = 0;
-	bool shared_gpio = false;
 	int32_t vreg_idx = -1;
 	struct cam_sensor_power_setting *power_setting = NULL;
 	struct msm_camera_gpio_num_info *gpio_num_info = NULL;
@@ -2007,9 +2007,6 @@ int cam_sensor_core_power_up(struct cam_sensor_power_ctrl_t *ctrl,
 		return -EINVAL;
 	}
 
-	if (soc_info->use_shared_clk)
-		cam_res_mgr_shared_clk_config(true);
-
 	ret = msm_camera_pinctrl_init(&(ctrl->pinctrl_info), ctrl->dev);
 	if (ret < 0) {
 		/* Some sensor subdev no pinctrl. */
@@ -2019,19 +2016,9 @@ int cam_sensor_core_power_up(struct cam_sensor_power_ctrl_t *ctrl,
 		ctrl->cam_pinctrl_status = 1;
 	}
 
-	shared_gpio = cam_sensor_util_check_gpio_is_shared(soc_info);
 	rc = cam_sensor_util_request_gpio_table(soc_info, 1);
-	if (rc < 0)
+	if (rc < 0) {
 		no_gpio = rc;
-
-	if (shared_gpio) {
-		rc = cam_res_mgr_shared_pinctrl_init();
-		if (rc) {
-			CAM_ERR(CAM_SENSOR,
-				"Failed to init shared pinctrl");
-			shared_gpio = false;
-			return -EINVAL;
-		}
 	}
 
 	if (ctrl->cam_pinctrl_status) {
@@ -2042,12 +2029,6 @@ int cam_sensor_core_power_up(struct cam_sensor_power_ctrl_t *ctrl,
 			CAM_ERR(CAM_SENSOR, "cannot set pin to active state");
 	}
 
-	if (shared_gpio) {
-		ret = cam_res_mgr_shared_pinctrl_select_state(true);
-		if (ret)
-			CAM_ERR(CAM_SENSOR,
-				"Cannot set shared pin to active state");
-	}
 	CAM_DBG(CAM_SENSOR, "power setting size: %d", ctrl->power_setting_size);
 
 	for (index = 0; index < ctrl->power_setting_size; index++) {
@@ -2332,16 +2313,7 @@ power_up_failed:
 		devm_pinctrl_put(ctrl->pinctrl_info.pinctrl);
 	}
 
-	if (soc_info->use_shared_clk)
-		cam_res_mgr_shared_clk_config(false);
-
-	if (shared_gpio) {
-		cam_res_mgr_shared_pinctrl_select_state(false);
-		cam_res_mgr_shared_pinctrl_put();
-	}
-
 	ctrl->cam_pinctrl_status = 0;
-
 	cam_sensor_util_request_gpio_table(soc_info, 0);
 
 	return rc;
@@ -2372,7 +2344,6 @@ int cam_sensor_util_power_down(struct cam_sensor_power_ctrl_t *ctrl,
 		struct cam_hw_soc_info *soc_info)
 {
 	int index = 0, ret = 0, num_vreg = 0, i;
-	bool shared_gpio = false;
 	struct cam_sensor_power_setting *pd = NULL;
 	struct cam_sensor_power_setting *ps = NULL;
 	struct msm_camera_gpio_num_info *gpio_num_info = NULL;
@@ -2383,7 +2354,6 @@ int cam_sensor_util_power_down(struct cam_sensor_power_ctrl_t *ctrl,
 		return -EINVAL;
 	}
 
-	shared_gpio = cam_sensor_util_check_gpio_is_shared(soc_info);
 	gpio_num_info = ctrl->gpio_num_info;
 	num_vreg = soc_info->num_rgltr;
 
@@ -2521,13 +2491,6 @@ int cam_sensor_util_power_down(struct cam_sensor_power_ctrl_t *ctrl,
 	}
 
 	cam_sensor_util_request_gpio_table(soc_info, 0);
-
-	if (soc_info->use_shared_clk)
-		cam_res_mgr_shared_clk_config(false);
-	if (shared_gpio) {
-		cam_res_mgr_shared_pinctrl_select_state(false);
-		cam_res_mgr_shared_pinctrl_put();
-	}
 	ctrl->cam_pinctrl_status = 0;
 
 	return 0;

+ 4 - 0
drivers/cam_sensor_module/cam_sensor_utils/cam_sensor_util.h

@@ -20,6 +20,8 @@
 #include "cam_sensor_io.h"
 
 #define INVALID_VREG 100
+#define RES_MGR_GPIO_NEED_HOLD   1
+#define RES_MGR_GPIO_CAN_FREE    2
 
 /*
  * Constant Factors needed to change QTimer ticks to nanoseconds
@@ -77,4 +79,6 @@ int32_t cam_sensor_update_power_settings(void *cmd_buf,
 
 int cam_sensor_bob_pwm_mode_switch(struct cam_hw_soc_info *soc_info,
 	int bob_reg_idx, bool flag);
+
+bool cam_sensor_util_check_gpio_is_shared(struct cam_hw_soc_info *soc_info);
 #endif /* _CAM_SENSOR_UTIL_H_ */