Skip to content

Commit fe89e9b

Browse files
committed
Merge tag 'rpmsg-v6.4' of git://git.kernel.org/pub/scm/linux/kernel/git/remoteproc/linux
Pull rpmsg updates from Bjorn Andersson: "The remove functions of the Qualcomm SMD and GLINK RPM platform drivers are transitioned to the new void returning prototype. Likewise is qcom_smd_unregister_edge() transitioned to void, as it unconditionally returned 0. An assumption about the ordering of the intent request acknowledgement and advertisement of a new intent in the GLINK implementation is corrected. Faulty error handling is corrected is improved in the TX path, and duplicated code, in the same path, is cleaned up" * tag 'rpmsg-v6.4' of git://git.kernel.org/pub/scm/linux/kernel/git/remoteproc/linux: rpmsg: glink: Consolidate TX_DATA and TX_DATA_CONT rpmsg: glink: Propagate TX failures in intentless mode as well rpmsg: glink: Wait for intent, not just request ack rpmsg: glink: Transition intent request signaling to wait queue rpmsg: qcom_smd: Convert to platform remove callback returning void rpmsg: qcom_glink_rpm: Convert to platform remove callback returning void rpmsg: qcom_smd: Make qcom_smd_unregister_edge() return void
2 parents c5c06e2 + ba7a475 commit fe89e9b

4 files changed

Lines changed: 57 additions & 65 deletions

File tree

drivers/rpmsg/qcom_glink_native.c

Lines changed: 42 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <linux/rpmsg.h>
1717
#include <linux/sizes.h>
1818
#include <linux/slab.h>
19+
#include <linux/wait.h>
1920
#include <linux/workqueue.h>
2021
#include <linux/mailbox_client.h>
2122

