Skip to content

Commit dacbb35

Browse files
Sricharan Randersson
authored andcommitted
rpmsg: glink: Receive and store the remote intent buffers
Just like we allocating and sending intent ids to remote, remote side allocates and sends us the intents as well. So save the intent ids and use it later while sending data targeting the appropriate intents based on the size. Acked-by: Arun Kumar Neelakantam <aneela@codeaurora.org> Signed-off-by: Sricharan R <sricharan@codeaurora.org> Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
1 parent 6bf68cb commit dacbb35

File tree

1 file changed

+70
-1
lines changed

1 file changed

+70
-1
lines changed

drivers/rpmsg/qcom_glink_native.c

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,9 @@ enum {
140140
* @name: unique channel name/identifier
141141
* @lcid: channel id, in local space
142142
* @rcid: channel id, in remote space
143-
* @intent_lock: lock for protection of @liids
143+
* @intent_lock: lock for protection of @liids, @riids
144144
* @liids: idr of all local intents
145+
* @riids: idr of all remote intents
145146
* @intent_work: worker responsible for transmitting rx_done packets
146147
* @done_intents: list of intents that needs to be announced rx_done
147148
* @buf: receive buffer, for gathering fragments
@@ -166,6 +167,7 @@ struct glink_channel {
166167

167168
spinlock_t intent_lock;
168169
struct idr liids;
170+
struct idr riids;
169171
struct work_struct intent_work;
170172
struct list_head done_intents;
171173

@@ -223,6 +225,7 @@ static struct glink_channel *qcom_glink_alloc_channel(struct qcom_glink *glink,
223225
INIT_WORK(&channel->intent_work, qcom_glink_rx_done_work);
224226

225227
idr_init(&channel->liids);
228+
idr_init(&channel->riids);
226229
kref_init(&channel->refcount);
227230

228231
return channel;
@@ -236,6 +239,7 @@ static void qcom_glink_channel_release(struct kref *ref)
236239

237240
spin_lock_irqsave(&channel->intent_lock, flags);
238241
idr_destroy(&channel->liids);
242+
idr_destroy(&channel->riids);
239243
spin_unlock_irqrestore(&channel->intent_lock, flags);
240244

241245
kfree(channel->name);
@@ -807,6 +811,68 @@ static int qcom_glink_rx_data(struct qcom_glink *glink, size_t avail)
807811
return ret;
808812
}
809813

814+
static void qcom_glink_handle_intent(struct qcom_glink *glink,
815+
unsigned int cid,
816+
unsigned int count,
817+
size_t avail)
818+
{
819+
struct glink_core_rx_intent *intent;
820+
struct glink_channel *channel;
821+
struct intent_pair {
822+
__le32 size;
823+
__le32 iid;
824+
};
825+
826+
struct {
827+
struct glink_msg msg;
828+
struct intent_pair intents[];
829+
} __packed * msg;
830+
831+
const size_t msglen = sizeof(*msg) + sizeof(struct intent_pair) * count;
832+
int ret;
833+
int i;
834+
unsigned long flags;
835+
836+
if (avail < msglen) {
837+
dev_dbg(glink->dev, "Not enough data in fifo\n");
838+
return;
839+
}
840+
841+
spin_lock_irqsave(&glink->idr_lock, flags);
842+
channel = idr_find(&glink->rcids, cid);
843+
spin_unlock_irqrestore(&glink->idr_lock, flags);
844+
if (!channel) {
845+
dev_err(glink->dev, "intents for non-existing channel\n");
846+
return;
847+
}
848+
849+
msg = kmalloc(msglen, GFP_ATOMIC);
850+
if (!msg)
851+
return;
852+
853+
qcom_glink_rx_peak(glink, msg, 0, msglen);
854+
855+
for (i = 0; i < count; ++i) {
856+
intent = kzalloc(sizeof(*intent), GFP_ATOMIC);
857+
if (!intent)
858+
break;
859+
860+
intent->id = le32_to_cpu(msg->intents[i].iid);
861+
intent->size = le32_to_cpu(msg->intents[i].size);
862+
863+
spin_lock_irqsave(&channel->intent_lock, flags);
864+
ret = idr_alloc(&channel->riids, intent,
865+
intent->id, intent->id + 1, GFP_ATOMIC);
866+
spin_unlock_irqrestore(&channel->intent_lock, flags);
867+
868+
if (ret < 0)
869+
dev_err(glink->dev, "failed to store remote intent\n");
870+
}
871+
872+
kfree(msg);
873+
qcom_glink_rx_advance(glink, ALIGN(msglen, 8));
874+
}
875+
810876
static int qcom_glink_rx_open_ack(struct qcom_glink *glink, unsigned int lcid)
811877
{
812878
struct glink_channel *channel;
@@ -872,6 +938,9 @@ static irqreturn_t qcom_glink_native_intr(int irq, void *data)
872938

873939
ret = 0;
874940
break;
941+
case RPM_CMD_INTENT:
942+
qcom_glink_handle_intent(glink, param1, param2, avail);
943+
break;
875944
default:
876945
dev_err(glink->dev, "unhandled rx cmd: %d\n", cmd);
877946
ret = -EINVAL;

0 commit comments

Comments
 (0)