|
@@ -1,6 +1,6 @@
|
|
|
// SPDX-License-Identifier: GPL-2.0-only
|
|
|
/*
|
|
|
- * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
|
|
+ * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
|
|
*/
|
|
|
|
|
|
#include <linux/delay.h>
|
|
@@ -180,10 +180,12 @@ void cam_cdm_notify_clients(struct cam_hw_info *cdm_hw,
|
|
|
(struct cam_cdm_bl_cb_request_entry *)data;
|
|
|
|
|
|
client_idx = CAM_CDM_GET_CLIENT_IDX(node->client_hdl);
|
|
|
+ mutex_lock(&cdm_hw->hw_mutex);
|
|
|
client = core->clients[client_idx];
|
|
|
if ((!client) || (client->handle != node->client_hdl)) {
|
|
|
CAM_ERR(CAM_CDM, "Invalid client %pK hdl=%x", client,
|
|
|
node->client_hdl);
|
|
|
+ mutex_unlock(&cdm_hw->hw_mutex);
|
|
|
return;
|
|
|
}
|
|
|
cam_cdm_get_client_refcount(client);
|
|
@@ -202,6 +204,7 @@ void cam_cdm_notify_clients(struct cam_hw_info *cdm_hw,
|
|
|
}
|
|
|
mutex_unlock(&client->lock);
|
|
|
cam_cdm_put_client_refcount(client);
|
|
|
+ mutex_unlock(&cdm_hw->hw_mutex);
|
|
|
return;
|
|
|
} else if (status == CAM_CDM_CB_STATUS_HW_RESET_DONE ||
|
|
|
status == CAM_CDM_CB_STATUS_HW_FLUSH ||
|
|
@@ -217,7 +220,7 @@ void cam_cdm_notify_clients(struct cam_hw_info *cdm_hw,
|
|
|
if ((!client) || (client->handle != node->client_hdl)) {
|
|
|
CAM_ERR(CAM_CDM, "Invalid client %pK hdl=%x", client,
|
|
|
node->client_hdl);
|
|
|
- return;
|
|
|
+ return;
|
|
|
}
|
|
|
cam_cdm_get_client_refcount(client);
|
|
|
mutex_lock(&client->lock);
|
|
@@ -239,6 +242,7 @@ void cam_cdm_notify_clients(struct cam_hw_info *cdm_hw,
|
|
|
|
|
|
for (i = 0; i < CAM_PER_CDM_MAX_REGISTERED_CLIENTS; i++) {
|
|
|
if (core->clients[i] != NULL) {
|
|
|
+ mutex_lock(&cdm_hw->hw_mutex);
|
|
|
client = core->clients[i];
|
|
|
cam_cdm_get_client_refcount(client);
|
|
|
mutex_lock(&client->lock);
|
|
@@ -261,6 +265,7 @@ void cam_cdm_notify_clients(struct cam_hw_info *cdm_hw,
|
|
|
}
|
|
|
mutex_unlock(&client->lock);
|
|
|
cam_cdm_put_client_refcount(client);
|
|
|
+ mutex_unlock(&cdm_hw->hw_mutex);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -320,35 +325,34 @@ int cam_cdm_stream_ops_internal(void *hw_priv,
|
|
|
return -EINVAL;
|
|
|
|
|
|
core = (struct cam_cdm *)cdm_hw->core_info;
|
|
|
+ mutex_lock(&cdm_hw->hw_mutex);
|
|
|
client_idx = CAM_CDM_GET_CLIENT_IDX(*handle);
|
|
|
client = core->clients[client_idx];
|
|
|
if (!client) {
|
|
|
CAM_ERR(CAM_CDM, "Invalid client %pK hdl=%x", client, *handle);
|
|
|
+ mutex_unlock(&cdm_hw->hw_mutex);
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
cam_cdm_get_client_refcount(client);
|
|
|
if (*handle != client->handle) {
|
|
|
CAM_ERR(CAM_CDM, "client id given handle=%x invalid", *handle);
|
|
|
- cam_cdm_put_client_refcount(client);
|
|
|
- return -EINVAL;
|
|
|
+ rc = -EINVAL;
|
|
|
+ goto end;
|
|
|
}
|
|
|
if (operation == true) {
|
|
|
if (true == client->stream_on) {
|
|
|
CAM_ERR(CAM_CDM,
|
|
|
"Invalid CDM client is already streamed ON");
|
|
|
- cam_cdm_put_client_refcount(client);
|
|
|
- return rc;
|
|
|
+ goto end;
|
|
|
}
|
|
|
} else {
|
|
|
if (client->stream_on == false) {
|
|
|
CAM_ERR(CAM_CDM,
|
|
|
"Invalid CDM client is already streamed Off");
|
|
|
- cam_cdm_put_client_refcount(client);
|
|
|
- return rc;
|
|
|
+ goto end;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- mutex_lock(&cdm_hw->hw_mutex);
|
|
|
if (operation == true) {
|
|
|
if (!cdm_hw->open_count) {
|
|
|
struct cam_ahb_vote ahb_vote;
|