@@ -145,7 +146,8 @@ enum {
145146
* @open_req: completed once open-request has been received
146147
* @intent_req_lock: Synchronises multiple intent requests
147148
* @intent_req_result: Result of intent request
148-
* @intent_req_comp: Completion for intent_req signalling
149+
* @intent_received: flag indicating that an intent has been received
150+
* @intent_req_wq: wait queue for intent_req signalling
149151
*/
150152
struct glink_channel {
151153
struct rpmsg_endpoint ept;
@@ -175,8 +177,9 @@ struct glink_channel {
175177
struct completion open_req;
176178

177179
struct mutex intent_req_lock;
178-
bool intent_req_result;
179-
struct completion intent_req_comp;
180+
int intent_req_result;
181+
bool intent_received;
182+
wait_queue_head_t intent_req_wq;
180183
};
181184

182185
#define to_glink_channel(_ept) container_of(_ept, struct glink_channel, ept)
@@ -221,7 +224,7 @@ static struct glink_channel *qcom_glink_alloc_channel(struct qcom_glink *glink,
221224

222225
init_completion(&channel->open_req);
223226
init_completion(&channel->open_ack);
224-
init_completion(&channel->intent_req_comp);
227+
init_waitqueue_head(&channel->intent_req_wq);
225228

226229
INIT_LIST_HEAD(&channel->done_intents);
227230
INIT_WORK(&channel->intent_work, qcom_glink_rx_done_work);
@@ -419,14 +422,14 @@ static void qcom_glink_handle_intent_req_ack(struct qcom_glink *glink,
419422
return;
420423
}
421424

422-
channel->intent_req_result = granted;
423-
complete(&channel->intent_req_comp);
425+
WRITE_ONCE(channel->intent_req_result, granted);
426+
wake_up_all(&channel->intent_req_wq);
424427
}
425428

426429
static void qcom_glink_intent_req_abort(struct glink_channel *channel)
427430
{
428-
channel->intent_req_result = 0;
429-
complete(&channel->intent_req_comp);
431+
WRITE_ONCE(channel->intent_req_result, 0);
432+
wake_up_all(&channel->intent_req_wq);
430433
}
431434

432435
/**
@@ -756,6 +759,11 @@ static void qcom_glink_handle_rx_done(struct qcom_glink *glink,
756759
kfree(intent);
757760
}
758761
spin_unlock_irqrestore(&channel->intent_lock, flags);
762+
763+
if (reuse) {
764+
WRITE_ONCE(channel->intent_received, true);
765+
wake_up_all(&channel->intent_req_wq);
766+
}
759767
}
760768

761769
/**
@@ -993,6 +1001,9 @@ static void qcom_glink_handle_intent(struct qcom_glink *glink,
9931001
dev_err(glink->dev, "failed to store remote intent\n");
9941002
}
9951003

1004+
WRITE_ONCE(channel->intent_received, true);
1005+
wake_up_all(&channel->intent_req_wq);
1006+
9961007
kfree(msg);
9971008
qcom_glink_rx_advance(glink, ALIGN(msglen, 8));
9981009
}
@@ -1271,7 +1282,8 @@ static int qcom_glink_request_intent(struct qcom_glink *glink,
12711282

12721283
mutex_lock(&channel->intent_req_lock);
12731284

1274-
reinit_completion(&channel->intent_req_comp);
1285+
WRITE_ONCE(channel->intent_req_result, -1);
1286+
WRITE_ONCE(channel->intent_received, false);
12751287

12761288
cmd.id = GLINK_CMD_RX_INTENT_REQ;
12771289
cmd.cid = channel->lcid;
@@ -1281,12 +1293,15 @@ static int qcom_glink_request_intent(struct qcom_glink *glink,
12811293
if (ret)
12821294
goto unlock;
12831295

1284-
ret = wait_for_completion_timeout(&channel->intent_req_comp, 10 * HZ);
1296+
ret = wait_event_timeout(channel->intent_req_wq,
1297+
READ_ONCE(channel->intent_req_result) >= 0 &&
1298+
READ_ONCE(channel->intent_received),
1299+
10 * HZ);
12851300
if (!ret) {
12861301
dev_err(glink->dev, "intent request timed out\n");
12871302
ret = -ETIMEDOUT;
12881303
} else {
1289-
ret = channel->intent_req_result ? 0 : -ECANCELED;
1304+
ret = READ_ONCE(channel->intent_req_result) ? 0 : -ECANCELED;
12901305
}
12911306

12921307
unlock:
@@ -1309,7 +1324,7 @@ static int __qcom_glink_send(struct glink_channel *channel,
13091324
int ret;
13101325
unsigned long flags;
13111326
int chunk_size = len;
1312-
int left_size = 0;
1327+
size_t offset = 0;
13131328

13141329
if (!glink->intentless) {
13151330
while (!intent) {
@@ -1343,47 +1358,29 @@ static int __qcom_glink_send(struct glink_channel *channel,
13431358
iid = intent->id;
13441359
}
13451360

1346-
if (wait && chunk_size > SZ_8K) {
1347-
chunk_size = SZ_8K;
1348-
left_size = len - chunk_size;
1349-
}
1350-
req.msg.cmd = cpu_to_le16(GLINK_CMD_TX_DATA);
1351-
req.msg.param1 = cpu_to_le16(channel->lcid);
1352-
req.msg.param2 = cpu_to_le32(iid);
1353-
req.chunk_size = cpu_to_le32(chunk_size);
1354-
req.left_size = cpu_to_le32(left_size);
1355-
1356-
ret = qcom_glink_tx(glink, &req, sizeof(req), data, chunk_size, wait);
1357-
1358-
/* Mark intent available if we failed */
1359-
if (ret && intent) {
1360-
intent->in_use = false;
1361-
return ret;
1362-
}
1363-
1364-
while (left_size > 0) {
1365-
data = (void *)((char *)data + chunk_size);
1366-
chunk_size = left_size;
1367-
if (chunk_size > SZ_8K)
1361+
while (offset < len) {
1362+
chunk_size = len - offset;
1363+
if (chunk_size > SZ_8K && wait)
13681364
chunk_size = SZ_8K;
1369-
left_size -= chunk_size;
13701365

1371-
req.msg.cmd = cpu_to_le16(GLINK_CMD_TX_DATA_CONT);
1366+
req.msg.cmd = cpu_to_le16(offset == 0 ? GLINK_CMD_TX_DATA : GLINK_CMD_TX_DATA_CONT);
13721367
req.msg.param1 = cpu_to_le16(channel->lcid);
13731368
req.msg.param2 = cpu_to_le32(iid);
13741369
req.chunk_size = cpu_to_le32(chunk_size);
1375-
req.left_size = cpu_to_le32(left_size);
1376-
1377-
ret = qcom_glink_tx(glink, &req, sizeof(req), data,
1378-
chunk_size, wait);
1370+
req.left_size = cpu_to_le32(len - offset - chunk_size);
13791371

1380-
/* Mark intent available if we failed */
1381-
if (ret && intent) {
1382-
intent->in_use = false;
1383-
break;
1372+
ret = qcom_glink_tx(glink, &req, sizeof(req), data + offset, chunk_size, wait);
1373+
if (ret) {
1374+
/* Mark intent available if we failed */
1375+
if (intent)
1376+
intent->in_use = false;
1377+
return ret;
13841378
}
1379+
1380+
offset += chunk_size;
13851381
}
1386-
return ret;
1382+
1383+
return 0;
13871384
}
13881385

13891386
static int qcom_glink_send(struct rpmsg_endpoint *ept, void *data, int len)

drivers/rpmsg/qcom_glink_rpm.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ static int glink_rpm_probe(struct platform_device *pdev)
361361
return 0;
362362
}
363363

364-
static int glink_rpm_remove(struct platform_device *pdev)
364+
static void glink_rpm_remove(struct platform_device *pdev)
365365
{
366366
struct glink_rpm *rpm = platform_get_drvdata(pdev);
367367
struct qcom_glink *glink = rpm->glink;
@@ -371,8 +371,6 @@ static int glink_rpm_remove(struct platform_device *pdev)
371371
qcom_glink_native_remove(glink);
372372

373373
mbox_free_channel(rpm->mbox_chan);
374-
375-
return 0;
376374
}
377375

378376
static const struct of_device_id glink_rpm_of_match[] = {
@@ -383,7 +381,7 @@ MODULE_DEVICE_TABLE(of, glink_rpm_of_match);
383381

384382
static struct platform_driver glink_rpm_driver = {
385383
.probe = glink_rpm_probe,
386-
.remove = glink_rpm_remove,
384+
.remove_new = glink_rpm_remove,
387385
.driver = {
388386
.name = "qcom_glink_rpm",
389387
.of_match_table = glink_rpm_of_match,

drivers/rpmsg/qcom_smd.c

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1533,7 +1533,7 @@ static int qcom_smd_remove_device(struct device *dev, void *data)
15331533
* qcom_smd_unregister_edge() - release an edge and its children
15341534
* @edge: edge reference acquired from qcom_smd_register_edge
15351535
*/
1536-
int qcom_smd_unregister_edge(struct qcom_smd_edge *edge)
1536+
void qcom_smd_unregister_edge(struct qcom_smd_edge *edge)
15371537
{
15381538
int ret;
15391539

@@ -1547,8 +1547,6 @@ int qcom_smd_unregister_edge(struct qcom_smd_edge *edge)
15471547

15481548
mbox_free_channel(edge->mbox_chan);
15491549
device_unregister(&edge->dev);
1550-
1551-
return 0;
15521550
}
15531551
EXPORT_SYMBOL(qcom_smd_unregister_edge);
15541552

@@ -1572,22 +1570,22 @@ static int qcom_smd_remove_edge(struct device *dev, void *data)
15721570
{
15731571
struct qcom_smd_edge *edge = to_smd_edge(dev);
15741572

1575-
return qcom_smd_unregister_edge(edge);
1573+
qcom_smd_unregister_edge(edge);
1574+
1575+
return 0;
15761576
}
15771577

15781578
/*
15791579
* Shut down all smd clients by making sure that each edge stops processing
15801580
* events and scanning for new channels, then call destroy on the devices.
15811581
*/
1582-
static int qcom_smd_remove(struct platform_device *pdev)
1582+
static void qcom_smd_remove(struct platform_device *pdev)
15831583
{
1584-
int ret;
1585-
1586-
ret = device_for_each_child(&pdev->dev, NULL, qcom_smd_remove_edge);
1587-
if (ret)
1588-
dev_warn(&pdev->dev, "can't remove smd device: %d\n", ret);
1589-
1590-
return ret;
1584+
/*
1585+
* qcom_smd_remove_edge always returns zero, so there is no need to
1586+
* check the return value of device_for_each_child.
1587+
*/
1588+
device_for_each_child(&pdev->dev, NULL, qcom_smd_remove_edge);
15911589
}
15921590

15931591
static const struct of_device_id qcom_smd_of_match[] = {
@@ -1598,7 +1596,7 @@ MODULE_DEVICE_TABLE(of, qcom_smd_of_match);
15981596

15991597
static struct platform_driver qcom_smd_driver = {
16001598
.probe = qcom_smd_probe,
1601-
.remove = qcom_smd_remove,
1599+
.remove_new = qcom_smd_remove,
16021600
.driver = {
16031601
.name = "qcom-smd",
16041602
.of_match_table = qcom_smd_of_match,

include/linux/rpmsg/qcom_smd.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ struct qcom_smd_edge;
1111

1212
struct qcom_smd_edge *qcom_smd_register_edge(struct device *parent,
1313
struct device_node *node);
14-
int qcom_smd_unregister_edge(struct qcom_smd_edge *edge);
14+
void qcom_smd_unregister_edge(struct qcom_smd_edge *edge);
1515

1616
#else
1717

@@ -22,9 +22,8 @@ qcom_smd_register_edge(struct device *parent,
2222
return NULL;
2323
}
2424

25-
static inline int qcom_smd_unregister_edge(struct qcom_smd_edge *edge)
25+
static inline void qcom_smd_unregister_edge(struct qcom_smd_edge *edge)
2626
{
27-
return 0;
2827
}
2928

3029
#endif

0 commit comments

Comments
 (0)