cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

rpmsg_core.c (20200B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * remote processor messaging bus
      4 *
      5 * Copyright (C) 2011 Texas Instruments, Inc.
      6 * Copyright (C) 2011 Google, Inc.
      7 *
      8 * Ohad Ben-Cohen <ohad@wizery.com>
      9 * Brian Swetland <swetland@google.com>
     10 */
     11
     12#define pr_fmt(fmt) "%s: " fmt, __func__
     13
     14#include <linux/kernel.h>
     15#include <linux/module.h>
     16#include <linux/rpmsg.h>
     17#include <linux/of_device.h>
     18#include <linux/pm_domain.h>
     19#include <linux/slab.h>
     20
     21#include "rpmsg_internal.h"
     22
     23struct class *rpmsg_class;
     24EXPORT_SYMBOL(rpmsg_class);
     25
     26/**
     27 * rpmsg_create_channel() - create a new rpmsg channel
     28 * using its name and address info.
     29 * @rpdev: rpmsg device
     30 * @chinfo: channel_info to bind
     31 *
     32 * Return: a pointer to the new rpmsg device on success, or NULL on error.
     33 */
     34struct rpmsg_device *rpmsg_create_channel(struct rpmsg_device *rpdev,
     35					  struct rpmsg_channel_info *chinfo)
     36{
     37	if (WARN_ON(!rpdev))
     38		return NULL;
     39	if (!rpdev->ops || !rpdev->ops->create_channel) {
     40		dev_err(&rpdev->dev, "no create_channel ops found\n");
     41		return NULL;
     42	}
     43
     44	return rpdev->ops->create_channel(rpdev, chinfo);
     45}
     46EXPORT_SYMBOL(rpmsg_create_channel);
     47
     48/**
     49 * rpmsg_release_channel() - release a rpmsg channel
     50 * using its name and address info.
     51 * @rpdev: rpmsg device
     52 * @chinfo: channel_info to bind
     53 *
     54 * Return: 0 on success or an appropriate error value.
     55 */
     56int rpmsg_release_channel(struct rpmsg_device *rpdev,
     57			  struct rpmsg_channel_info *chinfo)
     58{
     59	if (WARN_ON(!rpdev))
     60		return -EINVAL;
     61	if (!rpdev->ops || !rpdev->ops->release_channel) {
     62		dev_err(&rpdev->dev, "no release_channel ops found\n");
     63		return -ENXIO;
     64	}
     65
     66	return rpdev->ops->release_channel(rpdev, chinfo);
     67}
     68EXPORT_SYMBOL(rpmsg_release_channel);
     69
     70/**
     71 * rpmsg_create_ept() - create a new rpmsg_endpoint
     72 * @rpdev: rpmsg channel device
     73 * @cb: rx callback handler
     74 * @priv: private data for the driver's use
     75 * @chinfo: channel_info with the local rpmsg address to bind with @cb
     76 *
     77 * Every rpmsg address in the system is bound to an rx callback (so when
     78 * inbound messages arrive, they are dispatched by the rpmsg bus using the
     79 * appropriate callback handler) by means of an rpmsg_endpoint struct.
     80 *
     81 * This function allows drivers to create such an endpoint, and by that,
     82 * bind a callback, and possibly some private data too, to an rpmsg address
     83 * (either one that is known in advance, or one that will be dynamically
     84 * assigned for them).
     85 *
     86 * Simple rpmsg drivers need not call rpmsg_create_ept, because an endpoint
     87 * is already created for them when they are probed by the rpmsg bus
     88 * (using the rx callback provided when they registered to the rpmsg bus).
     89 *
     90 * So things should just work for simple drivers: they already have an
     91 * endpoint, their rx callback is bound to their rpmsg address, and when
     92 * relevant inbound messages arrive (i.e. messages which their dst address
     93 * equals to the src address of their rpmsg channel), the driver's handler
     94 * is invoked to process it.
     95 *
     96 * That said, more complicated drivers might need to allocate
     97 * additional rpmsg addresses, and bind them to different rx callbacks.
     98 * To accomplish that, those drivers need to call this function.
     99 *
    100 * Drivers should provide their @rpdev channel (so the new endpoint would belong
    101 * to the same remote processor their channel belongs to), an rx callback
    102 * function, an optional private data (which is provided back when the
    103 * rx callback is invoked), and an address they want to bind with the
    104 * callback. If @addr is RPMSG_ADDR_ANY, then rpmsg_create_ept will
    105 * dynamically assign them an available rpmsg address (drivers should have
    106 * a very good reason why not to always use RPMSG_ADDR_ANY here).
    107 *
    108 * Return: a pointer to the endpoint on success, or NULL on error.
    109 */
    110struct rpmsg_endpoint *rpmsg_create_ept(struct rpmsg_device *rpdev,
    111					rpmsg_rx_cb_t cb, void *priv,
    112					struct rpmsg_channel_info chinfo)
    113{
    114	if (WARN_ON(!rpdev))
    115		return NULL;
    116
    117	return rpdev->ops->create_ept(rpdev, cb, priv, chinfo);
    118}
    119EXPORT_SYMBOL(rpmsg_create_ept);
    120
    121/**
    122 * rpmsg_destroy_ept() - destroy an existing rpmsg endpoint
    123 * @ept: endpoing to destroy
    124 *
    125 * Should be used by drivers to destroy an rpmsg endpoint previously
    126 * created with rpmsg_create_ept(). As with other types of "free" NULL
    127 * is a valid parameter.
    128 */
    129void rpmsg_destroy_ept(struct rpmsg_endpoint *ept)
    130{
    131	if (ept && ept->ops)
    132		ept->ops->destroy_ept(ept);
    133}
    134EXPORT_SYMBOL(rpmsg_destroy_ept);
    135
    136/**
    137 * rpmsg_send() - send a message across to the remote processor
    138 * @ept: the rpmsg endpoint
    139 * @data: payload of message
    140 * @len: length of payload
    141 *
    142 * This function sends @data of length @len on the @ept endpoint.
    143 * The message will be sent to the remote processor which the @ept
    144 * endpoint belongs to, using @ept's address and its associated rpmsg
    145 * device destination addresses.
    146 * In case there are no TX buffers available, the function will block until
    147 * one becomes available, or a timeout of 15 seconds elapses. When the latter
    148 * happens, -ERESTARTSYS is returned.
    149 *
    150 * Can only be called from process context (for now).
    151 *
    152 * Return: 0 on success and an appropriate error value on failure.
    153 */
    154int rpmsg_send(struct rpmsg_endpoint *ept, void *data, int len)
    155{
    156	if (WARN_ON(!ept))
    157		return -EINVAL;
    158	if (!ept->ops->send)
    159		return -ENXIO;
    160
    161	return ept->ops->send(ept, data, len);
    162}
    163EXPORT_SYMBOL(rpmsg_send);
    164
    165/**
    166 * rpmsg_sendto() - send a message across to the remote processor, specify dst
    167 * @ept: the rpmsg endpoint
    168 * @data: payload of message
    169 * @len: length of payload
    170 * @dst: destination address
    171 *
    172 * This function sends @data of length @len to the remote @dst address.
    173 * The message will be sent to the remote processor which the @ept
    174 * endpoint belongs to, using @ept's address as source.
    175 * In case there are no TX buffers available, the function will block until
    176 * one becomes available, or a timeout of 15 seconds elapses. When the latter
    177 * happens, -ERESTARTSYS is returned.
    178 *
    179 * Can only be called from process context (for now).
    180 *
    181 * Return: 0 on success and an appropriate error value on failure.
    182 */
    183int rpmsg_sendto(struct rpmsg_endpoint *ept, void *data, int len, u32 dst)
    184{
    185	if (WARN_ON(!ept))
    186		return -EINVAL;
    187	if (!ept->ops->sendto)
    188		return -ENXIO;
    189
    190	return ept->ops->sendto(ept, data, len, dst);
    191}
    192EXPORT_SYMBOL(rpmsg_sendto);
    193
    194/**
    195 * rpmsg_send_offchannel() - send a message using explicit src/dst addresses
    196 * @ept: the rpmsg endpoint
    197 * @src: source address
    198 * @dst: destination address
    199 * @data: payload of message
    200 * @len: length of payload
    201 *
    202 * This function sends @data of length @len to the remote @dst address,
    203 * and uses @src as the source address.
    204 * The message will be sent to the remote processor which the @ept
    205 * endpoint belongs to.
    206 * In case there are no TX buffers available, the function will block until
    207 * one becomes available, or a timeout of 15 seconds elapses. When the latter
    208 * happens, -ERESTARTSYS is returned.
    209 *
    210 * Can only be called from process context (for now).
    211 *
    212 * Return: 0 on success and an appropriate error value on failure.
    213 */
    214int rpmsg_send_offchannel(struct rpmsg_endpoint *ept, u32 src, u32 dst,
    215			  void *data, int len)
    216{
    217	if (WARN_ON(!ept))
    218		return -EINVAL;
    219	if (!ept->ops->send_offchannel)
    220		return -ENXIO;
    221
    222	return ept->ops->send_offchannel(ept, src, dst, data, len);
    223}
    224EXPORT_SYMBOL(rpmsg_send_offchannel);
    225
    226/**
    227 * rpmsg_trysend() - send a message across to the remote processor
    228 * @ept: the rpmsg endpoint
    229 * @data: payload of message
    230 * @len: length of payload
    231 *
    232 * This function sends @data of length @len on the @ept endpoint.
    233 * The message will be sent to the remote processor which the @ept
    234 * endpoint belongs to, using @ept's address as source and its associated
    235 * rpdev's address as destination.
    236 * In case there are no TX buffers available, the function will immediately
    237 * return -ENOMEM without waiting until one becomes available.
    238 *
    239 * Can only be called from process context (for now).
    240 *
    241 * Return: 0 on success and an appropriate error value on failure.
    242 */
    243int rpmsg_trysend(struct rpmsg_endpoint *ept, void *data, int len)
    244{
    245	if (WARN_ON(!ept))
    246		return -EINVAL;
    247	if (!ept->ops->trysend)
    248		return -ENXIO;
    249
    250	return ept->ops->trysend(ept, data, len);
    251}
    252EXPORT_SYMBOL(rpmsg_trysend);
    253
    254/**
    255 * rpmsg_trysendto() - send a message across to the remote processor, specify dst
    256 * @ept: the rpmsg endpoint
    257 * @data: payload of message
    258 * @len: length of payload
    259 * @dst: destination address
    260 *
    261 * This function sends @data of length @len to the remote @dst address.
    262 * The message will be sent to the remote processor which the @ept
    263 * endpoint belongs to, using @ept's address as source.
    264 * In case there are no TX buffers available, the function will immediately
    265 * return -ENOMEM without waiting until one becomes available.
    266 *
    267 * Can only be called from process context (for now).
    268 *
    269 * Return: 0 on success and an appropriate error value on failure.
    270 */
    271int rpmsg_trysendto(struct rpmsg_endpoint *ept, void *data, int len, u32 dst)
    272{
    273	if (WARN_ON(!ept))
    274		return -EINVAL;
    275	if (!ept->ops->trysendto)
    276		return -ENXIO;
    277
    278	return ept->ops->trysendto(ept, data, len, dst);
    279}
    280EXPORT_SYMBOL(rpmsg_trysendto);
    281
    282/**
    283 * rpmsg_poll() - poll the endpoint's send buffers
    284 * @ept:	the rpmsg endpoint
    285 * @filp:	file for poll_wait()
    286 * @wait:	poll_table for poll_wait()
    287 *
    288 * Return: mask representing the current state of the endpoint's send buffers
    289 */
    290__poll_t rpmsg_poll(struct rpmsg_endpoint *ept, struct file *filp,
    291			poll_table *wait)
    292{
    293	if (WARN_ON(!ept))
    294		return 0;
    295	if (!ept->ops->poll)
    296		return 0;
    297
    298	return ept->ops->poll(ept, filp, wait);
    299}
    300EXPORT_SYMBOL(rpmsg_poll);
    301
    302/**
    303 * rpmsg_trysend_offchannel() - send a message using explicit src/dst addresses
    304 * @ept: the rpmsg endpoint
    305 * @src: source address
    306 * @dst: destination address
    307 * @data: payload of message
    308 * @len: length of payload
    309 *
    310 * This function sends @data of length @len to the remote @dst address,
    311 * and uses @src as the source address.
    312 * The message will be sent to the remote processor which the @ept
    313 * endpoint belongs to.
    314 * In case there are no TX buffers available, the function will immediately
    315 * return -ENOMEM without waiting until one becomes available.
    316 *
    317 * Can only be called from process context (for now).
    318 *
    319 * Return: 0 on success and an appropriate error value on failure.
    320 */
    321int rpmsg_trysend_offchannel(struct rpmsg_endpoint *ept, u32 src, u32 dst,
    322			     void *data, int len)
    323{
    324	if (WARN_ON(!ept))
    325		return -EINVAL;
    326	if (!ept->ops->trysend_offchannel)
    327		return -ENXIO;
    328
    329	return ept->ops->trysend_offchannel(ept, src, dst, data, len);
    330}
    331EXPORT_SYMBOL(rpmsg_trysend_offchannel);
    332
    333/**
    334 * rpmsg_get_mtu() - get maximum transmission buffer size for sending message.
    335 * @ept: the rpmsg endpoint
    336 *
    337 * This function returns maximum buffer size available for a single outgoing message.
    338 *
    339 * Return: the maximum transmission size on success and an appropriate error
    340 * value on failure.
    341 */
    342
    343ssize_t rpmsg_get_mtu(struct rpmsg_endpoint *ept)
    344{
    345	if (WARN_ON(!ept))
    346		return -EINVAL;
    347	if (!ept->ops->get_mtu)
    348		return -ENOTSUPP;
    349
    350	return ept->ops->get_mtu(ept);
    351}
    352EXPORT_SYMBOL(rpmsg_get_mtu);
    353
    354/*
    355 * match a rpmsg channel with a channel info struct.
    356 * this is used to make sure we're not creating rpmsg devices for channels
    357 * that already exist.
    358 */
    359static int rpmsg_device_match(struct device *dev, void *data)
    360{
    361	struct rpmsg_channel_info *chinfo = data;
    362	struct rpmsg_device *rpdev = to_rpmsg_device(dev);
    363
    364	if (chinfo->src != RPMSG_ADDR_ANY && chinfo->src != rpdev->src)
    365		return 0;
    366
    367	if (chinfo->dst != RPMSG_ADDR_ANY && chinfo->dst != rpdev->dst)
    368		return 0;
    369
    370	if (strncmp(chinfo->name, rpdev->id.name, RPMSG_NAME_SIZE))
    371		return 0;
    372
    373	/* found a match ! */
    374	return 1;
    375}
    376
    377struct device *rpmsg_find_device(struct device *parent,
    378				 struct rpmsg_channel_info *chinfo)
    379{
    380	return device_find_child(parent, chinfo, rpmsg_device_match);
    381
    382}
    383EXPORT_SYMBOL(rpmsg_find_device);
    384
    385/* sysfs show configuration fields */
    386#define rpmsg_show_attr(field, path, format_string)			\
    387static ssize_t								\
    388field##_show(struct device *dev,					\
    389			struct device_attribute *attr, char *buf)	\
    390{									\
    391	struct rpmsg_device *rpdev = to_rpmsg_device(dev);		\
    392									\
    393	return sprintf(buf, format_string, rpdev->path);		\
    394}									\
    395static DEVICE_ATTR_RO(field);
    396
    397#define rpmsg_string_attr(field, member)				\
    398static ssize_t								\
    399field##_store(struct device *dev, struct device_attribute *attr,	\
    400	      const char *buf, size_t sz)				\
    401{									\
    402	struct rpmsg_device *rpdev = to_rpmsg_device(dev);		\
    403	const char *old;						\
    404	char *new;							\
    405									\
    406	new = kstrndup(buf, sz, GFP_KERNEL);				\
    407	if (!new)							\
    408		return -ENOMEM;						\
    409	new[strcspn(new, "\n")] = '\0';					\
    410									\
    411	device_lock(dev);						\
    412	old = rpdev->member;						\
    413	if (strlen(new)) {						\
    414		rpdev->member = new;					\
    415	} else {							\
    416		kfree(new);						\
    417		rpdev->member = NULL;					\
    418	}								\
    419	device_unlock(dev);						\
    420									\
    421	kfree(old);							\
    422									\
    423	return sz;							\
    424}									\
    425static ssize_t								\
    426field##_show(struct device *dev,					\
    427	     struct device_attribute *attr, char *buf)			\
    428{									\
    429	struct rpmsg_device *rpdev = to_rpmsg_device(dev);		\
    430									\
    431	return sprintf(buf, "%s\n", rpdev->member);			\
    432}									\
    433static DEVICE_ATTR_RW(field)
    434
    435/* for more info, see Documentation/ABI/testing/sysfs-bus-rpmsg */
    436rpmsg_show_attr(name, id.name, "%s\n");
    437rpmsg_show_attr(src, src, "0x%x\n");
    438rpmsg_show_attr(dst, dst, "0x%x\n");
    439rpmsg_show_attr(announce, announce ? "true" : "false", "%s\n");
    440rpmsg_string_attr(driver_override, driver_override);
    441
    442static ssize_t modalias_show(struct device *dev,
    443			     struct device_attribute *attr, char *buf)
    444{
    445	struct rpmsg_device *rpdev = to_rpmsg_device(dev);
    446	ssize_t len;
    447
    448	len = of_device_modalias(dev, buf, PAGE_SIZE);
    449	if (len != -ENODEV)
    450		return len;
    451
    452	return sprintf(buf, RPMSG_DEVICE_MODALIAS_FMT "\n", rpdev->id.name);
    453}
    454static DEVICE_ATTR_RO(modalias);
    455
    456static struct attribute *rpmsg_dev_attrs[] = {
    457	&dev_attr_name.attr,
    458	&dev_attr_modalias.attr,
    459	&dev_attr_dst.attr,
    460	&dev_attr_src.attr,
    461	&dev_attr_announce.attr,
    462	&dev_attr_driver_override.attr,
    463	NULL,
    464};
    465ATTRIBUTE_GROUPS(rpmsg_dev);
    466
    467/* rpmsg devices and drivers are matched using the service name */
    468static inline int rpmsg_id_match(const struct rpmsg_device *rpdev,
    469				  const struct rpmsg_device_id *id)
    470{
    471	return strncmp(id->name, rpdev->id.name, RPMSG_NAME_SIZE) == 0;
    472}
    473
    474/* match rpmsg channel and rpmsg driver */
    475static int rpmsg_dev_match(struct device *dev, struct device_driver *drv)
    476{
    477	struct rpmsg_device *rpdev = to_rpmsg_device(dev);
    478	struct rpmsg_driver *rpdrv = to_rpmsg_driver(drv);
    479	const struct rpmsg_device_id *ids = rpdrv->id_table;
    480	unsigned int i;
    481
    482	if (rpdev->driver_override)
    483		return !strcmp(rpdev->driver_override, drv->name);
    484
    485	if (ids)
    486		for (i = 0; ids[i].name[0]; i++)
    487			if (rpmsg_id_match(rpdev, &ids[i])) {
    488				rpdev->id.driver_data = ids[i].driver_data;
    489				return 1;
    490			}
    491
    492	return of_driver_match_device(dev, drv);
    493}
    494
    495static int rpmsg_uevent(struct device *dev, struct kobj_uevent_env *env)
    496{
    497	struct rpmsg_device *rpdev = to_rpmsg_device(dev);
    498	int ret;
    499
    500	ret = of_device_uevent_modalias(dev, env);
    501	if (ret != -ENODEV)
    502		return ret;
    503
    504	return add_uevent_var(env, "MODALIAS=" RPMSG_DEVICE_MODALIAS_FMT,
    505					rpdev->id.name);
    506}
    507
    508/*
    509 * when an rpmsg driver is probed with a channel, we seamlessly create
    510 * it an endpoint, binding its rx callback to a unique local rpmsg
    511 * address.
    512 *
    513 * if we need to, we also announce about this channel to the remote
    514 * processor (needed in case the driver is exposing an rpmsg service).
    515 */
    516static int rpmsg_dev_probe(struct device *dev)
    517{
    518	struct rpmsg_device *rpdev = to_rpmsg_device(dev);
    519	struct rpmsg_driver *rpdrv = to_rpmsg_driver(rpdev->dev.driver);
    520	struct rpmsg_channel_info chinfo = {};
    521	struct rpmsg_endpoint *ept = NULL;
    522	int err;
    523
    524	err = dev_pm_domain_attach(dev, true);
    525	if (err)
    526		goto out;
    527
    528	if (rpdrv->callback) {
    529		strncpy(chinfo.name, rpdev->id.name, RPMSG_NAME_SIZE);
    530		chinfo.src = rpdev->src;
    531		chinfo.dst = RPMSG_ADDR_ANY;
    532
    533		ept = rpmsg_create_ept(rpdev, rpdrv->callback, NULL, chinfo);
    534		if (!ept) {
    535			dev_err(dev, "failed to create endpoint\n");
    536			err = -ENOMEM;
    537			goto out;
    538		}
    539
    540		rpdev->ept = ept;
    541		rpdev->src = ept->addr;
    542	}
    543
    544	err = rpdrv->probe(rpdev);
    545	if (err) {
    546		dev_err(dev, "%s: failed: %d\n", __func__, err);
    547		goto destroy_ept;
    548	}
    549
    550	if (ept && rpdev->ops->announce_create) {
    551		err = rpdev->ops->announce_create(rpdev);
    552		if (err) {
    553			dev_err(dev, "failed to announce creation\n");
    554			goto remove_rpdev;
    555		}
    556	}
    557
    558	return 0;
    559
    560remove_rpdev:
    561	if (rpdrv->remove)
    562		rpdrv->remove(rpdev);
    563destroy_ept:
    564	if (ept)
    565		rpmsg_destroy_ept(ept);
    566out:
    567	return err;
    568}
    569
    570static void rpmsg_dev_remove(struct device *dev)
    571{
    572	struct rpmsg_device *rpdev = to_rpmsg_device(dev);
    573	struct rpmsg_driver *rpdrv = to_rpmsg_driver(rpdev->dev.driver);
    574
    575	if (rpdev->ops->announce_destroy)
    576		rpdev->ops->announce_destroy(rpdev);
    577
    578	if (rpdrv->remove)
    579		rpdrv->remove(rpdev);
    580
    581	dev_pm_domain_detach(dev, true);
    582
    583	if (rpdev->ept)
    584		rpmsg_destroy_ept(rpdev->ept);
    585}
    586
    587static struct bus_type rpmsg_bus = {
    588	.name		= "rpmsg",
    589	.match		= rpmsg_dev_match,
    590	.dev_groups	= rpmsg_dev_groups,
    591	.uevent		= rpmsg_uevent,
    592	.probe		= rpmsg_dev_probe,
    593	.remove		= rpmsg_dev_remove,
    594};
    595
    596/*
    597 * A helper for registering rpmsg device with driver override and name.
    598 * Drivers should not be using it, but instead rpmsg_register_device().
    599 */
    600int rpmsg_register_device_override(struct rpmsg_device *rpdev,
    601				   const char *driver_override)
    602{
    603	struct device *dev = &rpdev->dev;
    604	int ret;
    605
    606	if (driver_override)
    607		strcpy(rpdev->id.name, driver_override);
    608
    609	dev_set_name(dev, "%s.%s.%d.%d", dev_name(dev->parent),
    610		     rpdev->id.name, rpdev->src, rpdev->dst);
    611
    612	dev->bus = &rpmsg_bus;
    613
    614	device_initialize(dev);
    615	if (driver_override) {
    616		ret = driver_set_override(dev, &rpdev->driver_override,
    617					  driver_override,
    618					  strlen(driver_override));
    619		if (ret) {
    620			dev_err(dev, "device_set_override failed: %d\n", ret);
    621			return ret;
    622		}
    623	}
    624
    625	ret = device_add(dev);
    626	if (ret) {
    627		dev_err(dev, "device_add failed: %d\n", ret);
    628		kfree(rpdev->driver_override);
    629		rpdev->driver_override = NULL;
    630		put_device(dev);
    631	}
    632
    633	return ret;
    634}
    635EXPORT_SYMBOL(rpmsg_register_device_override);
    636
    637int rpmsg_register_device(struct rpmsg_device *rpdev)
    638{
    639	return rpmsg_register_device_override(rpdev, NULL);
    640}
    641EXPORT_SYMBOL(rpmsg_register_device);
    642
    643/*
    644 * find an existing channel using its name + address properties,
    645 * and destroy it
    646 */
    647int rpmsg_unregister_device(struct device *parent,
    648			    struct rpmsg_channel_info *chinfo)
    649{
    650	struct device *dev;
    651
    652	dev = rpmsg_find_device(parent, chinfo);
    653	if (!dev)
    654		return -EINVAL;
    655
    656	device_unregister(dev);
    657
    658	put_device(dev);
    659
    660	return 0;
    661}
    662EXPORT_SYMBOL(rpmsg_unregister_device);
    663
    664/**
    665 * __register_rpmsg_driver() - register an rpmsg driver with the rpmsg bus
    666 * @rpdrv: pointer to a struct rpmsg_driver
    667 * @owner: owning module/driver
    668 *
    669 * Return: 0 on success, and an appropriate error value on failure.
    670 */
    671int __register_rpmsg_driver(struct rpmsg_driver *rpdrv, struct module *owner)
    672{
    673	rpdrv->drv.bus = &rpmsg_bus;
    674	rpdrv->drv.owner = owner;
    675	return driver_register(&rpdrv->drv);
    676}
    677EXPORT_SYMBOL(__register_rpmsg_driver);
    678
    679/**
    680 * unregister_rpmsg_driver() - unregister an rpmsg driver from the rpmsg bus
    681 * @rpdrv: pointer to a struct rpmsg_driver
    682 *
    683 * Return: 0 on success, and an appropriate error value on failure.
    684 */
    685void unregister_rpmsg_driver(struct rpmsg_driver *rpdrv)
    686{
    687	driver_unregister(&rpdrv->drv);
    688}
    689EXPORT_SYMBOL(unregister_rpmsg_driver);
    690
    691
    692static int __init rpmsg_init(void)
    693{
    694	int ret;
    695
    696	rpmsg_class = class_create(THIS_MODULE, "rpmsg");
    697	if (IS_ERR(rpmsg_class)) {
    698		pr_err("failed to create rpmsg class\n");
    699		return PTR_ERR(rpmsg_class);
    700	}
    701
    702	ret = bus_register(&rpmsg_bus);
    703	if (ret) {
    704		pr_err("failed to register rpmsg bus: %d\n", ret);
    705		class_destroy(rpmsg_class);
    706	}
    707	return ret;
    708}
    709postcore_initcall(rpmsg_init);
    710
    711static void __exit rpmsg_fini(void)
    712{
    713	bus_unregister(&rpmsg_bus);
    714	class_destroy(rpmsg_class);
    715}
    716module_exit(rpmsg_fini);
    717
    718MODULE_DESCRIPTION("remote processor messaging bus");
    719MODULE_LICENSE("GPL v2");