dsp: wait for apm_ready in audio_prm
Wait for spf_core_is_apm_ready before sending first command to spf after bootup and after SSR. Change-Id: I7c3a7fbb9e190310554ae716937fd6a0d036ce6f Signed-off-by: Ritu Sharma <ritushar@codeaurora.org>
此提交包含在:

提交者
Gerrit - the friendly Code Review server

父節點
54961362cb
當前提交
380d126f2a
@@ -15,14 +15,19 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <ipc/gpr-lite.h>
|
||||
#include <soc/snd_event.h>
|
||||
#include <dsp/audio_prm.h>
|
||||
#include <dsp/spf-core.h>
|
||||
#include <dsp/audio_notifier.h>
|
||||
|
||||
#define TIMEOUT_MS 500
|
||||
#define MAX_RETRY_COUNT 3
|
||||
#define APM_READY_WAIT_DURATION 2
|
||||
|
||||
struct audio_prm {
|
||||
struct gpr_device *adev;
|
||||
@@ -36,6 +41,8 @@ struct audio_prm {
|
||||
|
||||
static struct audio_prm g_prm;
|
||||
|
||||
static bool is_apm_ready_check_done = false;
|
||||
|
||||
static int audio_prm_callback(struct gpr_device *adev, void *data)
|
||||
{
|
||||
struct gpr_hdr *hdr = (struct gpr_hdr *)data;
|
||||
@@ -82,6 +89,7 @@ static int audio_prm_callback(struct gpr_device *adev, void *data)
|
||||
static int prm_gpr_send_pkt(struct gpr_pkt *pkt, wait_queue_head_t *wait)
|
||||
{
|
||||
int ret = 0;
|
||||
int retry;
|
||||
|
||||
if (wait)
|
||||
atomic_set(&g_prm.state, 1);
|
||||
@@ -95,6 +103,16 @@ static int prm_gpr_send_pkt(struct gpr_pkt *pkt, wait_queue_head_t *wait)
|
||||
mutex_unlock(&g_prm.lock);
|
||||
return -ENODEV;
|
||||
}
|
||||
if (!is_apm_ready_check_done && g_prm.is_adsp_up) {
|
||||
pr_info("%s: apm ready check not done\n", __func__);
|
||||
retry = 0;
|
||||
while (!spf_core_is_apm_ready() || retry < MAX_RETRY_COUNT) {
|
||||
msleep(APM_READY_WAIT_DURATION);
|
||||
retry++;
|
||||
}
|
||||
is_apm_ready_check_done = true;
|
||||
pr_info("%s: apm ready check done\n", __func__);
|
||||
}
|
||||
g_prm.resp_received = false;
|
||||
ret = gpr_send_pkt(g_prm.adev, pkt);
|
||||
if (ret < 0) {
|
||||
@@ -295,7 +313,34 @@ int audio_prm_set_lpass_clk_cfg (struct clk_cfg *clk, uint8_t enable)
|
||||
}
|
||||
EXPORT_SYMBOL(audio_prm_set_lpass_clk_cfg);
|
||||
|
||||
static int audio_prm_service_cb(struct notifier_block *this,
|
||||
unsigned long opcode, void *data)
|
||||
{
|
||||
pr_info("%s: Service opcode 0x%lx\n", __func__, opcode);
|
||||
|
||||
switch (opcode) {
|
||||
case AUDIO_NOTIFIER_SERVICE_DOWN:
|
||||
mutex_lock(&g_prm.lock);
|
||||
pr_debug("%s: making apm_ready check false\n", __func__);
|
||||
is_apm_ready_check_done = false;
|
||||
g_prm.is_adsp_up = false;
|
||||
mutex_unlock(&g_prm.lock);
|
||||
break;
|
||||
case AUDIO_NOTIFIER_SERVICE_UP:
|
||||
mutex_lock(&g_prm.lock);
|
||||
g_prm.is_adsp_up = true;
|
||||
mutex_unlock(&g_prm.lock);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
static struct notifier_block service_nb = {
|
||||
.notifier_call = audio_prm_service_cb,
|
||||
.priority = -INT_MAX,
|
||||
};
|
||||
|
||||
static int audio_prm_probe(struct gpr_device *adev)
|
||||
{
|
||||
@@ -307,8 +352,7 @@ static int audio_prm_probe(struct gpr_device *adev)
|
||||
g_prm.adev = adev;
|
||||
|
||||
init_waitqueue_head(&g_prm.wait);
|
||||
|
||||
|
||||
g_prm.is_adsp_up = true;
|
||||
pr_err("%s: prm probe success\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
@@ -318,6 +362,7 @@ static int audio_prm_remove(struct gpr_device *adev)
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&g_prm.lock);
|
||||
g_prm.is_adsp_up = false;
|
||||
g_prm.adev = NULL;
|
||||
mutex_unlock(&g_prm.lock);
|
||||
return ret;
|
||||
@@ -339,6 +384,31 @@ static struct gpr_driver qcom_audio_prm_driver = {
|
||||
},
|
||||
};
|
||||
|
||||
module_gpr_driver(qcom_audio_prm_driver);
|
||||
static int __init audio_prm_module_init(void)
|
||||
{
|
||||
int ret;
|
||||
ret = gpr_driver_register(&qcom_audio_prm_driver);
|
||||
if (ret) {
|
||||
pr_err("%s: gpr driver register failed = %d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
ret = audio_notifier_register("audio_prm", AUDIO_NOTIFIER_ADSP_DOMAIN,
|
||||
&service_nb);
|
||||
if (ret < 0) {
|
||||
pr_err("%s: Audio notifier register failed ret = %d\n",
|
||||
__func__, ret);
|
||||
return ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit audio_prm_module_exit(void)
|
||||
{
|
||||
audio_notifier_deregister("audio_prm");
|
||||
gpr_driver_unregister(&qcom_audio_prm_driver);
|
||||
}
|
||||
|
||||
module_init(audio_prm_module_init);
|
||||
module_exit(audio_prm_module_exit);
|
||||
MODULE_DESCRIPTION("audio prm");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
新增問題並參考
封鎖使用者