qseecom:Fix race condition while voting for clocks

In the current functionality, if DFAB clock is already on and a
request is made to turn on SFPB clock, the DFAB clock is turned
off and SFPB clock is turned on and vice-versa.

The above situation can lead to unexpected errors. The current fix
makes sure that clocks that are on are not voted to be off without
explicit request.

Change-Id: I6c3230e23b105c049cdb0aace579b8a176328c84
Signed-off-by: Ramesh Masavarapu <rameshm@codeaurora.org>
This commit is contained in:
Ramesh Masavarapu
2012-10-04 06:44:21 -07:00
parent d884d3323c
commit 8d7565828a
4 changed files with 121 additions and 19 deletions
+25
View File
@@ -1768,6 +1768,27 @@ static struct msm_bus_vectors qseecom_enable_sfpb_vectors[] = {
},
};
static struct msm_bus_vectors qseecom_enable_dfab_sfpb_vectors[] = {
{
.src = MSM_BUS_MASTER_ADM_PORT0,
.dst = MSM_BUS_SLAVE_EBI_CH0,
.ab = 70000000UL,
.ib = 70000000UL,
},
{
.src = MSM_BUS_MASTER_ADM_PORT1,
.dst = MSM_BUS_SLAVE_GSBI1_UART,
.ab = 2480000000UL,
.ib = 2480000000UL,
},
{
.src = MSM_BUS_MASTER_SPDM,
.dst = MSM_BUS_SLAVE_SPDM,
.ib = (64 * 8) * 1000000UL,
.ab = (64 * 8) * 100000UL,
},
};
static struct msm_bus_paths qseecom_hw_bus_scale_usecases[] = {
{
ARRAY_SIZE(qseecom_clks_init_vectors),
@@ -1781,6 +1802,10 @@ static struct msm_bus_paths qseecom_hw_bus_scale_usecases[] = {
ARRAY_SIZE(qseecom_enable_sfpb_vectors),
qseecom_enable_sfpb_vectors,
},
{
ARRAY_SIZE(qseecom_enable_dfab_sfpb_vectors),
qseecom_enable_dfab_sfpb_vectors,
},
};
static struct msm_bus_scale_pdata qseecom_bus_pdata = {
+25
View File
@@ -1047,6 +1047,27 @@ static struct msm_bus_vectors qseecom_enable_sfpb_vectors[] = {
},
};
static struct msm_bus_vectors qseecom_enable_dfab_sfpb_vectors[] = {
{
.src = MSM_BUS_MASTER_SPS,
.dst = MSM_BUS_SLAVE_EBI_CH0,
.ib = (492 * 8) * 1000000UL,
.ab = (492 * 8) * 100000UL,
},
{
.src = MSM_BUS_MASTER_SPS,
.dst = MSM_BUS_SLAVE_SPS,
.ib = (492 * 8) * 1000000UL,
.ab = (492 * 8) * 100000UL,
},
{
.src = MSM_BUS_MASTER_SPDM,
.dst = MSM_BUS_SLAVE_SPDM,
.ib = (64 * 8) * 1000000UL,
.ab = (64 * 8) * 100000UL,
},
};
static struct msm_bus_paths qseecom_hw_bus_scale_usecases[] = {
{
ARRAY_SIZE(qseecom_clks_init_vectors),
@@ -1060,6 +1081,10 @@ static struct msm_bus_paths qseecom_hw_bus_scale_usecases[] = {
ARRAY_SIZE(qseecom_enable_sfpb_vectors),
qseecom_enable_sfpb_vectors,
},
{
ARRAY_SIZE(qseecom_enable_dfab_sfpb_vectors),
qseecom_enable_dfab_sfpb_vectors,
},
};
static struct msm_bus_scale_pdata qseecom_bus_pdata = {
+25
View File
@@ -1112,6 +1112,27 @@ static struct msm_bus_vectors qseecom_enable_sfpb_vectors[] = {
},
};
static struct msm_bus_vectors qseecom_enable_dfab_sfpb_vectors[] = {
{
.src = MSM_BUS_MASTER_SPS,
.dst = MSM_BUS_SLAVE_EBI_CH0,
.ib = (492 * 8) * 1000000UL,
.ab = (492 * 8) * 100000UL,
},
{
.src = MSM_BUS_MASTER_SPS,
.dst = MSM_BUS_SLAVE_SPS,
.ib = (492 * 8) * 1000000UL,
.ab = (492 * 8) * 100000UL,
},
{
.src = MSM_BUS_MASTER_SPDM,
.dst = MSM_BUS_SLAVE_SPDM,
.ib = (64 * 8) * 1000000UL,
.ab = (64 * 8) * 100000UL,
},
};
static struct msm_bus_paths qseecom_hw_bus_scale_usecases[] = {
{
ARRAY_SIZE(qseecom_clks_init_vectors),
@@ -1125,6 +1146,10 @@ static struct msm_bus_paths qseecom_hw_bus_scale_usecases[] = {
ARRAY_SIZE(qseecom_enable_sfpb_vectors),
qseecom_enable_sfpb_vectors,
},
{
ARRAY_SIZE(qseecom_enable_dfab_sfpb_vectors),
qseecom_enable_dfab_sfpb_vectors,
},
};
static struct msm_bus_scale_pdata qseecom_bus_pdata = {
+46 -19
View File
@@ -142,7 +142,6 @@ static uint32_t pil_ref_cnt;
static DEFINE_MUTEX(pil_access_lock);
static DEFINE_MUTEX(qsee_bw_mutex);
static DEFINE_MUTEX(qsee_sfpb_bw_mutex);
static DEFINE_MUTEX(app_access_lock);
static int qsee_bw_count;
@@ -1198,28 +1197,41 @@ static int qsee_vote_for_clock(int32_t clk_type)
case CLK_DFAB:
mutex_lock(&qsee_bw_mutex);
if (!qsee_bw_count) {
ret = msm_bus_scale_client_update_request(
qsee_perf_client, 1);
if (qsee_sfpb_bw_count > 0)
ret = msm_bus_scale_client_update_request(
qsee_perf_client, 3);
else
ret = msm_bus_scale_client_update_request(
qsee_perf_client, 1);
if (ret)
pr_err("DFAB Bandwidth req failed (%d)\n",
ret);
else
qsee_bw_count++;
} else {
qsee_bw_count++;
}
mutex_unlock(&qsee_bw_mutex);
break;
case CLK_SFPB:
mutex_lock(&qsee_sfpb_bw_mutex);
mutex_lock(&qsee_bw_mutex);
if (!qsee_sfpb_bw_count) {
ret = msm_bus_scale_client_update_request(
qsee_perf_client, 2);
if (qsee_bw_count > 0)
ret = msm_bus_scale_client_update_request(
qsee_perf_client, 3);
else
ret = msm_bus_scale_client_update_request(
qsee_perf_client, 2);
if (ret)
pr_err("SFPB Bandwidth req failed (%d)\n",
ret);
else
qsee_sfpb_bw_count++;
} else {
qsee_sfpb_bw_count++;
}
mutex_unlock(&qsee_sfpb_bw_mutex);
mutex_unlock(&qsee_bw_mutex);
break;
default:
pr_err("Clock type not defined\n");
@@ -1238,29 +1250,44 @@ static void qsee_disable_clock_vote(int32_t clk_type)
switch (clk_type) {
case CLK_DFAB:
mutex_lock(&qsee_bw_mutex);
if (qsee_bw_count > 0) {
if (qsee_bw_count-- == 1) {
if (qsee_bw_count == 0) {
pr_err("Client error.Extra call to disable DFAB clk\n");
mutex_unlock(&qsee_bw_mutex);
return;
}
if ((qsee_bw_count > 0) && (qsee_bw_count-- == 1)) {
if (qsee_sfpb_bw_count > 0)
ret = msm_bus_scale_client_update_request(
qsee_perf_client, 2);
else
ret = msm_bus_scale_client_update_request(
qsee_perf_client, 0);
if (ret)
pr_err("SFPB Bandwidth req fail (%d)\n",
if (ret)
pr_err("SFPB Bandwidth req fail (%d)\n",
ret);
}
}
mutex_unlock(&qsee_bw_mutex);
break;
case CLK_SFPB:
mutex_lock(&qsee_sfpb_bw_mutex);
if (qsee_sfpb_bw_count > 0) {
if (qsee_sfpb_bw_count-- == 1) {
mutex_lock(&qsee_bw_mutex);
if (qsee_sfpb_bw_count == 0) {
pr_err("Client error.Extra call to disable SFPB clk\n");
mutex_unlock(&qsee_bw_mutex);
return;
}
if ((qsee_sfpb_bw_count > 0) && (qsee_sfpb_bw_count-- == 1)) {
if (qsee_bw_count > 0)
ret = msm_bus_scale_client_update_request(
qsee_perf_client, 1);
else
ret = msm_bus_scale_client_update_request(
qsee_perf_client, 0);
if (ret)
pr_err("SFPB Bandwidth req fail (%d)\n",
if (ret)
pr_err("SFPB Bandwidth req fail (%d)\n",
ret);
}
}
mutex_unlock(&qsee_sfpb_bw_mutex);
mutex_unlock(&qsee_bw_mutex);
break;
default:
pr_err("Clock type not defined\n");