Lines Matching full:glink
89 * @label: identifier of the glink edge
142 * @glink: qcom_glink context handle
167 struct qcom_glink *glink; member
225 static struct glink_channel *qcom_glink_alloc_channel(struct qcom_glink *glink, in qcom_glink_alloc_channel() argument
234 /* Setup glink internal glink_channel data */ in qcom_glink_alloc_channel()
239 channel->glink = glink; in qcom_glink_alloc_channel()
296 static size_t qcom_glink_rx_avail(struct qcom_glink *glink) in qcom_glink_rx_avail() argument
298 return glink->rx_pipe->avail(glink->rx_pipe); in qcom_glink_rx_avail()
301 static void qcom_glink_rx_peek(struct qcom_glink *glink, in qcom_glink_rx_peek() argument
304 glink->rx_pipe->peek(glink->rx_pipe, data, offset, count); in qcom_glink_rx_peek()
307 static void qcom_glink_rx_advance(struct qcom_glink *glink, size_t count) in qcom_glink_rx_advance() argument
309 glink->rx_pipe->advance(glink->rx_pipe, count); in qcom_glink_rx_advance()
312 static size_t qcom_glink_tx_avail(struct qcom_glink *glink) in qcom_glink_tx_avail() argument
314 return glink->tx_pipe->avail(glink->tx_pipe); in qcom_glink_tx_avail()
317 static void qcom_glink_tx_write(struct qcom_glink *glink, in qcom_glink_tx_write() argument
321 glink->tx_pipe->write(glink->tx_pipe, hdr, hlen, data, dlen); in qcom_glink_tx_write()
324 static void qcom_glink_tx_kick(struct qcom_glink *glink) in qcom_glink_tx_kick() argument
326 glink->tx_pipe->kick(glink->tx_pipe); in qcom_glink_tx_kick()
329 static void qcom_glink_send_read_notify(struct qcom_glink *glink) in qcom_glink_send_read_notify() argument
337 qcom_glink_tx_write(glink, &msg, sizeof(msg), NULL, 0); in qcom_glink_send_read_notify()
339 qcom_glink_tx_kick(glink); in qcom_glink_send_read_notify()
342 static int qcom_glink_tx(struct qcom_glink *glink, in qcom_glink_tx() argument
351 if (tlen >= glink->tx_pipe->length) in qcom_glink_tx()
354 spin_lock_irqsave(&glink->tx_lock, flags); in qcom_glink_tx()
356 if (glink->abort_tx) { in qcom_glink_tx()
361 while (qcom_glink_tx_avail(glink) < tlen) { in qcom_glink_tx()
367 if (glink->abort_tx) { in qcom_glink_tx()
372 if (!glink->sent_read_notify) { in qcom_glink_tx()
373 glink->sent_read_notify = true; in qcom_glink_tx()
374 qcom_glink_send_read_notify(glink); in qcom_glink_tx()
378 spin_unlock_irqrestore(&glink->tx_lock, flags); in qcom_glink_tx()
380 wait_event_timeout(glink->tx_avail_notify, in qcom_glink_tx()
381 qcom_glink_tx_avail(glink) >= tlen, 10 * HZ); in qcom_glink_tx()
383 spin_lock_irqsave(&glink->tx_lock, flags); in qcom_glink_tx()
385 if (qcom_glink_tx_avail(glink) >= tlen) in qcom_glink_tx()
386 glink->sent_read_notify = false; in qcom_glink_tx()
389 qcom_glink_tx_write(glink, hdr, hlen, data, dlen); in qcom_glink_tx()
390 qcom_glink_tx_kick(glink); in qcom_glink_tx()
393 spin_unlock_irqrestore(&glink->tx_lock, flags); in qcom_glink_tx()
398 static int qcom_glink_send_version(struct qcom_glink *glink) in qcom_glink_send_version() argument
404 msg.param2 = cpu_to_le32(glink->features); in qcom_glink_send_version()
406 trace_qcom_glink_cmd_version_tx(glink->label, GLINK_VERSION_1, glink->features); in qcom_glink_send_version()
408 return qcom_glink_tx(glink, &msg, sizeof(msg), NULL, 0, true); in qcom_glink_send_version()
411 static void qcom_glink_send_version_ack(struct qcom_glink *glink) in qcom_glink_send_version_ack() argument
417 msg.param2 = cpu_to_le32(glink->features); in qcom_glink_send_version_ack()
419 trace_qcom_glink_cmd_version_ack_tx(glink->label, msg.param1, msg.param2); in qcom_glink_send_version_ack()
421 qcom_glink_tx(glink, &msg, sizeof(msg), NULL, 0, true); in qcom_glink_send_version_ack()
424 static void qcom_glink_send_open_ack(struct qcom_glink *glink, in qcom_glink_send_open_ack() argument
433 trace_qcom_glink_cmd_open_ack_tx(glink->label, channel->name, in qcom_glink_send_open_ack()
436 qcom_glink_tx(glink, &msg, sizeof(msg), NULL, 0, true); in qcom_glink_send_open_ack()
439 static void qcom_glink_handle_intent_req_ack(struct qcom_glink *glink, in qcom_glink_handle_intent_req_ack() argument
445 qcom_glink_rx_advance(glink, ALIGN(sizeof(struct glink_msg), 8)); in qcom_glink_handle_intent_req_ack()
447 spin_lock_irqsave(&glink->idr_lock, flags); in qcom_glink_handle_intent_req_ack()
448 channel = idr_find(&glink->rcids, cid); in qcom_glink_handle_intent_req_ack()
449 spin_unlock_irqrestore(&glink->idr_lock, flags); in qcom_glink_handle_intent_req_ack()
451 trace_qcom_glink_cmd_rx_intent_req_ack_rx(glink->label, in qcom_glink_handle_intent_req_ack()
456 dev_err(glink->dev, "unable to find channel\n"); in qcom_glink_handle_intent_req_ack()
472 * @glink: Ptr to the glink edge
480 static int qcom_glink_send_open_req(struct qcom_glink *glink, in qcom_glink_send_open_req() argument
491 spin_lock_irqsave(&glink->idr_lock, flags); in qcom_glink_send_open_req()
492 ret = idr_alloc_cyclic(&glink->lcids, channel, in qcom_glink_send_open_req()
495 spin_unlock_irqrestore(&glink->idr_lock, flags); in qcom_glink_send_open_req()
506 trace_qcom_glink_cmd_open_tx(glink->label, channel->name, in qcom_glink_send_open_req()
509 ret = qcom_glink_tx(glink, req, req_len, NULL, 0, true); in qcom_glink_send_open_req()
516 spin_lock_irqsave(&glink->idr_lock, flags); in qcom_glink_send_open_req()
517 idr_remove(&glink->lcids, channel->lcid); in qcom_glink_send_open_req()
519 spin_unlock_irqrestore(&glink->idr_lock, flags); in qcom_glink_send_open_req()
524 static void qcom_glink_send_close_req(struct qcom_glink *glink, in qcom_glink_send_close_req() argument
533 trace_qcom_glink_cmd_close_tx(glink->label, channel->name, in qcom_glink_send_close_req()
536 qcom_glink_tx(glink, &req, sizeof(req), NULL, 0, true); in qcom_glink_send_close_req()
539 static void qcom_glink_send_close_ack(struct qcom_glink *glink, in qcom_glink_send_close_ack() argument
548 trace_qcom_glink_cmd_close_ack_tx(glink->label, channel->name, in qcom_glink_send_close_ack()
551 qcom_glink_tx(glink, &req, sizeof(req), NULL, 0, true); in qcom_glink_send_close_ack()
558 struct qcom_glink *glink = channel->glink; in qcom_glink_rx_done_work() local
582 trace_qcom_glink_cmd_rx_done_tx(glink->label, channel->name, in qcom_glink_rx_done_work()
585 qcom_glink_tx(glink, &cmd, sizeof(cmd), NULL, 0, true); in qcom_glink_rx_done_work()
595 static void qcom_glink_rx_done(struct qcom_glink *glink, in qcom_glink_rx_done() argument
600 if (glink->intentless) { in qcom_glink_rx_done()
624 * @glink: pointer to transport interface
631 static void qcom_glink_receive_version(struct qcom_glink *glink, in qcom_glink_receive_version() argument
635 trace_qcom_glink_cmd_version_rx(glink->label, version, features); in qcom_glink_receive_version()
641 glink->features &= features; in qcom_glink_receive_version()
644 qcom_glink_send_version_ack(glink); in qcom_glink_receive_version()
652 * @glink: pointer to transport interface
660 static void qcom_glink_receive_version_ack(struct qcom_glink *glink, in qcom_glink_receive_version_ack() argument
664 trace_qcom_glink_cmd_version_ack_rx(glink->label, version, features); in qcom_glink_receive_version_ack()
671 if (features == glink->features) in qcom_glink_receive_version_ack()
674 glink->features &= features; in qcom_glink_receive_version_ack()
677 qcom_glink_send_version(glink); in qcom_glink_receive_version_ack()
685 * @glink: The transport to transmit on.
686 * @channel: The glink channel
691 static int qcom_glink_send_intent_req_ack(struct qcom_glink *glink, in qcom_glink_send_intent_req_ack() argument
697 trace_qcom_glink_cmd_rx_intent_req_ack_tx(glink->label, channel->name, in qcom_glink_send_intent_req_ack()
705 qcom_glink_tx(glink, &msg, sizeof(msg), NULL, 0, true); in qcom_glink_send_intent_req_ack()
713 * @glink: The transport to transmit on.
719 static int qcom_glink_advertise_intent(struct qcom_glink *glink, in qcom_glink_advertise_intent() argument
738 trace_qcom_glink_cmd_intent_tx(glink->label, channel->name, in qcom_glink_advertise_intent()
742 qcom_glink_tx(glink, &cmd, sizeof(cmd), NULL, 0, true); in qcom_glink_advertise_intent()
748 qcom_glink_alloc_intent(struct qcom_glink *glink, in qcom_glink_alloc_intent() argument
786 static void qcom_glink_handle_rx_done(struct qcom_glink *glink, in qcom_glink_handle_rx_done() argument
794 qcom_glink_rx_advance(glink, ALIGN(sizeof(struct glink_msg), 8)); in qcom_glink_handle_rx_done()
796 spin_lock_irqsave(&glink->idr_lock, flags); in qcom_glink_handle_rx_done()
797 channel = idr_find(&glink->rcids, cid); in qcom_glink_handle_rx_done()
798 spin_unlock_irqrestore(&glink->idr_lock, flags); in qcom_glink_handle_rx_done()
800 trace_qcom_glink_cmd_rx_done_rx(glink->label, channel ? channel->name : NULL, in qcom_glink_handle_rx_done()
803 dev_err(glink->dev, "invalid channel id received\n"); in qcom_glink_handle_rx_done()
812 dev_err(glink->dev, "invalid intent id received\n"); in qcom_glink_handle_rx_done()
833 * @glink: Pointer to the transport interface
840 static void qcom_glink_handle_intent_req(struct qcom_glink *glink, in qcom_glink_handle_intent_req() argument
847 spin_lock_irqsave(&glink->idr_lock, flags); in qcom_glink_handle_intent_req()
848 channel = idr_find(&glink->rcids, cid); in qcom_glink_handle_intent_req()
849 spin_unlock_irqrestore(&glink->idr_lock, flags); in qcom_glink_handle_intent_req()
851 trace_qcom_glink_cmd_rx_intent_req_rx(glink->label, in qcom_glink_handle_intent_req()
860 intent = qcom_glink_alloc_intent(glink, channel, size, false); in qcom_glink_handle_intent_req()
862 qcom_glink_advertise_intent(glink, channel, intent); in qcom_glink_handle_intent_req()
864 qcom_glink_send_intent_req_ack(glink, channel, !!intent); in qcom_glink_handle_intent_req()
867 static int qcom_glink_rx_defer(struct qcom_glink *glink, size_t extra) in qcom_glink_rx_defer() argument
873 if (qcom_glink_rx_avail(glink) < sizeof(struct glink_msg) + extra) { in qcom_glink_rx_defer()
874 dev_dbg(glink->dev, "Insufficient data in rx fifo"); in qcom_glink_rx_defer()
884 qcom_glink_rx_peek(glink, in qcom_glink_rx_defer()
888 spin_lock(&glink->rx_lock); in qcom_glink_rx_defer()
889 list_add_tail(&dcmd->node, &glink->rx_queue); in qcom_glink_rx_defer()
890 spin_unlock(&glink->rx_lock); in qcom_glink_rx_defer()
892 schedule_work(&glink->rx_work); in qcom_glink_rx_defer()
893 qcom_glink_rx_advance(glink, sizeof(dcmd->msg) + extra); in qcom_glink_rx_defer()
898 static int qcom_glink_rx_data(struct qcom_glink *glink, size_t avail) in qcom_glink_rx_data() argument
915 dev_dbg(glink->dev, "Not enough data in fifo\n"); in qcom_glink_rx_data()
919 qcom_glink_rx_peek(glink, &hdr, 0, sizeof(hdr)); in qcom_glink_rx_data()
924 dev_dbg(glink->dev, "Payload not yet in fifo\n"); in qcom_glink_rx_data()
930 spin_lock_irqsave(&glink->idr_lock, flags); in qcom_glink_rx_data()
931 channel = idr_find(&glink->rcids, rcid); in qcom_glink_rx_data()
932 spin_unlock_irqrestore(&glink->idr_lock, flags); in qcom_glink_rx_data()
934 trace_qcom_glink_cmd_tx_data_rx(glink->label, channel ? channel->name : NULL, in qcom_glink_rx_data()
939 dev_dbg(glink->dev, "Data on non-existing channel\n"); in qcom_glink_rx_data()
945 if (glink->intentless) { in qcom_glink_rx_data()
973 dev_err(glink->dev, in qcom_glink_rx_data()
982 dev_err(glink->dev, "Insufficient space in intent\n"); in qcom_glink_rx_data()
988 qcom_glink_rx_peek(glink, intent->data + intent->offset, in qcom_glink_rx_data()
1007 qcom_glink_rx_done(glink, channel, intent); in qcom_glink_rx_data()
1011 qcom_glink_rx_advance(glink, ALIGN(sizeof(hdr) + chunk_size, 8)); in qcom_glink_rx_data()
1016 static void qcom_glink_rx_read_notif(struct qcom_glink *glink) in qcom_glink_rx_read_notif() argument
1018 trace_qcom_glink_cmd_read_notif_rx(glink->label); in qcom_glink_rx_read_notif()
1020 qcom_glink_rx_advance(glink, ALIGN(sizeof(struct glink_msg), 8)); in qcom_glink_rx_read_notif()
1021 qcom_glink_tx_kick(glink); in qcom_glink_rx_read_notif()
1024 static void qcom_glink_handle_intent(struct qcom_glink *glink, in qcom_glink_handle_intent() argument
1047 dev_dbg(glink->dev, "Not enough data in fifo\n"); in qcom_glink_handle_intent()
1051 spin_lock_irqsave(&glink->idr_lock, flags); in qcom_glink_handle_intent()
1052 channel = idr_find(&glink->rcids, cid); in qcom_glink_handle_intent()
1053 spin_unlock_irqrestore(&glink->idr_lock, flags); in qcom_glink_handle_intent()
1055 trace_qcom_glink_cmd_intent_rx(glink->label, NULL, 0, cid, count, 0, 0); in qcom_glink_handle_intent()
1056 dev_err(glink->dev, "intents for non-existing channel\n"); in qcom_glink_handle_intent()
1057 qcom_glink_rx_advance(glink, ALIGN(msglen, 8)); in qcom_glink_handle_intent()
1065 qcom_glink_rx_peek(glink, msg, 0, msglen); in qcom_glink_handle_intent()
1067 trace_qcom_glink_cmd_intent_rx(glink->label, channel->name, in qcom_glink_handle_intent()
1086 dev_err(glink->dev, "failed to store remote intent\n"); in qcom_glink_handle_intent()
1093 qcom_glink_rx_advance(glink, ALIGN(msglen, 8)); in qcom_glink_handle_intent()
1096 static int qcom_glink_rx_open_ack(struct qcom_glink *glink, unsigned int lcid) in qcom_glink_rx_open_ack() argument
1100 qcom_glink_rx_advance(glink, ALIGN(sizeof(struct glink_msg), 8)); in qcom_glink_rx_open_ack()
1102 spin_lock(&glink->idr_lock); in qcom_glink_rx_open_ack()
1103 channel = idr_find(&glink->lcids, lcid); in qcom_glink_rx_open_ack()
1104 spin_unlock(&glink->idr_lock); in qcom_glink_rx_open_ack()
1106 trace_qcom_glink_cmd_open_ack_rx(glink->label, channel ? channel->name : NULL, in qcom_glink_rx_open_ack()
1109 dev_err(glink->dev, "Invalid open ack packet\n"); in qcom_glink_rx_open_ack()
1129 struct qcom_glink *glink = channel->glink; in qcom_glink_set_flow_control() local
1140 trace_qcom_glink_cmd_signal_tx(glink->label, channel->name, in qcom_glink_set_flow_control()
1143 return qcom_glink_tx(glink, &msg, sizeof(msg), NULL, 0, true); in qcom_glink_set_flow_control()
1146 static void qcom_glink_handle_signals(struct qcom_glink *glink, in qcom_glink_handle_signals() argument
1153 qcom_glink_rx_advance(glink, ALIGN(sizeof(struct glink_msg), 8)); in qcom_glink_handle_signals()
1155 spin_lock_irqsave(&glink->idr_lock, flags); in qcom_glink_handle_signals()
1156 channel = idr_find(&glink->rcids, rcid); in qcom_glink_handle_signals()
1157 spin_unlock_irqrestore(&glink->idr_lock, flags); in qcom_glink_handle_signals()
1159 trace_qcom_glink_cmd_signal_rx(glink->label, channel ? channel->name : NULL, in qcom_glink_handle_signals()
1162 dev_err(glink->dev, "signal for non-existing channel\n"); in qcom_glink_handle_signals()
1172 void qcom_glink_native_rx(struct qcom_glink *glink) in qcom_glink_native_rx() argument
1182 wake_up_all(&glink->tx_avail_notify); in qcom_glink_native_rx()
1185 avail = qcom_glink_rx_avail(glink); in qcom_glink_native_rx()
1189 qcom_glink_rx_peek(glink, &msg, 0, sizeof(msg)); in qcom_glink_native_rx()
1201 ret = qcom_glink_rx_defer(glink, 0); in qcom_glink_native_rx()
1204 ret = qcom_glink_rx_open_ack(glink, param1); in qcom_glink_native_rx()
1208 ret = qcom_glink_rx_defer(glink, param2 & 0xffff); in qcom_glink_native_rx()
1212 ret = qcom_glink_rx_data(glink, avail); in qcom_glink_native_rx()
1215 qcom_glink_rx_read_notif(glink); in qcom_glink_native_rx()
1218 qcom_glink_handle_intent(glink, param1, param2, avail); in qcom_glink_native_rx()
1221 qcom_glink_handle_rx_done(glink, param1, param2, false); in qcom_glink_native_rx()
1224 qcom_glink_handle_rx_done(glink, param1, param2, true); in qcom_glink_native_rx()
1227 qcom_glink_handle_intent_req_ack(glink, param1, param2); in qcom_glink_native_rx()
1230 qcom_glink_handle_signals(glink, param1, param2); in qcom_glink_native_rx()
1233 dev_err(glink->dev, "unhandled rx cmd: %d\n", cmd); in qcom_glink_native_rx()
1245 static struct glink_channel *qcom_glink_create_local(struct qcom_glink *glink, in qcom_glink_create_local() argument
1252 channel = qcom_glink_alloc_channel(glink, name); in qcom_glink_create_local()
1256 ret = qcom_glink_send_open_req(glink, channel); in qcom_glink_create_local()
1268 qcom_glink_send_open_ack(glink, channel); in qcom_glink_create_local()
1274 spin_lock_irqsave(&glink->idr_lock, flags); in qcom_glink_create_local()
1275 idr_remove(&glink->lcids, channel->lcid); in qcom_glink_create_local()
1276 spin_unlock_irqrestore(&glink->idr_lock, flags); in qcom_glink_create_local()
1288 static int qcom_glink_create_remote(struct qcom_glink *glink, in qcom_glink_create_remote() argument
1293 qcom_glink_send_open_ack(glink, channel); in qcom_glink_create_remote()
1295 ret = qcom_glink_send_open_req(glink, channel); in qcom_glink_create_remote()
1314 qcom_glink_send_close_req(glink, channel); in qcom_glink_create_remote()
1327 struct qcom_glink *glink = parent->glink; in qcom_glink_create_ept() local
1334 spin_lock_irqsave(&glink->idr_lock, flags); in qcom_glink_create_ept()
1335 idr_for_each_entry(&glink->rcids, channel, cid) { in qcom_glink_create_ept()
1339 spin_unlock_irqrestore(&glink->idr_lock, flags); in qcom_glink_create_ept()
1342 channel = qcom_glink_create_local(glink, name); in qcom_glink_create_ept()
1346 ret = qcom_glink_create_remote(glink, channel); in qcom_glink_create_ept()
1364 struct qcom_glink *glink = channel->glink; in qcom_glink_announce_create() local
1373 if (glink->intentless || !completion_done(&channel->open_ack)) in qcom_glink_announce_create()
1387 intent = qcom_glink_alloc_intent(glink, channel, size, in qcom_glink_announce_create()
1392 qcom_glink_advertise_intent(glink, channel, intent); in qcom_glink_announce_create()
1401 struct qcom_glink *glink = channel->glink; in qcom_glink_destroy_ept() local
1411 qcom_glink_send_close_req(glink, channel); in qcom_glink_destroy_ept()
1414 static int qcom_glink_request_intent(struct qcom_glink *glink, in qcom_glink_request_intent() argument
1435 trace_qcom_glink_cmd_rx_intent_req_tx(glink->label, channel->name, in qcom_glink_request_intent()
1439 ret = qcom_glink_tx(glink, &cmd, sizeof(cmd), NULL, 0, true); in qcom_glink_request_intent()
1447 glink->abort_tx, in qcom_glink_request_intent()
1450 dev_err(glink->dev, "intent request timed out\n"); in qcom_glink_request_intent()
1452 } else if (glink->abort_tx) { in qcom_glink_request_intent()
1466 struct qcom_glink *glink = channel->glink; in __qcom_glink_send() local
1480 if (!glink->intentless) { in __qcom_glink_send()
1504 ret = qcom_glink_request_intent(glink, channel, len); in __qcom_glink_send()
1523 trace_qcom_glink_cmd_tx_data_tx(glink->label, channel->name, in __qcom_glink_send()
1529 ret = qcom_glink_tx(glink, &req, sizeof(req), data + offset, chunk_size, wait); in __qcom_glink_send()
1572 * Finds the device_node for the glink child interested in this channel.
1583 key = "qcom,glink-channels"; in qcom_glink_match_channel()
1617 static int qcom_glink_rx_open(struct qcom_glink *glink, unsigned int rcid, in qcom_glink_rx_open() argument
1628 spin_lock_irqsave(&glink->idr_lock, flags); in qcom_glink_rx_open()
1629 idr_for_each_entry(&glink->lcids, channel, lcid) { in qcom_glink_rx_open()
1633 spin_unlock_irqrestore(&glink->idr_lock, flags); in qcom_glink_rx_open()
1636 channel = qcom_glink_alloc_channel(glink, name); in qcom_glink_rx_open()
1644 trace_qcom_glink_cmd_open_rx(glink->label, name, channel->lcid, rcid); in qcom_glink_rx_open()
1646 spin_lock_irqsave(&glink->idr_lock, flags); in qcom_glink_rx_open()
1647 ret = idr_alloc(&glink->rcids, channel, rcid, rcid + 1, GFP_ATOMIC); in qcom_glink_rx_open()
1649 dev_err(glink->dev, "Unable to insert channel into rcid list\n"); in qcom_glink_rx_open()
1650 spin_unlock_irqrestore(&glink->idr_lock, flags); in qcom_glink_rx_open()
1654 spin_unlock_irqrestore(&glink->idr_lock, flags); in qcom_glink_rx_open()
1671 node = qcom_glink_match_channel(glink->dev->of_node, name); in qcom_glink_rx_open()
1673 rpdev->dev.parent = glink->dev; in qcom_glink_rx_open()
1686 spin_lock_irqsave(&glink->idr_lock, flags); in qcom_glink_rx_open()
1687 idr_remove(&glink->rcids, channel->rcid); in qcom_glink_rx_open()
1689 spin_unlock_irqrestore(&glink->idr_lock, flags); in qcom_glink_rx_open()
1698 static void qcom_glink_rx_close(struct qcom_glink *glink, unsigned int rcid) in qcom_glink_rx_close() argument
1704 spin_lock_irqsave(&glink->idr_lock, flags); in qcom_glink_rx_close()
1705 channel = idr_find(&glink->rcids, rcid); in qcom_glink_rx_close()
1706 spin_unlock_irqrestore(&glink->idr_lock, flags); in qcom_glink_rx_close()
1708 trace_qcom_glink_cmd_close_rx(glink->label, channel ? channel->name : NULL, in qcom_glink_rx_close()
1721 rpmsg_unregister_device(glink->dev, &chinfo); in qcom_glink_rx_close()
1725 qcom_glink_send_close_ack(glink, channel); in qcom_glink_rx_close()
1727 spin_lock_irqsave(&glink->idr_lock, flags); in qcom_glink_rx_close()
1728 idr_remove(&glink->rcids, channel->rcid); in qcom_glink_rx_close()
1730 spin_unlock_irqrestore(&glink->idr_lock, flags); in qcom_glink_rx_close()
1735 static void qcom_glink_rx_close_ack(struct qcom_glink *glink, unsigned int lcid) in qcom_glink_rx_close_ack() argument
1742 wake_up_all(&glink->tx_avail_notify); in qcom_glink_rx_close_ack()
1744 spin_lock_irqsave(&glink->idr_lock, flags); in qcom_glink_rx_close_ack()
1745 channel = idr_find(&glink->lcids, lcid); in qcom_glink_rx_close_ack()
1747 trace_qcom_glink_cmd_close_ack_rx(glink->label, channel ? channel->name : NULL, in qcom_glink_rx_close_ack()
1750 spin_unlock_irqrestore(&glink->idr_lock, flags); in qcom_glink_rx_close_ack()
1754 idr_remove(&glink->lcids, channel->lcid); in qcom_glink_rx_close_ack()
1756 spin_unlock_irqrestore(&glink->idr_lock, flags); in qcom_glink_rx_close_ack()
1764 rpmsg_unregister_device(glink->dev, &chinfo); in qcom_glink_rx_close_ack()
1773 struct qcom_glink *glink = container_of(work, struct qcom_glink, in qcom_glink_work() local
1783 spin_lock_irqsave(&glink->rx_lock, flags); in qcom_glink_work()
1784 if (list_empty(&glink->rx_queue)) { in qcom_glink_work()
1785 spin_unlock_irqrestore(&glink->rx_lock, flags); in qcom_glink_work()
1788 dcmd = list_first_entry(&glink->rx_queue, in qcom_glink_work()
1791 spin_unlock_irqrestore(&glink->rx_lock, flags); in qcom_glink_work()
1800 qcom_glink_receive_version(glink, param1, param2); in qcom_glink_work()
1803 qcom_glink_receive_version_ack(glink, param1, param2); in qcom_glink_work()
1806 qcom_glink_rx_open(glink, param1, msg->data); in qcom_glink_work()
1809 qcom_glink_rx_close(glink, param1); in qcom_glink_work()
1812 qcom_glink_rx_close_ack(glink, param1); in qcom_glink_work()
1815 qcom_glink_handle_intent_req(glink, param1, param2); in qcom_glink_work()
1826 static void qcom_glink_cancel_rx_work(struct qcom_glink *glink) in qcom_glink_cancel_rx_work() argument
1832 cancel_work_sync(&glink->rx_work); in qcom_glink_cancel_rx_work()
1834 list_for_each_entry_safe(dcmd, tmp, &glink->rx_queue, node) in qcom_glink_cancel_rx_work()
1869 static int qcom_glink_create_chrdev(struct qcom_glink *glink) in qcom_glink_create_chrdev() argument
1878 channel = qcom_glink_alloc_channel(glink, "rpmsg_chrdev"); in qcom_glink_create_chrdev()
1887 rpdev->dev.parent = glink->dev; in qcom_glink_create_chrdev()
1900 struct qcom_glink *glink; in qcom_glink_native_probe() local
1902 glink = devm_kzalloc(dev, sizeof(*glink), GFP_KERNEL); in qcom_glink_native_probe()
1903 if (!glink) in qcom_glink_native_probe()
1906 glink->dev = dev; in qcom_glink_native_probe()
1907 glink->tx_pipe = tx; in qcom_glink_native_probe()
1908 glink->rx_pipe = rx; in qcom_glink_native_probe()
1910 glink->features = features; in qcom_glink_native_probe()
1911 glink->intentless = intentless; in qcom_glink_native_probe()
1913 spin_lock_init(&glink->tx_lock); in qcom_glink_native_probe()
1914 spin_lock_init(&glink->rx_lock); in qcom_glink_native_probe()
1915 INIT_LIST_HEAD(&glink->rx_queue); in qcom_glink_native_probe()
1916 INIT_WORK(&glink->rx_work, qcom_glink_work); in qcom_glink_native_probe()
1917 init_waitqueue_head(&glink->tx_avail_notify); in qcom_glink_native_probe()
1919 spin_lock_init(&glink->idr_lock); in qcom_glink_native_probe()
1920 idr_init(&glink->lcids); in qcom_glink_native_probe()
1921 idr_init(&glink->rcids); in qcom_glink_native_probe()
1923 ret = of_property_read_string(dev->of_node, "label", &glink->label); in qcom_glink_native_probe()
1925 glink->label = dev->of_node->name; in qcom_glink_native_probe()
1927 glink->dev->groups = qcom_glink_groups; in qcom_glink_native_probe()
1933 ret = qcom_glink_send_version(glink); in qcom_glink_native_probe()
1937 ret = qcom_glink_create_chrdev(glink); in qcom_glink_native_probe()
1939 dev_err(glink->dev, "failed to register chrdev\n"); in qcom_glink_native_probe()
1941 return glink; in qcom_glink_native_probe()
1952 void qcom_glink_native_remove(struct qcom_glink *glink) in qcom_glink_native_remove() argument
1959 qcom_glink_cancel_rx_work(glink); in qcom_glink_native_remove()
1962 spin_lock_irqsave(&glink->tx_lock, flags); in qcom_glink_native_remove()
1963 glink->abort_tx = true; in qcom_glink_native_remove()
1964 wake_up_all(&glink->tx_avail_notify); in qcom_glink_native_remove()
1965 spin_unlock_irqrestore(&glink->tx_lock, flags); in qcom_glink_native_remove()
1968 spin_lock_irqsave(&glink->idr_lock, flags); in qcom_glink_native_remove()
1969 idr_for_each_entry(&glink->lcids, channel, cid) in qcom_glink_native_remove()
1971 spin_unlock_irqrestore(&glink->idr_lock, flags); in qcom_glink_native_remove()
1973 ret = device_for_each_child(glink->dev, NULL, qcom_glink_remove_device); in qcom_glink_native_remove()
1975 dev_warn(glink->dev, "Can't remove GLINK devices: %d\n", ret); in qcom_glink_native_remove()
1978 idr_for_each_entry(&glink->lcids, channel, cid) in qcom_glink_native_remove()
1982 idr_for_each_entry(&glink->rcids, channel, cid) in qcom_glink_native_remove()
1985 idr_destroy(&glink->lcids); in qcom_glink_native_remove()
1986 idr_destroy(&glink->rcids); in qcom_glink_native_remove()
1990 MODULE_DESCRIPTION("Qualcomm GLINK driver");