forked from rubenslte/android_kernel_samsung_msm8226
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:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user