msm: camera: csiphy: Handle process shutdown during secure camera
Use SCM 7 call during the process shutdown. This is to workaround a race condition between the close of camera FD and the invoke driver FD that leads to a device crash. Additionally, keep the Domain ID clocks on only during protect or unprotect operations. CRs-Fixed: 3509086 Change-Id: Ic091aa737df10bb2b41190c2f850c31fd17af9b2 Signed-off-by: Vijay Kumar Tumati <quic_vtumati@quicinc.com>
This commit is contained in:

committed by
Camera Software Integration

parent
ebaa2a7356
commit
16be1306ef
@@ -1234,11 +1234,11 @@ static int __cam_csiphy_prgm_bist_reg(struct csiphy_device *csiphy_dev, bool is_
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int cam_csiphy_program_secure_mode(struct csiphy_device *csiphy_dev,
|
static int cam_csiphy_program_secure_mode(struct csiphy_device *csiphy_dev,
|
||||||
bool protect, int32_t offset)
|
bool protect, int32_t offset, bool is_shutdown)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
if (csiphy_dev->domain_id_security && protect) {
|
if (csiphy_dev->domain_id_security) {
|
||||||
if (!csiphy_dev->csiphy_info[offset].secure_info_updated) {
|
if (!csiphy_dev->csiphy_info[offset].secure_info_updated) {
|
||||||
CAM_ERR(CAM_CSIPHY,
|
CAM_ERR(CAM_CSIPHY,
|
||||||
"PHY[%u] domain id info not updated, aborting secure call",
|
"PHY[%u] domain id info not updated, aborting secure call",
|
||||||
@@ -1252,11 +1252,11 @@ static int cam_csiphy_program_secure_mode(struct csiphy_device *csiphy_dev,
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = cam_csiphy_notify_secure_mode(csiphy_dev, protect, offset);
|
rc = cam_csiphy_notify_secure_mode(csiphy_dev, protect, offset, is_shutdown);
|
||||||
|
|
||||||
if (csiphy_dev->domain_id_security && !protect) {
|
if (csiphy_dev->domain_id_security) {
|
||||||
cam_cpas_enable_clks_for_domain_id(false);
|
cam_cpas_enable_clks_for_domain_id(false);
|
||||||
|
if (!protect)
|
||||||
csiphy_dev->csiphy_info[offset].secure_info_updated = false;
|
csiphy_dev->csiphy_info[offset].secure_info_updated = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1436,7 +1436,7 @@ void cam_csiphy_shutdown(struct csiphy_device *csiphy_dev)
|
|||||||
|
|
||||||
if (param->secure_mode)
|
if (param->secure_mode)
|
||||||
cam_csiphy_program_secure_mode(csiphy_dev,
|
cam_csiphy_program_secure_mode(csiphy_dev,
|
||||||
CAM_SECURE_MODE_NON_SECURE, i);
|
CAM_SECURE_MODE_NON_SECURE, i, true);
|
||||||
|
|
||||||
param->secure_mode = CAM_SECURE_MODE_NON_SECURE;
|
param->secure_mode = CAM_SECURE_MODE_NON_SECURE;
|
||||||
|
|
||||||
@@ -2216,7 +2216,7 @@ int32_t cam_csiphy_core_cfg(void *phy_dev,
|
|||||||
if (--csiphy_dev->start_dev_count) {
|
if (--csiphy_dev->start_dev_count) {
|
||||||
if (param->secure_mode)
|
if (param->secure_mode)
|
||||||
cam_csiphy_program_secure_mode(csiphy_dev,
|
cam_csiphy_program_secure_mode(csiphy_dev,
|
||||||
CAM_SECURE_MODE_NON_SECURE, offset);
|
CAM_SECURE_MODE_NON_SECURE, offset, false);
|
||||||
|
|
||||||
param->secure_mode = CAM_SECURE_MODE_NON_SECURE;
|
param->secure_mode = CAM_SECURE_MODE_NON_SECURE;
|
||||||
param->csiphy_cpas_cp_reg_mask = 0;
|
param->csiphy_cpas_cp_reg_mask = 0;
|
||||||
@@ -2253,7 +2253,7 @@ int32_t cam_csiphy_core_cfg(void *phy_dev,
|
|||||||
|
|
||||||
if (param->secure_mode)
|
if (param->secure_mode)
|
||||||
cam_csiphy_program_secure_mode(csiphy_dev, CAM_SECURE_MODE_NON_SECURE,
|
cam_csiphy_program_secure_mode(csiphy_dev, CAM_SECURE_MODE_NON_SECURE,
|
||||||
offset);
|
offset, false);
|
||||||
|
|
||||||
param->secure_mode = CAM_SECURE_MODE_NON_SECURE;
|
param->secure_mode = CAM_SECURE_MODE_NON_SECURE;
|
||||||
param->csiphy_cpas_cp_reg_mask = 0x0;
|
param->csiphy_cpas_cp_reg_mask = 0x0;
|
||||||
@@ -2323,7 +2323,7 @@ int32_t cam_csiphy_core_cfg(void *phy_dev,
|
|||||||
if (csiphy_dev->csiphy_info[offset].secure_mode)
|
if (csiphy_dev->csiphy_info[offset].secure_mode)
|
||||||
cam_csiphy_program_secure_mode(
|
cam_csiphy_program_secure_mode(
|
||||||
csiphy_dev,
|
csiphy_dev,
|
||||||
CAM_SECURE_MODE_NON_SECURE, offset);
|
CAM_SECURE_MODE_NON_SECURE, offset, false);
|
||||||
|
|
||||||
csiphy_dev->csiphy_info[offset].secure_mode =
|
csiphy_dev->csiphy_info[offset].secure_mode =
|
||||||
CAM_SECURE_MODE_NON_SECURE;
|
CAM_SECURE_MODE_NON_SECURE;
|
||||||
@@ -2503,7 +2503,7 @@ int32_t cam_csiphy_core_cfg(void *phy_dev,
|
|||||||
}
|
}
|
||||||
|
|
||||||
rc = cam_csiphy_program_secure_mode(csiphy_dev,
|
rc = cam_csiphy_program_secure_mode(csiphy_dev,
|
||||||
CAM_SECURE_MODE_SECURE, offset);
|
CAM_SECURE_MODE_SECURE, offset, false);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
csiphy_dev->csiphy_info[offset]
|
csiphy_dev->csiphy_info[offset]
|
||||||
.secure_mode =
|
.secure_mode =
|
||||||
@@ -2574,7 +2574,7 @@ int32_t cam_csiphy_core_cfg(void *phy_dev,
|
|||||||
|
|
||||||
rc = cam_csiphy_program_secure_mode(
|
rc = cam_csiphy_program_secure_mode(
|
||||||
csiphy_dev,
|
csiphy_dev,
|
||||||
CAM_SECURE_MODE_SECURE, offset);
|
CAM_SECURE_MODE_SECURE, offset, false);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
csiphy_dev->csiphy_info[offset].secure_mode =
|
csiphy_dev->csiphy_info[offset].secure_mode =
|
||||||
CAM_SECURE_MODE_NON_SECURE;
|
CAM_SECURE_MODE_NON_SECURE;
|
||||||
|
@@ -327,7 +327,7 @@ bool cam_is_mink_api_available(void)
|
|||||||
}
|
}
|
||||||
#if KERNEL_VERSION(6, 0, 0) <= LINUX_VERSION_CODE
|
#if KERNEL_VERSION(6, 0, 0) <= LINUX_VERSION_CODE
|
||||||
int cam_csiphy_notify_secure_mode(struct csiphy_device *csiphy_dev,
|
int cam_csiphy_notify_secure_mode(struct csiphy_device *csiphy_dev,
|
||||||
bool protect, int32_t offset)
|
bool protect, int32_t offset, bool is_shutdown)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
struct Object client_env, sc_object;
|
struct Object client_env, sc_object;
|
||||||
@@ -339,6 +339,7 @@ int cam_csiphy_notify_secure_mode(struct csiphy_device *csiphy_dev,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!is_shutdown) {
|
||||||
rc = get_client_env_object(&client_env);
|
rc = get_client_env_object(&client_env);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
CAM_ERR(CAM_CSIPHY, "Failed getting mink env object, rc: %d", rc);
|
CAM_ERR(CAM_CSIPHY, "Failed getting mink env object, rc: %d", rc);
|
||||||
@@ -370,11 +371,23 @@ int cam_csiphy_notify_secure_mode(struct csiphy_device *csiphy_dev,
|
|||||||
CAM_ERR(CAM_CSIPHY, "Failed releasing secure camera object, rc: %d", rc);
|
CAM_ERR(CAM_CSIPHY, "Failed releasing secure camera object, rc: %d", rc);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = Object_release(client_env);
|
rc = Object_release(client_env);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
CAM_ERR(CAM_CSIPHY, "Failed releasing mink env object, rc: %d", rc);
|
CAM_ERR(CAM_CSIPHY, "Failed releasing mink env object, rc: %d", rc);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
/* This is a temporary work around until the SMC Invoke driver is
|
||||||
|
* refactored to avoid the dependency on FDs, which was causing issues
|
||||||
|
* during process shutdown.
|
||||||
|
*/
|
||||||
|
rc = qcom_scm_camera_protect_phy_lanes(protect, 0);
|
||||||
|
if (rc) {
|
||||||
|
CAM_ERR(CAM_CSIPHY, "SCM call to hypervisor failed");
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@@ -66,7 +66,7 @@ int cam_ife_notify_safe_lut_scm(bool safe_trigger);
|
|||||||
int camera_component_match_add_drivers(struct device *master_dev,
|
int camera_component_match_add_drivers(struct device *master_dev,
|
||||||
struct component_match **match_list);
|
struct component_match **match_list);
|
||||||
int cam_csiphy_notify_secure_mode(struct csiphy_device *csiphy_dev,
|
int cam_csiphy_notify_secure_mode(struct csiphy_device *csiphy_dev,
|
||||||
bool protect, int32_t offset);
|
bool protect, int32_t offset, bool is_shutdown);
|
||||||
bool cam_is_mink_api_available(void);
|
bool cam_is_mink_api_available(void);
|
||||||
void cam_free_clear(const void *);
|
void cam_free_clear(const void *);
|
||||||
void cam_check_iommu_faults(struct iommu_domain *domain,
|
void cam_check_iommu_faults(struct iommu_domain *domain,
|
||||||
|
Reference in New Issue
Block a user