Lines Matching full:channel
63 * @in_use: To mark if intent is already in use for the channel
82 * @mbox_chan: mailbox channel
91 * @lcids: idr of all channels with a known local channel id
92 * @rcids: idr of all channels with a known remote channel id
133 * struct glink_channel - internal representation of a channel
135 * @ept: rpmsg endpoint this channel is associated with
137 * @refcount: refcount for the channel object
139 * @name: unique channel name/identifier
140 * @lcid: channel id, in local space
141 * @rcid: channel id, in remote space
214 struct glink_channel *channel; in qcom_glink_alloc_channel() local
216 channel = kzalloc(sizeof(*channel), GFP_KERNEL); in qcom_glink_alloc_channel()
217 if (!channel) in qcom_glink_alloc_channel()
221 spin_lock_init(&channel->recv_lock); in qcom_glink_alloc_channel()
222 spin_lock_init(&channel->intent_lock); in qcom_glink_alloc_channel()
223 mutex_init(&channel->intent_req_lock); in qcom_glink_alloc_channel()
225 channel->glink = glink; in qcom_glink_alloc_channel()
226 channel->name = kstrdup(name, GFP_KERNEL); in qcom_glink_alloc_channel()
228 init_completion(&channel->open_req); in qcom_glink_alloc_channel()
229 init_completion(&channel->open_ack); in qcom_glink_alloc_channel()
230 init_completion(&channel->intent_req_comp); in qcom_glink_alloc_channel()
232 INIT_LIST_HEAD(&channel->done_intents); in qcom_glink_alloc_channel()
233 INIT_WORK(&channel->intent_work, qcom_glink_rx_done_work); in qcom_glink_alloc_channel()
235 idr_init(&channel->liids); in qcom_glink_alloc_channel()
236 idr_init(&channel->riids); in qcom_glink_alloc_channel()
237 kref_init(&channel->refcount); in qcom_glink_alloc_channel()
239 return channel; in qcom_glink_alloc_channel()
244 struct glink_channel *channel = container_of(ref, struct glink_channel, in qcom_glink_channel_release() local
252 cancel_work_sync(&channel->intent_work); in qcom_glink_channel_release()
254 spin_lock_irqsave(&channel->intent_lock, flags); in qcom_glink_channel_release()
256 list_for_each_entry_safe(intent, tmp, &channel->done_intents, node) { in qcom_glink_channel_release()
263 idr_for_each_entry(&channel->liids, tmp, iid) { in qcom_glink_channel_release()
267 idr_destroy(&channel->liids); in qcom_glink_channel_release()
269 idr_for_each_entry(&channel->riids, tmp, iid) in qcom_glink_channel_release()
271 idr_destroy(&channel->riids); in qcom_glink_channel_release()
272 spin_unlock_irqrestore(&channel->intent_lock, flags); in qcom_glink_channel_release()
274 kfree(channel->name); in qcom_glink_channel_release()
275 kfree(channel); in qcom_glink_channel_release()
391 struct glink_channel *channel) in qcom_glink_send_open_ack() argument
396 msg.param1 = cpu_to_le16(channel->rcid); in qcom_glink_send_open_ack()
405 struct glink_channel *channel; in qcom_glink_handle_intent_req_ack() local
409 channel = idr_find(&glink->rcids, cid); in qcom_glink_handle_intent_req_ack()
411 if (!channel) { in qcom_glink_handle_intent_req_ack()
412 dev_err(glink->dev, "unable to find channel\n"); in qcom_glink_handle_intent_req_ack()
416 channel->intent_req_result = granted; in qcom_glink_handle_intent_req_ack()
417 complete(&channel->intent_req_comp); in qcom_glink_handle_intent_req_ack()
423 * @channel: Ptr to the channel that the open req is sent
425 * Allocates a local channel id and sends a RPM_CMD_OPEN message to the remote.
431 struct glink_channel *channel) in qcom_glink_send_open_req() argument
437 int name_len = strlen(channel->name) + 1; in qcom_glink_send_open_req()
442 kref_get(&channel->refcount); in qcom_glink_send_open_req()
445 ret = idr_alloc_cyclic(&glink->lcids, channel, in qcom_glink_send_open_req()
452 channel->lcid = ret; in qcom_glink_send_open_req()
455 req.msg.param1 = cpu_to_le16(channel->lcid); in qcom_glink_send_open_req()
457 strcpy(req.name, channel->name); in qcom_glink_send_open_req()
467 idr_remove(&glink->lcids, channel->lcid); in qcom_glink_send_open_req()
468 channel->lcid = 0; in qcom_glink_send_open_req()
475 struct glink_channel *channel) in qcom_glink_send_close_req() argument
480 req.param1 = cpu_to_le16(channel->lcid); in qcom_glink_send_close_req()
500 struct glink_channel *channel = container_of(work, struct glink_channel, in qcom_glink_rx_done_work() local
502 struct qcom_glink *glink = channel->glink; in qcom_glink_rx_done_work()
510 unsigned int cid = channel->lcid; in qcom_glink_rx_done_work()
515 spin_lock_irqsave(&channel->intent_lock, flags); in qcom_glink_rx_done_work()
516 list_for_each_entry_safe(intent, tmp, &channel->done_intents, node) { in qcom_glink_rx_done_work()
518 spin_unlock_irqrestore(&channel->intent_lock, flags); in qcom_glink_rx_done_work()
531 spin_lock_irqsave(&channel->intent_lock, flags); in qcom_glink_rx_done_work()
533 spin_unlock_irqrestore(&channel->intent_lock, flags); in qcom_glink_rx_done_work()
537 struct glink_channel *channel, in qcom_glink_rx_done() argument
549 spin_lock(&channel->intent_lock); in qcom_glink_rx_done()
550 idr_remove(&channel->liids, intent->id); in qcom_glink_rx_done()
551 spin_unlock(&channel->intent_lock); in qcom_glink_rx_done()
555 spin_lock(&channel->intent_lock); in qcom_glink_rx_done()
556 list_add_tail(&intent->node, &channel->done_intents); in qcom_glink_rx_done()
557 spin_unlock(&channel->intent_lock); in qcom_glink_rx_done()
559 schedule_work(&channel->intent_work); in qcom_glink_rx_done()
623 * @channel: The glink channel
629 struct glink_channel *channel, in qcom_glink_send_intent_req_ack() argument
635 msg.param1 = cpu_to_le16(channel->lcid); in qcom_glink_send_intent_req_ack()
647 * @channel: The local channel
653 struct glink_channel *channel, in qcom_glink_advertise_intent() argument
666 cmd.lcid = cpu_to_le16(channel->lcid); in qcom_glink_advertise_intent()
678 struct glink_channel *channel, in qcom_glink_alloc_intent() argument
694 spin_lock_irqsave(&channel->intent_lock, flags); in qcom_glink_alloc_intent()
695 ret = idr_alloc_cyclic(&channel->liids, intent, 1, -1, GFP_ATOMIC); in qcom_glink_alloc_intent()
697 spin_unlock_irqrestore(&channel->intent_lock, flags); in qcom_glink_alloc_intent()
700 spin_unlock_irqrestore(&channel->intent_lock, flags); in qcom_glink_alloc_intent()
720 struct glink_channel *channel; in qcom_glink_handle_rx_done() local
724 channel = idr_find(&glink->rcids, cid); in qcom_glink_handle_rx_done()
726 if (!channel) { in qcom_glink_handle_rx_done()
727 dev_err(glink->dev, "invalid channel id received\n"); in qcom_glink_handle_rx_done()
731 spin_lock_irqsave(&channel->intent_lock, flags); in qcom_glink_handle_rx_done()
732 intent = idr_find(&channel->riids, iid); in qcom_glink_handle_rx_done()
735 spin_unlock_irqrestore(&channel->intent_lock, flags); in qcom_glink_handle_rx_done()
743 idr_remove(&channel->riids, intent->id); in qcom_glink_handle_rx_done()
746 spin_unlock_irqrestore(&channel->intent_lock, flags); in qcom_glink_handle_rx_done()
753 * @cid: Remote channel ID
756 * The function searches for the local channel to which the request for
763 struct glink_channel *channel; in qcom_glink_handle_intent_req() local
767 channel = idr_find(&glink->rcids, cid); in qcom_glink_handle_intent_req()
770 if (!channel) { in qcom_glink_handle_intent_req()
771 pr_err("%s channel not found for cid %d\n", __func__, cid); in qcom_glink_handle_intent_req()
775 intent = qcom_glink_alloc_intent(glink, channel, size, false); in qcom_glink_handle_intent_req()
777 qcom_glink_advertise_intent(glink, channel, intent); in qcom_glink_handle_intent_req()
779 qcom_glink_send_intent_req_ack(glink, channel, !!intent); in qcom_glink_handle_intent_req()
814 struct glink_channel *channel; in qcom_glink_rx_data() local
843 channel = idr_find(&glink->rcids, rcid); in qcom_glink_rx_data()
845 if (!channel) { in qcom_glink_rx_data()
846 dev_dbg(glink->dev, "Data on non-existing channel\n"); in qcom_glink_rx_data()
854 if (!channel->buf) { in qcom_glink_rx_data()
870 channel->buf = intent; in qcom_glink_rx_data()
872 intent = channel->buf; in qcom_glink_rx_data()
877 spin_lock_irqsave(&channel->intent_lock, flags); in qcom_glink_rx_data()
878 intent = idr_find(&channel->liids, liid); in qcom_glink_rx_data()
879 spin_unlock_irqrestore(&channel->intent_lock, flags); in qcom_glink_rx_data()
883 "no intent found for channel %s intent %d", in qcom_glink_rx_data()
884 channel->name, liid); in qcom_glink_rx_data()
903 spin_lock(&channel->recv_lock); in qcom_glink_rx_data()
904 if (channel->ept.cb) { in qcom_glink_rx_data()
905 channel->ept.cb(channel->ept.rpdev, in qcom_glink_rx_data()
908 channel->ept.priv, in qcom_glink_rx_data()
911 spin_unlock(&channel->recv_lock); in qcom_glink_rx_data()
914 channel->buf = NULL; in qcom_glink_rx_data()
916 qcom_glink_rx_done(glink, channel, intent); in qcom_glink_rx_data()
931 struct glink_channel *channel; in qcom_glink_handle_intent() local
953 channel = idr_find(&glink->rcids, cid); in qcom_glink_handle_intent()
955 if (!channel) { in qcom_glink_handle_intent()
956 dev_err(glink->dev, "intents for non-existing channel\n"); in qcom_glink_handle_intent()
974 spin_lock_irqsave(&channel->intent_lock, flags); in qcom_glink_handle_intent()
975 ret = idr_alloc(&channel->riids, intent, in qcom_glink_handle_intent()
977 spin_unlock_irqrestore(&channel->intent_lock, flags); in qcom_glink_handle_intent()
989 struct glink_channel *channel; in qcom_glink_rx_open_ack() local
992 channel = idr_find(&glink->lcids, lcid); in qcom_glink_rx_open_ack()
994 if (!channel) { in qcom_glink_rx_open_ack()
999 complete_all(&channel->open_ack); in qcom_glink_rx_open_ack()
1085 struct glink_channel *channel; in qcom_glink_create_local() local
1089 channel = qcom_glink_alloc_channel(glink, name); in qcom_glink_create_local()
1090 if (IS_ERR(channel)) in qcom_glink_create_local()
1091 return ERR_CAST(channel); in qcom_glink_create_local()
1093 ret = qcom_glink_send_open_req(glink, channel); in qcom_glink_create_local()
1097 ret = wait_for_completion_timeout(&channel->open_ack, 5 * HZ); in qcom_glink_create_local()
1101 ret = wait_for_completion_timeout(&channel->open_req, 5 * HZ); in qcom_glink_create_local()
1105 qcom_glink_send_open_ack(glink, channel); in qcom_glink_create_local()
1107 return channel; in qcom_glink_create_local()
1110 /* qcom_glink_send_open_req() did register the channel in lcids*/ in qcom_glink_create_local()
1112 idr_remove(&glink->lcids, channel->lcid); in qcom_glink_create_local()
1117 kref_put(&channel->refcount, qcom_glink_channel_release); in qcom_glink_create_local()
1119 kref_put(&channel->refcount, qcom_glink_channel_release); in qcom_glink_create_local()
1126 struct glink_channel *channel) in qcom_glink_create_remote() argument
1130 qcom_glink_send_open_ack(glink, channel); in qcom_glink_create_remote()
1132 ret = qcom_glink_send_open_req(glink, channel); in qcom_glink_create_remote()
1136 ret = wait_for_completion_timeout(&channel->open_ack, 5 * HZ); in qcom_glink_create_remote()
1151 qcom_glink_send_close_req(glink, channel); in qcom_glink_create_remote()
1163 struct glink_channel *channel; in qcom_glink_create_ept() local
1172 idr_for_each_entry(&glink->rcids, channel, cid) { in qcom_glink_create_ept()
1173 if (!strcmp(channel->name, name)) in qcom_glink_create_ept()
1178 if (!channel) { in qcom_glink_create_ept()
1179 channel = qcom_glink_create_local(glink, name); in qcom_glink_create_ept()
1180 if (IS_ERR(channel)) in qcom_glink_create_ept()
1183 ret = qcom_glink_create_remote(glink, channel); in qcom_glink_create_ept()
1188 ept = &channel->ept; in qcom_glink_create_ept()
1199 struct glink_channel *channel = to_glink_channel(rpdev->ept); in qcom_glink_announce_create() local
1201 struct qcom_glink *glink = channel->glink; in qcom_glink_announce_create()
1210 if (glink->intentless || !completion_done(&channel->open_ack)) in qcom_glink_announce_create()
1219 /* Channel is now open, advertise base set of intents */ in qcom_glink_announce_create()
1224 intent = qcom_glink_alloc_intent(glink, channel, size, in qcom_glink_announce_create()
1229 qcom_glink_advertise_intent(glink, channel, intent); in qcom_glink_announce_create()
1237 struct glink_channel *channel = to_glink_channel(ept); in qcom_glink_destroy_ept() local
1238 struct qcom_glink *glink = channel->glink; in qcom_glink_destroy_ept()
1241 spin_lock_irqsave(&channel->recv_lock, flags); in qcom_glink_destroy_ept()
1242 channel->ept.cb = NULL; in qcom_glink_destroy_ept()
1243 spin_unlock_irqrestore(&channel->recv_lock, flags); in qcom_glink_destroy_ept()
1245 /* Decouple the potential rpdev from the channel */ in qcom_glink_destroy_ept()
1246 channel->rpdev = NULL; in qcom_glink_destroy_ept()
1248 qcom_glink_send_close_req(glink, channel); in qcom_glink_destroy_ept()
1252 struct glink_channel *channel, in qcom_glink_request_intent() argument
1263 mutex_lock(&channel->intent_req_lock); in qcom_glink_request_intent()
1265 reinit_completion(&channel->intent_req_comp); in qcom_glink_request_intent()
1268 cmd.cid = channel->lcid; in qcom_glink_request_intent()
1275 ret = wait_for_completion_timeout(&channel->intent_req_comp, 10 * HZ); in qcom_glink_request_intent()
1280 ret = channel->intent_req_result ? 0 : -ECANCELED; in qcom_glink_request_intent()
1284 mutex_unlock(&channel->intent_req_lock); in qcom_glink_request_intent()
1288 static int __qcom_glink_send(struct glink_channel *channel, in __qcom_glink_send() argument
1291 struct qcom_glink *glink = channel->glink; in __qcom_glink_send()
1307 spin_lock_irqsave(&channel->intent_lock, flags); in __qcom_glink_send()
1308 idr_for_each_entry(&channel->riids, tmp, iid) { in __qcom_glink_send()
1320 spin_unlock_irqrestore(&channel->intent_lock, flags); in __qcom_glink_send()
1329 ret = qcom_glink_request_intent(glink, channel, len); in __qcom_glink_send()
1342 req.msg.param1 = cpu_to_le16(channel->lcid); in __qcom_glink_send()
1363 req.msg.param1 = cpu_to_le16(channel->lcid); in __qcom_glink_send()
1382 struct glink_channel *channel = to_glink_channel(ept); in qcom_glink_send() local
1384 return __qcom_glink_send(channel, data, len, true); in qcom_glink_send()
1389 struct glink_channel *channel = to_glink_channel(ept); in qcom_glink_trysend() local
1391 return __qcom_glink_send(channel, data, len, false); in qcom_glink_trysend()
1396 struct glink_channel *channel = to_glink_channel(ept); in qcom_glink_sendto() local
1398 return __qcom_glink_send(channel, data, len, true); in qcom_glink_sendto()
1403 struct glink_channel *channel = to_glink_channel(ept); in qcom_glink_trysendto() local
1405 return __qcom_glink_send(channel, data, len, false); in qcom_glink_trysendto()
1409 * Finds the device_node for the glink child interested in this channel.
1412 const char *channel) in qcom_glink_match_channel() argument
1425 if (strcmp(name, channel) == 0) in qcom_glink_match_channel()
1455 struct glink_channel *channel; in qcom_glink_rx_open() local
1464 idr_for_each_entry(&glink->lcids, channel, lcid) { in qcom_glink_rx_open()
1465 if (!strcmp(channel->name, name)) in qcom_glink_rx_open()
1470 if (!channel) { in qcom_glink_rx_open()
1471 channel = qcom_glink_alloc_channel(glink, name); in qcom_glink_rx_open()
1472 if (IS_ERR(channel)) in qcom_glink_rx_open()
1473 return PTR_ERR(channel); in qcom_glink_rx_open()
1480 ret = idr_alloc(&glink->rcids, channel, rcid, rcid + 1, GFP_ATOMIC); in qcom_glink_rx_open()
1482 dev_err(glink->dev, "Unable to insert channel into rcid list\n"); in qcom_glink_rx_open()
1486 channel->rcid = ret; in qcom_glink_rx_open()
1489 complete_all(&channel->open_req); in qcom_glink_rx_open()
1498 rpdev->ept = &channel->ept; in qcom_glink_rx_open()
1513 channel->rpdev = rpdev; in qcom_glink_rx_open()
1520 idr_remove(&glink->rcids, channel->rcid); in qcom_glink_rx_open()
1521 channel->rcid = 0; in qcom_glink_rx_open()
1526 kref_put(&channel->refcount, qcom_glink_channel_release); in qcom_glink_rx_open()
1534 struct glink_channel *channel; in qcom_glink_rx_close() local
1538 channel = idr_find(&glink->rcids, rcid); in qcom_glink_rx_close()
1540 if (WARN(!channel, "close request on unknown channel\n")) in qcom_glink_rx_close()
1544 cancel_work_sync(&channel->intent_work); in qcom_glink_rx_close()
1546 if (channel->rpdev) { in qcom_glink_rx_close()
1547 strscpy_pad(chinfo.name, channel->name, sizeof(chinfo.name)); in qcom_glink_rx_close()
1553 channel->rpdev = NULL; in qcom_glink_rx_close()
1555 qcom_glink_send_close_ack(glink, channel->rcid); in qcom_glink_rx_close()
1558 idr_remove(&glink->rcids, channel->rcid); in qcom_glink_rx_close()
1559 channel->rcid = 0; in qcom_glink_rx_close()
1562 kref_put(&channel->refcount, qcom_glink_channel_release); in qcom_glink_rx_close()
1568 struct glink_channel *channel; in qcom_glink_rx_close_ack() local
1575 channel = idr_find(&glink->lcids, lcid); in qcom_glink_rx_close_ack()
1576 if (WARN(!channel, "close ack on unknown channel\n")) { in qcom_glink_rx_close_ack()
1581 idr_remove(&glink->lcids, channel->lcid); in qcom_glink_rx_close_ack()
1582 channel->lcid = 0; in qcom_glink_rx_close_ack()
1585 /* Decouple the potential rpdev from the channel */ in qcom_glink_rx_close_ack()
1586 if (channel->rpdev) { in qcom_glink_rx_close_ack()
1587 strscpy(chinfo.name, channel->name, sizeof(chinfo.name)); in qcom_glink_rx_close_ack()
1593 channel->rpdev = NULL; in qcom_glink_rx_close_ack()
1595 kref_put(&channel->refcount, qcom_glink_channel_release); in qcom_glink_rx_close_ack()
1688 struct glink_channel *channel = to_glink_channel(rpdev->ept); in qcom_glink_device_release() local
1691 kref_put(&channel->refcount, qcom_glink_channel_release); in qcom_glink_device_release()
1698 struct glink_channel *channel; in qcom_glink_create_chrdev() local
1704 channel = qcom_glink_alloc_channel(glink, "rpmsg_chrdev"); in qcom_glink_create_chrdev()
1705 if (IS_ERR(channel)) { in qcom_glink_create_chrdev()
1707 return PTR_ERR(channel); in qcom_glink_create_chrdev()
1709 channel->rpdev = rpdev; in qcom_glink_create_chrdev()
1711 rpdev->ept = &channel->ept; in qcom_glink_create_chrdev()
1761 dev_err(dev, "failed to acquire IPC channel\n"); in qcom_glink_native_probe()
1798 struct glink_channel *channel; in qcom_glink_native_remove() local
1810 idr_for_each_entry(&glink->lcids, channel, cid) in qcom_glink_native_remove()
1811 kref_put(&channel->refcount, qcom_glink_channel_release); in qcom_glink_native_remove()
1814 idr_for_each_entry(&glink->rcids, channel, cid) in qcom_glink_native_remove()
1815 kref_put(&channel->refcount, qcom_glink_channel_release); in qcom_glink_native_remove()