Skip to content

Commit becc1fb

Browse files
committed
Merge tag 'rpmsg-v5.16' of git://git.kernel.org/pub/scm/linux/kernel/git/remoteproc/linux
Pull rpmsg updates from Bjorn Andersson: "For the GLINK implementation this adds support for splitting outgoing messages that are too large to fit in the fifo, it introduces the use of "read notifications", to avoid polling in the case where the outgoing fifo is full and a few bugs are squashed. The return value of rpmsg_create_ept() for when RPMSG is disabled is corrected to return a valid error, the Mediatek rpmsg driver is updated to match the DT binding and a couple of cleanups are done in the virtio rpmsg driver" * tag 'rpmsg-v5.16' of git://git.kernel.org/pub/scm/linux/kernel/git/remoteproc/linux: rpmsg: glink: Send READ_NOTIFY command in FIFO full case rpmsg: glink: Remove channel decouple from rpdev release rpmsg: glink: Remove the rpmsg dev in close_ack rpmsg: glink: Add TX_DATA_CONT command while sending rpmsg: virtio_rpmsg_bus: use dev_warn_ratelimited for msg with no recipient rpmsg: virtio: Remove unused including <linux/of_device.h> rpmsg: Change naming of mediatek rpmsg property rpmsg: Fix rpmsg_create_ept return when RPMSG config is not defined rpmsg: glink: Replace strncpy() with strscpy_pad()
2 parents cb690f5 + b16a37e commit becc1fb

File tree

4 files changed

+85
-12
lines changed

4 files changed

+85
-12
lines changed

drivers/rpmsg/mtk_rpmsg.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ mtk_rpmsg_match_device_subnode(struct device_node *node, const char *channel)
183183
int ret;
184184

