Lines Matching +full:rpmsg +full:- +full:channel +full:- +full:name

1 // SPDX-License-Identifier: GPL-2.0
14 #include <linux/rpmsg.h>
29 const char *name; member
76 * sysmon_send_event() - send notification of other remote's SSR event
87 len = snprintf(req, sizeof(req), "ssr:%s:%s", event->subsys_name, in sysmon_send_event()
88 sysmon_state_string[event->ssr_event]); in sysmon_send_event()
92 mutex_lock(&sysmon->lock); in sysmon_send_event()
93 reinit_completion(&sysmon->comp); in sysmon_send_event()
94 sysmon->ssr_ack = false; in sysmon_send_event()
96 ret = rpmsg_send(sysmon->ept, req, len); in sysmon_send_event()
98 dev_err(sysmon->dev, "failed to send sysmon event\n"); in sysmon_send_event()
102 ret = wait_for_completion_timeout(&sysmon->comp, in sysmon_send_event()
105 dev_err(sysmon->dev, "timeout waiting for sysmon ack\n"); in sysmon_send_event()
109 if (!sysmon->ssr_ack) in sysmon_send_event()
110 dev_err(sysmon->dev, "unexpected response to sysmon event\n"); in sysmon_send_event()
113 mutex_unlock(&sysmon->lock); in sysmon_send_event()
117 * sysmon_request_shutdown() - request graceful shutdown of remote
128 mutex_lock(&sysmon->lock); in sysmon_request_shutdown()
129 reinit_completion(&sysmon->comp); in sysmon_request_shutdown()
130 sysmon->ssr_ack = false; in sysmon_request_shutdown()
132 ret = rpmsg_send(sysmon->ept, req, strlen(req) + 1); in sysmon_request_shutdown()
134 dev_err(sysmon->dev, "send sysmon shutdown request failed\n"); in sysmon_request_shutdown()
138 ret = wait_for_completion_timeout(&sysmon->comp, in sysmon_request_shutdown()
141 dev_err(sysmon->dev, "timeout waiting for sysmon ack\n"); in sysmon_request_shutdown()
145 if (!sysmon->ssr_ack) in sysmon_request_shutdown()
146 dev_err(sysmon->dev, in sysmon_request_shutdown()
152 mutex_unlock(&sysmon->lock); in sysmon_request_shutdown()
165 return -EINVAL; in sysmon_callback()
168 sysmon->ssr_ack = true; in sysmon_callback()
170 complete(&sysmon->comp); in sysmon_callback()
294 complete(&sysmon->ind_comp); in sysmon_ind_cb()
312 ret = wait_for_completion_timeout(&sysmon->shutdown_comp, 10 * HZ); in ssctl_request_shutdown_wait()
316 ret = try_wait_for_completion(&sysmon->ind_comp); in ssctl_request_shutdown_wait()
320 dev_err(sysmon->dev, "timeout waiting for shutdown ack\n"); in ssctl_request_shutdown_wait()
325 * ssctl_request_shutdown() - request shutdown via SSCTL QMI service
337 reinit_completion(&sysmon->ind_comp); in ssctl_request_shutdown()
338 reinit_completion(&sysmon->shutdown_comp); in ssctl_request_shutdown()
339 ret = qmi_txn_init(&sysmon->qmi, &txn, ssctl_shutdown_resp_ei, &resp); in ssctl_request_shutdown()
341 dev_err(sysmon->dev, "failed to allocate QMI txn\n"); in ssctl_request_shutdown()
345 ret = qmi_send_request(&sysmon->qmi, &sysmon->ssctl, &txn, in ssctl_request_shutdown()
348 dev_err(sysmon->dev, "failed to send shutdown request\n"); in ssctl_request_shutdown()
355 dev_err(sysmon->dev, "timeout waiting for shutdown response\n"); in ssctl_request_shutdown()
357 dev_err(sysmon->dev, "shutdown request rejected\n"); in ssctl_request_shutdown()
359 dev_dbg(sysmon->dev, "shutdown request completed\n"); in ssctl_request_shutdown()
363 if (sysmon->shutdown_irq > 0) in ssctl_request_shutdown()
370 * ssctl_send_event() - send notification of other remote's SSR event
383 ret = qmi_txn_init(&sysmon->qmi, &txn, ssctl_subsys_event_resp_ei, &resp); in ssctl_send_event()
385 dev_err(sysmon->dev, "failed to allocate QMI txn\n"); in ssctl_send_event()
390 strscpy(req.subsys_name, event->subsys_name, sizeof(req.subsys_name)); in ssctl_send_event()
392 req.event = event->ssr_event; in ssctl_send_event()
396 ret = qmi_send_request(&sysmon->qmi, &sysmon->ssctl, &txn, in ssctl_send_event()
400 dev_err(sysmon->dev, "failed to send subsystem event\n"); in ssctl_send_event()
407 dev_err(sysmon->dev, "timeout waiting for subsystem event response\n"); in ssctl_send_event()
409 dev_err(sysmon->dev, "subsystem event rejected\n"); in ssctl_send_event()
411 dev_dbg(sysmon->dev, "subsystem event accepted\n"); in ssctl_send_event()
415 * ssctl_new_server() - QMI callback indicating a new service
419 * Return: 0 if we're interested in this service, -EINVAL otherwise.
425 switch (svc->version) { in ssctl_new_server()
427 if (svc->instance != 0) in ssctl_new_server()
428 return -EINVAL; in ssctl_new_server()
429 if (strcmp(sysmon->name, "modem")) in ssctl_new_server()
430 return -EINVAL; in ssctl_new_server()
433 if (svc->instance != sysmon->ssctl_instance) in ssctl_new_server()
434 return -EINVAL; in ssctl_new_server()
437 return -EINVAL; in ssctl_new_server()
440 sysmon->ssctl_version = svc->version; in ssctl_new_server()
442 sysmon->ssctl.sq_family = AF_QIPCRTR; in ssctl_new_server()
443 sysmon->ssctl.sq_node = svc->node; in ssctl_new_server()
444 sysmon->ssctl.sq_port = svc->port; in ssctl_new_server()
446 svc->priv = sysmon; in ssctl_new_server()
448 complete(&sysmon->ssctl_comp); in ssctl_new_server()
454 * ssctl_del_server() - QMI callback indicating that @svc is removed
460 struct qcom_sysmon *sysmon = svc->priv; in ssctl_del_server()
462 sysmon->ssctl_version = 0; in ssctl_del_server()
475 .subsys_name = sysmon->name, in sysmon_prepare()
479 mutex_lock(&sysmon->state_lock); in sysmon_prepare()
480 sysmon->state = SSCTL_SSR_EVENT_BEFORE_POWERUP; in sysmon_prepare()
482 mutex_unlock(&sysmon->state_lock); in sysmon_prepare()
488 * sysmon_start() - start callback for the sysmon remoteproc subdevice
502 .subsys_name = sysmon->name, in sysmon_start()
506 reinit_completion(&sysmon->ssctl_comp); in sysmon_start()
507 mutex_lock(&sysmon->state_lock); in sysmon_start()
508 sysmon->state = SSCTL_SSR_EVENT_AFTER_POWERUP; in sysmon_start()
510 mutex_unlock(&sysmon->state_lock); in sysmon_start()
514 mutex_lock(&target->state_lock); in sysmon_start()
515 if (target == sysmon || target->state != SSCTL_SSR_EVENT_AFTER_POWERUP) { in sysmon_start()
516 mutex_unlock(&target->state_lock); in sysmon_start()
520 event.subsys_name = target->name; in sysmon_start()
521 event.ssr_event = target->state; in sysmon_start()
523 if (sysmon->ssctl_version == 2) in sysmon_start()
525 else if (sysmon->ept) in sysmon_start()
527 mutex_unlock(&target->state_lock); in sysmon_start()
538 .subsys_name = sysmon->name, in sysmon_stop()
542 sysmon->shutdown_acked = false; in sysmon_stop()
544 mutex_lock(&sysmon->state_lock); in sysmon_stop()
545 sysmon->state = SSCTL_SSR_EVENT_BEFORE_SHUTDOWN; in sysmon_stop()
547 mutex_unlock(&sysmon->state_lock); in sysmon_stop()
553 if (sysmon->ssctl_instance) { in sysmon_stop()
554 if (!wait_for_completion_timeout(&sysmon->ssctl_comp, HZ / 2)) in sysmon_stop()
555 dev_err(sysmon->dev, "timeout waiting for ssctl service\n"); in sysmon_stop()
558 if (sysmon->ssctl_version) in sysmon_stop()
559 sysmon->shutdown_acked = ssctl_request_shutdown(sysmon); in sysmon_stop()
560 else if (sysmon->ept) in sysmon_stop()
561 sysmon->shutdown_acked = sysmon_request_shutdown(sysmon); in sysmon_stop()
569 .subsys_name = sysmon->name, in sysmon_unprepare()
573 mutex_lock(&sysmon->state_lock); in sysmon_unprepare()
574 sysmon->state = SSCTL_SSR_EVENT_AFTER_SHUTDOWN; in sysmon_unprepare()
576 mutex_unlock(&sysmon->state_lock); in sysmon_unprepare()
580 * sysmon_notify() - notify sysmon target of another's SSR
591 /* Skip non-running rprocs and the originating instance */ in sysmon_notify()
592 if (sysmon->state != SSCTL_SSR_EVENT_AFTER_POWERUP || in sysmon_notify()
593 !strcmp(sysmon_event->subsys_name, sysmon->name)) { in sysmon_notify()
594 dev_dbg(sysmon->dev, "not notifying %s\n", sysmon->name); in sysmon_notify()
599 if (sysmon->ssctl_version == 2) in sysmon_notify()
601 else if (sysmon->ept) in sysmon_notify()
611 complete(&sysmon->shutdown_comp); in sysmon_shutdown_interrupt()
617 * qcom_add_sysmon_subdev() - create a sysmon subdev for the given remoteproc
619 * @name: name of this subdev, to use in SSR
625 const char *name, in qcom_add_sysmon_subdev() argument
633 return ERR_PTR(-ENOMEM); in qcom_add_sysmon_subdev()
635 sysmon->dev = rproc->dev.parent; in qcom_add_sysmon_subdev()
636 sysmon->rproc = rproc; in qcom_add_sysmon_subdev()
638 sysmon->name = name; in qcom_add_sysmon_subdev()
639 sysmon->ssctl_instance = ssctl_instance; in qcom_add_sysmon_subdev()
641 init_completion(&sysmon->comp); in qcom_add_sysmon_subdev()
642 init_completion(&sysmon->ind_comp); in qcom_add_sysmon_subdev()
643 init_completion(&sysmon->shutdown_comp); in qcom_add_sysmon_subdev()
644 init_completion(&sysmon->ssctl_comp); in qcom_add_sysmon_subdev()
645 mutex_init(&sysmon->lock); in qcom_add_sysmon_subdev()
646 mutex_init(&sysmon->state_lock); in qcom_add_sysmon_subdev()
648 sysmon->shutdown_irq = of_irq_get_byname(sysmon->dev->of_node, in qcom_add_sysmon_subdev()
649 "shutdown-ack"); in qcom_add_sysmon_subdev()
650 if (sysmon->shutdown_irq < 0) { in qcom_add_sysmon_subdev()
651 if (sysmon->shutdown_irq != -ENODATA) { in qcom_add_sysmon_subdev()
652 dev_err(sysmon->dev, in qcom_add_sysmon_subdev()
653 "failed to retrieve shutdown-ack IRQ\n"); in qcom_add_sysmon_subdev()
654 ret = sysmon->shutdown_irq; in qcom_add_sysmon_subdev()
659 ret = devm_request_threaded_irq(sysmon->dev, in qcom_add_sysmon_subdev()
660 sysmon->shutdown_irq, in qcom_add_sysmon_subdev()
663 "q6v5 shutdown-ack", sysmon); in qcom_add_sysmon_subdev()
665 dev_err(sysmon->dev, in qcom_add_sysmon_subdev()
666 "failed to acquire shutdown-ack IRQ\n"); in qcom_add_sysmon_subdev()
672 ret = qmi_handle_init(&sysmon->qmi, SSCTL_MAX_MSG_LEN, &ssctl_ops, in qcom_add_sysmon_subdev()
675 dev_err(sysmon->dev, "failed to initialize qmi handle\n"); in qcom_add_sysmon_subdev()
680 qmi_add_lookup(&sysmon->qmi, 43, 0, 0); in qcom_add_sysmon_subdev()
682 sysmon->subdev.prepare = sysmon_prepare; in qcom_add_sysmon_subdev()
683 sysmon->subdev.start = sysmon_start; in qcom_add_sysmon_subdev()
684 sysmon->subdev.stop = sysmon_stop; in qcom_add_sysmon_subdev()
685 sysmon->subdev.unprepare = sysmon_unprepare; in qcom_add_sysmon_subdev()
687 rproc_add_subdev(rproc, &sysmon->subdev); in qcom_add_sysmon_subdev()
689 sysmon->nb.notifier_call = sysmon_notify; in qcom_add_sysmon_subdev()
690 blocking_notifier_chain_register(&sysmon_notifiers, &sysmon->nb); in qcom_add_sysmon_subdev()
693 list_add(&sysmon->node, &sysmon_list); in qcom_add_sysmon_subdev()
701 * qcom_remove_sysmon_subdev() - release a qcom_sysmon
710 list_del(&sysmon->node); in qcom_remove_sysmon_subdev()
713 blocking_notifier_chain_unregister(&sysmon_notifiers, &sysmon->nb); in qcom_remove_sysmon_subdev()
715 rproc_remove_subdev(sysmon->rproc, &sysmon->subdev); in qcom_remove_sysmon_subdev()
717 qmi_handle_release(&sysmon->qmi); in qcom_remove_sysmon_subdev()
724 * qcom_sysmon_shutdown_acked() - query the success of the last shutdown
735 return sysmon && sysmon->shutdown_acked; in qcom_sysmon_shutdown_acked()
740 * sysmon_probe() - probe sys_mon channel
741 * @rpdev: rpmsg device handle
744 * this rpmsg device with said sysmon context.
753 rproc = rproc_get_by_child(&rpdev->dev); in sysmon_probe()
755 dev_err(&rpdev->dev, "sysmon device not child of rproc\n"); in sysmon_probe()
756 return -EINVAL; in sysmon_probe()
761 if (sysmon->rproc == rproc) in sysmon_probe()
766 dev_err(&rpdev->dev, "no sysmon associated with parent rproc\n"); in sysmon_probe()
768 return -EINVAL; in sysmon_probe()
773 rpdev->ept->priv = sysmon; in sysmon_probe()
774 sysmon->ept = rpdev->ept; in sysmon_probe()
780 * sysmon_remove() - sys_mon channel remove handler
781 * @rpdev: rpmsg device handle
783 * Disassociate the rpmsg device with the sysmon instance.
787 struct qcom_sysmon *sysmon = rpdev->ept->priv; in sysmon_remove()
789 sysmon->ept = NULL; in sysmon_remove()
803 .name = "qcom_sysmon",