Lines Matching +full:rpmsg +full:- +full:name
1 // SPDX-License-Identifier: GPL-2.0
15 #include <linux/rpmsg.h>
30 const char *name; member
75 * sysmon_send_event() - send notification of other remote's SSR event
86 len = snprintf(req, sizeof(req), "ssr:%s:%s", event->subsys_name, in sysmon_send_event()
87 sysmon_state_string[event->ssr_event]); in sysmon_send_event()
91 mutex_lock(&sysmon->lock); in sysmon_send_event()
92 reinit_completion(&sysmon->comp); in sysmon_send_event()
93 sysmon->ssr_ack = false; in sysmon_send_event()
95 ret = rpmsg_send(sysmon->ept, req, len); in sysmon_send_event()
97 dev_err(sysmon->dev, "failed to send sysmon event\n"); in sysmon_send_event()
101 ret = wait_for_completion_timeout(&sysmon->comp, in sysmon_send_event()
104 dev_err(sysmon->dev, "timeout waiting for sysmon ack\n"); in sysmon_send_event()
108 if (!sysmon->ssr_ack) in sysmon_send_event()
109 dev_err(sysmon->dev, "unexpected response to sysmon event\n"); in sysmon_send_event()
112 mutex_unlock(&sysmon->lock); in sysmon_send_event()
116 * sysmon_request_shutdown() - request graceful shutdown of remote
124 mutex_lock(&sysmon->lock); in sysmon_request_shutdown()
125 reinit_completion(&sysmon->comp); in sysmon_request_shutdown()
126 sysmon->ssr_ack = false; in sysmon_request_shutdown()
128 ret = rpmsg_send(sysmon->ept, req, strlen(req) + 1); in sysmon_request_shutdown()
130 dev_err(sysmon->dev, "send sysmon shutdown request failed\n"); in sysmon_request_shutdown()
134 ret = wait_for_completion_timeout(&sysmon->comp, in sysmon_request_shutdown()
137 dev_err(sysmon->dev, "timeout waiting for sysmon ack\n"); in sysmon_request_shutdown()
141 if (!sysmon->ssr_ack) in sysmon_request_shutdown()
142 dev_err(sysmon->dev, in sysmon_request_shutdown()
146 mutex_unlock(&sysmon->lock); in sysmon_request_shutdown()
157 return -EINVAL; in sysmon_callback()
160 sysmon->ssr_ack = true; in sysmon_callback()
162 complete(&sysmon->comp); in sysmon_callback()
286 complete(&sysmon->ind_comp); in sysmon_ind_cb()
301 * ssctl_request_shutdown() - request shutdown via SSCTL QMI service
310 reinit_completion(&sysmon->ind_comp); in ssctl_request_shutdown()
311 reinit_completion(&sysmon->shutdown_comp); in ssctl_request_shutdown()
312 ret = qmi_txn_init(&sysmon->qmi, &txn, ssctl_shutdown_resp_ei, &resp); in ssctl_request_shutdown()
314 dev_err(sysmon->dev, "failed to allocate QMI txn\n"); in ssctl_request_shutdown()
318 ret = qmi_send_request(&sysmon->qmi, &sysmon->ssctl, &txn, in ssctl_request_shutdown()
321 dev_err(sysmon->dev, "failed to send shutdown request\n"); in ssctl_request_shutdown()
328 dev_err(sysmon->dev, "failed receiving QMI response\n"); in ssctl_request_shutdown()
330 dev_err(sysmon->dev, "shutdown request failed\n"); in ssctl_request_shutdown()
332 dev_dbg(sysmon->dev, "shutdown request completed\n"); in ssctl_request_shutdown()
334 if (sysmon->shutdown_irq > 0) { in ssctl_request_shutdown()
335 ret = wait_for_completion_timeout(&sysmon->shutdown_comp, in ssctl_request_shutdown()
338 ret = try_wait_for_completion(&sysmon->ind_comp); in ssctl_request_shutdown()
340 dev_err(sysmon->dev, in ssctl_request_shutdown()
347 * ssctl_send_event() - send notification of other remote's SSR event
360 ret = qmi_txn_init(&sysmon->qmi, &txn, ssctl_subsys_event_resp_ei, &resp); in ssctl_send_event()
362 dev_err(sysmon->dev, "failed to allocate QMI txn\n"); in ssctl_send_event()
367 strlcpy(req.subsys_name, event->subsys_name, sizeof(req.subsys_name)); in ssctl_send_event()
369 req.event = event->ssr_event; in ssctl_send_event()
373 ret = qmi_send_request(&sysmon->qmi, &sysmon->ssctl, &txn, in ssctl_send_event()
377 dev_err(sysmon->dev, "failed to send shutdown request\n"); in ssctl_send_event()
384 dev_err(sysmon->dev, "failed receiving QMI response\n"); in ssctl_send_event()
386 dev_err(sysmon->dev, "ssr event send failed\n"); in ssctl_send_event()
388 dev_dbg(sysmon->dev, "ssr event send completed\n"); in ssctl_send_event()
392 * ssctl_new_server() - QMI callback indicating a new service
396 * Return: 0 if we're interested in this service, -EINVAL otherwise.
402 switch (svc->version) { in ssctl_new_server()
404 if (svc->instance != 0) in ssctl_new_server()
405 return -EINVAL; in ssctl_new_server()
406 if (strcmp(sysmon->name, "modem")) in ssctl_new_server()
407 return -EINVAL; in ssctl_new_server()
410 if (svc->instance != sysmon->ssctl_instance) in ssctl_new_server()
411 return -EINVAL; in ssctl_new_server()
414 return -EINVAL; in ssctl_new_server()
417 sysmon->ssctl_version = svc->version; in ssctl_new_server()
419 sysmon->ssctl.sq_family = AF_QIPCRTR; in ssctl_new_server()
420 sysmon->ssctl.sq_node = svc->node; in ssctl_new_server()
421 sysmon->ssctl.sq_port = svc->port; in ssctl_new_server()
423 svc->priv = sysmon; in ssctl_new_server()
429 * ssctl_del_server() - QMI callback indicating that @svc is removed
435 struct qcom_sysmon *sysmon = svc->priv; in ssctl_del_server()
437 sysmon->ssctl_version = 0; in ssctl_del_server()
450 .subsys_name = sysmon->name, in sysmon_prepare()
454 mutex_lock(&sysmon->state_lock); in sysmon_prepare()
455 sysmon->state = SSCTL_SSR_EVENT_BEFORE_POWERUP; in sysmon_prepare()
457 mutex_unlock(&sysmon->state_lock); in sysmon_prepare()
463 * sysmon_start() - start callback for the sysmon remoteproc subdevice
477 .subsys_name = sysmon->name, in sysmon_start()
481 mutex_lock(&sysmon->state_lock); in sysmon_start()
482 sysmon->state = SSCTL_SSR_EVENT_AFTER_POWERUP; in sysmon_start()
484 mutex_unlock(&sysmon->state_lock); in sysmon_start()
491 mutex_lock(&target->state_lock); in sysmon_start()
492 event.subsys_name = target->name; in sysmon_start()
493 event.ssr_event = target->state; in sysmon_start()
495 if (sysmon->ssctl_version == 2) in sysmon_start()
497 else if (sysmon->ept) in sysmon_start()
499 mutex_unlock(&target->state_lock); in sysmon_start()
510 .subsys_name = sysmon->name, in sysmon_stop()
514 mutex_lock(&sysmon->state_lock); in sysmon_stop()
515 sysmon->state = SSCTL_SSR_EVENT_BEFORE_SHUTDOWN; in sysmon_stop()
517 mutex_unlock(&sysmon->state_lock); in sysmon_stop()
523 if (sysmon->ssctl_version) in sysmon_stop()
525 else if (sysmon->ept) in sysmon_stop()
534 .subsys_name = sysmon->name, in sysmon_unprepare()
538 mutex_lock(&sysmon->state_lock); in sysmon_unprepare()
539 sysmon->state = SSCTL_SSR_EVENT_AFTER_SHUTDOWN; in sysmon_unprepare()
541 mutex_unlock(&sysmon->state_lock); in sysmon_unprepare()
545 * sysmon_notify() - notify sysmon target of another's SSR
556 /* Skip non-running rprocs and the originating instance */ in sysmon_notify()
557 if (sysmon->state != SSCTL_SSR_EVENT_AFTER_POWERUP || in sysmon_notify()
558 !strcmp(sysmon_event->subsys_name, sysmon->name)) { in sysmon_notify()
559 dev_dbg(sysmon->dev, "not notifying %s\n", sysmon->name); in sysmon_notify()
564 if (sysmon->ssctl_version == 2) in sysmon_notify()
566 else if (sysmon->ept) in sysmon_notify()
576 complete(&sysmon->shutdown_comp); in sysmon_shutdown_interrupt()
582 * qcom_add_sysmon_subdev() - create a sysmon subdev for the given remoteproc
584 * @name: name of this subdev, to use in SSR
590 const char *name, in qcom_add_sysmon_subdev() argument
598 return ERR_PTR(-ENOMEM); in qcom_add_sysmon_subdev()
600 sysmon->dev = rproc->dev.parent; in qcom_add_sysmon_subdev()
601 sysmon->rproc = rproc; in qcom_add_sysmon_subdev()
603 sysmon->name = name; in qcom_add_sysmon_subdev()
604 sysmon->ssctl_instance = ssctl_instance; in qcom_add_sysmon_subdev()
606 init_completion(&sysmon->comp); in qcom_add_sysmon_subdev()
607 init_completion(&sysmon->ind_comp); in qcom_add_sysmon_subdev()
608 init_completion(&sysmon->shutdown_comp); in qcom_add_sysmon_subdev()
609 mutex_init(&sysmon->lock); in qcom_add_sysmon_subdev()
610 mutex_init(&sysmon->state_lock); in qcom_add_sysmon_subdev()
612 sysmon->shutdown_irq = of_irq_get_byname(sysmon->dev->of_node, in qcom_add_sysmon_subdev()
613 "shutdown-ack"); in qcom_add_sysmon_subdev()
614 if (sysmon->shutdown_irq < 0) { in qcom_add_sysmon_subdev()
615 if (sysmon->shutdown_irq != -ENODATA) { in qcom_add_sysmon_subdev()
616 dev_err(sysmon->dev, in qcom_add_sysmon_subdev()
617 "failed to retrieve shutdown-ack IRQ\n"); in qcom_add_sysmon_subdev()
618 return ERR_PTR(sysmon->shutdown_irq); in qcom_add_sysmon_subdev()
621 ret = devm_request_threaded_irq(sysmon->dev, in qcom_add_sysmon_subdev()
622 sysmon->shutdown_irq, in qcom_add_sysmon_subdev()
625 "q6v5 shutdown-ack", sysmon); in qcom_add_sysmon_subdev()
627 dev_err(sysmon->dev, in qcom_add_sysmon_subdev()
628 "failed to acquire shutdown-ack IRQ\n"); in qcom_add_sysmon_subdev()
633 ret = qmi_handle_init(&sysmon->qmi, SSCTL_MAX_MSG_LEN, &ssctl_ops, in qcom_add_sysmon_subdev()
636 dev_err(sysmon->dev, "failed to initialize qmi handle\n"); in qcom_add_sysmon_subdev()
641 qmi_add_lookup(&sysmon->qmi, 43, 0, 0); in qcom_add_sysmon_subdev()
643 sysmon->subdev.prepare = sysmon_prepare; in qcom_add_sysmon_subdev()
644 sysmon->subdev.start = sysmon_start; in qcom_add_sysmon_subdev()
645 sysmon->subdev.stop = sysmon_stop; in qcom_add_sysmon_subdev()
646 sysmon->subdev.unprepare = sysmon_unprepare; in qcom_add_sysmon_subdev()
648 rproc_add_subdev(rproc, &sysmon->subdev); in qcom_add_sysmon_subdev()
650 sysmon->nb.notifier_call = sysmon_notify; in qcom_add_sysmon_subdev()
651 blocking_notifier_chain_register(&sysmon_notifiers, &sysmon->nb); in qcom_add_sysmon_subdev()
654 list_add(&sysmon->node, &sysmon_list); in qcom_add_sysmon_subdev()
662 * qcom_remove_sysmon_subdev() - release a qcom_sysmon
671 list_del(&sysmon->node); in qcom_remove_sysmon_subdev()
674 blocking_notifier_chain_unregister(&sysmon_notifiers, &sysmon->nb); in qcom_remove_sysmon_subdev()
676 rproc_remove_subdev(sysmon->rproc, &sysmon->subdev); in qcom_remove_sysmon_subdev()
678 qmi_handle_release(&sysmon->qmi); in qcom_remove_sysmon_subdev()
685 * sysmon_probe() - probe sys_mon channel
686 * @rpdev: rpmsg device handle
689 * this rpmsg device with said sysmon context.
698 rproc = rproc_get_by_child(&rpdev->dev); in sysmon_probe()
700 dev_err(&rpdev->dev, "sysmon device not child of rproc\n"); in sysmon_probe()
701 return -EINVAL; in sysmon_probe()
706 if (sysmon->rproc == rproc) in sysmon_probe()
711 dev_err(&rpdev->dev, "no sysmon associated with parent rproc\n"); in sysmon_probe()
713 return -EINVAL; in sysmon_probe()
718 rpdev->ept->priv = sysmon; in sysmon_probe()
719 sysmon->ept = rpdev->ept; in sysmon_probe()
725 * sysmon_remove() - sys_mon channel remove handler
726 * @rpdev: rpmsg device handle
728 * Disassociate the rpmsg device with the sysmon instance.
732 struct qcom_sysmon *sysmon = rpdev->ept->priv; in sysmon_remove()
734 sysmon->ept = NULL; in sysmon_remove()
748 .name = "qcom_sysmon",