blob: 03e164b12406bd96bcb63c408400781eff369059 [file] [log] [blame]
Mikael Olsson7c843dc2023-08-03 12:41:48 +02001/*
Mikael Olssond4ad9e52024-02-07 11:22:26 +01002 * SPDX-FileCopyrightText: Copyright 2023-2024 Arm Limited and/or its affiliates <open-source-office@arm.com>
3 * SPDX-License-Identifier: GPL-2.0-only
Mikael Olsson7c843dc2023-08-03 12:41:48 +02004 *
5 * This program is free software and is provided to you under the terms of the
6 * GNU General Public License version 2 as published by the Free Software
7 * Foundation, and any use by you of this program is subject to the terms
8 * of such GNU licence.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, you can access it online at
17 * http://www.gnu.org/licenses/gpl-2.0.html.
Mikael Olsson7c843dc2023-08-03 12:41:48 +020018 */
19
20/****************************************************************************
21 * Includes
22 ****************************************************************************/
23
Mikael Olssond4ad9e52024-02-07 11:22:26 +010024#include <rpmsg/ethosu_rpmsg_version.h>
25#include <rpmsg/ethosu_rpmsg.h>
Mikael Olsson7c843dc2023-08-03 12:41:48 +020026
27#include <linux/errno.h>
28
29/****************************************************************************
30 * Defines
31 ****************************************************************************/
32
33#define VERSION_RESP_TIMEOUT_MS 2000
34
35/****************************************************************************
36 * Functions
37 ****************************************************************************/
38
39static void ethosu_version_fail(struct ethosu_mailbox_msg *msg)
40{
41 struct ethosu_version *version =
42 container_of(msg, typeof(*version), msg);
43
44 if (completion_done(&version->done))
45 return;
46
47 version->errno = -EFAULT;
48 complete(&version->done);
49}
50
51void ethosu_version_rsp(struct ethosu_mailbox *mailbox,
52 int msg_id,
53 struct ethosu_core_msg_version_rsp *rsp)
54{
55 struct device *dev = mailbox->dev;
56 struct ethosu_mailbox_msg *msg;
57 struct ethosu_version *version;
58
59 msg = ethosu_mailbox_find(mailbox, msg_id,
60 ETHOSU_CORE_MSG_VERSION_REQ);
61 if (IS_ERR(msg)) {
62 dev_warn(dev,
63 "Id for version msg not found. Id=0x%0x: %ld\n",
64 msg_id, PTR_ERR(msg));
65
66 return;
67 }
68
69 version = container_of(msg, typeof(*version), msg);
70
71 if (completion_done(&version->done))
72 return;
73
74 if (rsp->major != ETHOSU_CORE_MSG_VERSION_MAJOR ||
75 rsp->minor != ETHOSU_CORE_MSG_VERSION_MINOR) {
76 dev_warn(dev,
77 "Msg: Protocol version mismatch. Expected %u.%u.X but got %u.%u.%u",
78 ETHOSU_CORE_MSG_VERSION_MAJOR,
79 ETHOSU_CORE_MSG_VERSION_MINOR,
80 rsp->major, rsp->minor, rsp->patch);
81 version->errno = -EPROTO;
82 } else {
83 version->errno = 0;
84 }
85
86 complete(&version->done);
87}
88
89int ethosu_version_check_request(struct device *dev,
90 struct ethosu_mailbox *mailbox)
91{
92 struct ethosu_version *version;
93 int ret;
94 int timeout;
95
96 version = devm_kzalloc(dev, sizeof(*version), GFP_KERNEL);
97 if (!version)
98 return -ENOMEM;
99
100 version->dev = dev;
101 init_completion(&version->done);
102 version->msg.fail = ethosu_version_fail;
103
104 ret = ethosu_mailbox_register(mailbox, &version->msg);
105 if (ret < 0)
106 goto free_version;
107
108 dev_dbg(dev, "Protocol version request created. Id=0x%x, handle=%pK\n",
109 version->msg.id, version);
110
111 ret = ethosu_mailbox_version_request(mailbox, &version->msg);
112 if (ret)
113 goto deregister;
114
115 /* Unlock the mutex to not block other messages while waiting */
116 device_unlock(dev);
117
118 /* Wait for version response */
119 timeout = wait_for_completion_timeout(&version->done,
120 msecs_to_jiffies(
121 VERSION_RESP_TIMEOUT_MS));
122
123 /* Take back the mutex before resuming to do anything */
124 device_lock(dev);
125
126 if (0 == timeout) {
127 dev_warn(dev, "Protocol version response timeout");
128 ret = -ETIME;
129 goto deregister;
130 }
131
132 if (version->errno) {
133 ret = version->errno;
134 goto deregister;
135 }
136
137deregister:
138 ethosu_mailbox_deregister(mailbox, &version->msg);
139
140free_version:
141 dev_dbg(dev, "Protocol version destroy. Id=0x%x, handle=%pK\n",
142 version->msg.id,
143 version);
144 devm_kfree(dev, version);
145
146 return ret;
147}