Lines Matching +full:packet +full:- +full:processor

1 // SPDX-License-Identifier: GPL-2.0
4 * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
27 * The Qualcomm Shared Memory communication solution provides point-to-point
28 * channels for clients to send and receive streaming or packet based data.
35 * pair of items by name, type and remote processor.
37 * Upon creating a new channel the remote processor allocates channel info and
43 * The remote processor signals it intent for bring up the communication
49 * Upon closing a channel, the remote processor will update the state of its
56 * processor.
58 * The remote processor does the equivalent when it transfer data and upon
96 * struct qcom_smd_edge - representing a remote processor
101 * @remote_pid: identifier of remote processor
177 * struct qcom_smd_channel - smd channel struct
195 * @pkt_size: size of the currently handled packet
277 BUILD_BUG_ON(sizeof(channel->info->rx.param) != sizeof(u8)); \
278 channel->info_word ? \
279 le32_to_cpu(channel->info_word->rx.param) : \
280 channel->info->rx.param; \
285 BUILD_BUG_ON(sizeof(channel->info->rx.param) != sizeof(u32)); \
286 le32_to_cpu(channel->info_word ? \
287 channel->info_word->rx.param : \
288 channel->info->rx.param); \
293 BUILD_BUG_ON(sizeof(channel->info->rx.param) != sizeof(u8)); \
294 if (channel->info_word) \
295 channel->info_word->rx.param = cpu_to_le32(value); \
297 channel->info->rx.param = value; \
302 BUILD_BUG_ON(sizeof(channel->info->rx.param) != sizeof(u32)); \
303 if (channel->info_word) \
304 channel->info_word->rx.param = cpu_to_le32(value); \
306 channel->info->rx.param = cpu_to_le32(value); \
311 BUILD_BUG_ON(sizeof(channel->info->tx.param) != sizeof(u8)); \
312 channel->info_word ? \
313 le32_to_cpu(channel->info_word->tx.param) : \
314 channel->info->tx.param; \
319 BUILD_BUG_ON(sizeof(channel->info->tx.param) != sizeof(u32)); \
320 le32_to_cpu(channel->info_word ? \
321 channel->info_word->tx.param : \
322 channel->info->tx.param); \
327 BUILD_BUG_ON(sizeof(channel->info->tx.param) != sizeof(u8)); \
328 if (channel->info_word) \
329 channel->info_word->tx.param = cpu_to_le32(value); \
331 channel->info->tx.param = value; \
336 BUILD_BUG_ON(sizeof(channel->info->tx.param) != sizeof(u32)); \
337 if (channel->info_word) \
338 channel->info_word->tx.param = cpu_to_le32(value); \
340 channel->info->tx.param = cpu_to_le32(value); \
344 * struct qcom_smd_alloc_entry - channel allocation entry
362 * Each smd packet contains a 20 byte header, with the first 4 being the length
363 * of the packet.
368 * Signal the remote processor associated with 'channel'.
372 struct qcom_smd_edge *edge = channel->edge; in qcom_smd_signal_channel()
374 if (edge->mbox_chan) { in qcom_smd_signal_channel()
380 mbox_send_message(edge->mbox_chan, NULL); in qcom_smd_signal_channel()
381 mbox_client_txdone(edge->mbox_chan, 0); in qcom_smd_signal_channel()
383 regmap_write(edge->ipc_regmap, edge->ipc_offset, BIT(edge->ipc_bit)); in qcom_smd_signal_channel()
406 channel->state = SMD_CHANNEL_CLOSED; in qcom_smd_channel_reset()
407 channel->pkt_size = 0; in qcom_smd_channel_reset()
416 struct rpmsg_endpoint *ept = &channel->qsept->ept; in qcom_smd_channel_set_callback()
419 spin_lock_irqsave(&channel->recv_lock, flags); in qcom_smd_channel_set_callback()
420 ept->cb = cb; in qcom_smd_channel_set_callback()
421 spin_unlock_irqrestore(&channel->recv_lock, flags); in qcom_smd_channel_set_callback()
435 return (head - tail) & (channel->fifo_size - 1); in qcom_smd_channel_get_rx_avail()
439 * Set tx channel state and inform the remote processor
444 struct qcom_smd_edge *edge = channel->edge; in qcom_smd_channel_set_state()
447 if (channel->state == state) in qcom_smd_channel_set_state()
450 dev_dbg(&edge->dev, "set_state(%s, %d)\n", channel->name, state); in qcom_smd_channel_set_state()
459 channel->state = state; in qcom_smd_channel_set_state()
504 word_aligned = channel->info_word; in qcom_smd_channel_peek()
507 len = min_t(size_t, count, channel->fifo_size - tail); in qcom_smd_channel_peek()
510 channel->rx_fifo + tail, in qcom_smd_channel_peek()
517 channel->rx_fifo, in qcom_smd_channel_peek()
518 count - len, in qcom_smd_channel_peek()
535 tail &= (channel->fifo_size - 1); in qcom_smd_channel_advance()
540 * Read out a single packet from the rx fifo and deliver it to the device
544 struct rpmsg_endpoint *ept = &channel->qsept->ept; in qcom_smd_channel_recv_single()
553 if (tail + channel->pkt_size >= channel->fifo_size) { in qcom_smd_channel_recv_single()
554 ptr = channel->bounce_buffer; in qcom_smd_channel_recv_single()
555 len = qcom_smd_channel_peek(channel, ptr, channel->pkt_size); in qcom_smd_channel_recv_single()
557 ptr = channel->rx_fifo + tail; in qcom_smd_channel_recv_single()
558 len = channel->pkt_size; in qcom_smd_channel_recv_single()
561 ret = ept->cb(ept->rpdev, ptr, len, ept->priv, RPMSG_ADDR_ANY); in qcom_smd_channel_recv_single()
568 channel->pkt_size = 0; in qcom_smd_channel_recv_single()
586 if (remote_state != channel->remote_state) { in qcom_smd_channel_intr()
587 channel->remote_state = remote_state; in qcom_smd_channel_intr()
590 wake_up_interruptible_all(&channel->state_change_event); in qcom_smd_channel_intr()
597 wake_up_interruptible_all(&channel->fblockread_event); in qcom_smd_channel_intr()
600 if (channel->state != SMD_CHANNEL_OPENED) in qcom_smd_channel_intr()
610 if (!channel->pkt_size && avail >= SMD_PACKET_HEADER_LEN) { in qcom_smd_channel_intr()
613 channel->pkt_size = le32_to_cpu(pktlen); in qcom_smd_channel_intr()
614 } else if (channel->pkt_size && avail >= channel->pkt_size) { in qcom_smd_channel_intr()
639 * The edge interrupts are triggered by the remote processor on state changes,
653 spin_lock(&edge->channels_lock); in qcom_smd_edge_intr()
654 list_for_each_entry(channel, &edge->channels, list) { in qcom_smd_edge_intr()
655 spin_lock(&channel->recv_lock); in qcom_smd_edge_intr()
657 spin_unlock(&channel->recv_lock); in qcom_smd_edge_intr()
659 spin_unlock(&edge->channels_lock); in qcom_smd_edge_intr()
666 available = qcom_smem_get_free_space(edge->remote_pid); in qcom_smd_edge_intr()
667 if (available != edge->smem_available) { in qcom_smd_edge_intr()
668 edge->smem_available = available; in qcom_smd_edge_intr()
673 schedule_work(&edge->scan_work); in qcom_smd_edge_intr()
675 schedule_work(&edge->state_work); in qcom_smd_edge_intr()
687 unsigned mask = channel->fifo_size - 1; in qcom_smd_get_tx_avail()
692 return mask - ((head - tail) & mask); in qcom_smd_get_tx_avail()
706 word_aligned = channel->info_word; in qcom_smd_write_fifo()
709 len = min_t(size_t, count, channel->fifo_size - head); in qcom_smd_write_fifo()
711 smd_copy_to_fifo(channel->tx_fifo + head, in qcom_smd_write_fifo()
718 smd_copy_to_fifo(channel->tx_fifo, in qcom_smd_write_fifo()
720 count - len, in qcom_smd_write_fifo()
725 head &= (channel->fifo_size - 1); in qcom_smd_write_fifo()
732 * __qcom_smd_send - write data to smd channel
752 if (channel->info_word && len % 4) in __qcom_smd_send()
753 return -EINVAL; in __qcom_smd_send()
756 if (tlen >= channel->fifo_size) in __qcom_smd_send()
757 return -EINVAL; in __qcom_smd_send()
763 spin_lock_irqsave(&channel->tx_lock, flags); in __qcom_smd_send()
766 channel->state == SMD_CHANNEL_OPENED) { in __qcom_smd_send()
768 ret = -EAGAIN; in __qcom_smd_send()
775 spin_unlock_irqrestore(&channel->tx_lock, flags); in __qcom_smd_send()
777 ret = wait_event_interruptible(channel->fblockread_event, in __qcom_smd_send()
779 channel->state != SMD_CHANNEL_OPENED); in __qcom_smd_send()
783 spin_lock_irqsave(&channel->tx_lock, flags); in __qcom_smd_send()
789 if (channel->state != SMD_CHANNEL_OPENED) { in __qcom_smd_send()
790 ret = -EPIPE; in __qcom_smd_send()
807 spin_unlock_irqrestore(&channel->tx_lock, flags); in __qcom_smd_send()
818 struct qcom_smd_edge *edge = channel->edge; in qcom_smd_channel_open()
825 bb_size = min(channel->fifo_size, SZ_4K); in qcom_smd_channel_open()
826 channel->bounce_buffer = kmalloc(bb_size, GFP_KERNEL); in qcom_smd_channel_open()
827 if (!channel->bounce_buffer) in qcom_smd_channel_open()
828 return -ENOMEM; in qcom_smd_channel_open()
834 ret = wait_event_interruptible_timeout(channel->state_change_event, in qcom_smd_channel_open()
835 channel->remote_state == SMD_CHANNEL_OPENING || in qcom_smd_channel_open()
836 channel->remote_state == SMD_CHANNEL_OPENED, in qcom_smd_channel_open()
839 dev_err(&edge->dev, "remote side did not enter opening state\n"); in qcom_smd_channel_open()
846 ret = wait_event_interruptible_timeout(channel->state_change_event, in qcom_smd_channel_open()
847 channel->remote_state == SMD_CHANNEL_OPENED, in qcom_smd_channel_open()
850 dev_err(&edge->dev, "remote side did not enter open state\n"); in qcom_smd_channel_open()
858 return -ETIMEDOUT; in qcom_smd_channel_open()
868 kfree(channel->bounce_buffer); in qcom_smd_channel_close()
869 channel->bounce_buffer = NULL; in qcom_smd_channel_close()
882 spin_lock_irqsave(&edge->channels_lock, flags); in qcom_smd_find_channel()
883 list_for_each_entry(channel, &edge->channels, list) { in qcom_smd_find_channel()
884 if (!strcmp(channel->name, name)) { in qcom_smd_find_channel()
889 spin_unlock_irqrestore(&edge->channels_lock, flags); in qcom_smd_find_channel()
908 struct qcom_smd_edge *edge = qsdev->edge; in qcom_smd_create_ept()
914 ret = wait_event_interruptible_timeout(edge->new_channel_event, in qcom_smd_create_ept()
920 if (channel->state != SMD_CHANNEL_CLOSED) { in qcom_smd_create_ept()
921 dev_err(&rpdev->dev, "channel %s is busy\n", channel->name); in qcom_smd_create_ept()
929 ept = &qsept->ept; in qcom_smd_create_ept()
931 kref_init(&ept->refcount); in qcom_smd_create_ept()
933 ept->rpdev = rpdev; in qcom_smd_create_ept()
934 ept->cb = cb; in qcom_smd_create_ept()
935 ept->priv = priv; in qcom_smd_create_ept()
936 ept->ops = &qcom_smd_endpoint_ops; in qcom_smd_create_ept()
938 channel->qsept = qsept; in qcom_smd_create_ept()
939 qsept->qsch = channel; in qcom_smd_create_ept()
948 channel->qsept = NULL; in qcom_smd_create_ept()
949 kref_put(&ept->refcount, __ept_release); in qcom_smd_create_ept()
956 struct qcom_smd_channel *ch = qsept->qsch; in qcom_smd_destroy_ept()
959 ch->qsept = NULL; in qcom_smd_destroy_ept()
960 kref_put(&ept->refcount, __ept_release); in qcom_smd_destroy_ept()
967 return __qcom_smd_send(qsept->qsch, data, len, true); in qcom_smd_send()
974 return __qcom_smd_send(qsept->qsch, data, len, false); in qcom_smd_trysend()
981 return __qcom_smd_send(qsept->qsch, data, len, true); in qcom_smd_sendto()
988 return __qcom_smd_send(qsept->qsch, data, len, false); in qcom_smd_trysendto()
995 struct qcom_smd_channel *channel = qsept->qsch; in qcom_smd_poll()
998 poll_wait(filp, &channel->fblockread_event, wait); in qcom_smd_poll()
1018 key = "qcom,smd-channels"; in qcom_smd_match_channel()
1032 struct qcom_smd_endpoint *qept = to_smd_endpoint(rpdev->ept); in qcom_smd_announce_create()
1033 struct qcom_smd_channel *channel = qept->qsch; in qcom_smd_announce_create()
1037 spin_lock_irqsave(&channel->recv_lock, flags); in qcom_smd_announce_create()
1039 spin_unlock_irqrestore(&channel->recv_lock, flags); in qcom_smd_announce_create()
1042 schedule_work(&channel->edge->state_work); in qcom_smd_announce_create()
1076 struct qcom_smd_edge *edge = channel->edge; in qcom_smd_create_device()
1078 dev_dbg(&edge->dev, "registering '%s'\n", channel->name); in qcom_smd_create_device()
1082 return -ENOMEM; in qcom_smd_create_device()
1085 qsdev->edge = edge; in qcom_smd_create_device()
1088 qsdev->rpdev.ops = &qcom_smd_device_ops; in qcom_smd_create_device()
1091 rpdev = &qsdev->rpdev; in qcom_smd_create_device()
1092 strscpy_pad(rpdev->id.name, channel->name, RPMSG_NAME_SIZE); in qcom_smd_create_device()
1093 rpdev->src = RPMSG_ADDR_ANY; in qcom_smd_create_device()
1094 rpdev->dst = RPMSG_ADDR_ANY; in qcom_smd_create_device()
1096 rpdev->dev.of_node = qcom_smd_match_channel(edge->of_node, channel->name); in qcom_smd_create_device()
1097 rpdev->dev.parent = &edge->dev; in qcom_smd_create_device()
1098 rpdev->dev.release = qcom_smd_release_device; in qcom_smd_create_device()
1109 return -ENOMEM; in qcom_smd_create_chrdev()
1111 qsdev->edge = edge; in qcom_smd_create_chrdev()
1112 qsdev->rpdev.ops = &qcom_smd_device_ops; in qcom_smd_create_chrdev()
1113 qsdev->rpdev.dev.parent = &edge->dev; in qcom_smd_create_chrdev()
1114 qsdev->rpdev.dev.release = qcom_smd_release_device; in qcom_smd_create_chrdev()
1116 return rpmsg_ctrldev_register_device(&qsdev->rpdev); in qcom_smd_create_chrdev()
1137 return ERR_PTR(-ENOMEM); in qcom_smd_create_channel()
1139 channel->edge = edge; in qcom_smd_create_channel()
1140 channel->name = kstrdup(name, GFP_KERNEL); in qcom_smd_create_channel()
1141 if (!channel->name) { in qcom_smd_create_channel()
1142 ret = -ENOMEM; in qcom_smd_create_channel()
1146 spin_lock_init(&channel->tx_lock); in qcom_smd_create_channel()
1147 spin_lock_init(&channel->recv_lock); in qcom_smd_create_channel()
1148 init_waitqueue_head(&channel->fblockread_event); in qcom_smd_create_channel()
1149 init_waitqueue_head(&channel->state_change_event); in qcom_smd_create_channel()
1151 info = qcom_smem_get(edge->remote_pid, smem_info_item, &info_size); in qcom_smd_create_channel()
1162 channel->info_word = info; in qcom_smd_create_channel()
1164 channel->info = info; in qcom_smd_create_channel()
1166 dev_err(&edge->dev, in qcom_smd_create_channel()
1168 ret = -EINVAL; in qcom_smd_create_channel()
1172 fifo_base = qcom_smem_get(edge->remote_pid, smem_fifo_item, &fifo_size); in qcom_smd_create_channel()
1181 dev_dbg(&edge->dev, "new channel '%s' info-size: %zu fifo-size: %zu\n", in qcom_smd_create_channel()
1184 channel->tx_fifo = fifo_base; in qcom_smd_create_channel()
1185 channel->rx_fifo = fifo_base + fifo_size; in qcom_smd_create_channel()
1186 channel->fifo_size = fifo_size; in qcom_smd_create_channel()
1193 kfree(channel->name); in qcom_smd_create_channel()
1219 alloc_tbl = qcom_smem_get(edge->remote_pid, in qcom_channel_scan_worker()
1226 eflags = le32_to_cpu(entry->flags); in qcom_channel_scan_worker()
1227 if (test_bit(i, edge->allocated[tbl])) in qcom_channel_scan_worker()
1230 if (entry->ref_count == 0) in qcom_channel_scan_worker()
1233 if (!entry->name[0]) in qcom_channel_scan_worker()
1239 if ((eflags & SMD_CHANNEL_FLAGS_EDGE_MASK) != edge->edge_id) in qcom_channel_scan_worker()
1242 cid = le32_to_cpu(entry->cid); in qcom_channel_scan_worker()
1246 channel = qcom_smd_create_channel(edge, info_id, fifo_id, entry->name); in qcom_channel_scan_worker()
1250 spin_lock_irqsave(&edge->channels_lock, flags); in qcom_channel_scan_worker()
1251 list_add(&channel->list, &edge->channels); in qcom_channel_scan_worker()
1252 spin_unlock_irqrestore(&edge->channels_lock, flags); in qcom_channel_scan_worker()
1254 dev_dbg(&edge->dev, "new channel found: '%s'\n", channel->name); in qcom_channel_scan_worker()
1255 set_bit(i, edge->allocated[tbl]); in qcom_channel_scan_worker()
1257 wake_up_interruptible_all(&edge->new_channel_event); in qcom_channel_scan_worker()
1261 schedule_work(&edge->state_work); in qcom_channel_scan_worker()
1269 * LOCKING: edge->channels_lock only needs to cover the list operations, as the
1283 * Register a device for any closed channel where the remote processor in qcom_channel_state_worker()
1286 spin_lock_irqsave(&edge->channels_lock, flags); in qcom_channel_state_worker()
1287 list_for_each_entry(channel, &edge->channels, list) { in qcom_channel_state_worker()
1288 if (channel->state != SMD_CHANNEL_CLOSED) in qcom_channel_state_worker()
1298 strcmp(channel->name, "rpm_requests")) in qcom_channel_state_worker()
1301 if (channel->registered) in qcom_channel_state_worker()
1304 spin_unlock_irqrestore(&edge->channels_lock, flags); in qcom_channel_state_worker()
1306 spin_lock_irqsave(&edge->channels_lock, flags); in qcom_channel_state_worker()
1307 channel->registered = true; in qcom_channel_state_worker()
1312 * remote processor is closing the channel. in qcom_channel_state_worker()
1314 list_for_each_entry(channel, &edge->channels, list) { in qcom_channel_state_worker()
1315 if (channel->state != SMD_CHANNEL_OPENING && in qcom_channel_state_worker()
1316 channel->state != SMD_CHANNEL_OPENED) in qcom_channel_state_worker()
1324 spin_unlock_irqrestore(&edge->channels_lock, flags); in qcom_channel_state_worker()
1326 strscpy_pad(chinfo.name, channel->name, sizeof(chinfo.name)); in qcom_channel_state_worker()
1329 rpmsg_unregister_device(&edge->dev, &chinfo); in qcom_channel_state_worker()
1330 channel->registered = false; in qcom_channel_state_worker()
1331 spin_lock_irqsave(&edge->channels_lock, flags); in qcom_channel_state_worker()
1333 spin_unlock_irqrestore(&edge->channels_lock, flags); in qcom_channel_state_worker()
1348 INIT_LIST_HEAD(&edge->channels); in qcom_smd_parse_edge()
1349 spin_lock_init(&edge->channels_lock); in qcom_smd_parse_edge()
1351 INIT_WORK(&edge->scan_work, qcom_channel_scan_worker); in qcom_smd_parse_edge()
1352 INIT_WORK(&edge->state_work, qcom_channel_state_worker); in qcom_smd_parse_edge()
1354 edge->of_node = of_node_get(node); in qcom_smd_parse_edge()
1356 key = "qcom,smd-edge"; in qcom_smd_parse_edge()
1357 ret = of_property_read_u32(node, key, &edge->edge_id); in qcom_smd_parse_edge()
1363 edge->remote_pid = QCOM_SMEM_HOST_ANY; in qcom_smd_parse_edge()
1364 key = "qcom,remote-pid"; in qcom_smd_parse_edge()
1365 of_property_read_u32(node, key, &edge->remote_pid); in qcom_smd_parse_edge()
1367 edge->mbox_client.dev = dev; in qcom_smd_parse_edge()
1368 edge->mbox_client.knows_txdone = true; in qcom_smd_parse_edge()
1369 edge->mbox_chan = mbox_request_channel(&edge->mbox_client, 0); in qcom_smd_parse_edge()
1370 if (IS_ERR(edge->mbox_chan)) { in qcom_smd_parse_edge()
1371 if (PTR_ERR(edge->mbox_chan) != -ENODEV) { in qcom_smd_parse_edge()
1372 ret = PTR_ERR(edge->mbox_chan); in qcom_smd_parse_edge()
1376 edge->mbox_chan = NULL; in qcom_smd_parse_edge()
1381 ret = -ENODEV; in qcom_smd_parse_edge()
1385 edge->ipc_regmap = syscon_node_to_regmap(syscon_np); in qcom_smd_parse_edge()
1387 if (IS_ERR(edge->ipc_regmap)) { in qcom_smd_parse_edge()
1388 ret = PTR_ERR(edge->ipc_regmap); in qcom_smd_parse_edge()
1393 ret = of_property_read_u32_index(node, key, 1, &edge->ipc_offset); in qcom_smd_parse_edge()
1399 ret = of_property_read_u32_index(node, key, 2, &edge->ipc_bit); in qcom_smd_parse_edge()
1406 ret = of_property_read_string(node, "label", &edge->name); in qcom_smd_parse_edge()
1408 edge->name = node->name; in qcom_smd_parse_edge()
1413 ret = -EINVAL; in qcom_smd_parse_edge()
1419 node->name, edge); in qcom_smd_parse_edge()
1425 edge->irq = irq; in qcom_smd_parse_edge()
1431 edge->of_node = NULL; in qcom_smd_parse_edge()
1445 list_for_each_entry_safe(channel, tmp, &edge->channels, list) { in qcom_smd_edge_release()
1446 list_del(&channel->list); in qcom_smd_edge_release()
1447 kfree(channel->name); in qcom_smd_edge_release()
1459 return sprintf(buf, "%s\n", edge->name); in rpmsg_name_show()
1470 * qcom_smd_register_edge() - register an edge based on an device_node
1483 return ERR_PTR(-EPROBE_DEFER); in qcom_smd_register_edge()
1487 return ERR_PTR(-ENOMEM); in qcom_smd_register_edge()
1489 init_waitqueue_head(&edge->new_channel_event); in qcom_smd_register_edge()
1491 edge->dev.parent = parent; in qcom_smd_register_edge()
1492 edge->dev.release = qcom_smd_edge_release; in qcom_smd_register_edge()
1493 edge->dev.of_node = node; in qcom_smd_register_edge()
1494 edge->dev.groups = qcom_smd_edge_groups; in qcom_smd_register_edge()
1495 dev_set_name(&edge->dev, "%s:%pOFn", dev_name(parent), node); in qcom_smd_register_edge()
1496 ret = device_register(&edge->dev); in qcom_smd_register_edge()
1499 put_device(&edge->dev); in qcom_smd_register_edge()
1503 ret = qcom_smd_parse_edge(&edge->dev, node, edge); in qcom_smd_register_edge()
1505 dev_err(&edge->dev, "failed to parse smd edge\n"); in qcom_smd_register_edge()
1511 dev_err(&edge->dev, "failed to register chrdev for edge\n"); in qcom_smd_register_edge()
1515 schedule_work(&edge->scan_work); in qcom_smd_register_edge()
1520 if (!IS_ERR_OR_NULL(edge->mbox_chan)) in qcom_smd_register_edge()
1521 mbox_free_channel(edge->mbox_chan); in qcom_smd_register_edge()
1523 device_unregister(&edge->dev); in qcom_smd_register_edge()
1536 * qcom_smd_unregister_edge() - release an edge and its children
1543 disable_irq(edge->irq); in qcom_smd_unregister_edge()
1544 cancel_work_sync(&edge->scan_work); in qcom_smd_unregister_edge()
1545 cancel_work_sync(&edge->state_work); in qcom_smd_unregister_edge()
1547 ret = device_for_each_child(&edge->dev, NULL, qcom_smd_remove_device); in qcom_smd_unregister_edge()
1549 dev_warn(&edge->dev, "can't remove smd device: %d\n", ret); in qcom_smd_unregister_edge()
1551 mbox_free_channel(edge->mbox_chan); in qcom_smd_unregister_edge()
1552 device_unregister(&edge->dev); in qcom_smd_unregister_edge()
1561 return -EPROBE_DEFER; in qcom_smd_probe()
1563 for_each_available_child_of_node(pdev->dev.of_node, node) in qcom_smd_probe()
1564 qcom_smd_register_edge(&pdev->dev, node); in qcom_smd_probe()
1588 device_for_each_child(&pdev->dev, NULL, qcom_smd_remove_edge); in qcom_smd_remove()
1601 .name = "qcom-smd",