Lines Matching full:smp2p
31 * The Shared Memory Point to Point (SMP2P) protocol facilitates communication
40 * single-writer, SMP2P does not require any remote locking mechanisms.
87 * @smp2p: reference to the device driver context
100 struct qcom_smp2p *smp2p; member
159 static void qcom_smp2p_kick(struct qcom_smp2p *smp2p) in qcom_smp2p_kick() argument
164 if (smp2p->mbox_chan) { in qcom_smp2p_kick()
165 mbox_send_message(smp2p->mbox_chan, NULL); in qcom_smp2p_kick()
166 mbox_client_txdone(smp2p->mbox_chan, 0); in qcom_smp2p_kick()
168 regmap_write(smp2p->ipc_regmap, smp2p->ipc_offset, BIT(smp2p->ipc_bit)); in qcom_smp2p_kick()
175 * @data: smp2p driver context
184 struct qcom_smp2p *smp2p = data; in qcom_smp2p_intr() local
185 unsigned smem_id = smp2p->smem_items[SMP2P_INBOUND]; in qcom_smp2p_intr()
186 unsigned pid = smp2p->remote_pid; in qcom_smp2p_intr()
194 in = smp2p->in; in qcom_smp2p_intr()
200 dev_err(smp2p->dev, in qcom_smp2p_intr()
201 "Unable to acquire remote smp2p item\n"); in qcom_smp2p_intr()
205 smp2p->in = in; in qcom_smp2p_intr()
209 for (i = smp2p->valid_entries; i < in->valid_entries; i++) { in qcom_smp2p_intr()
210 list_for_each_entry(entry, &smp2p->inbound, node) { in qcom_smp2p_intr()
218 smp2p->valid_entries = i; in qcom_smp2p_intr()
221 list_for_each_entry(entry, &smp2p->inbound, node) { in qcom_smp2p_intr()
288 .name = "smp2p",
313 static int qcom_smp2p_inbound_entry(struct qcom_smp2p *smp2p, in qcom_smp2p_inbound_entry() argument
319 dev_err(smp2p->dev, "failed to add irq_domain\n"); in qcom_smp2p_inbound_entry()
340 qcom_smp2p_kick(entry->smp2p); in smp2p_update_bits()
349 static int qcom_smp2p_outbound_entry(struct qcom_smp2p *smp2p, in qcom_smp2p_outbound_entry() argument
353 struct smp2p_smem_item *out = smp2p->out; in qcom_smp2p_outbound_entry()
367 dev_err(smp2p->dev, "failed to register qcom_smem_state\n"); in qcom_smp2p_outbound_entry()
374 static int qcom_smp2p_alloc_outbound_item(struct qcom_smp2p *smp2p) in qcom_smp2p_alloc_outbound_item() argument
377 unsigned smem_id = smp2p->smem_items[SMP2P_OUTBOUND]; in qcom_smp2p_alloc_outbound_item()
378 unsigned pid = smp2p->remote_pid; in qcom_smp2p_alloc_outbound_item()
384 dev_err(smp2p->dev, in qcom_smp2p_alloc_outbound_item()
385 "unable to allocate local smp2p item\n"); in qcom_smp2p_alloc_outbound_item()
391 dev_err(smp2p->dev, "Unable to acquire local smp2p item\n"); in qcom_smp2p_alloc_outbound_item()
397 out->local_pid = smp2p->local_pid; in qcom_smp2p_alloc_outbound_item()
398 out->remote_pid = smp2p->remote_pid; in qcom_smp2p_alloc_outbound_item()
409 qcom_smp2p_kick(smp2p); in qcom_smp2p_alloc_outbound_item()
411 smp2p->out = out; in qcom_smp2p_alloc_outbound_item()
416 static int smp2p_parse_ipc(struct qcom_smp2p *smp2p) in smp2p_parse_ipc() argument
419 struct device *dev = smp2p->dev; in smp2p_parse_ipc()
429 smp2p->ipc_regmap = syscon_node_to_regmap(syscon); in smp2p_parse_ipc()
430 if (IS_ERR(smp2p->ipc_regmap)) in smp2p_parse_ipc()
431 return PTR_ERR(smp2p->ipc_regmap); in smp2p_parse_ipc()
434 ret = of_property_read_u32_index(dev->of_node, key, 1, &smp2p->ipc_offset); in smp2p_parse_ipc()
440 ret = of_property_read_u32_index(dev->of_node, key, 2, &smp2p->ipc_bit); in smp2p_parse_ipc()
453 struct qcom_smp2p *smp2p; in qcom_smp2p_probe() local
458 smp2p = devm_kzalloc(&pdev->dev, sizeof(*smp2p), GFP_KERNEL); in qcom_smp2p_probe()
459 if (!smp2p) in qcom_smp2p_probe()
462 smp2p->dev = &pdev->dev; in qcom_smp2p_probe()
463 INIT_LIST_HEAD(&smp2p->inbound); in qcom_smp2p_probe()
464 INIT_LIST_HEAD(&smp2p->outbound); in qcom_smp2p_probe()
466 platform_set_drvdata(pdev, smp2p); in qcom_smp2p_probe()
470 smp2p->smem_items, 2); in qcom_smp2p_probe()
475 ret = of_property_read_u32(pdev->dev.of_node, key, &smp2p->local_pid); in qcom_smp2p_probe()
480 ret = of_property_read_u32(pdev->dev.of_node, key, &smp2p->remote_pid); in qcom_smp2p_probe()
486 dev_err(&pdev->dev, "unable to acquire smp2p interrupt\n"); in qcom_smp2p_probe()
490 smp2p->mbox_client.dev = &pdev->dev; in qcom_smp2p_probe()
491 smp2p->mbox_client.knows_txdone = true; in qcom_smp2p_probe()
492 smp2p->mbox_chan = mbox_request_channel(&smp2p->mbox_client, 0); in qcom_smp2p_probe()
493 if (IS_ERR(smp2p->mbox_chan)) { in qcom_smp2p_probe()
494 if (PTR_ERR(smp2p->mbox_chan) != -ENODEV) in qcom_smp2p_probe()
495 return PTR_ERR(smp2p->mbox_chan); in qcom_smp2p_probe()
497 smp2p->mbox_chan = NULL; in qcom_smp2p_probe()
499 ret = smp2p_parse_ipc(smp2p); in qcom_smp2p_probe()
504 ret = qcom_smp2p_alloc_outbound_item(smp2p); in qcom_smp2p_probe()
515 entry->smp2p = smp2p; in qcom_smp2p_probe()
523 ret = qcom_smp2p_inbound_entry(smp2p, entry, node); in qcom_smp2p_probe()
527 list_add(&entry->node, &smp2p->inbound); in qcom_smp2p_probe()
529 ret = qcom_smp2p_outbound_entry(smp2p, entry, node); in qcom_smp2p_probe()
533 list_add(&entry->node, &smp2p->outbound); in qcom_smp2p_probe()
538 qcom_smp2p_kick(smp2p); in qcom_smp2p_probe()
543 "smp2p", (void *)smp2p); in qcom_smp2p_probe()
553 list_for_each_entry(entry, &smp2p->inbound, node) in qcom_smp2p_probe()
556 list_for_each_entry(entry, &smp2p->outbound, node) in qcom_smp2p_probe()
559 smp2p->out->valid_entries = 0; in qcom_smp2p_probe()
562 mbox_free_channel(smp2p->mbox_chan); in qcom_smp2p_probe()
573 struct qcom_smp2p *smp2p = platform_get_drvdata(pdev); in qcom_smp2p_remove() local
576 list_for_each_entry(entry, &smp2p->inbound, node) in qcom_smp2p_remove()
579 list_for_each_entry(entry, &smp2p->outbound, node) in qcom_smp2p_remove()
582 mbox_free_channel(smp2p->mbox_chan); in qcom_smp2p_remove()
584 smp2p->out->valid_entries = 0; in qcom_smp2p_remove()
590 { .compatible = "qcom,smp2p" },