aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rpmsg
diff options
context:
space:
mode:
authorBjorn Andersson <bjorn.andersson@linaro.org>2016-09-01 18:28:04 -0400
committerBjorn Andersson <bjorn.andersson@linaro.org>2016-09-09 01:15:23 -0400
commit5e619b48677ca8c9fb907c58383859cea78705c9 (patch)
treef67ad937b0c8531b0e3cad8d28acb2229733db72 /drivers/rpmsg
parent6eed598a049193917a2e15b163abb58c5c1ef466 (diff)
rpmsg: Split rpmsg core and virtio backend
Extract the generic rpmsg core functionality from the virtio rpmsg implementation, splitting the implementation in a rpmsg core and a virtio backend. Based on initial work by Sricharan R <sricharan@codeaurora.org> Cc: Sricharan R <sricharan@codeaurora.org> Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Diffstat (limited to 'drivers/rpmsg')
-rw-r--r--drivers/rpmsg/rpmsg_core.c231
-rw-r--r--drivers/rpmsg/rpmsg_internal.h4
-rw-r--r--drivers/rpmsg/virtio_rpmsg_bus.c225
3 files changed, 237 insertions, 223 deletions
diff --git a/drivers/rpmsg/rpmsg_core.c b/drivers/rpmsg/rpmsg_core.c
index 81101775fed0..e1d765a7372c 100644
--- a/drivers/rpmsg/rpmsg_core.c
+++ b/drivers/rpmsg/rpmsg_core.c
@@ -262,3 +262,234 @@ struct device *rpmsg_find_device(struct device *parent,
262 262
263} 263}
264EXPORT_SYMBOL(rpmsg_find_device); 264EXPORT_SYMBOL(rpmsg_find_device);
265
266/* sysfs show configuration fields */
267#define rpmsg_show_attr(field, path, format_string) \
268static ssize_t \
269field##_show(struct device *dev, \
270 struct device_attribute *attr, char *buf) \
271{ \
272 struct rpmsg_device *rpdev = to_rpmsg_device(dev); \
273 \
274 return sprintf(buf, format_string, rpdev->path); \
275}
276
277/* for more info, see Documentation/ABI/testing/sysfs-bus-rpmsg */
278rpmsg_show_attr(name, id.name, "%s\n");
279rpmsg_show_attr(src, src, "0x%x\n");
280rpmsg_show_attr(dst, dst, "0x%x\n");
281rpmsg_show_attr(announce, announce ? "true" : "false", "%s\n");
282
283static ssize_t modalias_show(struct device *dev,
284 struct device_attribute *attr, char *buf)
285{
286 struct rpmsg_device *rpdev = to_rpmsg_device(dev);
287
288 return sprintf(buf, RPMSG_DEVICE_MODALIAS_FMT "\n", rpdev->id.name);
289}
290
291static struct device_attribute rpmsg_dev_attrs[] = {
292 __ATTR_RO(name),
293 __ATTR_RO(modalias),
294 __ATTR_RO(dst),
295 __ATTR_RO(src),
296 __ATTR_RO(announce),
297 __ATTR_NULL
298};
299
300/* rpmsg devices and drivers are matched using the service name */
301static inline int rpmsg_id_match(const struct rpmsg_device *rpdev,
302 const struct rpmsg_device_id *id)
303{
304 return strncmp(id->name, rpdev->id.name, RPMSG_NAME_SIZE) == 0;
305}
306
307/* match rpmsg channel and rpmsg driver */
308static int rpmsg_dev_match(struct device *dev, struct device_driver *drv)
309{
310 struct rpmsg_device *rpdev = to_rpmsg_device(dev);
311 struct rpmsg_driver *rpdrv = to_rpmsg_driver(drv);
312 const struct rpmsg_device_id *ids = rpdrv->id_table;
313 unsigned int i;
314
315 if (ids)
316 for (i = 0; ids[i].name[0]; i++)
317 if (rpmsg_id_match(rpdev, &ids[i]))
318 return 1;
319
320 return of_driver_match_device(dev, drv);
321}
322
323static int rpmsg_uevent(struct device *dev, struct kobj_uevent_env *env)
324{
325 struct rpmsg_device *rpdev = to_rpmsg_device(dev);
326
327 return add_uevent_var(env, "MODALIAS=" RPMSG_DEVICE_MODALIAS_FMT,
328 rpdev->id.name);
329}
330
331/*
332 * when an rpmsg driver is probed with a channel, we seamlessly create
333 * it an endpoint, binding its rx callback to a unique local rpmsg
334 * address.
335 *
336 * if we need to, we also announce about this channel to the remote
337 * processor (needed in case the driver is exposing an rpmsg service).
338 */
339static int rpmsg_dev_probe(struct device *dev)
340{
341 struct rpmsg_device *rpdev = to_rpmsg_device(dev);
342 struct rpmsg_driver *rpdrv = to_rpmsg_driver(rpdev->dev.driver);
343 struct rpmsg_channel_info chinfo = {};
344 struct rpmsg_endpoint *ept;
345 int err;
346
347 strncpy(chinfo.name, rpdev->id.name, RPMSG_NAME_SIZE);
348 chinfo.src = rpdev->src;
349 chinfo.dst = RPMSG_ADDR_ANY;
350
351 ept = rpmsg_create_ept(rpdev, rpdrv->callback, NULL, chinfo);
352 if (!ept) {
353 dev_err(dev, "failed to create endpoint\n");
354 err = -ENOMEM;
355 goto out;
356 }
357
358 rpdev->ept = ept;
359 rpdev->src = ept->addr;
360
361 err = rpdrv->probe(rpdev);
362 if (err) {
363 dev_err(dev, "%s: failed: %d\n", __func__, err);
364 rpmsg_destroy_ept(ept);
365 goto out;
366 }
367
368 if (rpdev->ops->announce_create)
369 err = rpdev->ops->announce_create(rpdev);
370out:
371 return err;
372}
373
374static int rpmsg_dev_remove(struct device *dev)
375{
376 struct rpmsg_device *rpdev = to_rpmsg_device(dev);
377 struct rpmsg_driver *rpdrv = to_rpmsg_driver(rpdev->dev.driver);
378 int err = 0;
379
380 if (rpdev->ops->announce_destroy)
381 err = rpdev->ops->announce_destroy(rpdev);
382
383 rpdrv->remove(rpdev);
384
385 rpmsg_destroy_ept(rpdev->ept);
386
387 return err;
388}
389
390static struct bus_type rpmsg_bus = {
391 .name = "rpmsg",
392 .match = rpmsg_dev_match,
393 .dev_attrs = rpmsg_dev_attrs,
394 .uevent = rpmsg_uevent,
395 .probe = rpmsg_dev_probe,
396 .remove = rpmsg_dev_remove,
397};
398
399static void rpmsg_release_device(struct device *dev)
400{
401 struct rpmsg_device *rpdev = to_rpmsg_device(dev);
402
403 kfree(rpdev);
404}
405
406int rpmsg_register_device(struct rpmsg_device *rpdev)
407{
408 struct device *dev = &rpdev->dev;
409 int ret;
410
411 dev_set_name(&rpdev->dev, "%s:%s",
412 dev_name(dev->parent), rpdev->id.name);
413
414 rpdev->dev.bus = &rpmsg_bus;
415 rpdev->dev.release = rpmsg_release_device;
416
417 ret = device_register(&rpdev->dev);
418 if (ret) {
419 dev_err(dev, "device_register failed: %d\n", ret);
420 put_device(&rpdev->dev);
421 }
422
423 return ret;
424}
425EXPORT_SYMBOL(rpmsg_register_device);
426
427/*
428 * find an existing channel using its name + address properties,
429 * and destroy it
430 */
431int rpmsg_unregister_device(struct device *parent,
432 struct rpmsg_channel_info *chinfo)
433{
434 struct device *dev;
435
436 dev = rpmsg_find_device(parent, chinfo);
437 if (!dev)
438 return -EINVAL;
439
440 device_unregister(dev);
441
442 put_device(dev);
443
444 return 0;
445}
446EXPORT_SYMBOL(rpmsg_unregister_device);
447
448/**
449 * __register_rpmsg_driver() - register an rpmsg driver with the rpmsg bus
450 * @rpdrv: pointer to a struct rpmsg_driver
451 * @owner: owning module/driver
452 *
453 * Returns 0 on success, and an appropriate error value on failure.
454 */
455int __register_rpmsg_driver(struct rpmsg_driver *rpdrv, struct module *owner)
456{
457 rpdrv->drv.bus = &rpmsg_bus;
458 rpdrv->drv.owner = owner;
459 return driver_register(&rpdrv->drv);
460}
461EXPORT_SYMBOL(__register_rpmsg_driver);
462
463/**
464 * unregister_rpmsg_driver() - unregister an rpmsg driver from the rpmsg bus
465 * @rpdrv: pointer to a struct rpmsg_driver
466 *
467 * Returns 0 on success, and an appropriate error value on failure.
468 */
469void unregister_rpmsg_driver(struct rpmsg_driver *rpdrv)
470{
471 driver_unregister(&rpdrv->drv);
472}
473EXPORT_SYMBOL(unregister_rpmsg_driver);
474
475
476static int __init rpmsg_init(void)
477{
478 int ret;
479
480 ret = bus_register(&rpmsg_bus);
481 if (ret)
482 pr_err("failed to register rpmsg bus: %d\n", ret);
483
484 return ret;
485}
486postcore_initcall(rpmsg_init);
487
488static void __exit rpmsg_fini(void)
489{
490 bus_unregister(&rpmsg_bus);
491}
492module_exit(rpmsg_fini);
493
494MODULE_DESCRIPTION("remote processor messaging bus");
495MODULE_LICENSE("GPL v2");
diff --git a/drivers/rpmsg/rpmsg_internal.h b/drivers/rpmsg/rpmsg_internal.h
index 205debf4ea65..8ac98fd0bf1d 100644
--- a/drivers/rpmsg/rpmsg_internal.h
+++ b/drivers/rpmsg/rpmsg_internal.h
@@ -25,6 +25,10 @@
25#define to_rpmsg_device(d) container_of(d, struct rpmsg_device, dev) 25#define to_rpmsg_device(d) container_of(d, struct rpmsg_device, dev)
26#define to_rpmsg_driver(d) container_of(d, struct rpmsg_driver, drv) 26#define to_rpmsg_driver(d) container_of(d, struct rpmsg_driver, drv)
27 27
28int rpmsg_register_device(struct rpmsg_device *rpdev);
29int rpmsg_unregister_device(struct device *parent,
30 struct rpmsg_channel_info *chinfo);
31
28struct device *rpmsg_find_device(struct device *parent, 32struct device *rpmsg_find_device(struct device *parent,
29 struct rpmsg_channel_info *chinfo); 33 struct rpmsg_channel_info *chinfo);
30 34
diff --git a/drivers/rpmsg/virtio_rpmsg_bus.c b/drivers/rpmsg/virtio_rpmsg_bus.c
index e1052622c6a2..31cd526f690d 100644
--- a/drivers/rpmsg/virtio_rpmsg_bus.c
+++ b/drivers/rpmsg/virtio_rpmsg_bus.c
@@ -75,9 +75,6 @@ struct virtproc_info {
75 struct rpmsg_endpoint *ns_ept; 75 struct rpmsg_endpoint *ns_ept;
76}; 76};
77 77
78#define to_rpmsg_device(d) container_of(d, struct rpmsg_device, dev)
79#define to_rpmsg_driver(d) container_of(d, struct rpmsg_driver, drv)
80
81/* 78/*
82 * We're allocating buffers of 512 bytes each for communications. The 79 * We're allocating buffers of 512 bytes each for communications. The
83 * number of buffers will be computed from the number of buffers supported 80 * number of buffers will be computed from the number of buffers supported
@@ -120,72 +117,6 @@ static int virtio_rpmsg_trysendto(struct rpmsg_endpoint *ept, void *data,
120 int len, u32 dst); 117 int len, u32 dst);
121static int virtio_rpmsg_trysend_offchannel(struct rpmsg_endpoint *ept, u32 src, 118static int virtio_rpmsg_trysend_offchannel(struct rpmsg_endpoint *ept, u32 src,
122 u32 dst, void *data, int len); 119 u32 dst, void *data, int len);
123static int rpmsg_register_device(struct rpmsg_device *rpdev);
124
125/* sysfs show configuration fields */
126#define rpmsg_show_attr(field, path, format_string) \
127static ssize_t \
128field##_show(struct device *dev, \
129 struct device_attribute *attr, char *buf) \
130{ \
131 struct rpmsg_device *rpdev = to_rpmsg_device(dev); \
132 \
133 return sprintf(buf, format_string, rpdev->path); \
134}
135
136/* for more info, see Documentation/ABI/testing/sysfs-bus-rpmsg */
137rpmsg_show_attr(name, id.name, "%s\n");
138rpmsg_show_attr(src, src, "0x%x\n");
139rpmsg_show_attr(dst, dst, "0x%x\n");
140rpmsg_show_attr(announce, announce ? "true" : "false", "%s\n");
141
142static ssize_t modalias_show(struct device *dev,
143 struct device_attribute *attr, char *buf)
144{
145 struct rpmsg_device *rpdev = to_rpmsg_device(dev);
146
147 return sprintf(buf, RPMSG_DEVICE_MODALIAS_FMT "\n", rpdev->id.name);
148}
149
150static struct device_attribute rpmsg_dev_attrs[] = {
151 __ATTR_RO(name),
152 __ATTR_RO(modalias),
153 __ATTR_RO(dst),
154 __ATTR_RO(src),
155 __ATTR_RO(announce),
156 __ATTR_NULL
157};
158
159/* rpmsg devices and drivers are matched using the service name */
160static inline int rpmsg_id_match(const struct rpmsg_device *rpdev,
161 const struct rpmsg_device_id *id)
162{
163 return strncmp(id->name, rpdev->id.name, RPMSG_NAME_SIZE) == 0;
164}
165
166/* match rpmsg channel and rpmsg driver */
167static int rpmsg_dev_match(struct device *dev, struct device_driver *drv)
168{
169 struct rpmsg_device *rpdev = to_rpmsg_device(dev);
170 struct rpmsg_driver *rpdrv = to_rpmsg_driver(drv);
171 const struct rpmsg_device_id *ids = rpdrv->id_table;
172 unsigned int i;
173
174 if (ids)
175 for (i = 0; ids[i].name[0]; i++)
176 if (rpmsg_id_match(rpdev, &ids[i]))
177 return 1;
178
179 return of_driver_match_device(dev, drv);
180}
181
182static int rpmsg_uevent(struct device *dev, struct kobj_uevent_env *env)
183{
184 struct rpmsg_device *rpdev = to_rpmsg_device(dev);
185
186 return add_uevent_var(env, "MODALIAS=" RPMSG_DEVICE_MODALIAS_FMT,
187 rpdev->id.name);
188}
189 120
190static const struct rpmsg_endpoint_ops virtio_endpoint_ops = { 121static const struct rpmsg_endpoint_ops virtio_endpoint_ops = {
191 .destroy_ept = virtio_rpmsg_destroy_ept, 122 .destroy_ept = virtio_rpmsg_destroy_ept,
@@ -307,49 +238,6 @@ static void virtio_rpmsg_destroy_ept(struct rpmsg_endpoint *ept)
307 __rpmsg_destroy_ept(ept->rpdev->vrp, ept); 238 __rpmsg_destroy_ept(ept->rpdev->vrp, ept);
308} 239}
309 240
310/*
311 * when an rpmsg driver is probed with a channel, we seamlessly create
312 * it an endpoint, binding its rx callback to a unique local rpmsg
313 * address.
314 *
315 * if we need to, we also announce about this channel to the remote
316 * processor (needed in case the driver is exposing an rpmsg service).
317 */
318static int rpmsg_dev_probe(struct device *dev)
319{
320 struct rpmsg_device *rpdev = to_rpmsg_device(dev);
321 struct rpmsg_driver *rpdrv = to_rpmsg_driver(rpdev->dev.driver);
322 struct rpmsg_channel_info chinfo = {};
323 struct rpmsg_endpoint *ept;
324 int err;
325
326 strncpy(chinfo.name, rpdev->id.name, RPMSG_NAME_SIZE);
327 chinfo.src = rpdev->src;
328 chinfo.dst = RPMSG_ADDR_ANY;
329
330 ept = rpmsg_create_ept(rpdev, rpdrv->callback, NULL, chinfo);
331 if (!ept) {
332 dev_err(dev, "failed to create endpoint\n");
333 err = -ENOMEM;
334 goto out;
335 }
336
337 rpdev->ept = ept;
338 rpdev->src = ept->addr;
339
340 err = rpdrv->probe(rpdev);
341 if (err) {
342 dev_err(dev, "%s: failed: %d\n", __func__, err);
343 rpmsg_destroy_ept(ept);
344 goto out;
345 }
346
347 if (rpdev->ops->announce_create)
348 err = rpdev->ops->announce_create(rpdev);
349out:
350 return err;
351}
352
353static int virtio_rpmsg_announce_create(struct rpmsg_device *rpdev) 241static int virtio_rpmsg_announce_create(struct rpmsg_device *rpdev)
354{ 242{
355 struct virtproc_info *vrp = rpdev->vrp; 243 struct virtproc_info *vrp = rpdev->vrp;
@@ -396,65 +284,6 @@ static int virtio_rpmsg_announce_destroy(struct rpmsg_device *rpdev)
396 return err; 284 return err;
397} 285}
398 286
399static int rpmsg_dev_remove(struct device *dev)
400{
401 struct rpmsg_device *rpdev = to_rpmsg_device(dev);
402 struct rpmsg_driver *rpdrv = to_rpmsg_driver(rpdev->dev.driver);
403 int err = 0;
404
405 if (rpdev->ops->announce_destroy)
406 err = rpdev->ops->announce_destroy(rpdev);
407
408 rpdrv->remove(rpdev);
409
410 rpmsg_destroy_ept(rpdev->ept);
411
412 return err;
413}
414
415static struct bus_type rpmsg_bus = {
416 .name = "rpmsg",
417 .match = rpmsg_dev_match,
418 .dev_attrs = rpmsg_dev_attrs,
419 .uevent = rpmsg_uevent,
420 .probe = rpmsg_dev_probe,
421 .remove = rpmsg_dev_remove,
422};
423
424/**
425 * __register_rpmsg_driver() - register an rpmsg driver with the rpmsg bus
426 * @rpdrv: pointer to a struct rpmsg_driver
427 * @owner: owning module/driver
428 *
429 * Returns 0 on success, and an appropriate error value on failure.
430 */
431int __register_rpmsg_driver(struct rpmsg_driver *rpdrv, struct module *owner)
432{
433 rpdrv->drv.bus = &rpmsg_bus;
434 rpdrv->drv.owner = owner;
435 return driver_register(&rpdrv->drv);
436}
437EXPORT_SYMBOL(__register_rpmsg_driver);
438
439/**
440 * unregister_rpmsg_driver() - unregister an rpmsg driver from the rpmsg bus
441 * @rpdrv: pointer to a struct rpmsg_driver
442 *
443 * Returns 0 on success, and an appropriate error value on failure.
444 */
445void unregister_rpmsg_driver(struct rpmsg_driver *rpdrv)
446{
447 driver_unregister(&rpdrv->drv);
448}
449EXPORT_SYMBOL(unregister_rpmsg_driver);
450
451static void rpmsg_release_device(struct device *dev)
452{
453 struct rpmsg_device *rpdev = to_rpmsg_device(dev);
454
455 kfree(rpdev);
456}
457
458static const struct rpmsg_device_ops virtio_rpmsg_ops = { 287static const struct rpmsg_device_ops virtio_rpmsg_ops = {
459 .create_ept = virtio_rpmsg_create_ept, 288 .create_ept = virtio_rpmsg_create_ept,
460 .announce_create = virtio_rpmsg_announce_create, 289 .announce_create = virtio_rpmsg_announce_create,
@@ -508,47 +337,6 @@ static struct rpmsg_device *rpmsg_create_channel(struct virtproc_info *vrp,
508 return rpdev; 337 return rpdev;
509} 338}
510 339
511static int rpmsg_register_device(struct rpmsg_device *rpdev)
512{
513 struct device *dev = &rpdev->dev;
514 int ret;
515
516 dev_set_name(&rpdev->dev, "%s:%s",
517 dev_name(dev->parent), rpdev->id.name);
518
519 rpdev->dev.bus = &rpmsg_bus;
520 rpdev->dev.release = rpmsg_release_device;
521
522 ret = device_register(&rpdev->dev);
523 if (ret) {
524 dev_err(dev, "device_register failed: %d\n", ret);
525 put_device(&rpdev->dev);
526 }
527
528 return ret;
529}
530
531/*
532 * find an existing channel using its name + address properties,
533 * and destroy it
534 */
535static int rpmsg_destroy_channel(struct virtproc_info *vrp,
536 struct rpmsg_channel_info *chinfo)
537{
538 struct virtio_device *vdev = vrp->vdev;
539 struct device *dev;
540
541 dev = rpmsg_find_device(&vdev->dev, chinfo);
542 if (!dev)
543 return -EINVAL;
544
545 device_unregister(dev);
546
547 put_device(dev);
548
549 return 0;
550}
551
552/* super simple buffer "allocator" that is just enough for now */ 340/* super simple buffer "allocator" that is just enough for now */
553static void *get_a_tx_buf(struct virtproc_info *vrp) 341static void *get_a_tx_buf(struct virtproc_info *vrp)
554{ 342{
@@ -967,7 +755,7 @@ static void rpmsg_ns_cb(struct rpmsg_device *rpdev, void *data, int len,
967 chinfo.dst = msg->addr; 755 chinfo.dst = msg->addr;
968 756
969 if (msg->flags & RPMSG_NS_DESTROY) { 757 if (msg->flags & RPMSG_NS_DESTROY) {
970 ret = rpmsg_destroy_channel(vrp, &chinfo); 758 ret = rpmsg_unregister_device(&vrp->vdev->dev, &chinfo);
971 if (ret) 759 if (ret)
972 dev_err(dev, "rpmsg_destroy_channel failed: %d\n", ret); 760 dev_err(dev, "rpmsg_destroy_channel failed: %d\n", ret);
973 } else { 761 } else {
@@ -1152,17 +940,9 @@ static int __init rpmsg_init(void)
1152{ 940{
1153 int ret; 941 int ret;
1154 942
1155 ret = bus_register(&rpmsg_bus);
1156 if (ret) {
1157 pr_err("failed to register rpmsg bus: %d\n", ret);
1158 return ret;
1159 }
1160
1161 ret = register_virtio_driver(&virtio_ipc_driver); 943 ret = register_virtio_driver(&virtio_ipc_driver);
1162 if (ret) { 944 if (ret)
1163 pr_err("failed to register virtio driver: %d\n", ret); 945 pr_err("failed to register virtio driver: %d\n", ret);
1164 bus_unregister(&rpmsg_bus);
1165 }
1166 946
1167 return ret; 947 return ret;
1168} 948}
@@ -1171,7 +951,6 @@ subsys_initcall(rpmsg_init);
1171static void __exit rpmsg_fini(void) 951static void __exit rpmsg_fini(void)
1172{ 952{
1173 unregister_virtio_driver(&virtio_ipc_driver); 953 unregister_virtio_driver(&virtio_ipc_driver);
1174 bus_unregister(&rpmsg_bus);
1175} 954}
1176module_exit(rpmsg_fini); 955module_exit(rpmsg_fini);
1177 956