ASoC: msm: qdsp6v2: add wakelock hook in misc driver

add PM_AWAKE and PM_RELAX interfaces as to allow userspace clients to
hold ARM core during timeout count down.

Change-Id: Ia07a4f8675e1c2f25f698119e7f91e752de9dc78
Signed-off-by: Weiyin Jiang <wjiang@codeaurora.org>
This commit is contained in:
Weiyin Jiang 2015-09-22 18:55:35 +08:00
parent 17ea8ef017
commit 58a907ebf0
5 changed files with 86 additions and 3 deletions

View File

@ -19,6 +19,7 @@
#include <linux/uaccess.h>
#include <linux/sched.h>
#include <linux/wait.h>
#include <linux/wakelock.h>
#include <linux/dma-mapping.h>
#include <linux/slab.h>
#include <linux/atomic.h>
@ -571,6 +572,15 @@ int audio_aio_release(struct inode *inode, struct file *file)
pr_debug("%s[%p]\n", __func__, audio);
mutex_lock(&audio->lock);
audio->wflush = 1;
if (audio->wakelock_voted) {
audio->wakelock_voted = false;
mutex_lock(&audio->audio_ws_mgr->ws_lock);
if ((audio->audio_ws_mgr->ref_cnt > 0) &&
(--audio->audio_ws_mgr->ref_cnt == 0)) {
pm_relax(audio->miscdevice->this_device);
}
mutex_unlock(&audio->audio_ws_mgr->ws_lock);
}
if (audio->enabled)
audio_aio_flush(audio);
audio->wflush = 0;
@ -1473,6 +1483,34 @@ static long audio_aio_shared_ioctl(struct file *file, unsigned int cmd,
mutex_unlock(&audio->lock);
break;
}
case AUDIO_PM_AWAKE: {
pr_debug("%s[%p]:AUDIO_PM_AWAKE\n", __func__, audio);
mutex_lock(&audio->lock);
if (!audio->wakelock_voted) {
audio->wakelock_voted = true;
mutex_lock(&audio->audio_ws_mgr->ws_lock);
if (audio->audio_ws_mgr->ref_cnt++ == 0)
pm_stay_awake(audio->miscdevice->this_device);
mutex_unlock(&audio->audio_ws_mgr->ws_lock);
}
mutex_unlock(&audio->lock);
break;
}
case AUDIO_PM_RELAX: {
pr_debug("%s[%p]:AUDIO_PM_RELAX\n", __func__, audio);
mutex_lock(&audio->lock);
if (audio->wakelock_voted) {
audio->wakelock_voted = false;
mutex_lock(&audio->audio_ws_mgr->ws_lock);
if ((audio->audio_ws_mgr->ref_cnt > 0) &&
(--audio->audio_ws_mgr->ref_cnt == 0)) {
pm_relax(audio->miscdevice->this_device);
}
mutex_unlock(&audio->audio_ws_mgr->ws_lock);
}
mutex_unlock(&audio->lock);
break;
}
default:
pr_err("%s: Unknown ioctl cmd = %d", __func__, cmd);
rc = -EINVAL;
@ -1495,6 +1533,8 @@ static long audio_aio_ioctl(struct file *file, unsigned int cmd,
case AUDIO_PAUSE:
case AUDIO_FLUSH:
case AUDIO_GET_SESSION_ID:
case AUDIO_PM_AWAKE:
case AUDIO_PM_RELAX:
rc = audio_aio_shared_ioctl(file, cmd, arg);
break;
case AUDIO_GET_STATS: {
@ -1783,6 +1823,8 @@ static long audio_aio_compat_ioctl(struct file *file, unsigned int cmd,
case AUDIO_PAUSE:
case AUDIO_FLUSH:
case AUDIO_GET_SESSION_ID:
case AUDIO_PM_AWAKE:
case AUDIO_PM_RELAX:
rc = audio_aio_shared_ioctl(file, cmd, arg);
break;
case AUDIO_GET_STATS_32: {

View File

@ -104,6 +104,12 @@ union meta_data {
struct dec_meta_in meta_in;
} __packed;
/* per device wakeup source manager */
struct ws_mgr {
struct mutex ws_lock;
uint32_t ref_cnt;
};
#define PCM_BUF_COUNT (2)
/* Buffer with meta */
#define PCM_BUFSZ_MIN ((4*1024) + sizeof(struct dec_meta_out))
@ -165,6 +171,10 @@ struct q6audio_aio {
spinlock_t dsp_lock;
spinlock_t event_queue_lock;
struct miscdevice *miscdevice;
uint32_t wakelock_voted;
struct ws_mgr *audio_ws_mgr;
#ifdef CONFIG_DEBUG_FS
struct dentry *dentry;
#endif

View File

@ -18,8 +18,12 @@
#include <linux/types.h>
#include <linux/msm_audio_wma.h>
#include <linux/compat.h>
#include <linux/wakelock.h>
#include "audio_utils_aio.h"
struct miscdevice audio_wma_misc;
struct ws_mgr audio_wma_ws_mgr;
#ifdef CONFIG_DEBUG_FS
static const struct file_operations audio_wma_debug_fops = {
.read = audio_aio_debug_read,
@ -244,6 +248,9 @@ static int audio_open(struct inode *inode, struct file *file)
}
audio->pcm_cfg.buffer_size = PCM_BUFSZ_MIN;
audio->miscdevice = &audio_wma_misc;
audio->wakelock_voted = false;
audio->audio_ws_mgr = &audio_wma_ws_mgr;
audio->ac = q6asm_audio_client_alloc((app_cb) q6_audio_cb,
(void *)audio);
@ -326,7 +333,14 @@ struct miscdevice audio_wma_misc = {
static int __init audio_wma_init(void)
{
return misc_register(&audio_wma_misc);
int ret = misc_register(&audio_wma_misc);
if (ret == 0)
device_init_wakeup(audio_wma_misc.this_device, true);
audio_wma_ws_mgr.ref_cnt = 0;
mutex_init(&audio_wma_ws_mgr.ws_lock);
return ret;
}
device_initcall(audio_wma_init);

View File

@ -18,8 +18,12 @@
#include <linux/types.h>
#include <linux/msm_audio_wmapro.h>
#include <linux/compat.h>
#include <linux/wakelock.h>
#include "audio_utils_aio.h"
struct miscdevice audio_wmapro_misc;
struct ws_mgr audio_wmapro_ws_mgr;
#ifdef CONFIG_DEBUG_FS
static const struct file_operations audio_wmapro_debug_fops = {
.read = audio_aio_debug_read,
@ -317,6 +321,9 @@ static int audio_open(struct inode *inode, struct file *file)
audio->pcm_cfg.buffer_size = PCM_BUFSZ_MIN;
audio->miscdevice = &audio_wmapro_misc;
audio->wakelock_voted = false;
audio->audio_ws_mgr = &audio_wmapro_ws_mgr;
audio->ac = q6asm_audio_client_alloc((app_cb) q6_audio_cb,
(void *)audio);
@ -399,7 +406,14 @@ struct miscdevice audio_wmapro_misc = {
static int __init audio_wmapro_init(void)
{
return misc_register(&audio_wmapro_misc);
int ret = misc_register(&audio_wmapro_misc);
if (ret == 0)
device_init_wakeup(audio_wmapro_misc.this_device, true);
audio_wmapro_ws_mgr.ref_cnt = 0;
mutex_init(&audio_wmapro_ws_mgr.ws_lock);
return ret;
}
device_initcall(audio_wmapro_init);

View File

@ -114,7 +114,10 @@
#define AUDIO_EFFECTS_READ _IOWR(AUDIO_IOCTL_MAGIC, 103, void *)
#define AUDIO_EFFECTS_SET_PP_PARAMS _IOW(AUDIO_IOCTL_MAGIC, 104, void *)
#define AUDIO_MAX_COMMON_IOCTL_NUM 105
#define AUDIO_PM_AWAKE _IOW(AUDIO_IOCTL_MAGIC, 105, unsigned)
#define AUDIO_PM_RELAX _IOW(AUDIO_IOCTL_MAGIC, 106, unsigned)
#define AUDIO_MAX_COMMON_IOCTL_NUM 107
#define HANDSET_MIC 0x01