drivers: soc: Add intent notification callback for APR Glink

APR is required not to send any packet until the far end queues
at least one intent. Add the wait during client registration time.

Change-Id: Ie29ddda4527ae7a70afff2c595d6e3c76500a8af
Signed-off-by: Deven Patel <cdevenp@codeaurora.org>
Signed-off-by: Josh Kirsch <jkirsch@codeaurora.org>
This commit is contained in:
Josh Kirsch 2016-04-15 14:05:05 -07:00 committed by Jeevan Shriram
parent 82496f5cb3
commit 1f2cb1a4a4
2 changed files with 31 additions and 0 deletions

View file

@ -210,6 +210,25 @@ bool apr_tal_notify_rx_intent_req(void *handle, const void *priv,
return false;
}
static void apr_tal_notify_remote_rx_intent(void *handle, const void *priv,
size_t size)
{
struct apr_svc_ch_dev *apr_ch = (struct apr_svc_ch_dev *)priv;
if (!apr_ch) {
pr_err("%s: Invalid apr_ch\n", __func__);
return;
}
/*
* This is to make sure that the far end has queued at least one intent
* before we attmpt any IPC. A simple bool flag is used here instead of
* a counter, as the far end is required to guarantee intent
* availability for all use cases once the channel is fully opened.
*/
pr_debug("%s: remote queued an intent\n", __func__);
apr_ch->if_remote_intent_ready = true;
}
void apr_tal_notify_state(void *handle, const void *priv, unsigned event)
{
struct apr_svc_ch_dev *apr_ch = (struct apr_svc_ch_dev *)priv;
@ -295,6 +314,7 @@ struct apr_svc_ch_dev *apr_tal_open(uint32_t clnt, uint32_t dest, uint32_t dl,
open_cfg.notify_tx_done = apr_tal_notify_tx_done;
open_cfg.notify_state = apr_tal_notify_state;
open_cfg.notify_rx_intent_req = apr_tal_notify_rx_intent_req;
open_cfg.notify_remote_rx_intent = apr_tal_notify_remote_rx_intent;
open_cfg.priv = apr_ch;
/*
* The transport name "smd_trans" is required if far end is using SMD.
@ -321,6 +341,15 @@ struct apr_svc_ch_dev *apr_tal_open(uint32_t clnt, uint32_t dest, uint32_t dl,
goto close_link;
}
/*
* Remote intent is not required for GLINK <--> SMD IPC, so this is
* designed not to fail the open call.
*/
rc = wait_event_timeout(apr_ch->wait,
apr_ch->if_remote_intent_ready, 5 * HZ);
if (rc == 0)
pr_err("%s: TIMEOUT for remote intent readiness\n", __func__);
rc = apr_tal_rx_intents_config(apr_ch, APR_DEFAULT_NUM_OF_INTENTS,
APR_MAX_BUF);
if (rc) {
@ -356,6 +385,7 @@ int apr_tal_close(struct apr_svc_ch_dev *apr_ch)
apr_ch->handle = NULL;
apr_ch->func = NULL;
apr_ch->priv = NULL;
apr_ch->if_remote_intent_ready = false;
mutex_unlock(&apr_ch->m_lock);
exit:
return rc;

View file

@ -87,6 +87,7 @@ struct apr_svc_ch_dev {
wait_queue_head_t wait;
void *priv;
unsigned channel_state;
bool if_remote_intent_ready;
};
#else
struct apr_svc_ch_dev {