Lines Matching full:edge
97 * @dev: device associated with this edge
98 * @name: name of this edge
99 * @of_node: of_node handle for information related to this edge
100 * @edge_id: identifier of this edge
102 * @irq: interrupt for signals on this edge
108 * @channels: list of all channels detected on this edge
114 * @state_work: work item for edge state changes
163 struct qcom_smd_edge *edge; member
178 * @edge: qcom_smd_edge this channel is living on
200 struct qcom_smd_edge *edge; member
347 * @flags: channel flags and edge id
372 struct qcom_smd_edge *edge = channel->edge; in qcom_smd_signal_channel() local
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()
444 struct qcom_smd_edge *edge = channel->edge; in qcom_smd_channel_set_state() local
450 dev_dbg(&edge->dev, "set_state(%s, %d)\n", channel->name, state); in qcom_smd_channel_set_state()
639 * The edge interrupts are triggered by the remote processor on state changes,
644 struct qcom_smd_edge *edge = data; in qcom_smd_edge_intr() local
651 * Handle state changes or data on each of the channels on this edge in qcom_smd_edge_intr()
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()
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()
818 struct qcom_smd_edge *edge = channel->edge; in qcom_smd_channel_open() local
839 dev_err(&edge->dev, "remote side did not enter opening state\n"); in qcom_smd_channel_open()
850 dev_err(&edge->dev, "remote side did not enter open state\n"); in qcom_smd_channel_open()
876 qcom_smd_find_channel(struct qcom_smd_edge *edge, const char *name) in qcom_smd_find_channel() argument
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()
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() local
914 ret = wait_event_interruptible_timeout(edge->new_channel_event, in qcom_smd_create_ept()
915 (channel = qcom_smd_find_channel(edge, name)) != NULL, in qcom_smd_create_ept()
1028 schedule_work(&channel->edge->state_work); in qcom_smd_announce_create()
1060 struct qcom_smd_edge *edge = channel->edge; in qcom_smd_create_device() local
1062 dev_dbg(&edge->dev, "registering '%s'\n", channel->name); in qcom_smd_create_device()
1068 /* Link qsdev to our SMD edge */ in qcom_smd_create_device()
1069 qsdev->edge = edge; in qcom_smd_create_device()
1080 rpdev->dev.of_node = qcom_smd_match_channel(edge->of_node, channel->name); in qcom_smd_create_device()
1081 rpdev->dev.parent = &edge->dev; in qcom_smd_create_device()
1087 static int qcom_smd_create_chrdev(struct qcom_smd_edge *edge) in qcom_smd_create_chrdev() argument
1095 qsdev->edge = edge; in qcom_smd_create_chrdev()
1097 qsdev->rpdev.dev.parent = &edge->dev; in qcom_smd_create_chrdev()
1107 static struct qcom_smd_channel *qcom_smd_create_channel(struct qcom_smd_edge *edge, in qcom_smd_create_channel() argument
1123 channel->edge = edge; in qcom_smd_create_channel()
1135 info = qcom_smem_get(edge->remote_pid, smem_info_item, &info_size); in qcom_smd_create_channel()
1150 dev_err(&edge->dev, in qcom_smd_create_channel()
1156 fifo_base = qcom_smem_get(edge->remote_pid, smem_fifo_item, &fifo_size); in qcom_smd_create_channel()
1165 dev_dbg(&edge->dev, "new channel '%s' info-size: %zu fifo-size: %zu\n", in qcom_smd_create_channel()
1187 * them to the edge's list of channels.
1191 struct qcom_smd_edge *edge = container_of(work, struct qcom_smd_edge, scan_work); in qcom_channel_scan_worker() local
1203 alloc_tbl = qcom_smem_get(edge->remote_pid, in qcom_channel_scan_worker()
1211 if (test_bit(i, edge->allocated[tbl])) in qcom_channel_scan_worker()
1223 if ((eflags & SMD_CHANNEL_FLAGS_EDGE_MASK) != edge->edge_id) in qcom_channel_scan_worker()
1230 channel = qcom_smd_create_channel(edge, info_id, fifo_id, entry->name); in qcom_channel_scan_worker()
1234 spin_lock_irqsave(&edge->channels_lock, flags); in qcom_channel_scan_worker()
1235 list_add(&channel->list, &edge->channels); in qcom_channel_scan_worker()
1236 spin_unlock_irqrestore(&edge->channels_lock, flags); in qcom_channel_scan_worker()
1238 dev_dbg(&edge->dev, "new channel found: '%s'\n", channel->name); in qcom_channel_scan_worker()
1239 set_bit(i, edge->allocated[tbl]); in qcom_channel_scan_worker()
1241 wake_up_interruptible_all(&edge->new_channel_event); in qcom_channel_scan_worker()
1245 schedule_work(&edge->state_work); in qcom_channel_scan_worker()
1249 * This per edge worker scans smem for any new channels and register these. It
1253 * LOCKING: edge->channels_lock only needs to cover the list operations, as the
1259 struct qcom_smd_edge *edge = container_of(work, in qcom_channel_state_worker() local
1270 spin_lock_irqsave(&edge->channels_lock, flags); in qcom_channel_state_worker()
1271 list_for_each_entry(channel, &edge->channels, list) { in qcom_channel_state_worker()
1283 spin_unlock_irqrestore(&edge->channels_lock, flags); in qcom_channel_state_worker()
1286 spin_lock_irqsave(&edge->channels_lock, flags); in qcom_channel_state_worker()
1295 list_for_each_entry(channel, &edge->channels, list) { in qcom_channel_state_worker()
1305 spin_unlock_irqrestore(&edge->channels_lock, flags); in qcom_channel_state_worker()
1310 rpmsg_unregister_device(&edge->dev, &chinfo); in qcom_channel_state_worker()
1312 spin_lock_irqsave(&edge->channels_lock, flags); in qcom_channel_state_worker()
1314 spin_unlock_irqrestore(&edge->channels_lock, flags); in qcom_channel_state_worker()
1318 * Parses an of_node describing an edge.
1322 struct qcom_smd_edge *edge) in qcom_smd_parse_edge() argument
1329 INIT_LIST_HEAD(&edge->channels); in qcom_smd_parse_edge()
1330 spin_lock_init(&edge->channels_lock); in qcom_smd_parse_edge()
1332 INIT_WORK(&edge->scan_work, qcom_channel_scan_worker); in qcom_smd_parse_edge()
1333 INIT_WORK(&edge->state_work, qcom_channel_state_worker); in qcom_smd_parse_edge()
1335 edge->of_node = of_node_get(node); in qcom_smd_parse_edge()
1337 key = "qcom,smd-edge"; in qcom_smd_parse_edge()
1338 ret = of_property_read_u32(node, key, &edge->edge_id); in qcom_smd_parse_edge()
1340 dev_err(dev, "edge missing %s property\n", key); in qcom_smd_parse_edge()
1344 edge->remote_pid = QCOM_SMEM_HOST_ANY; in qcom_smd_parse_edge()
1346 of_property_read_u32(node, key, &edge->remote_pid); in qcom_smd_parse_edge()
1348 edge->mbox_client.dev = dev; in qcom_smd_parse_edge()
1349 edge->mbox_client.knows_txdone = true; in qcom_smd_parse_edge()
1350 edge->mbox_chan = mbox_request_channel(&edge->mbox_client, 0); in qcom_smd_parse_edge()
1351 if (IS_ERR(edge->mbox_chan)) { in qcom_smd_parse_edge()
1352 if (PTR_ERR(edge->mbox_chan) != -ENODEV) { in qcom_smd_parse_edge()
1353 ret = PTR_ERR(edge->mbox_chan); in qcom_smd_parse_edge()
1357 edge->mbox_chan = NULL; in qcom_smd_parse_edge()
1366 edge->ipc_regmap = syscon_node_to_regmap(syscon_np); in qcom_smd_parse_edge()
1367 if (IS_ERR(edge->ipc_regmap)) { in qcom_smd_parse_edge()
1368 ret = PTR_ERR(edge->ipc_regmap); in qcom_smd_parse_edge()
1373 ret = of_property_read_u32_index(node, key, 1, &edge->ipc_offset); in qcom_smd_parse_edge()
1379 ret = of_property_read_u32_index(node, key, 2, &edge->ipc_bit); in qcom_smd_parse_edge()
1386 ret = of_property_read_string(node, "label", &edge->name); in qcom_smd_parse_edge()
1388 edge->name = node->name; in qcom_smd_parse_edge()
1399 node->name, edge); in qcom_smd_parse_edge()
1405 edge->irq = irq; in qcom_smd_parse_edge()
1411 edge->of_node = NULL; in qcom_smd_parse_edge()
1417 * Release function for an edge.
1418 * Reset the state of each associated channel and free the edge context.
1423 struct qcom_smd_edge *edge = to_smd_edge(dev); in qcom_smd_edge_release() local
1425 list_for_each_entry_safe(channel, tmp, &edge->channels, list) { in qcom_smd_edge_release()
1431 kfree(edge); in qcom_smd_edge_release()
1437 struct qcom_smd_edge *edge = to_smd_edge(dev); in rpmsg_name_show() local
1439 return sprintf(buf, "%s\n", edge->name); in rpmsg_name_show()
1450 * qcom_smd_register_edge() - register an edge based on an device_node
1451 * @parent: parent device for the edge
1452 * @node: device_node describing the edge
1454 * Returns an edge reference, or negative ERR_PTR() on failure.
1459 struct qcom_smd_edge *edge; in qcom_smd_register_edge() local
1462 edge = kzalloc(sizeof(*edge), GFP_KERNEL); in qcom_smd_register_edge()
1463 if (!edge) in qcom_smd_register_edge()
1466 init_waitqueue_head(&edge->new_channel_event); in qcom_smd_register_edge()
1468 edge->dev.parent = parent; in qcom_smd_register_edge()
1469 edge->dev.release = qcom_smd_edge_release; in qcom_smd_register_edge()
1470 edge->dev.of_node = node; in qcom_smd_register_edge()
1471 edge->dev.groups = qcom_smd_edge_groups; in qcom_smd_register_edge()
1472 dev_set_name(&edge->dev, "%s:%pOFn", dev_name(parent), node); in qcom_smd_register_edge()
1473 ret = device_register(&edge->dev); in qcom_smd_register_edge()
1475 pr_err("failed to register smd edge\n"); in qcom_smd_register_edge()
1476 put_device(&edge->dev); in qcom_smd_register_edge()
1480 ret = qcom_smd_parse_edge(&edge->dev, node, edge); in qcom_smd_register_edge()
1482 dev_err(&edge->dev, "failed to parse smd edge\n"); in qcom_smd_register_edge()
1486 ret = qcom_smd_create_chrdev(edge); in qcom_smd_register_edge()
1488 dev_err(&edge->dev, "failed to register chrdev for edge\n"); in qcom_smd_register_edge()
1492 schedule_work(&edge->scan_work); in qcom_smd_register_edge()
1494 return edge; in qcom_smd_register_edge()
1497 if (!IS_ERR_OR_NULL(edge->mbox_chan)) in qcom_smd_register_edge()
1498 mbox_free_channel(edge->mbox_chan); in qcom_smd_register_edge()
1500 device_unregister(&edge->dev); in qcom_smd_register_edge()
1513 * qcom_smd_unregister_edge() - release an edge and its children
1514 * @edge: edge reference acquired from qcom_smd_register_edge
1516 int qcom_smd_unregister_edge(struct qcom_smd_edge *edge) in qcom_smd_unregister_edge() argument
1520 disable_irq(edge->irq); in qcom_smd_unregister_edge()
1521 cancel_work_sync(&edge->scan_work); in qcom_smd_unregister_edge()
1522 cancel_work_sync(&edge->state_work); in qcom_smd_unregister_edge()
1524 ret = device_for_each_child(&edge->dev, NULL, qcom_smd_remove_device); in qcom_smd_unregister_edge()
1526 dev_warn(&edge->dev, "can't remove smd device: %d\n", ret); in qcom_smd_unregister_edge()
1528 mbox_free_channel(edge->mbox_chan); in qcom_smd_unregister_edge()
1529 device_unregister(&edge->dev); in qcom_smd_unregister_edge()
1553 struct qcom_smd_edge *edge = to_smd_edge(dev); in qcom_smd_remove_edge() local
1555 return qcom_smd_unregister_edge(edge); in qcom_smd_remove_edge()
1559 * Shut down all smd clients by making sure that each edge stops processing