msm: camera: sensor: Add logic to call the res_mgr api if needed
Currently any slave can call pinctrl api for res_mgr which may lead in corruption of pinctrl state. This change identify whether slave is resposible for the shared pinctrl access by searching/matching the gpio defined under res_mgr dtsi. Also remove post_init pinctrl as this functionality is not used anymore. This can help to avoid the unnecessary calls to the res_mgr which can avoid mutex operations to imporve the performance. CRs-Fixed: 2758167 Change-Id: Id0e863ae00eeef6c3877f02d34878c131695a604 Signed-off-by: Jigarkumar Zala <jzala@codeaurora.org>
Tento commit je obsažen v:
@@ -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;
|
||||
|
@@ -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
|
||||
|
@@ -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;
|
||||
}
|
||||
|
Odkázat v novém úkolu
Zablokovat Uživatele