Lines Matching refs:glink
158 struct qcom_glink *glink; member
209 static struct glink_channel *qcom_glink_alloc_channel(struct qcom_glink *glink, in qcom_glink_alloc_channel() argument
223 channel->glink = glink; in qcom_glink_alloc_channel()
255 static size_t qcom_glink_rx_avail(struct qcom_glink *glink) in qcom_glink_rx_avail() argument
257 return glink->rx_pipe->avail(glink->rx_pipe); in qcom_glink_rx_avail()
260 static void qcom_glink_rx_peak(struct qcom_glink *glink, in qcom_glink_rx_peak() argument
263 glink->rx_pipe->peak(glink->rx_pipe, data, offset, count); in qcom_glink_rx_peak()
266 static void qcom_glink_rx_advance(struct qcom_glink *glink, size_t count) in qcom_glink_rx_advance() argument
268 glink->rx_pipe->advance(glink->rx_pipe, count); in qcom_glink_rx_advance()
271 static size_t qcom_glink_tx_avail(struct qcom_glink *glink) in qcom_glink_tx_avail() argument
273 return glink->tx_pipe->avail(glink->tx_pipe); in qcom_glink_tx_avail()
276 static void qcom_glink_tx_write(struct qcom_glink *glink, in qcom_glink_tx_write() argument
280 glink->tx_pipe->write(glink->tx_pipe, hdr, hlen, data, dlen); in qcom_glink_tx_write()
283 static int qcom_glink_tx(struct qcom_glink *glink, in qcom_glink_tx() argument
292 if (tlen >= glink->tx_pipe->length) in qcom_glink_tx()
295 spin_lock_irqsave(&glink->tx_lock, flags); in qcom_glink_tx()
297 while (qcom_glink_tx_avail(glink) < tlen) { in qcom_glink_tx()
304 spin_unlock_irqrestore(&glink->tx_lock, flags); in qcom_glink_tx()
308 spin_lock_irqsave(&glink->tx_lock, flags); in qcom_glink_tx()
311 qcom_glink_tx_write(glink, hdr, hlen, data, dlen); in qcom_glink_tx()
313 mbox_send_message(glink->mbox_chan, NULL); in qcom_glink_tx()
314 mbox_client_txdone(glink->mbox_chan, 0); in qcom_glink_tx()
317 spin_unlock_irqrestore(&glink->tx_lock, flags); in qcom_glink_tx()
322 static int qcom_glink_send_version(struct qcom_glink *glink) in qcom_glink_send_version() argument
328 msg.param2 = cpu_to_le32(glink->features); in qcom_glink_send_version()
330 return qcom_glink_tx(glink, &msg, sizeof(msg), NULL, 0, true); in qcom_glink_send_version()
333 static void qcom_glink_send_version_ack(struct qcom_glink *glink) in qcom_glink_send_version_ack() argument
339 msg.param2 = cpu_to_le32(glink->features); in qcom_glink_send_version_ack()
341 qcom_glink_tx(glink, &msg, sizeof(msg), NULL, 0, true); in qcom_glink_send_version_ack()
344 static void qcom_glink_send_open_ack(struct qcom_glink *glink, in qcom_glink_send_open_ack() argument
353 qcom_glink_tx(glink, &msg, sizeof(msg), NULL, 0, true); in qcom_glink_send_open_ack()
356 static void qcom_glink_handle_intent_req_ack(struct qcom_glink *glink, in qcom_glink_handle_intent_req_ack() argument
362 spin_lock_irqsave(&glink->idr_lock, flags); in qcom_glink_handle_intent_req_ack()
363 channel = idr_find(&glink->rcids, cid); in qcom_glink_handle_intent_req_ack()
364 spin_unlock_irqrestore(&glink->idr_lock, flags); in qcom_glink_handle_intent_req_ack()
366 dev_err(glink->dev, "unable to find channel\n"); in qcom_glink_handle_intent_req_ack()
384 static int qcom_glink_send_open_req(struct qcom_glink *glink, in qcom_glink_send_open_req() argument
398 spin_lock_irqsave(&glink->idr_lock, flags); in qcom_glink_send_open_req()
399 ret = idr_alloc_cyclic(&glink->lcids, channel, in qcom_glink_send_open_req()
402 spin_unlock_irqrestore(&glink->idr_lock, flags); in qcom_glink_send_open_req()
413 ret = qcom_glink_tx(glink, &req, req_len, NULL, 0, true); in qcom_glink_send_open_req()
420 spin_lock_irqsave(&glink->idr_lock, flags); in qcom_glink_send_open_req()
421 idr_remove(&glink->lcids, channel->lcid); in qcom_glink_send_open_req()
423 spin_unlock_irqrestore(&glink->idr_lock, flags); in qcom_glink_send_open_req()
428 static void qcom_glink_send_close_req(struct qcom_glink *glink, in qcom_glink_send_close_req() argument
437 qcom_glink_tx(glink, &req, sizeof(req), NULL, 0, true); in qcom_glink_send_close_req()
440 static void qcom_glink_send_close_ack(struct qcom_glink *glink, in qcom_glink_send_close_ack() argument
449 qcom_glink_tx(glink, &req, sizeof(req), NULL, 0, true); in qcom_glink_send_close_ack()
456 struct qcom_glink *glink = channel->glink; in qcom_glink_rx_done_work() local
480 qcom_glink_tx(glink, &cmd, sizeof(cmd), NULL, 0, true); in qcom_glink_rx_done_work()
490 static void qcom_glink_rx_done(struct qcom_glink *glink, in qcom_glink_rx_done() argument
495 if (glink->intentless) { in qcom_glink_rx_done()
526 static void qcom_glink_receive_version(struct qcom_glink *glink, in qcom_glink_receive_version() argument
534 glink->features &= features; in qcom_glink_receive_version()
537 qcom_glink_send_version_ack(glink); in qcom_glink_receive_version()
553 static void qcom_glink_receive_version_ack(struct qcom_glink *glink, in qcom_glink_receive_version_ack() argument
562 if (features == glink->features) in qcom_glink_receive_version_ack()
565 glink->features &= features; in qcom_glink_receive_version_ack()
568 qcom_glink_send_version(glink); in qcom_glink_receive_version_ack()
582 static int qcom_glink_send_intent_req_ack(struct qcom_glink *glink, in qcom_glink_send_intent_req_ack() argument
592 qcom_glink_tx(glink, &msg, sizeof(msg), NULL, 0, true); in qcom_glink_send_intent_req_ack()
606 static int qcom_glink_advertise_intent(struct qcom_glink *glink, in qcom_glink_advertise_intent() argument
625 qcom_glink_tx(glink, &cmd, sizeof(cmd), NULL, 0, true); in qcom_glink_advertise_intent()
631 qcom_glink_alloc_intent(struct qcom_glink *glink, in qcom_glink_alloc_intent() argument
669 static void qcom_glink_handle_rx_done(struct qcom_glink *glink, in qcom_glink_handle_rx_done() argument
677 spin_lock_irqsave(&glink->idr_lock, flags); in qcom_glink_handle_rx_done()
678 channel = idr_find(&glink->rcids, cid); in qcom_glink_handle_rx_done()
679 spin_unlock_irqrestore(&glink->idr_lock, flags); in qcom_glink_handle_rx_done()
681 dev_err(glink->dev, "invalid channel id received\n"); in qcom_glink_handle_rx_done()
690 dev_err(glink->dev, "invalid intent id received\n"); in qcom_glink_handle_rx_done()
713 static void qcom_glink_handle_intent_req(struct qcom_glink *glink, in qcom_glink_handle_intent_req() argument
720 spin_lock_irqsave(&glink->idr_lock, flags); in qcom_glink_handle_intent_req()
721 channel = idr_find(&glink->rcids, cid); in qcom_glink_handle_intent_req()
722 spin_unlock_irqrestore(&glink->idr_lock, flags); in qcom_glink_handle_intent_req()
729 intent = qcom_glink_alloc_intent(glink, channel, size, false); in qcom_glink_handle_intent_req()
731 qcom_glink_advertise_intent(glink, channel, intent); in qcom_glink_handle_intent_req()
733 qcom_glink_send_intent_req_ack(glink, channel, !!intent); in qcom_glink_handle_intent_req()
736 static int qcom_glink_rx_defer(struct qcom_glink *glink, size_t extra) in qcom_glink_rx_defer() argument
742 if (qcom_glink_rx_avail(glink) < sizeof(struct glink_msg) + extra) { in qcom_glink_rx_defer()
743 dev_dbg(glink->dev, "Insufficient data in rx fifo"); in qcom_glink_rx_defer()
753 qcom_glink_rx_peak(glink, &dcmd->msg, 0, sizeof(dcmd->msg) + extra); in qcom_glink_rx_defer()
755 spin_lock(&glink->rx_lock); in qcom_glink_rx_defer()
756 list_add_tail(&dcmd->node, &glink->rx_queue); in qcom_glink_rx_defer()
757 spin_unlock(&glink->rx_lock); in qcom_glink_rx_defer()
759 schedule_work(&glink->rx_work); in qcom_glink_rx_defer()
760 qcom_glink_rx_advance(glink, sizeof(dcmd->msg) + extra); in qcom_glink_rx_defer()
765 static int qcom_glink_rx_data(struct qcom_glink *glink, size_t avail) in qcom_glink_rx_data() argument
782 dev_dbg(glink->dev, "Not enough data in fifo\n"); in qcom_glink_rx_data()
786 qcom_glink_rx_peak(glink, &hdr, 0, sizeof(hdr)); in qcom_glink_rx_data()
791 dev_dbg(glink->dev, "Payload not yet in fifo\n"); in qcom_glink_rx_data()
796 spin_lock_irqsave(&glink->idr_lock, flags); in qcom_glink_rx_data()
797 channel = idr_find(&glink->rcids, rcid); in qcom_glink_rx_data()
798 spin_unlock_irqrestore(&glink->idr_lock, flags); in qcom_glink_rx_data()
800 dev_dbg(glink->dev, "Data on non-existing channel\n"); in qcom_glink_rx_data()
806 if (glink->intentless) { in qcom_glink_rx_data()
836 dev_err(glink->dev, in qcom_glink_rx_data()
844 dev_err(glink->dev, "Insufficient space in intent\n"); in qcom_glink_rx_data()
850 qcom_glink_rx_peak(glink, intent->data + intent->offset, in qcom_glink_rx_data()
869 qcom_glink_rx_done(glink, channel, intent); in qcom_glink_rx_data()
873 qcom_glink_rx_advance(glink, ALIGN(sizeof(hdr) + chunk_size, 8)); in qcom_glink_rx_data()
878 static void qcom_glink_handle_intent(struct qcom_glink *glink, in qcom_glink_handle_intent() argument
901 dev_dbg(glink->dev, "Not enough data in fifo\n"); in qcom_glink_handle_intent()
905 spin_lock_irqsave(&glink->idr_lock, flags); in qcom_glink_handle_intent()
906 channel = idr_find(&glink->rcids, cid); in qcom_glink_handle_intent()
907 spin_unlock_irqrestore(&glink->idr_lock, flags); in qcom_glink_handle_intent()
909 dev_err(glink->dev, "intents for non-existing channel\n"); in qcom_glink_handle_intent()
917 qcom_glink_rx_peak(glink, msg, 0, msglen); in qcom_glink_handle_intent()
933 dev_err(glink->dev, "failed to store remote intent\n"); in qcom_glink_handle_intent()
937 qcom_glink_rx_advance(glink, ALIGN(msglen, 8)); in qcom_glink_handle_intent()
940 static int qcom_glink_rx_open_ack(struct qcom_glink *glink, unsigned int lcid) in qcom_glink_rx_open_ack() argument
944 spin_lock(&glink->idr_lock); in qcom_glink_rx_open_ack()
945 channel = idr_find(&glink->lcids, lcid); in qcom_glink_rx_open_ack()
946 spin_unlock(&glink->idr_lock); in qcom_glink_rx_open_ack()
948 dev_err(glink->dev, "Invalid open ack packet\n"); in qcom_glink_rx_open_ack()
959 struct qcom_glink *glink = data; in qcom_glink_native_intr() local
968 avail = qcom_glink_rx_avail(glink); in qcom_glink_native_intr()
972 qcom_glink_rx_peak(glink, &msg, 0, sizeof(msg)); in qcom_glink_native_intr()
984 ret = qcom_glink_rx_defer(glink, 0); in qcom_glink_native_intr()
987 ret = qcom_glink_rx_open_ack(glink, param1); in qcom_glink_native_intr()
988 qcom_glink_rx_advance(glink, ALIGN(sizeof(msg), 8)); in qcom_glink_native_intr()
991 ret = qcom_glink_rx_defer(glink, param2); in qcom_glink_native_intr()
995 ret = qcom_glink_rx_data(glink, avail); in qcom_glink_native_intr()
998 qcom_glink_rx_advance(glink, ALIGN(sizeof(msg), 8)); in qcom_glink_native_intr()
1000 mbox_send_message(glink->mbox_chan, NULL); in qcom_glink_native_intr()
1001 mbox_client_txdone(glink->mbox_chan, 0); in qcom_glink_native_intr()
1004 qcom_glink_handle_intent(glink, param1, param2, avail); in qcom_glink_native_intr()
1007 qcom_glink_handle_rx_done(glink, param1, param2, false); in qcom_glink_native_intr()
1008 qcom_glink_rx_advance(glink, ALIGN(sizeof(msg), 8)); in qcom_glink_native_intr()
1011 qcom_glink_handle_rx_done(glink, param1, param2, true); in qcom_glink_native_intr()
1012 qcom_glink_rx_advance(glink, ALIGN(sizeof(msg), 8)); in qcom_glink_native_intr()
1015 qcom_glink_handle_intent_req_ack(glink, param1, param2); in qcom_glink_native_intr()
1016 qcom_glink_rx_advance(glink, ALIGN(sizeof(msg), 8)); in qcom_glink_native_intr()
1019 dev_err(glink->dev, "unhandled rx cmd: %d\n", cmd); in qcom_glink_native_intr()
1032 static struct glink_channel *qcom_glink_create_local(struct qcom_glink *glink, in qcom_glink_create_local() argument
1039 channel = qcom_glink_alloc_channel(glink, name); in qcom_glink_create_local()
1043 ret = qcom_glink_send_open_req(glink, channel); in qcom_glink_create_local()
1055 qcom_glink_send_open_ack(glink, channel); in qcom_glink_create_local()
1061 spin_lock_irqsave(&glink->idr_lock, flags); in qcom_glink_create_local()
1062 idr_remove(&glink->lcids, channel->lcid); in qcom_glink_create_local()
1063 spin_unlock_irqrestore(&glink->idr_lock, flags); in qcom_glink_create_local()
1075 static int qcom_glink_create_remote(struct qcom_glink *glink, in qcom_glink_create_remote() argument
1080 qcom_glink_send_open_ack(glink, channel); in qcom_glink_create_remote()
1082 ret = qcom_glink_send_open_req(glink, channel); in qcom_glink_create_remote()
1099 qcom_glink_send_close_req(glink, channel); in qcom_glink_create_remote()
1115 struct qcom_glink *glink = parent->glink; in qcom_glink_create_ept() local
1122 spin_lock_irqsave(&glink->idr_lock, flags); in qcom_glink_create_ept()
1123 idr_for_each_entry(&glink->rcids, channel, cid) { in qcom_glink_create_ept()
1127 spin_unlock_irqrestore(&glink->idr_lock, flags); in qcom_glink_create_ept()
1130 channel = qcom_glink_create_local(glink, name); in qcom_glink_create_ept()
1134 ret = qcom_glink_create_remote(glink, channel); in qcom_glink_create_ept()
1152 struct qcom_glink *glink = channel->glink; in qcom_glink_announce_create() local
1161 if (glink->intentless) in qcom_glink_announce_create()
1175 intent = qcom_glink_alloc_intent(glink, channel, size, in qcom_glink_announce_create()
1180 qcom_glink_advertise_intent(glink, channel, intent); in qcom_glink_announce_create()
1189 struct qcom_glink *glink = channel->glink; in qcom_glink_destroy_ept() local
1199 qcom_glink_send_close_req(glink, channel); in qcom_glink_destroy_ept()
1202 static int qcom_glink_request_intent(struct qcom_glink *glink, in qcom_glink_request_intent() argument
1222 ret = qcom_glink_tx(glink, &cmd, sizeof(cmd), NULL, 0, true); in qcom_glink_request_intent()
1228 dev_err(glink->dev, "intent request timed out\n"); in qcom_glink_request_intent()
1242 struct qcom_glink *glink = channel->glink; in __qcom_glink_send() local
1254 if (!glink->intentless) { in __qcom_glink_send()
1278 ret = qcom_glink_request_intent(glink, channel, len); in __qcom_glink_send()
1292 ret = qcom_glink_tx(glink, &req, sizeof(req), data, len, wait); in __qcom_glink_send()
1359 static int qcom_glink_rx_open(struct qcom_glink *glink, unsigned int rcid, in qcom_glink_rx_open() argument
1370 spin_lock_irqsave(&glink->idr_lock, flags); in qcom_glink_rx_open()
1371 idr_for_each_entry(&glink->lcids, channel, lcid) { in qcom_glink_rx_open()
1375 spin_unlock_irqrestore(&glink->idr_lock, flags); in qcom_glink_rx_open()
1378 channel = qcom_glink_alloc_channel(glink, name); in qcom_glink_rx_open()
1386 spin_lock_irqsave(&glink->idr_lock, flags); in qcom_glink_rx_open()
1387 ret = idr_alloc(&glink->rcids, channel, rcid, rcid + 1, GFP_ATOMIC); in qcom_glink_rx_open()
1389 dev_err(glink->dev, "Unable to insert channel into rcid list\n"); in qcom_glink_rx_open()
1390 spin_unlock_irqrestore(&glink->idr_lock, flags); in qcom_glink_rx_open()
1394 spin_unlock_irqrestore(&glink->idr_lock, flags); in qcom_glink_rx_open()
1411 node = qcom_glink_match_channel(glink->dev->of_node, name); in qcom_glink_rx_open()
1413 rpdev->dev.parent = glink->dev; in qcom_glink_rx_open()
1428 spin_lock_irqsave(&glink->idr_lock, flags); in qcom_glink_rx_open()
1429 idr_remove(&glink->rcids, channel->rcid); in qcom_glink_rx_open()
1431 spin_unlock_irqrestore(&glink->idr_lock, flags); in qcom_glink_rx_open()
1440 static void qcom_glink_rx_close(struct qcom_glink *glink, unsigned int rcid) in qcom_glink_rx_close() argument
1446 spin_lock_irqsave(&glink->idr_lock, flags); in qcom_glink_rx_close()
1447 channel = idr_find(&glink->rcids, rcid); in qcom_glink_rx_close()
1448 spin_unlock_irqrestore(&glink->idr_lock, flags); in qcom_glink_rx_close()
1460 rpmsg_unregister_device(glink->dev, &chinfo); in qcom_glink_rx_close()
1463 qcom_glink_send_close_ack(glink, channel->rcid); in qcom_glink_rx_close()
1465 spin_lock_irqsave(&glink->idr_lock, flags); in qcom_glink_rx_close()
1466 idr_remove(&glink->rcids, channel->rcid); in qcom_glink_rx_close()
1468 spin_unlock_irqrestore(&glink->idr_lock, flags); in qcom_glink_rx_close()
1473 static void qcom_glink_rx_close_ack(struct qcom_glink *glink, unsigned int lcid) in qcom_glink_rx_close_ack() argument
1478 spin_lock_irqsave(&glink->idr_lock, flags); in qcom_glink_rx_close_ack()
1479 channel = idr_find(&glink->lcids, lcid); in qcom_glink_rx_close_ack()
1481 spin_unlock_irqrestore(&glink->idr_lock, flags); in qcom_glink_rx_close_ack()
1485 idr_remove(&glink->lcids, channel->lcid); in qcom_glink_rx_close_ack()
1487 spin_unlock_irqrestore(&glink->idr_lock, flags); in qcom_glink_rx_close_ack()
1494 struct qcom_glink *glink = container_of(work, struct qcom_glink, in qcom_glink_work() local
1504 spin_lock_irqsave(&glink->rx_lock, flags); in qcom_glink_work()
1505 if (list_empty(&glink->rx_queue)) { in qcom_glink_work()
1506 spin_unlock_irqrestore(&glink->rx_lock, flags); in qcom_glink_work()
1509 dcmd = list_first_entry(&glink->rx_queue, in qcom_glink_work()
1512 spin_unlock_irqrestore(&glink->rx_lock, flags); in qcom_glink_work()
1521 qcom_glink_receive_version(glink, param1, param2); in qcom_glink_work()
1524 qcom_glink_receive_version_ack(glink, param1, param2); in qcom_glink_work()
1527 qcom_glink_rx_open(glink, param1, msg->data); in qcom_glink_work()
1530 qcom_glink_rx_close(glink, param1); in qcom_glink_work()
1533 qcom_glink_rx_close_ack(glink, param1); in qcom_glink_work()
1536 qcom_glink_handle_intent_req(glink, param1, param2); in qcom_glink_work()
1555 struct qcom_glink *glink; in qcom_glink_native_probe() local
1557 glink = devm_kzalloc(dev, sizeof(*glink), GFP_KERNEL); in qcom_glink_native_probe()
1558 if (!glink) in qcom_glink_native_probe()
1561 glink->dev = dev; in qcom_glink_native_probe()
1562 glink->tx_pipe = tx; in qcom_glink_native_probe()
1563 glink->rx_pipe = rx; in qcom_glink_native_probe()
1565 glink->features = features; in qcom_glink_native_probe()
1566 glink->intentless = intentless; in qcom_glink_native_probe()
1568 spin_lock_init(&glink->tx_lock); in qcom_glink_native_probe()
1569 spin_lock_init(&glink->rx_lock); in qcom_glink_native_probe()
1570 INIT_LIST_HEAD(&glink->rx_queue); in qcom_glink_native_probe()
1571 INIT_WORK(&glink->rx_work, qcom_glink_work); in qcom_glink_native_probe()
1573 spin_lock_init(&glink->idr_lock); in qcom_glink_native_probe()
1574 idr_init(&glink->lcids); in qcom_glink_native_probe()
1575 idr_init(&glink->rcids); in qcom_glink_native_probe()
1577 ret = of_property_read_string(dev->of_node, "label", &glink->name); in qcom_glink_native_probe()
1579 glink->name = dev->of_node->name; in qcom_glink_native_probe()
1581 glink->mbox_client.dev = dev; in qcom_glink_native_probe()
1582 glink->mbox_client.knows_txdone = true; in qcom_glink_native_probe()
1583 glink->mbox_chan = mbox_request_channel(&glink->mbox_client, 0); in qcom_glink_native_probe()
1584 if (IS_ERR(glink->mbox_chan)) { in qcom_glink_native_probe()
1585 if (PTR_ERR(glink->mbox_chan) != -EPROBE_DEFER) in qcom_glink_native_probe()
1587 return ERR_CAST(glink->mbox_chan); in qcom_glink_native_probe()
1594 "glink-native", glink); in qcom_glink_native_probe()
1600 glink->irq = irq; in qcom_glink_native_probe()
1602 ret = qcom_glink_send_version(glink); in qcom_glink_native_probe()
1606 return glink; in qcom_glink_native_probe()
1617 void qcom_glink_native_remove(struct qcom_glink *glink) in qcom_glink_native_remove() argument
1624 disable_irq(glink->irq); in qcom_glink_native_remove()
1625 cancel_work_sync(&glink->rx_work); in qcom_glink_native_remove()
1627 ret = device_for_each_child(glink->dev, NULL, qcom_glink_remove_device); in qcom_glink_native_remove()
1629 dev_warn(glink->dev, "Can't remove GLINK devices: %d\n", ret); in qcom_glink_native_remove()
1631 spin_lock_irqsave(&glink->idr_lock, flags); in qcom_glink_native_remove()
1633 idr_for_each_entry(&glink->lcids, channel, cid) in qcom_glink_native_remove()
1636 idr_destroy(&glink->lcids); in qcom_glink_native_remove()
1637 idr_destroy(&glink->rcids); in qcom_glink_native_remove()
1638 spin_unlock_irqrestore(&glink->idr_lock, flags); in qcom_glink_native_remove()
1639 mbox_free_channel(glink->mbox_chan); in qcom_glink_native_remove()
1643 void qcom_glink_native_unregister(struct qcom_glink *glink) in qcom_glink_native_unregister() argument
1645 device_unregister(glink->dev); in qcom_glink_native_unregister()