blob: 81101775fed02b663863ccebeef53767188040fc [file] [log] [blame]
Bjorn Andersson026dad42016-09-01 15:27:59 -07001/*
2 * remote processor messaging bus
3 *
4 * Copyright (C) 2011 Texas Instruments, Inc.
5 * Copyright (C) 2011 Google, Inc.
6 *
7 * Ohad Ben-Cohen <ohad@wizery.com>
8 * Brian Swetland <swetland@google.com>
9 *
10 * This software is licensed under the terms of the GNU General Public
11 * License version 2, as published by the Free Software Foundation, and
12 * may be copied, distributed, and modified under those terms.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 */
19
20#define pr_fmt(fmt) "%s: " fmt, __func__
21
22#include <linux/kernel.h>
23#include <linux/rpmsg.h>
24
Bjorn Andersson8b881c02016-09-01 15:28:02 -070025#include "rpmsg_internal.h"
26
Bjorn Andersson026dad42016-09-01 15:27:59 -070027/**
28 * rpmsg_create_ept() - create a new rpmsg_endpoint
29 * @rpdev: rpmsg channel device
30 * @cb: rx callback handler
31 * @priv: private data for the driver's use
32 * @chinfo: channel_info with the local rpmsg address to bind with @cb
33 *
34 * Every rpmsg address in the system is bound to an rx callback (so when
35 * inbound messages arrive, they are dispatched by the rpmsg bus using the
36 * appropriate callback handler) by means of an rpmsg_endpoint struct.
37 *
38 * This function allows drivers to create such an endpoint, and by that,
39 * bind a callback, and possibly some private data too, to an rpmsg address
40 * (either one that is known in advance, or one that will be dynamically
41 * assigned for them).
42 *
43 * Simple rpmsg drivers need not call rpmsg_create_ept, because an endpoint
44 * is already created for them when they are probed by the rpmsg bus
45 * (using the rx callback provided when they registered to the rpmsg bus).
46 *
47 * So things should just work for simple drivers: they already have an
48 * endpoint, their rx callback is bound to their rpmsg address, and when
49 * relevant inbound messages arrive (i.e. messages which their dst address
50 * equals to the src address of their rpmsg channel), the driver's handler
51 * is invoked to process it.
52 *
53 * That said, more complicated drivers might do need to allocate
54 * additional rpmsg addresses, and bind them to different rx callbacks.
55 * To accomplish that, those drivers need to call this function.
56 *
57 * Drivers should provide their @rpdev channel (so the new endpoint would belong
58 * to the same remote processor their channel belongs to), an rx callback
59 * function, an optional private data (which is provided back when the
60 * rx callback is invoked), and an address they want to bind with the
61 * callback. If @addr is RPMSG_ADDR_ANY, then rpmsg_create_ept will
62 * dynamically assign them an available rpmsg address (drivers should have
63 * a very good reason why not to always use RPMSG_ADDR_ANY here).
64 *
65 * Returns a pointer to the endpoint on success, or NULL on error.
66 */
67struct rpmsg_endpoint *rpmsg_create_ept(struct rpmsg_device *rpdev,
68 rpmsg_rx_cb_t cb, void *priv,
69 struct rpmsg_channel_info chinfo)
70{
71 return rpdev->ops->create_ept(rpdev, cb, priv, chinfo);
72}
73EXPORT_SYMBOL(rpmsg_create_ept);
Bjorn Anderssonc9bd6f42016-09-01 15:28:01 -070074
75/**
76 * rpmsg_destroy_ept() - destroy an existing rpmsg endpoint
77 * @ept: endpoing to destroy
78 *
79 * Should be used by drivers to destroy an rpmsg endpoint previously
80 * created with rpmsg_create_ept().
81 */
82void rpmsg_destroy_ept(struct rpmsg_endpoint *ept)
83{
84 ept->ops->destroy_ept(ept);
85}
86EXPORT_SYMBOL(rpmsg_destroy_ept);
87
88/**
89 * rpmsg_send() - send a message across to the remote processor
90 * @ept: the rpmsg endpoint
91 * @data: payload of message
92 * @len: length of payload
93 *
94 * This function sends @data of length @len on the @ept endpoint.
95 * The message will be sent to the remote processor which the @ept
96 * endpoint belongs to, using @ept's address and its associated rpmsg
97 * device destination addresses.
98 * In case there are no TX buffers available, the function will block until
99 * one becomes available, or a timeout of 15 seconds elapses. When the latter
100 * happens, -ERESTARTSYS is returned.
101 *
102 * Can only be called from process context (for now).
103 *
104 * Returns 0 on success and an appropriate error value on failure.
105 */
106int rpmsg_send(struct rpmsg_endpoint *ept, void *data, int len)
107{
108 return ept->ops->send(ept, data, len);
109}
110EXPORT_SYMBOL(rpmsg_send);
111
112/**
113 * rpmsg_sendto() - send a message across to the remote processor, specify dst
114 * @ept: the rpmsg endpoint
115 * @data: payload of message
116 * @len: length of payload
117 * @dst: destination address
118 *
119 * This function sends @data of length @len to the remote @dst address.
120 * The message will be sent to the remote processor which the @ept
121 * endpoint belongs to, using @ept's address as source.
122 * In case there are no TX buffers available, the function will block until
123 * one becomes available, or a timeout of 15 seconds elapses. When the latter
124 * happens, -ERESTARTSYS is returned.
125 *
126 * Can only be called from process context (for now).
127 *
128 * Returns 0 on success and an appropriate error value on failure.
129 */
130int rpmsg_sendto(struct rpmsg_endpoint *ept, void *data, int len, u32 dst)
131{
132 return ept->ops->sendto(ept, data, len, dst);
133}
134EXPORT_SYMBOL(rpmsg_sendto);
135
136/**
137 * rpmsg_send_offchannel() - send a message using explicit src/dst addresses
138 * @ept: the rpmsg endpoint
139 * @src: source address
140 * @dst: destination address
141 * @data: payload of message
142 * @len: length of payload
143 *
144 * This function sends @data of length @len to the remote @dst address,
145 * and uses @src as the source address.
146 * The message will be sent to the remote processor which the @ept
147 * endpoint belongs to.
148 * In case there are no TX buffers available, the function will block until
149 * one becomes available, or a timeout of 15 seconds elapses. When the latter
150 * happens, -ERESTARTSYS is returned.
151 *
152 * Can only be called from process context (for now).
153 *
154 * Returns 0 on success and an appropriate error value on failure.
155 */
156int rpmsg_send_offchannel(struct rpmsg_endpoint *ept, u32 src, u32 dst,
157 void *data, int len)
158{
159 return ept->ops->send_offchannel(ept, src, dst, data, len);
160}
161EXPORT_SYMBOL(rpmsg_send_offchannel);
162
163/**
164 * rpmsg_send() - send a message across to the remote processor
165 * @ept: the rpmsg endpoint
166 * @data: payload of message
167 * @len: length of payload
168 *
169 * This function sends @data of length @len on the @ept endpoint.
170 * The message will be sent to the remote processor which the @ept
171 * endpoint belongs to, using @ept's address as source and its associated
172 * rpdev's address as destination.
173 * In case there are no TX buffers available, the function will immediately
174 * return -ENOMEM without waiting until one becomes available.
175 *
176 * Can only be called from process context (for now).
177 *
178 * Returns 0 on success and an appropriate error value on failure.
179 */
180int rpmsg_trysend(struct rpmsg_endpoint *ept, void *data, int len)
181{
182 return ept->ops->trysend(ept, data, len);
183}
184EXPORT_SYMBOL(rpmsg_trysend);
185
186/**
187 * rpmsg_sendto() - send a message across to the remote processor, specify dst
188 * @ept: the rpmsg endpoint
189 * @data: payload of message
190 * @len: length of payload
191 * @dst: destination address
192 *
193 * This function sends @data of length @len to the remote @dst address.
194 * The message will be sent to the remote processor which the @ept
195 * endpoint belongs to, using @ept's address as source.
196 * In case there are no TX buffers available, the function will immediately
197 * return -ENOMEM without waiting until one becomes available.
198 *
199 * Can only be called from process context (for now).
200 *
201 * Returns 0 on success and an appropriate error value on failure.
202 */
203int rpmsg_trysendto(struct rpmsg_endpoint *ept, void *data, int len, u32 dst)
204{
205 return ept->ops->trysendto(ept, data, len, dst);
206}
207EXPORT_SYMBOL(rpmsg_trysendto);
208
209/**
210 * rpmsg_send_offchannel() - send a message using explicit src/dst addresses
211 * @ept: the rpmsg endpoint
212 * @src: source address
213 * @dst: destination address
214 * @data: payload of message
215 * @len: length of payload
216 *
217 * This function sends @data of length @len to the remote @dst address,
218 * and uses @src as the source address.
219 * The message will be sent to the remote processor which the @ept
220 * endpoint belongs to.
221 * In case there are no TX buffers available, the function will immediately
222 * return -ENOMEM without waiting until one becomes available.
223 *
224 * Can only be called from process context (for now).
225 *
226 * Returns 0 on success and an appropriate error value on failure.
227 */
228int rpmsg_trysend_offchannel(struct rpmsg_endpoint *ept, u32 src, u32 dst,
229 void *data, int len)
230{
231 return ept->ops->trysend_offchannel(ept, src, dst, data, len);
232}
233EXPORT_SYMBOL(rpmsg_trysend_offchannel);
Bjorn Andersson8b881c02016-09-01 15:28:02 -0700234
235/*
236 * match an rpmsg channel with a channel info struct.
237 * this is used to make sure we're not creating rpmsg devices for channels
238 * that already exist.
239 */
240static int rpmsg_device_match(struct device *dev, void *data)
241{
242 struct rpmsg_channel_info *chinfo = data;
243 struct rpmsg_device *rpdev = to_rpmsg_device(dev);
244
245 if (chinfo->src != RPMSG_ADDR_ANY && chinfo->src != rpdev->src)
246 return 0;
247
248 if (chinfo->dst != RPMSG_ADDR_ANY && chinfo->dst != rpdev->dst)
249 return 0;
250
251 if (strncmp(chinfo->name, rpdev->id.name, RPMSG_NAME_SIZE))
252 return 0;
253
254 /* found a match ! */
255 return 1;
256}
257
258struct device *rpmsg_find_device(struct device *parent,
259 struct rpmsg_channel_info *chinfo)
260{
261 return device_find_child(parent, chinfo, rpmsg_device_match);
262
263}
264EXPORT_SYMBOL(rpmsg_find_device);