@@ -92,6 +92,8 @@ struct glink_core_rx_intent {
92
92
* @rcids: idr of all channels with a known remote channel id
93
93
* @features: remote features
94
94
* @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
95
97
*/
96
98
struct qcom_glink {
97
99
struct device * dev ;
@@ -118,6 +120,8 @@ struct qcom_glink {
118
120
unsigned long features ;
119
121
120
122
bool intentless ;
123
+ wait_queue_head_t tx_avail_notify ;
124
+ bool sent_read_notify ;
121
125
};
122
126
123
127
enum {
@@ -301,6 +305,20 @@ static void qcom_glink_tx_write(struct qcom_glink *glink,
301
305
glink -> tx_pipe -> write (glink -> tx_pipe , hdr , hlen , data , dlen );
302
306
}
303
307
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
+
304
322
static int qcom_glink_tx (struct qcom_glink * glink ,
305
323
const void * hdr , size_t hlen ,
306
324
const void * data , size_t dlen , bool wait )
@@ -321,12 +339,21 @@ static int qcom_glink_tx(struct qcom_glink *glink,
321
339
goto out ;
322
340
}
323
341
342
+ if (!glink -> sent_read_notify ) {
343
+ glink -> sent_read_notify = true;
344
+ qcom_glink_send_read_notify (glink );
345
+ }
346
+
324
347
/* Wait without holding the tx_lock */
325
348
spin_unlock_irqrestore (& glink -> tx_lock , flags );
326
349
327
- usleep_range (10000 , 15000 );
350
+ wait_event_timeout (glink -> tx_avail_notify ,
351
+ qcom_glink_tx_avail (glink ) >= tlen , 10 * HZ );
328
352
329
353
spin_lock_irqsave (& glink -> tx_lock , flags );
354
+
355
+ if (qcom_glink_tx_avail (glink ) >= tlen )
356
+ glink -> sent_read_notify = false;
330
357
}
331
358
332
359
qcom_glink_tx_write (glink , hdr , hlen , data , dlen );
@@ -986,6 +1013,9 @@ static irqreturn_t qcom_glink_native_intr(int irq, void *data)
986
1013
unsigned int cmd ;
987
1014
int ret = 0 ;
988
1015
1016
+ /* To wakeup any blocking writers */
1017
+ wake_up_all (& glink -> tx_avail_notify );
1018
+
989
1019
for (;;) {
990
1020
avail = qcom_glink_rx_avail (glink );
991
1021
if (avail < sizeof (msg ))
@@ -1271,6 +1301,8 @@ static int __qcom_glink_send(struct glink_channel *channel,
1271
1301
} __packed req ;
1272
1302
int ret ;
1273
1303
unsigned long flags ;
1304
+ int chunk_size = len ;
1305
+ int left_size = 0 ;
1274
1306
1275
1307
if (!glink -> intentless ) {
1276
1308
while (!intent ) {
@@ -1304,18 +1336,46 @@ static int __qcom_glink_send(struct glink_channel *channel,
1304
1336
iid = intent -> id ;
1305
1337
}
1306
1338
1339
+ if (wait && chunk_size > SZ_8K ) {
1340
+ chunk_size = SZ_8K ;
1341
+ left_size = len - chunk_size ;
1342
+ }
1307
1343
req .msg .cmd = cpu_to_le16 (RPM_CMD_TX_DATA );
1308
1344
req .msg .param1 = cpu_to_le16 (channel -> lcid );
1309
1345
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 );
1312
1348
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 );
1314
1350
1315
1351
/* Mark intent available if we failed */
1316
- if (ret && intent )
1352
+ if (ret && intent ) {
1317
1353
intent -> in_use = false;
1354
+ return ret ;
1355
+ }
1318
1356
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
+ }
1319
1379
return ret ;
1320
1380
}
1321
1381
@@ -1387,9 +1447,7 @@ static const struct rpmsg_endpoint_ops glink_endpoint_ops = {
1387
1447
static void qcom_glink_rpdev_release (struct device * dev )
1388
1448
{
1389
1449
struct rpmsg_device * rpdev = to_rpmsg_device (dev );
1390
- struct glink_channel * channel = to_glink_channel (rpdev -> ept );
1391
1450
1392
- channel -> rpdev = NULL ;
1393
1451
kfree (rpdev );
1394
1452
}
1395
1453
@@ -1440,7 +1498,7 @@ static int qcom_glink_rx_open(struct qcom_glink *glink, unsigned int rcid,
1440
1498
}
1441
1499
1442
1500
rpdev -> ept = & channel -> ept ;
1443
- strncpy (rpdev -> id .name , name , RPMSG_NAME_SIZE );
1501
+ strscpy_pad (rpdev -> id .name , name , RPMSG_NAME_SIZE );
1444
1502
rpdev -> src = RPMSG_ADDR_ANY ;
1445
1503
rpdev -> dst = RPMSG_ADDR_ANY ;
1446
1504
rpdev -> ops = & glink_device_ops ;
@@ -1494,6 +1552,7 @@ static void qcom_glink_rx_close(struct qcom_glink *glink, unsigned int rcid)
1494
1552
1495
1553
rpmsg_unregister_device (glink -> dev , & chinfo );
1496
1554
}
1555
+ channel -> rpdev = NULL ;
1497
1556
1498
1557
qcom_glink_send_close_ack (glink , channel -> rcid );
1499
1558
@@ -1507,9 +1566,13 @@ static void qcom_glink_rx_close(struct qcom_glink *glink, unsigned int rcid)
1507
1566
1508
1567
static void qcom_glink_rx_close_ack (struct qcom_glink * glink , unsigned int lcid )
1509
1568
{
1569
+ struct rpmsg_channel_info chinfo ;
1510
1570
struct glink_channel * channel ;
1511
1571
unsigned long flags ;
1512
1572
1573
+ /* To wakeup any blocking writers */
1574
+ wake_up_all (& glink -> tx_avail_notify );
1575
+
1513
1576
spin_lock_irqsave (& glink -> idr_lock , flags );
1514
1577
channel = idr_find (& glink -> lcids , lcid );
1515
1578
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)
1521
1584
channel -> lcid = 0 ;
1522
1585
spin_unlock_irqrestore (& glink -> idr_lock , flags );
1523
1586
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
+
1524
1597
kref_put (& channel -> refcount , qcom_glink_channel_release );
1525
1598
}
1526
1599
@@ -1670,6 +1743,7 @@ struct qcom_glink *qcom_glink_native_probe(struct device *dev,
1670
1743
spin_lock_init (& glink -> rx_lock );
1671
1744
INIT_LIST_HEAD (& glink -> rx_queue );
1672
1745
INIT_WORK (& glink -> rx_work , qcom_glink_work );
1746
+ init_waitqueue_head (& glink -> tx_avail_notify );
1673
1747
1674
1748
spin_lock_init (& glink -> idr_lock );
1675
1749
idr_init (& glink -> lcids );
0 commit comments