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:
Jigarkumar Zala
2020-08-14 14:08:11 -07:00
rodič 3da4eff78a
revize 7ed86436a3
3 změnil soubory, kde provedl 108 přidání a 67 odebrání

Zobrazit soubor

@@ -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;

Zobrazit soubor

@@ -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

Zobrazit soubor

@@ -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;
}