Loading drivers/soc/qcom/qdsp6v2/voice_svc.c +39 −3 Original line number Diff line number Diff line /* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. * * 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 Loading @@ -14,6 +14,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/errno.h> #include <linux/spinlock.h> #include <linux/fs.h> #include <linux/uaccess.h> #include <linux/slab.h> Loading Loading @@ -67,7 +68,11 @@ static void *dummy_q6_mvm; static void *dummy_q6_cvs; dev_t device_num; static spinlock_t voicesvc_lock; static bool is_released; static int voice_svc_dummy_reg(void); static int voice_svc_dummy_dereg(void); static int32_t qdsp_dummy_apr_callback(struct apr_client_data *data, void *priv); Loading @@ -82,10 +87,16 @@ static int32_t qdsp_apr_callback(struct apr_client_data *data, void *priv) return -EINVAL; } spin_lock(&voicesvc_lock); if (is_released) { spin_unlock(&voicesvc_lock); return 0; } prtd = (struct voice_svc_prvt *)priv; if (prtd == NULL) { pr_err("%s: private data is NULL\n", __func__); spin_unlock(&voicesvc_lock); return -EINVAL; } Loading Loading @@ -128,6 +139,7 @@ static int32_t qdsp_apr_callback(struct apr_client_data *data, void *priv) spin_unlock_irqrestore(&prtd->response_lock, spin_flags); spin_unlock(&voicesvc_lock); return -ENOMEM; } Loading Loading @@ -156,6 +168,7 @@ static int32_t qdsp_apr_callback(struct apr_client_data *data, void *priv) __func__); } spin_unlock(&voicesvc_lock); return 0; } Loading Loading @@ -614,6 +627,21 @@ err: return -EINVAL; } static int voice_svc_dummy_dereg(void) { pr_debug("%s\n", __func__); if (dummy_q6_mvm != NULL) { apr_deregister(dummy_q6_mvm); dummy_q6_mvm = NULL; } if (dummy_q6_cvs != NULL) { apr_deregister(dummy_q6_cvs); dummy_q6_cvs = NULL; } return 0; } static int voice_svc_open(struct inode *inode, struct file *file) { struct voice_svc_prvt *prtd = NULL; Loading @@ -637,6 +665,7 @@ static int voice_svc_open(struct inode *inode, struct file *file) mutex_init(&prtd->response_mutex_lock); file->private_data = (void *)prtd; is_released = 0; /* Current APR implementation doesn't support session based * multiple service registrations. The apr_deregister() * function sets the destination and client IDs to zero, if Loading Loading @@ -669,6 +698,11 @@ static int voice_svc_release(struct inode *inode, struct file *file) goto done; } mutex_lock(&prtd->response_mutex_lock); if (reg_dummy_sess) { voice_svc_dummy_dereg(); reg_dummy_sess = 0; } if (prtd->apr_q6_cvs != NULL) { svc_name = VOICE_SVC_MVM_STR; handle = &prtd->apr_q6_cvs; Loading @@ -685,7 +719,6 @@ static int voice_svc_release(struct inode *inode, struct file *file) pr_err("%s: Failed to dereg MVM %d\n", __func__, ret); } mutex_lock(&prtd->response_mutex_lock); spin_lock_irqsave(&prtd->response_lock, spin_flags); while (!list_empty(&prtd->response_queue)) { Loading @@ -703,9 +736,11 @@ static int voice_svc_release(struct inode *inode, struct file *file) mutex_destroy(&prtd->response_mutex_lock); spin_lock(&voicesvc_lock); kfree(file->private_data); file->private_data = NULL; is_released = 1; spin_unlock(&voicesvc_lock); done: return ret; } Loading Loading @@ -774,6 +809,7 @@ static int voice_svc_probe(struct platform_device *pdev) goto add_err; } pr_debug("%s: Device created\n", __func__); spin_lock_init(&voicesvc_lock); goto done; add_err: Loading Loading
drivers/soc/qcom/qdsp6v2/voice_svc.c +39 −3 Original line number Diff line number Diff line /* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. * * 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 Loading @@ -14,6 +14,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/errno.h> #include <linux/spinlock.h> #include <linux/fs.h> #include <linux/uaccess.h> #include <linux/slab.h> Loading Loading @@ -67,7 +68,11 @@ static void *dummy_q6_mvm; static void *dummy_q6_cvs; dev_t device_num; static spinlock_t voicesvc_lock; static bool is_released; static int voice_svc_dummy_reg(void); static int voice_svc_dummy_dereg(void); static int32_t qdsp_dummy_apr_callback(struct apr_client_data *data, void *priv); Loading @@ -82,10 +87,16 @@ static int32_t qdsp_apr_callback(struct apr_client_data *data, void *priv) return -EINVAL; } spin_lock(&voicesvc_lock); if (is_released) { spin_unlock(&voicesvc_lock); return 0; } prtd = (struct voice_svc_prvt *)priv; if (prtd == NULL) { pr_err("%s: private data is NULL\n", __func__); spin_unlock(&voicesvc_lock); return -EINVAL; } Loading Loading @@ -128,6 +139,7 @@ static int32_t qdsp_apr_callback(struct apr_client_data *data, void *priv) spin_unlock_irqrestore(&prtd->response_lock, spin_flags); spin_unlock(&voicesvc_lock); return -ENOMEM; } Loading Loading @@ -156,6 +168,7 @@ static int32_t qdsp_apr_callback(struct apr_client_data *data, void *priv) __func__); } spin_unlock(&voicesvc_lock); return 0; } Loading Loading @@ -614,6 +627,21 @@ err: return -EINVAL; } static int voice_svc_dummy_dereg(void) { pr_debug("%s\n", __func__); if (dummy_q6_mvm != NULL) { apr_deregister(dummy_q6_mvm); dummy_q6_mvm = NULL; } if (dummy_q6_cvs != NULL) { apr_deregister(dummy_q6_cvs); dummy_q6_cvs = NULL; } return 0; } static int voice_svc_open(struct inode *inode, struct file *file) { struct voice_svc_prvt *prtd = NULL; Loading @@ -637,6 +665,7 @@ static int voice_svc_open(struct inode *inode, struct file *file) mutex_init(&prtd->response_mutex_lock); file->private_data = (void *)prtd; is_released = 0; /* Current APR implementation doesn't support session based * multiple service registrations. The apr_deregister() * function sets the destination and client IDs to zero, if Loading Loading @@ -669,6 +698,11 @@ static int voice_svc_release(struct inode *inode, struct file *file) goto done; } mutex_lock(&prtd->response_mutex_lock); if (reg_dummy_sess) { voice_svc_dummy_dereg(); reg_dummy_sess = 0; } if (prtd->apr_q6_cvs != NULL) { svc_name = VOICE_SVC_MVM_STR; handle = &prtd->apr_q6_cvs; Loading @@ -685,7 +719,6 @@ static int voice_svc_release(struct inode *inode, struct file *file) pr_err("%s: Failed to dereg MVM %d\n", __func__, ret); } mutex_lock(&prtd->response_mutex_lock); spin_lock_irqsave(&prtd->response_lock, spin_flags); while (!list_empty(&prtd->response_queue)) { Loading @@ -703,9 +736,11 @@ static int voice_svc_release(struct inode *inode, struct file *file) mutex_destroy(&prtd->response_mutex_lock); spin_lock(&voicesvc_lock); kfree(file->private_data); file->private_data = NULL; is_released = 1; spin_unlock(&voicesvc_lock); done: return ret; } Loading Loading @@ -774,6 +809,7 @@ static int voice_svc_probe(struct platform_device *pdev) goto add_err; } pr_debug("%s: Device created\n", __func__); spin_lock_init(&voicesvc_lock); goto done; add_err: Loading