ipc: add api to vote for upgrading thread priority
For some time critical tasks, the thread priority might need to be upgraded to Real-Time Thread priority level. Expose an interface from APR layer so that clients can vote for a priority upgrade whenever needed. Change-Id: Ieb4afa914905750eccdf7672020a8751fdcf6462 Signed-off-by: Banajit Goswami <bgoswami@codeaurora.org>
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2010-2016, The Linux Foundation. All rights reserved.
|
/* Copyright (c) 2010-2017, The Linux Foundation. All rights reserved.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License version 2 and
|
* it under the terms of the GNU General Public License version 2 and
|
||||||
@@ -188,4 +188,6 @@ int apr_set_q6_state(enum apr_subsys_state state);
|
|||||||
void apr_set_subsys_state(void);
|
void apr_set_subsys_state(void);
|
||||||
const char *apr_get_lpass_subsys_name(void);
|
const char *apr_get_lpass_subsys_name(void);
|
||||||
uint16_t apr_get_reset_domain(uint16_t proc);
|
uint16_t apr_get_reset_domain(uint16_t proc);
|
||||||
|
int apr_start_rx_rt(void *handle);
|
||||||
|
int apr_end_rx_rt(void *handle);
|
||||||
#endif
|
#endif
|
||||||
|
@@ -74,7 +74,8 @@ int apr_tal_close(struct apr_svc_ch_dev *apr_ch);
|
|||||||
int apr_tal_rx_intents_config(struct apr_svc_ch_dev *apr_ch,
|
int apr_tal_rx_intents_config(struct apr_svc_ch_dev *apr_ch,
|
||||||
int num_of_intents, uint32_t size);
|
int num_of_intents, uint32_t size);
|
||||||
int apr_tal_init(void);
|
int apr_tal_init(void);
|
||||||
|
int apr_tal_start_rx_rt(struct apr_svc_ch_dev *apr_ch);
|
||||||
|
int apr_tal_end_rx_rt(struct apr_svc_ch_dev *apr_ch);
|
||||||
|
|
||||||
struct apr_svc_ch_dev {
|
struct apr_svc_ch_dev {
|
||||||
void *handle;
|
void *handle;
|
||||||
|
101
ipc/apr.c
101
ipc/apr.c
@@ -774,6 +774,107 @@ static void apr_reset_deregister(struct work_struct *work)
|
|||||||
kfree(apr_reset);
|
kfree(apr_reset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* apr_start_rx_rt - Clients call to vote for thread
|
||||||
|
* priority upgrade whenever needed.
|
||||||
|
*
|
||||||
|
* @handle: APR service handle
|
||||||
|
*
|
||||||
|
* Returns 0 on success or error otherwise.
|
||||||
|
*/
|
||||||
|
int apr_start_rx_rt(void *handle)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
struct apr_svc *svc = handle;
|
||||||
|
uint16_t dest_id = 0;
|
||||||
|
uint16_t client_id = 0;
|
||||||
|
|
||||||
|
if (!svc) {
|
||||||
|
pr_err("%s: Invalid APR handle\n", __func__);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_lock(&svc->m_lock);
|
||||||
|
dest_id = svc->dest_id;
|
||||||
|
client_id = svc->client_id;
|
||||||
|
|
||||||
|
if ((client_id >= APR_CLIENT_MAX) || (dest_id >= APR_DEST_MAX)) {
|
||||||
|
pr_err("%s: %s invalid. client_id = %u, dest_id = %u\n",
|
||||||
|
__func__,
|
||||||
|
client_id >= APR_CLIENT_MAX ? "Client ID" : "Dest ID",
|
||||||
|
client_id, dest_id);
|
||||||
|
rc = -EINVAL;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!client[dest_id][client_id].handle) {
|
||||||
|
pr_err("%s: Client handle is NULL\n", __func__);
|
||||||
|
rc = -EINVAL;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = apr_tal_start_rx_rt(client[dest_id][client_id].handle);
|
||||||
|
if (rc)
|
||||||
|
pr_err("%s: failed to set RT thread priority for APR RX. rc = %d\n",
|
||||||
|
__func__, rc);
|
||||||
|
|
||||||
|
exit:
|
||||||
|
mutex_unlock(&svc->m_lock);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(apr_start_rx_rt);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* apr_end_rx_rt - Clients call to unvote for thread
|
||||||
|
* priority upgrade (perviously voted with
|
||||||
|
* apr_start_rx_rt()).
|
||||||
|
*
|
||||||
|
* @handle: APR service handle
|
||||||
|
*
|
||||||
|
* Returns 0 on success or error otherwise.
|
||||||
|
*/
|
||||||
|
int apr_end_rx_rt(void *handle)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
struct apr_svc *svc = handle;
|
||||||
|
uint16_t dest_id = 0;
|
||||||
|
uint16_t client_id = 0;
|
||||||
|
|
||||||
|
if (!svc) {
|
||||||
|
pr_err("%s: Invalid APR handle\n", __func__);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_lock(&svc->m_lock);
|
||||||
|
dest_id = svc->dest_id;
|
||||||
|
client_id = svc->client_id;
|
||||||
|
|
||||||
|
if ((client_id >= APR_CLIENT_MAX) || (dest_id >= APR_DEST_MAX)) {
|
||||||
|
pr_err("%s: %s invalid. client_id = %u, dest_id = %u\n",
|
||||||
|
__func__,
|
||||||
|
client_id >= APR_CLIENT_MAX ? "Client ID" : "Dest ID",
|
||||||
|
client_id, dest_id);
|
||||||
|
rc = -EINVAL;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!client[dest_id][client_id].handle) {
|
||||||
|
pr_err("%s: Client handle is NULL\n", __func__);
|
||||||
|
rc = -EINVAL;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = apr_tal_end_rx_rt(client[dest_id][client_id].handle);
|
||||||
|
if (rc)
|
||||||
|
pr_err("%s: failed to reset RT thread priority for APR RX. rc = %d\n",
|
||||||
|
__func__, rc);
|
||||||
|
|
||||||
|
exit:
|
||||||
|
mutex_unlock(&svc->m_lock);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(apr_end_rx_rt);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* apr_deregister - Clients call to de-register
|
* apr_deregister - Clients call to de-register
|
||||||
* from APR.
|
* from APR.
|
||||||
|
@@ -357,6 +357,38 @@ unlock:
|
|||||||
return rc ? NULL : apr_ch;
|
return rc ? NULL : apr_ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int apr_tal_start_rx_rt(struct apr_svc_ch_dev *apr_ch)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
if (!apr_ch || !apr_ch->handle) {
|
||||||
|
rc = -EINVAL;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_lock(&apr_ch->m_lock);
|
||||||
|
rc = glink_start_rx_rt(apr_ch->handle);
|
||||||
|
mutex_unlock(&apr_ch->m_lock);
|
||||||
|
exit:
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
int apr_tal_end_rx_rt(struct apr_svc_ch_dev *apr_ch)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
if (!apr_ch || !apr_ch->handle) {
|
||||||
|
rc = -EINVAL;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_lock(&apr_ch->m_lock);
|
||||||
|
rc = glink_end_rx_rt(apr_ch->handle);
|
||||||
|
mutex_unlock(&apr_ch->m_lock);
|
||||||
|
exit:
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
int apr_tal_close(struct apr_svc_ch_dev *apr_ch)
|
int apr_tal_close(struct apr_svc_ch_dev *apr_ch)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
Reference in New Issue
Block a user