1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20#define pr_fmt(fmt) "%s: " fmt, __func__
21
22#include <linux/kernel.h>
23#include <linux/module.h>
24#include <linux/rpmsg.h>
25#include <linux/of_device.h>
26#include <linux/slab.h>
27
28#include "rpmsg_internal.h"
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70struct rpmsg_endpoint *rpmsg_create_ept(struct rpmsg_device *rpdev,
71 rpmsg_rx_cb_t cb, void *priv,
72 struct rpmsg_channel_info chinfo)
73{
74 if (WARN_ON(!rpdev))
75 return NULL;
76
77 return rpdev->ops->create_ept(rpdev, cb, priv, chinfo);
78}
79EXPORT_SYMBOL(rpmsg_create_ept);
80
81
82
83
84
85
86
87
88
89void rpmsg_destroy_ept(struct rpmsg_endpoint *ept)
90{
91 if (ept)
92 ept->ops->destroy_ept(ept);
93}
94EXPORT_SYMBOL(rpmsg_destroy_ept);
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114int rpmsg_send(struct rpmsg_endpoint *ept, void *data, int len)
115{
116 if (WARN_ON(!ept))
117 return -EINVAL;
118 if (!ept->ops->send)
119 return -ENXIO;
120
121 return ept->ops->send(ept, data, len);
122}
123EXPORT_SYMBOL(rpmsg_send);
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143int rpmsg_sendto(struct rpmsg_endpoint *ept, void *data, int len, u32 dst)
144{
145 if (WARN_ON(!ept))
146 return -EINVAL;
147 if (!ept->ops->sendto)
148 return -ENXIO;
149
150 return ept->ops->sendto(ept, data, len, dst);
151}
152EXPORT_SYMBOL(rpmsg_sendto);
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174int rpmsg_send_offchannel(struct rpmsg_endpoint *ept, u32 src, u32 dst,
175 void *data, int len)
176{
177 if (WARN_ON(!ept))
178 return -EINVAL;
179 if (!ept->ops->send_offchannel)
180 return -ENXIO;
181
182 return ept->ops->send_offchannel(ept, src, dst, data, len);
183}
184EXPORT_SYMBOL(rpmsg_send_offchannel);
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203int rpmsg_trysend(struct rpmsg_endpoint *ept, void *data, int len)
204{
205 if (WARN_ON(!ept))
206 return -EINVAL;
207 if (!ept->ops->trysend)
208 return -ENXIO;
209
210 return ept->ops->trysend(ept, data, len);
211}
212EXPORT_SYMBOL(rpmsg_trysend);
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231int rpmsg_trysendto(struct rpmsg_endpoint *ept, void *data, int len, u32 dst)
232{
233 if (WARN_ON(!ept))
234 return -EINVAL;
235 if (!ept->ops->trysendto)
236 return -ENXIO;
237
238 return ept->ops->trysendto(ept, data, len, dst);
239}
240EXPORT_SYMBOL(rpmsg_trysendto);
241
242
243
244
245
246
247
248
249
250unsigned int rpmsg_poll(struct rpmsg_endpoint *ept, struct file *filp,
251 poll_table *wait)
252{
253 if (WARN_ON(!ept))
254 return 0;
255 if (!ept->ops->poll)
256 return 0;
257
258 return ept->ops->poll(ept, filp, wait);
259}
260EXPORT_SYMBOL(rpmsg_poll);
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281int rpmsg_trysend_offchannel(struct rpmsg_endpoint *ept, u32 src, u32 dst,
282 void *data, int len)
283{
284 if (WARN_ON(!ept))
285 return -EINVAL;
286 if (!ept->ops->trysend_offchannel)
287 return -ENXIO;
288
289 return ept->ops->trysend_offchannel(ept, src, dst, data, len);
290}
291EXPORT_SYMBOL(rpmsg_trysend_offchannel);
292
293
294
295
296
297
298static int rpmsg_device_match(struct device *dev, void *data)
299{
300 struct rpmsg_channel_info *chinfo = data;
301 struct rpmsg_device *rpdev = to_rpmsg_device(dev);
302
303 if (chinfo->src != RPMSG_ADDR_ANY && chinfo->src != rpdev->src)
304 return 0;
305
306 if (chinfo->dst != RPMSG_ADDR_ANY && chinfo->dst != rpdev->dst)
307 return 0;
308
309 if (strncmp(chinfo->name, rpdev->id.name, RPMSG_NAME_SIZE))
310 return 0;
311
312
313 return 1;
314}
315
316struct device *rpmsg_find_device(struct device *parent,
317 struct rpmsg_channel_info *chinfo)
318{
319 return device_find_child(parent, chinfo, rpmsg_device_match);
320
321}
322EXPORT_SYMBOL(rpmsg_find_device);
323
324
325#define rpmsg_show_attr(field, path, format_string) \
326static ssize_t \
327field##_show(struct device *dev, \
328 struct device_attribute *attr, char *buf) \
329{ \
330 struct rpmsg_device *rpdev = to_rpmsg_device(dev); \
331 \
332 return sprintf(buf, format_string, rpdev->path); \
333} \
334static DEVICE_ATTR_RO(field);
335
336
337rpmsg_show_attr(name, id.name, "%s\n");
338rpmsg_show_attr(src, src, "0x%x\n");
339rpmsg_show_attr(dst, dst, "0x%x\n");
340rpmsg_show_attr(announce, announce ? "true" : "false", "%s\n");
341
342static ssize_t modalias_show(struct device *dev,
343 struct device_attribute *attr, char *buf)
344{
345 struct rpmsg_device *rpdev = to_rpmsg_device(dev);
346 ssize_t len;
347
348 len = of_device_modalias(dev, buf, PAGE_SIZE);
349 if (len != -ENODEV)
350 return len;
351
352 return sprintf(buf, RPMSG_DEVICE_MODALIAS_FMT "\n", rpdev->id.name);
353}
354static DEVICE_ATTR_RO(modalias);
355
356static struct attribute *rpmsg_dev_attrs[] = {
357 &dev_attr_name.attr,
358 &dev_attr_modalias.attr,
359 &dev_attr_dst.attr,
360 &dev_attr_src.attr,
361 &dev_attr_announce.attr,
362 NULL,
363};
364ATTRIBUTE_GROUPS(rpmsg_dev);
365
366
367static inline int rpmsg_id_match(const struct rpmsg_device *rpdev,
368 const struct rpmsg_device_id *id)
369{
370 return strncmp(id->name, rpdev->id.name, RPMSG_NAME_SIZE) == 0;
371}
372
373
374static int rpmsg_dev_match(struct device *dev, struct device_driver *drv)
375{
376 struct rpmsg_device *rpdev = to_rpmsg_device(dev);
377 struct rpmsg_driver *rpdrv = to_rpmsg_driver(drv);
378 const struct rpmsg_device_id *ids = rpdrv->id_table;
379 unsigned int i;
380
381 if (rpdev->driver_override)
382 return !strcmp(rpdev->driver_override, drv->name);
383
384 if (ids)
385 for (i = 0; ids[i].name[0]; i++)
386 if (rpmsg_id_match(rpdev, &ids[i]))
387 return 1;
388
389 return of_driver_match_device(dev, drv);
390}
391
392static int rpmsg_uevent(struct device *dev, struct kobj_uevent_env *env)
393{
394 struct rpmsg_device *rpdev = to_rpmsg_device(dev);
395 int ret;
396
397 ret = of_device_uevent_modalias(dev, env);
398 if (ret != -ENODEV)
399 return ret;
400
401 return add_uevent_var(env, "MODALIAS=" RPMSG_DEVICE_MODALIAS_FMT,
402 rpdev->id.name);
403}
404
405
406
407
408
409
410
411
412
413static int rpmsg_dev_probe(struct device *dev)
414{
415 struct rpmsg_device *rpdev = to_rpmsg_device(dev);
416 struct rpmsg_driver *rpdrv = to_rpmsg_driver(rpdev->dev.driver);
417 struct rpmsg_channel_info chinfo = {};
418 struct rpmsg_endpoint *ept = NULL;
419 int err;
420
421 if (rpdrv->callback) {
422 strncpy(chinfo.name, rpdev->id.name, RPMSG_NAME_SIZE);
423 chinfo.src = rpdev->src;
424 chinfo.dst = RPMSG_ADDR_ANY;
425
426 ept = rpmsg_create_ept(rpdev, rpdrv->callback, NULL, chinfo);
427 if (!ept) {
428 dev_err(dev, "failed to create endpoint\n");
429 err = -ENOMEM;
430 goto out;
431 }
432
433 rpdev->ept = ept;
434 rpdev->src = ept->addr;
435 }
436
437 err = rpdrv->probe(rpdev);
438 if (err) {
439 dev_err(dev, "%s: failed: %d\n", __func__, err);
440 if (ept)
441 rpmsg_destroy_ept(ept);
442 goto out;
443 }
444
445 if (rpdev->ops->announce_create)
446 err = rpdev->ops->announce_create(rpdev);
447out:
448 return err;
449}
450
451static int rpmsg_dev_remove(struct device *dev)
452{
453 struct rpmsg_device *rpdev = to_rpmsg_device(dev);
454 struct rpmsg_driver *rpdrv = to_rpmsg_driver(rpdev->dev.driver);
455 int err = 0;
456
457 if (rpdev->ops->announce_destroy)
458 err = rpdev->ops->announce_destroy(rpdev);
459
460 rpdrv->remove(rpdev);
461
462 if (rpdev->ept)
463 rpmsg_destroy_ept(rpdev->ept);
464
465 return err;
466}
467
468static struct bus_type rpmsg_bus = {
469 .name = "rpmsg",
470 .match = rpmsg_dev_match,
471 .dev_groups = rpmsg_dev_groups,
472 .uevent = rpmsg_uevent,
473 .probe = rpmsg_dev_probe,
474 .remove = rpmsg_dev_remove,
475};
476
477int rpmsg_register_device(struct rpmsg_device *rpdev)
478{
479 struct device *dev = &rpdev->dev;
480 int ret;
481
482 dev_set_name(&rpdev->dev, "%s.%s.%d.%d", dev_name(dev->parent),
483 rpdev->id.name, rpdev->src, rpdev->dst);
484
485 rpdev->dev.bus = &rpmsg_bus;
486
487 ret = device_register(&rpdev->dev);
488 if (ret) {
489 dev_err(dev, "device_register failed: %d\n", ret);
490 put_device(&rpdev->dev);
491 }
492
493 return ret;
494}
495EXPORT_SYMBOL(rpmsg_register_device);
496
497
498
499
500
501int rpmsg_unregister_device(struct device *parent,
502 struct rpmsg_channel_info *chinfo)
503{
504 struct device *dev;
505
506 dev = rpmsg_find_device(parent, chinfo);
507 if (!dev)
508 return -EINVAL;
509
510 device_unregister(dev);
511
512 put_device(dev);
513
514 return 0;
515}
516EXPORT_SYMBOL(rpmsg_unregister_device);
517
518
519
520
521
522
523
524
525int __register_rpmsg_driver(struct rpmsg_driver *rpdrv, struct module *owner)
526{
527 rpdrv->drv.bus = &rpmsg_bus;
528 rpdrv->drv.owner = owner;
529 return driver_register(&rpdrv->drv);
530}
531EXPORT_SYMBOL(__register_rpmsg_driver);
532
533
534
535
536
537
538
539void unregister_rpmsg_driver(struct rpmsg_driver *rpdrv)
540{
541 driver_unregister(&rpdrv->drv);
542}
543EXPORT_SYMBOL(unregister_rpmsg_driver);
544
545
546static int __init rpmsg_init(void)
547{
548 int ret;
549
550 ret = bus_register(&rpmsg_bus);
551 if (ret)
552 pr_err("failed to register rpmsg bus: %d\n", ret);
553
554 return ret;
555}
556postcore_initcall(rpmsg_init);
557
558static void __exit rpmsg_fini(void)
559{
560 bus_unregister(&rpmsg_bus);
561}
562module_exit(rpmsg_fini);
563
564MODULE_DESCRIPTION("remote processor messaging bus");
565MODULE_LICENSE("GPL v2");
566