diff --git a/drivers/cam_sensor_module/cam_res_mgr/cam_res_mgr.c b/drivers/cam_sensor_module/cam_res_mgr/cam_res_mgr.c index abe1b2c7a0fd..592b68002c87 100644 --- a/drivers/cam_sensor_module/cam_res_mgr/cam_res_mgr.c +++ b/drivers/cam_sensor_module/cam_res_mgr/cam_res_mgr.c @@ -318,43 +318,6 @@ int cam_res_mgr_shared_pinctrl_select_state(bool active) } EXPORT_SYMBOL(cam_res_mgr_shared_pinctrl_select_state); -int cam_res_mgr_shared_pinctrl_post_init(void) -{ - int ret = 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 ret; - } - - mutex_lock(&cam_res->gpio_res_lock); - if (cam_res->pstatus == PINCTRL_STATUS_PUT) { - CAM_DBG(CAM_RES, "The shared pinctrl alerady been put.!"); - mutex_unlock(&cam_res->gpio_res_lock); - return ret; - } - - pinctrl_info = &cam_res->dt.pinctrl_info; - - /* - * If no gpio resource in gpio_res_list, and - * no shared clk now, it means this device - * don't have shared gpio. - */ - if (list_empty(&cam_res->gpio_res_list) && - cam_res->shared_clk_ref_count < 1) { - ret = pinctrl_select_state(pinctrl_info->pinctrl, - pinctrl_info->gpio_state_suspend); - devm_pinctrl_put(pinctrl_info->pinctrl); - cam_res->pstatus = PINCTRL_STATUS_PUT; - } - mutex_unlock(&cam_res->gpio_res_lock); - - return ret; -} -EXPORT_SYMBOL(cam_res_mgr_shared_pinctrl_post_init); - static int cam_res_mgr_add_device(struct device *dev, struct cam_gpio_res *gpio_res) { @@ -477,6 +440,35 @@ int cam_res_mgr_gpio_request(struct device *dev, uint gpio, } EXPORT_SYMBOL(cam_res_mgr_gpio_request); +bool cam_res_mgr_check_if_gpio_is_shared( + struct gpio *gpio_tbl, uint8_t size) +{ + bool found = false; + int i = 0; + + if (!cam_res) { + CAM_DBG(CAM_RES, "cam_res data is not avaialbe"); + return false; + } + + if (!cam_res->shared_gpio_enabled) { + CAM_DBG(CAM_RES, "shared gpio support is not enabled"); + return false; + } + + 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; + } + } + + return found; +} +EXPORT_SYMBOL(cam_res_mgr_check_if_gpio_is_shared); + static void cam_res_mgr_gpio_free(struct device *dev, uint gpio) { bool found = false; diff --git a/drivers/cam_sensor_module/cam_res_mgr/cam_res_mgr_api.h b/drivers/cam_sensor_module/cam_res_mgr/cam_res_mgr_api.h index b47c68dea675..096cb0916e7d 100644 --- a/drivers/cam_sensor_module/cam_res_mgr/cam_res_mgr_api.h +++ b/drivers/cam_sensor_module/cam_res_mgr/cam_res_mgr_api.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. */ #ifndef __CAM_RES_MGR_API_H__ @@ -75,14 +75,18 @@ void cam_res_mgr_shared_pinctrl_put(void); int cam_res_mgr_shared_pinctrl_select_state(bool active); /** - * @brief: Post init shared pinctrl + * @brief: Check for shared gpio * - * Post init to check if the device really has shared gpio, - * suspend and put the pinctrl if not use shared gpio. + * Will check whether requested device shares the gpio with other + * device. This function check against gpio table from device and + * shared gpio resources has been defined at res-mgr level * - * @return Status of operation. Negative in case of error. Zero otherwise. + * @gpio_tbl : The GPIO table for respective device + * @size : GPIO table size + * @return Status of operation. False if not shared, true otherwise. */ -int cam_res_mgr_shared_pinctrl_post_init(void); +bool cam_res_mgr_check_if_gpio_is_shared( + struct gpio *gpio_tbl, uint8_t size); /** * @brief: Request a gpio diff --git a/drivers/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c b/drivers/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c index 7334c9accbb2..9b13ff7e4d02 100644 --- a/drivers/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c +++ b/drivers/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c @@ -1227,6 +1227,45 @@ int cam_sensor_util_request_gpio_table( return rc; } +static bool cam_sensor_util_check_gpio_is_shared( + struct cam_hw_soc_info *soc_info) +{ + int rc = 0; + uint8_t size = 0; + struct cam_soc_gpio_data *gpio_conf = + soc_info->gpio_data; + struct gpio *gpio_tbl = NULL; + + if (!gpio_conf) { + CAM_DBG(CAM_SENSOR, "No GPIO data"); + return false; + } + + if (gpio_conf->cam_gpio_common_tbl_size <= 0) { + CAM_DBG(CAM_SENSOR, "No GPIO entry"); + return false; + } + + gpio_tbl = gpio_conf->cam_gpio_req_tbl; + size = gpio_conf->cam_gpio_req_tbl_size; + + if (!gpio_tbl || !size) { + CAM_ERR(CAM_SENSOR, "invalid gpio_tbl %pK / size %d", + gpio_tbl, size); + return false; + } + + rc = cam_res_mgr_check_if_gpio_is_shared( + gpio_tbl, size); + if (!rc) { + CAM_DBG(CAM_SENSOR, + "dev: %s don't have shared gpio resources", + soc_info->dev_name); + return false; + } + + return true; +} static int32_t cam_sensor_validate(void *ptr, size_t remain_buf) { @@ -1949,6 +1988,7 @@ 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; @@ -1979,16 +2019,21 @@ int cam_sensor_core_power_up(struct cam_sensor_power_ctrl_t *ctrl, ctrl->cam_pinctrl_status = 1; } - if (cam_res_mgr_shared_pinctrl_init()) { - CAM_ERR(CAM_SENSOR, - "Failed to init shared pinctrl"); - return -EINVAL; - } - + shared_gpio = cam_sensor_util_check_gpio_is_shared(soc_info); rc = cam_sensor_util_request_gpio_table(soc_info, 1); 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) { ret = pinctrl_select_state( ctrl->pinctrl_info.pinctrl, @@ -1997,11 +2042,12 @@ int cam_sensor_core_power_up(struct cam_sensor_power_ctrl_t *ctrl, CAM_ERR(CAM_SENSOR, "cannot set pin to active state"); } - ret = cam_res_mgr_shared_pinctrl_select_state(true); - if (ret) - CAM_ERR(CAM_SENSOR, - "Cannot set shared 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++) { @@ -2185,11 +2231,6 @@ int cam_sensor_core_power_up(struct cam_sensor_power_ctrl_t *ctrl, (power_setting->delay * 1000) + 1000); } - ret = cam_res_mgr_shared_pinctrl_post_init(); - if (ret) - CAM_ERR(CAM_SENSOR, - "Failed to post init shared pinctrl"); - return 0; power_up_failed: CAM_ERR(CAM_SENSOR, "failed"); @@ -2294,8 +2335,10 @@ power_up_failed: if (soc_info->use_shared_clk) cam_res_mgr_shared_clk_config(false); - cam_res_mgr_shared_pinctrl_select_state(false); - cam_res_mgr_shared_pinctrl_put(); + if (shared_gpio) { + cam_res_mgr_shared_pinctrl_select_state(false); + cam_res_mgr_shared_pinctrl_put(); + } ctrl->cam_pinctrl_status = 0; @@ -2329,6 +2372,7 @@ 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; @@ -2339,6 +2383,7 @@ 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; @@ -2475,15 +2520,15 @@ int cam_sensor_util_power_down(struct cam_sensor_power_ctrl_t *ctrl, devm_pinctrl_put(ctrl->pinctrl_info.pinctrl); } + cam_sensor_util_request_gpio_table(soc_info, 0); + if (soc_info->use_shared_clk) cam_res_mgr_shared_clk_config(false); - - cam_res_mgr_shared_pinctrl_select_state(false); - cam_res_mgr_shared_pinctrl_put(); - + 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 0; }