summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarthikeyan Ramasubramanian <kramasub@codeaurora.org>2016-04-20 12:10:48 -0600
committerKarthikeyan Ramasubramanian <kramasub@codeaurora.org>2016-08-03 11:37:13 -0600
commita1fa510e64cfbe4001d5586f9646644f9b381820 (patch)
treeea8d3e4d7fdee90b825db3c3bb8e191b515064e7
parent60aacdb787e6040d86bea2cd54897085a638a728 (diff)
soc: qcom: glink: Receive remote rx_intent with a cookie
Currently the remote rx_intent is stored with the primary information. The transport cannot provide a cookie to be retrieved and used later during transmission. Add support to receive a remote rx_intent with a cookie. CRs-Fixed: 1045916 Change-Id: Id5f204647205b2fde9e5cb422a3ddc8cc4f3a5a0 Signed-off-by: Karthikeyan Ramasubramanian <kramasub@codeaurora.org>
-rw-r--r--drivers/soc/qcom/glink.c56
-rw-r--r--drivers/soc/qcom/glink_core_if.h7
-rw-r--r--drivers/soc/qcom/glink_xprt_if.h4
3 files changed, 56 insertions, 11 deletions
diff --git a/drivers/soc/qcom/glink.c b/drivers/soc/qcom/glink.c
index 464fe17158cf..1b94699e7e7c 100644
--- a/drivers/soc/qcom/glink.c
+++ b/drivers/soc/qcom/glink.c
@@ -372,10 +372,10 @@ static struct channel_ctx *ch_name_to_ch_ctx_create(
const char *name);
static void ch_push_remote_rx_intent(struct channel_ctx *ctx, size_t size,
- uint32_t riid);
+ uint32_t riid, void *cookie);
static int ch_pop_remote_rx_intent(struct channel_ctx *ctx, size_t size,
- uint32_t *riid_ptr, size_t *intent_size);
+ uint32_t *riid_ptr, size_t *intent_size, void **cookie);
static struct glink_core_rx_intent *ch_push_local_rx_intent(
struct channel_ctx *ctx, const void *pkt_priv, size_t size);
@@ -1139,11 +1139,12 @@ bool ch_check_duplicate_riid(struct channel_ctx *ctx, int riid)
* @ctx: Local channel context
* @size: Size of Intent
* @riid_ptr: Pointer to return value of remote intent ID
+ * @cookie: Transport-specific cookie to return
*
* This functions searches for an RX intent that is >= to the requested size.
*/
int ch_pop_remote_rx_intent(struct channel_ctx *ctx, size_t size,
- uint32_t *riid_ptr, size_t *intent_size)
+ uint32_t *riid_ptr, size_t *intent_size, void **cookie)
{
struct glink_core_rx_intent *intent;
struct glink_core_rx_intent *intent_tmp;
@@ -1177,6 +1178,7 @@ int ch_pop_remote_rx_intent(struct channel_ctx *ctx, size_t size,
intent->intent_size);
*riid_ptr = intent->id;
*intent_size = intent->intent_size;
+ *cookie = intent->cookie;
kfree(intent);
spin_unlock_irqrestore(
&ctx->rmt_rx_intent_lst_lock_lhc2, flags);
@@ -1192,11 +1194,12 @@ int ch_pop_remote_rx_intent(struct channel_ctx *ctx, size_t size,
* @ctx: Local channel context
* @size: Size of Intent
* @riid: Remote intent ID
+ * @cookie: Transport-specific cookie to cache
*
* This functions adds a remote RX intent to the remote RX intent list.
*/
void ch_push_remote_rx_intent(struct channel_ctx *ctx, size_t size,
- uint32_t riid)
+ uint32_t riid, void *cookie)
{
struct glink_core_rx_intent *intent;
unsigned long flags;
@@ -1225,6 +1228,7 @@ void ch_push_remote_rx_intent(struct channel_ctx *ctx, size_t size,
}
intent->id = riid;
intent->intent_size = size;
+ intent->cookie = cookie;
spin_lock_irqsave(&ctx->rmt_rx_intent_lst_lock_lhc2, flags);
list_add_tail(&intent->list, &ctx->rmt_rx_intent_list);
@@ -2794,6 +2798,7 @@ static int glink_tx_common(void *handle, void *pkt_priv,
bool is_atomic =
tx_flags & (GLINK_TX_SINGLE_THREADED | GLINK_TX_ATOMIC);
unsigned long flags;
+ void *cookie = NULL;
if (!size)
return -EINVAL;
@@ -2826,7 +2831,7 @@ static int glink_tx_common(void *handle, void *pkt_priv,
}
/* find matching rx intent (first-fit algorithm for now) */
- if (ch_pop_remote_rx_intent(ctx, size, &riid, &intent_size)) {
+ if (ch_pop_remote_rx_intent(ctx, size, &riid, &intent_size, &cookie)) {
if (!(tx_flags & GLINK_TX_REQ_INTENT)) {
/* no rx intent available */
GLINK_ERR_CH(ctx,
@@ -2856,7 +2861,7 @@ static int glink_tx_common(void *handle, void *pkt_priv,
}
while (ch_pop_remote_rx_intent(ctx, size, &riid,
- &intent_size)) {
+ &intent_size, &cookie)) {
rwref_get(&ctx->ch_state_lhb2);
rwref_read_put(&ctx->ch_state_lhb2);
if (is_atomic) {
@@ -2928,7 +2933,7 @@ static int glink_tx_common(void *handle, void *pkt_priv,
is_atomic ? GFP_ATOMIC : GFP_KERNEL);
if (!tx_info) {
GLINK_ERR_CH(ctx, "%s: No memory for allocation\n", __func__);
- ch_push_remote_rx_intent(ctx, intent_size, riid);
+ ch_push_remote_rx_intent(ctx, intent_size, riid, cookie);
rwref_read_put(&ctx->ch_state_lhb2);
return -ENOMEM;
}
@@ -2946,6 +2951,7 @@ static int glink_tx_common(void *handle, void *pkt_priv,
tx_info->vprovider = vbuf_provider;
tx_info->pprovider = pbuf_provider;
tx_info->intent_size = intent_size;
+ tx_info->cookie = cookie;
/* schedule packet for transmit */
if ((tx_flags & GLINK_TX_SINGLE_THREADED) &&
@@ -4844,7 +4850,35 @@ static void glink_core_remote_rx_intent_put(struct glink_transport_if *if_ptr,
return;
}
- ch_push_remote_rx_intent(ctx, size, riid);
+ ch_push_remote_rx_intent(ctx, size, riid, NULL);
+ rwref_put(&ctx->ch_state_lhb2);
+}
+
+/**
+ * glink_core_remote_rx_intent_put_cookie() - Receive remove intent
+ *
+ * @if_ptr: Pointer to transport instance
+ * @rcid: Remote Channel ID
+ * @riid: Remote Intent ID
+ * @size: Size of the remote intent ID
+ * @cookie: Transport-specific cookie to cache
+ */
+static void glink_core_remote_rx_intent_put_cookie(
+ struct glink_transport_if *if_ptr,
+ uint32_t rcid, uint32_t riid, size_t size, void *cookie)
+{
+ struct channel_ctx *ctx;
+
+ ctx = xprt_rcid_to_ch_ctx_get(if_ptr->glink_core_priv, rcid);
+ if (!ctx) {
+ /* unknown rcid received - this shouldn't happen */
+ GLINK_ERR_XPRT(if_ptr->glink_core_priv,
+ "%s: invalid rcid received %u\n", __func__,
+ (unsigned)rcid);
+ return;
+ }
+
+ ch_push_remote_rx_intent(ctx, size, riid, cookie);
rwref_put(&ctx->ch_state_lhb2);
}
@@ -5050,6 +5084,7 @@ void glink_core_rx_cmd_tx_done(struct glink_transport_if *if_ptr,
struct glink_core_tx_pkt *tx_pkt;
unsigned long flags;
size_t intent_size;
+ void *cookie;
ctx = xprt_rcid_to_ch_ctx_get(if_ptr->glink_core_priv, rcid);
if (!ctx) {
@@ -5082,11 +5117,12 @@ void glink_core_rx_cmd_tx_done(struct glink_transport_if *if_ptr,
ctx->notify_tx_done(ctx, ctx->user_priv, tx_pkt->pkt_priv,
tx_pkt->data ? tx_pkt->data : tx_pkt->iovec);
intent_size = tx_pkt->intent_size;
+ cookie = tx_pkt->cookie;
ch_remove_tx_pending_remote_done(ctx, tx_pkt);
spin_unlock_irqrestore(&ctx->tx_lists_lock_lhc3, flags);
if (reuse)
- ch_push_remote_rx_intent(ctx, intent_size, riid);
+ ch_push_remote_rx_intent(ctx, intent_size, riid, cookie);
rwref_put(&ctx->ch_state_lhb2);
}
@@ -5525,6 +5561,8 @@ static struct glink_core_if core_impl = {
.rx_get_pkt_ctx = glink_core_rx_get_pkt_ctx,
.rx_put_pkt_ctx = glink_core_rx_put_pkt_ctx,
.rx_cmd_remote_rx_intent_put = glink_core_remote_rx_intent_put,
+ .rx_cmd_remote_rx_intent_put_cookie =
+ glink_core_remote_rx_intent_put_cookie,
.rx_cmd_remote_rx_intent_req = glink_core_rx_cmd_remote_rx_intent_req,
.rx_cmd_rx_intent_req_ack = glink_core_rx_cmd_rx_intent_req_ack,
.rx_cmd_tx_done = glink_core_rx_cmd_tx_done,
diff --git a/drivers/soc/qcom/glink_core_if.h b/drivers/soc/qcom/glink_core_if.h
index 93c59d9c4aa1..14113305a50e 100644
--- a/drivers/soc/qcom/glink_core_if.h
+++ b/drivers/soc/qcom/glink_core_if.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -64,6 +64,7 @@ struct glink_core_version {
* iovec: Pointer to vector buffer if the transport passes a vector buffer
* vprovider: Virtual address-space buffer provider for a vector buffer
* pprovider: Physical address-space buffer provider for a vector buffer
+ * cookie: Private transport specific cookie
* pkt_priv: G-Link core owned packet-private data
* list: G-Link core owned list node
* bounce_buf: Pointer to the temporary/internal bounce buffer
@@ -78,6 +79,7 @@ struct glink_core_rx_intent {
void *iovec;
void * (*vprovider)(void *iovec, size_t offset, size_t *size);
void * (*pprovider)(void *iovec, size_t offset, size_t *size);
+ void *cookie;
/* G-Link-Core-owned elements - please ignore */
struct list_head list;
@@ -151,6 +153,9 @@ struct glink_core_if {
struct glink_core_rx_intent *intent_ptr, bool complete);
void (*rx_cmd_remote_rx_intent_put)(struct glink_transport_if *if_ptr,
uint32_t rcid, uint32_t riid, size_t size);
+ void (*rx_cmd_remote_rx_intent_put_cookie)(
+ struct glink_transport_if *if_ptr, uint32_t rcid,
+ uint32_t riid, size_t size, void *cookie);
void (*rx_cmd_tx_done)(struct glink_transport_if *if_ptr, uint32_t rcid,
uint32_t riid, bool reuse);
void (*rx_cmd_remote_rx_intent_req)(struct glink_transport_if *if_ptr,
diff --git a/drivers/soc/qcom/glink_xprt_if.h b/drivers/soc/qcom/glink_xprt_if.h
index 6242e867fe72..fbc445aa06b6 100644
--- a/drivers/soc/qcom/glink_xprt_if.h
+++ b/drivers/soc/qcom/glink_xprt_if.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -56,6 +56,7 @@ enum xprt_ids {
* @iovec: Pointer to the vector buffer packet.
* @vprovider: Packet-specific virtual buffer provider function.
* @pprovider: Packet-specific physical buffer provider function.
+ * @cookie: Transport-specific cookie
* @pkt_ref: Active references to the packet.
*/
struct glink_core_tx_pkt {
@@ -73,6 +74,7 @@ struct glink_core_tx_pkt {
void *iovec;
void * (*vprovider)(void *iovec, size_t offset, size_t *size);
void * (*pprovider)(void *iovec, size_t offset, size_t *size);
+ void *cookie;
struct rwref_lock pkt_ref;
};