summaryrefslogtreecommitdiff
path: root/drivers/rpmsg/qcom_glink_native.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/rpmsg/qcom_glink_native.c')
-rw-r--r--drivers/rpmsg/qcom_glink_native.c96
1 files changed, 94 insertions, 2 deletions
diff --git a/drivers/rpmsg/qcom_glink_native.c b/drivers/rpmsg/qcom_glink_native.c
index ba0ea28df821..c7c3c21a7156 100644
--- a/drivers/rpmsg/qcom_glink_native.c
+++ b/drivers/rpmsg/qcom_glink_native.c
@@ -23,6 +23,9 @@
#include "rpmsg_internal.h"
#include "qcom_glink_native.h"
+#define CREATE_TRACE_POINTS
+#include "qcom_glink_trace.h"
+
#define GLINK_NAME_SIZE 32
#define GLINK_VERSION_1 1
@@ -78,6 +81,7 @@ struct glink_core_rx_intent {
/**
* struct qcom_glink - driver context, relates to one remote subsystem
* @dev: reference to the associated struct device
+ * @label: identifier of the glink edge
* @rx_pipe: pipe object for receive FIFO
* @tx_pipe: pipe object for transmit FIFO
* @rx_work: worker for handling received control messages
@@ -96,6 +100,8 @@ struct glink_core_rx_intent {
struct qcom_glink {
struct device *dev;
+ const char *label;
+
struct qcom_glink_pipe *rx_pipe;
struct qcom_glink_pipe *tx_pipe;
@@ -392,6 +398,8 @@ static int qcom_glink_send_version(struct qcom_glink *glink)
msg.param1 = cpu_to_le16(GLINK_VERSION_1);
msg.param2 = cpu_to_le32(glink->features);
+ trace_qcom_glink_cmd_version_tx(glink->label, GLINK_VERSION_1, glink->features);
+
return qcom_glink_tx(glink, &msg, sizeof(msg), NULL, 0, true);
}
@@ -403,6 +411,8 @@ static void qcom_glink_send_version_ack(struct qcom_glink *glink)
msg.param1 = cpu_to_le16(GLINK_VERSION_1);
msg.param2 = cpu_to_le32(glink->features);
+ trace_qcom_glink_cmd_version_ack_tx(glink->label, msg.param1, msg.param2);
+
qcom_glink_tx(glink, &msg, sizeof(msg), NULL, 0, true);
}
@@ -415,6 +425,9 @@ static void qcom_glink_send_open_ack(struct qcom_glink *glink,
msg.param1 = cpu_to_le16(channel->rcid);
msg.param2 = cpu_to_le32(0);
+ trace_qcom_glink_cmd_open_ack_tx(glink->label, channel->name,
+ channel->lcid, channel->rcid);
+
qcom_glink_tx(glink, &msg, sizeof(msg), NULL, 0, true);
}
@@ -429,6 +442,11 @@ static void qcom_glink_handle_intent_req_ack(struct qcom_glink *glink,
spin_lock_irqsave(&glink->idr_lock, flags);
channel = idr_find(&glink->rcids, cid);
spin_unlock_irqrestore(&glink->idr_lock, flags);
+
+ trace_qcom_glink_cmd_rx_intent_req_ack_rx(glink->label,
+ channel ? channel->name : NULL,
+ channel ? channel->lcid : 0,
+ cid, granted);
if (!channel) {
dev_err(glink->dev, "unable to find channel\n");
return;
@@ -483,6 +501,9 @@ static int qcom_glink_send_open_req(struct qcom_glink *glink,
req.msg.param2 = cpu_to_le32(name_len);
strcpy(req.name, channel->name);
+ trace_qcom_glink_cmd_open_tx(glink->label, channel->name,
+ channel->lcid, channel->rcid);
+
ret = qcom_glink_tx(glink, &req, req_len, NULL, 0, true);
if (ret)
goto remove_idr;
@@ -507,6 +528,9 @@ static void qcom_glink_send_close_req(struct qcom_glink *glink,
req.param1 = cpu_to_le16(channel->lcid);
req.param2 = 0;
+ trace_qcom_glink_cmd_close_tx(glink->label, channel->name,
+ channel->lcid, channel->rcid);
+
qcom_glink_tx(glink, &req, sizeof(req), NULL, 0, true);
}
@@ -519,6 +543,9 @@ static void qcom_glink_send_close_ack(struct qcom_glink *glink,
req.param1 = cpu_to_le16(channel->rcid);
req.param2 = 0;
+ trace_qcom_glink_cmd_close_ack_tx(glink->label, channel->name,
+ channel->lcid, channel->rcid);
+
qcom_glink_tx(glink, &req, sizeof(req), NULL, 0, true);
}
@@ -550,6 +577,9 @@ static void qcom_glink_rx_done_work(struct work_struct *work)
cmd.lcid = cid;
cmd.liid = iid;
+ trace_qcom_glink_cmd_rx_done_tx(glink->label, channel->name,
+ channel->lcid, channel->rcid, cmd.liid, reuse);
+
qcom_glink_tx(glink, &cmd, sizeof(cmd), NULL, 0, true);
if (!reuse) {
kfree(intent->data);
@@ -600,6 +630,8 @@ static void qcom_glink_receive_version(struct qcom_glink *glink,
u32 version,
u32 features)
{
+ trace_qcom_glink_cmd_version_rx(glink->label, version, features);
+
switch (version) {
case 0:
break;
@@ -627,6 +659,8 @@ static void qcom_glink_receive_version_ack(struct qcom_glink *glink,
u32 version,
u32 features)
{
+ trace_qcom_glink_cmd_version_ack_rx(glink->label, version, features);
+
switch (version) {
case 0:
/* Version negotiation failed */
@@ -658,6 +692,10 @@ static int qcom_glink_send_intent_req_ack(struct qcom_glink *glink,
{
struct glink_msg msg;
+ trace_qcom_glink_cmd_rx_intent_req_ack_tx(glink->label, channel->name,
+ channel->lcid, channel->rcid,
+ granted);
+
msg.cmd = cpu_to_le16(GLINK_CMD_RX_INTENT_REQ_ACK);
msg.param1 = cpu_to_le16(channel->lcid);
msg.param2 = cpu_to_le32(granted);
@@ -695,6 +733,10 @@ static int qcom_glink_advertise_intent(struct qcom_glink *glink,
cmd.size = cpu_to_le32(intent->size);
cmd.liid = cpu_to_le32(intent->id);
+ trace_qcom_glink_cmd_intent_tx(glink->label, channel->name,
+ channel->lcid, channel->rcid,
+ cmd.count, cmd.size, cmd.liid);
+
qcom_glink_tx(glink, &cmd, sizeof(cmd), NULL, 0, true);
return 0;
@@ -752,6 +794,9 @@ static void qcom_glink_handle_rx_done(struct qcom_glink *glink,
spin_lock_irqsave(&glink->idr_lock, flags);
channel = idr_find(&glink->rcids, cid);
spin_unlock_irqrestore(&glink->idr_lock, flags);
+
+ trace_qcom_glink_cmd_rx_done_rx(glink->label, channel ? channel->name : NULL,
+ channel ? channel->lcid : 0, cid, iid, reuse);
if (!channel) {
dev_err(glink->dev, "invalid channel id received\n");
return;
@@ -801,6 +846,10 @@ static void qcom_glink_handle_intent_req(struct qcom_glink *glink,
channel = idr_find(&glink->rcids, cid);
spin_unlock_irqrestore(&glink->idr_lock, flags);
+ trace_qcom_glink_cmd_rx_intent_req_rx(glink->label,
+ channel ? channel->name : NULL,
+ channel ? channel->lcid : 0,
+ cid, size);
if (!channel) {
pr_err("%s channel not found for cid %d\n", __func__, cid);
return;
@@ -873,9 +922,15 @@ static int qcom_glink_rx_data(struct qcom_glink *glink, size_t avail)
}
rcid = le16_to_cpu(hdr.msg.param1);
+ liid = le32_to_cpu(hdr.msg.param2);
spin_lock_irqsave(&glink->idr_lock, flags);
channel = idr_find(&glink->rcids, rcid);
spin_unlock_irqrestore(&glink->idr_lock, flags);
+
+ trace_qcom_glink_cmd_tx_data_rx(glink->label, channel ? channel->name : NULL,
+ channel ? channel->lcid : 0, rcid,
+ liid, chunk_size, left_size,
+ hdr.msg.cmd == GLINK_CMD_TX_DATA_CONT);
if (!channel) {
dev_dbg(glink->dev, "Data on non-existing channel\n");
@@ -906,8 +961,6 @@ static int qcom_glink_rx_data(struct qcom_glink *glink, size_t avail)
intent = channel->buf;
}
} else {
- liid = le32_to_cpu(hdr.msg.param2);
-
spin_lock_irqsave(&channel->intent_lock, flags);
intent = idr_find(&channel->liids, liid);
spin_unlock_irqrestore(&channel->intent_lock, flags);
@@ -958,6 +1011,8 @@ advance_rx:
static void qcom_glink_rx_read_notif(struct qcom_glink *glink)
{
+ trace_qcom_glink_cmd_read_notif_rx(glink->label);
+
qcom_glink_rx_advance(glink, ALIGN(sizeof(struct glink_msg), 8));
qcom_glink_tx_kick(glink);
}
@@ -993,6 +1048,7 @@ static void qcom_glink_handle_intent(struct qcom_glink *glink,
channel = idr_find(&glink->rcids, cid);
spin_unlock_irqrestore(&glink->idr_lock, flags);
if (!channel) {
+ trace_qcom_glink_cmd_intent_rx(glink->label, NULL, 0, cid, count, 0, 0);
dev_err(glink->dev, "intents for non-existing channel\n");
qcom_glink_rx_advance(glink, ALIGN(msglen, 8));
return;
@@ -1004,6 +1060,11 @@ static void qcom_glink_handle_intent(struct qcom_glink *glink,
qcom_glink_rx_peek(glink, msg, 0, msglen);
+ trace_qcom_glink_cmd_intent_rx(glink->label, channel->name,
+ channel->lcid, cid, count,
+ count > 0 ? msg->intents[0].size : 0,
+ count > 0 ? msg->intents[0].iid : 0);
+
for (i = 0; i < count; ++i) {
intent = kzalloc(sizeof(*intent), GFP_ATOMIC);
if (!intent)
@@ -1037,6 +1098,9 @@ static int qcom_glink_rx_open_ack(struct qcom_glink *glink, unsigned int lcid)
spin_lock(&glink->idr_lock);
channel = idr_find(&glink->lcids, lcid);
spin_unlock(&glink->idr_lock);
+
+ trace_qcom_glink_cmd_open_ack_rx(glink->label, channel ? channel->name : NULL,
+ lcid, channel ? channel->rcid : 0);
if (!channel) {
dev_err(glink->dev, "Invalid open ack packet\n");
return -EINVAL;
@@ -1069,6 +1133,9 @@ static int qcom_glink_set_flow_control(struct rpmsg_endpoint *ept, bool pause, u
msg.param1 = cpu_to_le16(channel->lcid);
msg.param2 = cpu_to_le32(sigs);
+ trace_qcom_glink_cmd_signal_tx(glink->label, channel->name,
+ channel->lcid, channel->rcid, sigs);
+
return qcom_glink_tx(glink, &msg, sizeof(msg), NULL, 0, true);
}
@@ -1084,6 +1151,9 @@ static void qcom_glink_handle_signals(struct qcom_glink *glink,
spin_lock_irqsave(&glink->idr_lock, flags);
channel = idr_find(&glink->rcids, rcid);
spin_unlock_irqrestore(&glink->idr_lock, flags);
+
+ trace_qcom_glink_cmd_signal_rx(glink->label, channel ? channel->name : NULL,
+ channel ? channel->lcid : 0, rcid, sigs);
if (!channel) {
dev_err(glink->dev, "signal for non-existing channel\n");
return;
@@ -1357,6 +1427,10 @@ static int qcom_glink_request_intent(struct qcom_glink *glink,
cmd.cid = channel->lcid;
cmd.size = size;
+ trace_qcom_glink_cmd_rx_intent_req_tx(glink->label, channel->name,
+ channel->lcid, channel->rcid,
+ cmd.size);
+
ret = qcom_glink_tx(glink, &cmd, sizeof(cmd), NULL, 0, true);
if (ret)
goto unlock;
@@ -1437,6 +1511,12 @@ static int __qcom_glink_send(struct glink_channel *channel,
req.chunk_size = cpu_to_le32(chunk_size);
req.left_size = cpu_to_le32(len - offset - chunk_size);
+ trace_qcom_glink_cmd_tx_data_tx(glink->label, channel->name,
+ channel->lcid, channel->rcid,
+ iid, chunk_size,
+ len - offset - chunk_size,
+ offset > 0);
+
ret = qcom_glink_tx(glink, &req, sizeof(req), data + offset, chunk_size, wait);
if (ret) {
/* Mark intent available if we failed */
@@ -1552,6 +1632,8 @@ static int qcom_glink_rx_open(struct qcom_glink *glink, unsigned int rcid,
create_device = true;
}
+ trace_qcom_glink_cmd_open_rx(glink->label, name, channel->lcid, rcid);
+
spin_lock_irqsave(&glink->idr_lock, flags);
ret = idr_alloc(&glink->rcids, channel, rcid, rcid + 1, GFP_ATOMIC);
if (ret < 0) {
@@ -1613,6 +1695,9 @@ static void qcom_glink_rx_close(struct qcom_glink *glink, unsigned int rcid)
spin_lock_irqsave(&glink->idr_lock, flags);
channel = idr_find(&glink->rcids, rcid);
spin_unlock_irqrestore(&glink->idr_lock, flags);
+
+ trace_qcom_glink_cmd_close_rx(glink->label, channel ? channel->name : NULL,
+ channel ? channel->lcid : 0, rcid);
if (WARN(!channel, "close request on unknown channel\n"))
return;
@@ -1649,6 +1734,9 @@ static void qcom_glink_rx_close_ack(struct qcom_glink *glink, unsigned int lcid)
spin_lock_irqsave(&glink->idr_lock, flags);
channel = idr_find(&glink->lcids, lcid);
+
+ trace_qcom_glink_cmd_close_ack_rx(glink->label, channel ? channel->name : NULL,
+ lcid, channel ? channel->rcid : 0);
if (WARN(!channel, "close ack on unknown channel\n")) {
spin_unlock_irqrestore(&glink->idr_lock, flags);
return;
@@ -1823,6 +1911,10 @@ struct qcom_glink *qcom_glink_native_probe(struct device *dev,
idr_init(&glink->lcids);
idr_init(&glink->rcids);
+ ret = of_property_read_string(dev->of_node, "label", &glink->label);
+ if (ret < 0)
+ glink->label = dev->of_node->name;
+
glink->dev->groups = qcom_glink_groups;
ret = device_add_groups(dev, qcom_glink_groups);