avtimer: avoid timer query from clients during SSR

Update AV timer driver to schecdule a workqueue to
make sure the ADSP on modem is up while honouring the
requests from client for timer query.

Change-Id: I3c3283e778c836fce1a68cf8a5dc439124ef2f1f
Signed-off-by: Santosh Mardi <gsantosh@codeaurora.org>
Signed-off-by: Laxminath Kasam <lkasam@codeaurora.org>
This commit is contained in:
Laxminath Kasam
2014-10-30 22:32:01 -07:00
parent b32438d38a
commit ce806743eb
+31 -8
View File
@@ -31,6 +31,9 @@
#define TIMEOUT_MS 1000
#define CORE_CLIENT 1
#define TEMP_PORT ((CORE_CLIENT << 8) | 0x0001)
#define SSR_WAKETIME 1000
#define Q6_READY_RETRY 250
#define Q6_READY_MAX_RETRIES 40
#define AVCS_CMD_REMOTE_AVTIMER_VOTE_REQUEST 0x00012914
#define AVCS_CMD_RSP_REMOTE_AVTIMER_VOTE_REQUEST 0x00012915
@@ -54,6 +57,7 @@ struct avtimer_t {
struct mutex avtimer_lock;
int avtimer_open_cnt;
struct dev_avtimer_data avtimer_pdata;
struct delayed_work ssr_dwork;
wait_queue_head_t adsp_resp_wait;
int enable_timer_resp_recieved;
int timer_handle;
@@ -61,6 +65,7 @@ struct avtimer_t {
void __iomem *p_avtimer_lsw;
uint32_t clk_div;
atomic_t adsp_ready;
int num_retries;
};
static struct avtimer_t avtimer;
@@ -105,7 +110,10 @@ static int32_t aprv2_core_fn_q(struct apr_client_data *data, void *priv)
pr_debug("%s: Reset event received in AV timer\n", __func__);
apr_reset(avtimer.core_handle_q);
avtimer.core_handle_q = NULL;
avtimer.avtimer_open_cnt = 0;
atomic_set(&avtimer.adsp_ready, 0);
schedule_delayed_work(&avtimer.ssr_dwork,
msecs_to_jiffies(SSR_WAKETIME));
break;
}
@@ -263,21 +271,33 @@ done:
}
EXPORT_SYMBOL(avcs_core_disable_power_collapse);
static void reset_work(struct work_struct *work)
{
if (q6core_is_adsp_ready()) {
avcs_core_disable_power_collapse(1);
avtimer.num_retries = Q6_READY_MAX_RETRIES;
return;
}
pr_debug("%s:Q6 not ready-retry after sometime\n", __func__);
if (--avtimer.num_retries > 0) {
schedule_delayed_work(&avtimer.ssr_dwork,
msecs_to_jiffies(Q6_READY_RETRY));
} else {
pr_err("%s: Q6 failed responding after multiple retries\n",
__func__);
avtimer.num_retries = Q6_READY_MAX_RETRIES;
}
}
int avcs_core_query_timer(uint64_t *avtimer_tick)
{
int ret = 0;
uint32_t avtimer_msw = 0, avtimer_lsw = 0;
uint32_t res = 0;
uint64_t avtimer_tick_temp;
if (!atomic_read(&avtimer.adsp_ready)) {
if (q6core_is_adsp_ready()) {
ret = avcs_core_disable_power_collapse(1);
if (ret)
return ret;
} else {
return -ENETRESET;
}
pr_debug("%s:In SSR, return\n", __func__);
return -ENETRESET;
}
avtimer_lsw = ioread32(avtimer.p_avtimer_lsw);
avtimer_msw = ioread32(avtimer.p_avtimer_msw);
@@ -374,6 +394,8 @@ static int dev_avtimer_probe(struct platform_device *pdev)
"avtimer_msb_addr", __func__);
return -EINVAL;
}
INIT_DELAYED_WORK(&avtimer.ssr_dwork, reset_work);
avtimer.p_avtimer_lsw = devm_ioremap_nocache(&pdev->dev,
reg_lsb->start, resource_size(reg_lsb));
if (!avtimer.p_avtimer_lsw) {
@@ -389,6 +411,7 @@ static int dev_avtimer_probe(struct platform_device *pdev)
__func__);
goto unmap;
}
avtimer.num_retries = Q6_READY_MAX_RETRIES;
/* get the device number */
if (major)
result = register_chrdev_region(dev, 1, DEVICE_NAME);