diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/soc/qcom/qdsp6v2/apr.c | 103 | ||||
| -rw-r--r-- | drivers/soc/qcom/qdsp6v2/apr_tal_glink.c | 34 |
2 files changed, 135 insertions, 2 deletions
diff --git a/drivers/soc/qcom/qdsp6v2/apr.c b/drivers/soc/qcom/qdsp6v2/apr.c index 8cd86915be98..9e55a25001ae 100644 --- a/drivers/soc/qcom/qdsp6v2/apr.c +++ b/drivers/soc/qcom/qdsp6v2/apr.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2014, 2016, 2018 The Linux Foundation. +/* Copyright (c) 2010-2014, 2016, 2018-2019 The Linux Foundation. * All rights reserved. * * This program is free software; you can redistribute it and/or modify @@ -758,6 +758,107 @@ static void apr_reset_deregister(struct work_struct *work) 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); + int apr_deregister(void *handle) { struct apr_svc *svc = handle; diff --git a/drivers/soc/qcom/qdsp6v2/apr_tal_glink.c b/drivers/soc/qcom/qdsp6v2/apr_tal_glink.c index 8a2be787b70e..f11787deac47 100644 --- a/drivers/soc/qcom/qdsp6v2/apr_tal_glink.c +++ b/drivers/soc/qcom/qdsp6v2/apr_tal_glink.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2017 The Linux Foundation. +/* Copyright (c) 2016-2017, 2019 The Linux Foundation. * All rights reserved. * * This program is free software; you can redistribute it and/or modify @@ -358,6 +358,38 @@ unlock: 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 rc; |