185185
for_each_available_child_of_node(node, child) {
186-
ret = of_property_read_string(child, "mtk,rpmsg-name", &name);
186+
ret = of_property_read_string(child, "mediatek,rpmsg-name", &name);
187187
if (ret)
188188
continue;
189189

drivers/rpmsg/qcom_glink_native.c

Lines changed: 82 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ struct glink_core_rx_intent {
9292
* @rcids: idr of all channels with a known remote channel id
9393
* @features: remote features
9494
* @intentless: flag to indicate that there is no intent
95+
* @tx_avail_notify: Waitqueue for pending tx tasks
96+
* @sent_read_notify: flag to check cmd sent or not
9597
*/
9698
struct qcom_glink {
9799
struct device *dev;
@@ -118,6 +120,8 @@ struct qcom_glink {
118120
unsigned long features;
119121

120122
bool intentless;
123+
wait_queue_head_t tx_avail_notify;
124+
bool sent_read_notify;
121125
};
122126

123127
enum {
@@ -301,6 +305,20 @@ static void qcom_glink_tx_write(struct qcom_glink *glink,
301305
glink->tx_pipe->write(glink->tx_pipe, hdr, hlen, data, dlen);
302306
}
303307

308+
static void qcom_glink_send_read_notify(struct qcom_glink *glink)
309+
{
310+
struct glink_msg msg;
311+
312+
msg.cmd = cpu_to_le16(RPM_CMD_READ_NOTIF);
313+
msg.param1 = 0;
314+
msg.param2 = 0;
315+
316+
qcom_glink_tx_write(glink, &msg, sizeof(msg), NULL, 0);
317+
318+
mbox_send_message(glink->mbox_chan, NULL);
319+
mbox_client_txdone(glink->mbox_chan, 0);
320+
}
321+
304322
static int qcom_glink_tx(struct qcom_glink *glink,
305323
const void *hdr, size_t hlen,
306324
const void *data, size_t dlen, bool wait)
@@ -321,12 +339,21 @@ static int qcom_glink_tx(struct qcom_glink *glink,
321339
goto out;
322340
}
323341

342+
if (!glink->sent_read_notify) {
343+
glink->sent_read_notify = true;
344+
qcom_glink_send_read_notify(glink);
345+
}
346+
324347
/* Wait without holding the tx_lock */
325348
spin_unlock_irqrestore(&glink->tx_lock, flags);
326349

327-
usleep_range(10000, 15000);
350+
wait_event_timeout(glink->tx_avail_notify,
351+
qcom_glink_tx_avail(glink) >= tlen, 10 * HZ);
328352

329353
spin_lock_irqsave(&glink->tx_lock, flags);
354+
355+
if (qcom_glink_tx_avail(glink) >= tlen)
356+
glink->sent_read_notify = false;
330357
}
331358

332359
qcom_glink_tx_write(glink, hdr, hlen, data, dlen);
@@ -986,6 +1013,9 @@ static irqreturn_t qcom_glink_native_intr(int irq, void *data)
9861013
unsigned int cmd;
9871014
int ret = 0;
9881015

1016+
/* To wakeup any blocking writers */
1017+
wake_up_all(&glink->tx_avail_notify);
1018+
9891019
for (;;) {
9901020
avail = qcom_glink_rx_avail(glink);
9911021
if (avail < sizeof(msg))
@@ -1271,6 +1301,8 @@ static int __qcom_glink_send(struct glink_channel *channel,
12711301
} __packed req;
12721302
int ret;
12731303
unsigned long flags;
1304+
int chunk_size = len;
1305+
int left_size = 0;
12741306

12751307
if (!glink->intentless) {
12761308
while (!intent) {
@@ -1304,18 +1336,46 @@ static int __qcom_glink_send(struct glink_channel *channel,
13041336
iid = intent->id;
13051337
}
13061338

1339+
if (wait && chunk_size > SZ_8K) {
1340+
chunk_size = SZ_8K;
1341+
left_size = len - chunk_size;
1342+
}
13071343
req.msg.cmd = cpu_to_le16(RPM_CMD_TX_DATA);
13081344
req.msg.param1 = cpu_to_le16(channel->lcid);
13091345
req.msg.param2 = cpu_to_le32(iid);
1310-
req.chunk_size = cpu_to_le32(len);
1311-
req.left_size = cpu_to_le32(0);
1346+
req.chunk_size = cpu_to_le32(chunk_size);
1347+
req.left_size = cpu_to_le32(left_size);
13121348

1313-
ret = qcom_glink_tx(glink, &req, sizeof(req), data, len, wait);
1349+
ret = qcom_glink_tx(glink, &req, sizeof(req), data, chunk_size, wait);
13141350

13151351
/* Mark intent available if we failed */
1316-
if (ret && intent)
1352+
if (ret && intent) {
13171353
intent->in_use = false;
1354+
return ret;
1355+
}
13181356

1357+
while (left_size > 0) {
1358+
data = (void *)((char *)data + chunk_size);
1359+
chunk_size = left_size;
1360+
if (chunk_size > SZ_8K)
1361+
chunk_size = SZ_8K;
1362+
left_size -= chunk_size;
1363+
1364+
req.msg.cmd = cpu_to_le16(RPM_CMD_TX_DATA_CONT);
1365+
req.msg.param1 = cpu_to_le16(channel->lcid);
1366+
req.msg.param2 = cpu_to_le32(iid);
1367+
req.chunk_size = cpu_to_le32(chunk_size);
1368+
req.left_size = cpu_to_le32(left_size);
1369+
1370+
ret = qcom_glink_tx(glink, &req, sizeof(req), data,
1371+
chunk_size, wait);
1372+
1373+
/* Mark intent available if we failed */
1374+
if (ret && intent) {
1375+
intent->in_use = false;
1376+
break;
1377+
}
1378+
}
13191379
return ret;
13201380
}
13211381

@@ -1387,9 +1447,7 @@ static const struct rpmsg_endpoint_ops glink_endpoint_ops = {
13871447
static void qcom_glink_rpdev_release(struct device *dev)
13881448
{
13891449
struct rpmsg_device *rpdev = to_rpmsg_device(dev);
1390-
struct glink_channel *channel = to_glink_channel(rpdev->ept);
13911450

1392-
channel->rpdev = NULL;
13931451
kfree(rpdev);
13941452
}
13951453

@@ -1440,7 +1498,7 @@ static int qcom_glink_rx_open(struct qcom_glink *glink, unsigned int rcid,
14401498
}
14411499

14421500
rpdev->ept = &channel->ept;
1443-
strncpy(rpdev->id.name, name, RPMSG_NAME_SIZE);
1501+
strscpy_pad(rpdev->id.name, name, RPMSG_NAME_SIZE);
14441502
rpdev->src = RPMSG_ADDR_ANY;
14451503
rpdev->dst = RPMSG_ADDR_ANY;
14461504
rpdev->ops = &glink_device_ops;
@@ -1494,6 +1552,7 @@ static void qcom_glink_rx_close(struct qcom_glink *glink, unsigned int rcid)
14941552

14951553
rpmsg_unregister_device(glink->dev, &chinfo);
14961554
}
1555+
channel->rpdev = NULL;
14971556

14981557
qcom_glink_send_close_ack(glink, channel->rcid);
14991558

@@ -1507,9 +1566,13 @@ static void qcom_glink_rx_close(struct qcom_glink *glink, unsigned int rcid)
15071566

15081567
static void qcom_glink_rx_close_ack(struct qcom_glink *glink, unsigned int lcid)
15091568
{
1569+
struct rpmsg_channel_info chinfo;
15101570
struct glink_channel *channel;
15111571
unsigned long flags;
15121572

1573+
/* To wakeup any blocking writers */
1574+
wake_up_all(&glink->tx_avail_notify);
1575+
15131576
spin_lock_irqsave(&glink->idr_lock, flags);
15141577
channel = idr_find(&glink->lcids, lcid);
15151578
if (WARN(!channel, "close ack on unknown channel\n")) {
@@ -1521,6 +1584,16 @@ static void qcom_glink_rx_close_ack(struct qcom_glink *glink, unsigned int lcid)
15211584
channel->lcid = 0;
15221585
spin_unlock_irqrestore(&glink->idr_lock, flags);
15231586

1587+
/* Decouple the potential rpdev from the channel */
1588+
if (channel->rpdev) {
1589+
strscpy(chinfo.name, channel->name, sizeof(chinfo.name));
1590+
chinfo.src = RPMSG_ADDR_ANY;
1591+
chinfo.dst = RPMSG_ADDR_ANY;
1592+
1593+
rpmsg_unregister_device(glink->dev, &chinfo);
1594+
}
1595+
channel->rpdev = NULL;
1596+
15241597
kref_put(&channel->refcount, qcom_glink_channel_release);
15251598
}
15261599

@@ -1670,6 +1743,7 @@ struct qcom_glink *qcom_glink_native_probe(struct device *dev,
16701743
spin_lock_init(&glink->rx_lock);
16711744
INIT_LIST_HEAD(&glink->rx_queue);
16721745
INIT_WORK(&glink->rx_work, qcom_glink_work);
1746+
init_waitqueue_head(&glink->tx_avail_notify);
16731747

16741748
spin_lock_init(&glink->idr_lock);
16751749
idr_init(&glink->lcids);

drivers/rpmsg/virtio_rpmsg_bus.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
#include <linux/kernel.h>
1818
#include <linux/module.h>
1919
#include <linux/mutex.h>
20-
#include <linux/of_device.h>
2120
#include <linux/rpmsg.h>
2221
#include <linux/rpmsg/byteorder.h>
2322
#include <linux/rpmsg/ns.h>
@@ -759,7 +758,7 @@ static int rpmsg_recv_single(struct virtproc_info *vrp, struct device *dev,
759758
/* farewell, ept, we don't need you anymore */
760759
kref_put(&ept->refcount, __ept_release);
761760
} else
762-
dev_warn(dev, "msg received with no recipient\n");
761+
dev_warn_ratelimited(dev, "msg received with no recipient\n");
763762

764763
/* publish the real size of the buffer */
765764
rpmsg_sg_init(&sg, msg, vrp->buf_size);

include/linux/rpmsg.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ static inline struct rpmsg_endpoint *rpmsg_create_ept(struct rpmsg_device *rpdev
233233
/* This shouldn't be possible */
234234
WARN_ON(1);
235235

236-
return ERR_PTR(-ENXIO);
236+
return NULL;
237237
}
238238

239239
static inline int rpmsg_send(struct rpmsg_endpoint *ept, void *data, int len)

0 commit comments

Comments
 (0)