rpmsg updates for v5.13
In addition to some bug fixes and cleanups this adds support for exposing the virtio based transport to user space using the rpmsg_char driver. -----BEGIN PGP SIGNATURE----- iQJPBAABCAA5FiEEBd4DzF816k8JZtUlCx85Pw2ZrcUFAmCRYXsbHGJqb3JuLmFu ZGVyc3NvbkBsaW5hcm8ub3JnAAoJEAsfOT8Nma3FXiEP/RC4cXMaHCtIKvXDbwwB yP0Gl+gnP1LEEK8IkD5PJVzS5oi/s6KGct4x3EadvQEq42uJCxskbYZMN/R+wMGd XTz2N0Bt7wErLQznD0dqDCdpihrkoao1zSu4rSDlnBzRZEGuWQBgTTeiEPh1sVXF 40r2zuUrvkERKG27DsflbE15Iqaz3ZoEc7X/0Mv9YQtBV+0HTtd6n0X8Vus6JcGR un7t9Op9SlvYcEtsyqCewNrgpJhb9orpWDnIV+V7VXrvEBr0UOat881t2QZN3geM pdIo+bU66VnqWy8Rd2g5zJl9jHr5C8YbpTgUy0+WFAjNu6CV0sW9jlMFKBMxMrDi XpKqj/4TUqTvdSe30Y70/HdCQelbFVxNEFljX86hqD2Isg6P5DAe2GKDApt1SsMo apy6Snp0F4JTL8rb0g5e/WUnWh11bKyhFSYFKnzPZKpQWfE0ppfOLKfDMlvksxyI IZIqVz87VVu2itVPuYAvSBTtL+5KQP1U39LIOrX4y9Y3eordlbjIMU1wiem7uU3c B3VYgaJY0iElElNqyrGZWvJxHuJf/IgOqg4V2P8x5fcw+vmSuz2prS6a2kU8doKU D3cZrIpSGZLBfJw47bOBsdEnVNh16gC+TbGuh/hzEA+wJ+nu/haLl/KQf6yUQd24 ifIRQ0csTeptssTb/5rjLtNf =pv2g -----END PGP SIGNATURE----- Merge tag 'rpmsg-v5.13' of git://git.kernel.org/pub/scm/linux/kernel/git/andersson/remoteproc Pull rpmsg updates from Bjorn Andersson: "In addition to some bug fixes and cleanups this adds support for exposing the virtio based transport to user space using the rpmsg_char driver" * tag 'rpmsg-v5.13' of git://git.kernel.org/pub/scm/linux/kernel/git/andersson/remoteproc: rpmsg: qcom_glink_native: fix error return code of qcom_glink_rx_data() rpmsg: char: Return an error if device already open rpmsg: virtio: Register the rpmsg_char device rpmsg: char: Use rpmsg_sendto to specify the message destination address rpmsg: Add short description of the IOCTL defined in UAPI. rpmsg: Move RPMSG_ADDR_ANY in user API rpmsg: char: Rename rpmsg_char_init to rpmsg_chrdev_init
This commit is contained in:
Коммит
a01d9524ca
|
@ -857,6 +857,7 @@ static int qcom_glink_rx_data(struct qcom_glink *glink, size_t avail)
|
|||
dev_err(glink->dev,
|
||||
"no intent found for channel %s intent %d",
|
||||
channel->name, liid);
|
||||
ret = -ENOENT;
|
||||
goto advance_rx;
|
||||
}
|
||||
}
|
||||
|
@ -1332,6 +1333,20 @@ static int qcom_glink_trysend(struct rpmsg_endpoint *ept, void *data, int len)
|
|||
return __qcom_glink_send(channel, data, len, false);
|
||||
}
|
||||
|
||||
static int qcom_glink_sendto(struct rpmsg_endpoint *ept, void *data, int len, u32 dst)
|
||||
{
|
||||
struct glink_channel *channel = to_glink_channel(ept);
|
||||
|
||||
return __qcom_glink_send(channel, data, len, true);
|
||||
}
|
||||
|
||||
static int qcom_glink_trysendto(struct rpmsg_endpoint *ept, void *data, int len, u32 dst)
|
||||
{
|
||||
struct glink_channel *channel = to_glink_channel(ept);
|
||||
|
||||
return __qcom_glink_send(channel, data, len, false);
|
||||
}
|
||||
|
||||
/*
|
||||
* Finds the device_node for the glink child interested in this channel.
|
||||
*/
|
||||
|
@ -1364,7 +1379,9 @@ static const struct rpmsg_device_ops glink_device_ops = {
|
|||
static const struct rpmsg_endpoint_ops glink_endpoint_ops = {
|
||||
.destroy_ept = qcom_glink_destroy_ept,
|
||||
.send = qcom_glink_send,
|
||||
.sendto = qcom_glink_sendto,
|
||||
.trysend = qcom_glink_trysend,
|
||||
.trysendto = qcom_glink_trysendto,
|
||||
};
|
||||
|
||||
static void qcom_glink_rpdev_release(struct device *dev)
|
||||
|
|
|
@ -974,6 +974,20 @@ static int qcom_smd_trysend(struct rpmsg_endpoint *ept, void *data, int len)
|
|||
return __qcom_smd_send(qsept->qsch, data, len, false);
|
||||
}
|
||||
|
||||
static int qcom_smd_sendto(struct rpmsg_endpoint *ept, void *data, int len, u32 dst)
|
||||
{
|
||||
struct qcom_smd_endpoint *qsept = to_smd_endpoint(ept);
|
||||
|
||||
return __qcom_smd_send(qsept->qsch, data, len, true);
|
||||
}
|
||||
|
||||
static int qcom_smd_trysendto(struct rpmsg_endpoint *ept, void *data, int len, u32 dst)
|
||||
{
|
||||
struct qcom_smd_endpoint *qsept = to_smd_endpoint(ept);
|
||||
|
||||
return __qcom_smd_send(qsept->qsch, data, len, false);
|
||||
}
|
||||
|
||||
static __poll_t qcom_smd_poll(struct rpmsg_endpoint *ept,
|
||||
struct file *filp, poll_table *wait)
|
||||
{
|
||||
|
@ -1038,7 +1052,9 @@ static const struct rpmsg_device_ops qcom_smd_device_ops = {
|
|||
static const struct rpmsg_endpoint_ops qcom_smd_endpoint_ops = {
|
||||
.destroy_ept = qcom_smd_destroy_ept,
|
||||
.send = qcom_smd_send,
|
||||
.sendto = qcom_smd_sendto,
|
||||
.trysend = qcom_smd_trysend,
|
||||
.trysendto = qcom_smd_trysendto,
|
||||
.poll = qcom_smd_poll,
|
||||
};
|
||||
|
||||
|
|
|
@ -127,6 +127,9 @@ static int rpmsg_eptdev_open(struct inode *inode, struct file *filp)
|
|||
struct rpmsg_device *rpdev = eptdev->rpdev;
|
||||
struct device *dev = &eptdev->dev;
|
||||
|
||||
if (eptdev->ept)
|
||||
return -EBUSY;
|
||||
|
||||
get_device(dev);
|
||||
|
||||
ept = rpmsg_create_ept(rpdev, rpmsg_ept_cb, eptdev, eptdev->chinfo);
|
||||
|
@ -239,9 +242,9 @@ static ssize_t rpmsg_eptdev_write_iter(struct kiocb *iocb,
|
|||
}
|
||||
|
||||
if (filp->f_flags & O_NONBLOCK)
|
||||
ret = rpmsg_trysend(eptdev->ept, kbuf, len);
|
||||
ret = rpmsg_trysendto(eptdev->ept, kbuf, len, eptdev->chinfo.dst);
|
||||
else
|
||||
ret = rpmsg_send(eptdev->ept, kbuf, len);
|
||||
ret = rpmsg_sendto(eptdev->ept, kbuf, len, eptdev->chinfo.dst);
|
||||
|
||||
unlock_eptdev:
|
||||
mutex_unlock(&eptdev->ept_lock);
|
||||
|
@ -543,7 +546,7 @@ static struct rpmsg_driver rpmsg_chrdev_driver = {
|
|||
},
|
||||
};
|
||||
|
||||
static int rpmsg_char_init(void)
|
||||
static int rpmsg_chrdev_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
@ -569,7 +572,7 @@ static int rpmsg_char_init(void)
|
|||
|
||||
return ret;
|
||||
}
|
||||
postcore_initcall(rpmsg_char_init);
|
||||
postcore_initcall(rpmsg_chrdev_init);
|
||||
|
||||
static void rpmsg_chrdev_exit(void)
|
||||
{
|
||||
|
|
|
@ -813,14 +813,57 @@ static void rpmsg_xmit_done(struct virtqueue *svq)
|
|||
wake_up_interruptible(&vrp->sendq);
|
||||
}
|
||||
|
||||
/*
|
||||
* Called to expose to user a /dev/rpmsg_ctrlX interface allowing to
|
||||
* create endpoint-to-endpoint communication without associated RPMsg channel.
|
||||
* The endpoints are rattached to the ctrldev RPMsg device.
|
||||
*/
|
||||
static struct rpmsg_device *rpmsg_virtio_add_ctrl_dev(struct virtio_device *vdev)
|
||||
{
|
||||
struct virtproc_info *vrp = vdev->priv;
|
||||
struct virtio_rpmsg_channel *vch;
|
||||
struct rpmsg_device *rpdev_ctrl;
|
||||
int err = 0;
|
||||
|
||||
vch = kzalloc(sizeof(*vch), GFP_KERNEL);
|
||||
if (!vch)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
/* Link the channel to the vrp */
|
||||
vch->vrp = vrp;
|
||||
|
||||
/* Assign public information to the rpmsg_device */
|
||||
rpdev_ctrl = &vch->rpdev;
|
||||
rpdev_ctrl->ops = &virtio_rpmsg_ops;
|
||||
|
||||
rpdev_ctrl->dev.parent = &vrp->vdev->dev;
|
||||
rpdev_ctrl->dev.release = virtio_rpmsg_release_device;
|
||||
rpdev_ctrl->little_endian = virtio_is_little_endian(vrp->vdev);
|
||||
|
||||
err = rpmsg_chrdev_register_device(rpdev_ctrl);
|
||||
if (err) {
|
||||
kfree(vch);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
return rpdev_ctrl;
|
||||
}
|
||||
|
||||
static void rpmsg_virtio_del_ctrl_dev(struct rpmsg_device *rpdev_ctrl)
|
||||
{
|
||||
if (!rpdev_ctrl)
|
||||
return;
|
||||
kfree(to_virtio_rpmsg_channel(rpdev_ctrl));
|
||||
}
|
||||
|
||||
static int rpmsg_probe(struct virtio_device *vdev)
|
||||
{
|
||||
vq_callback_t *vq_cbs[] = { rpmsg_recv_done, rpmsg_xmit_done };
|
||||
static const char * const names[] = { "input", "output" };
|
||||
struct virtqueue *vqs[2];
|
||||
struct virtproc_info *vrp;
|
||||
struct virtio_rpmsg_channel *vch;
|
||||
struct rpmsg_device *rpdev_ns;
|
||||
struct virtio_rpmsg_channel *vch = NULL;
|
||||
struct rpmsg_device *rpdev_ns, *rpdev_ctrl;
|
||||
void *bufs_va;
|
||||
int err = 0, i;
|
||||
size_t total_buf_space;
|
||||
|
@ -894,12 +937,18 @@ static int rpmsg_probe(struct virtio_device *vdev)
|
|||
|
||||
vdev->priv = vrp;
|
||||
|
||||
rpdev_ctrl = rpmsg_virtio_add_ctrl_dev(vdev);
|
||||
if (IS_ERR(rpdev_ctrl)) {
|
||||
err = PTR_ERR(rpdev_ctrl);
|
||||
goto free_coherent;
|
||||
}
|
||||
|
||||
/* if supported by the remote processor, enable the name service */
|
||||
if (virtio_has_feature(vdev, VIRTIO_RPMSG_F_NS)) {
|
||||
vch = kzalloc(sizeof(*vch), GFP_KERNEL);
|
||||
if (!vch) {
|
||||
err = -ENOMEM;
|
||||
goto free_coherent;
|
||||
goto free_ctrldev;
|
||||
}
|
||||
|
||||
/* Link the channel to our vrp */
|
||||
|
@ -915,7 +964,7 @@ static int rpmsg_probe(struct virtio_device *vdev)
|
|||
|
||||
err = rpmsg_ns_register_device(rpdev_ns);
|
||||
if (err)
|
||||
goto free_coherent;
|
||||
goto free_vch;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -939,8 +988,11 @@ static int rpmsg_probe(struct virtio_device *vdev)
|
|||
|
||||
return 0;
|
||||
|
||||
free_coherent:
|
||||
free_vch:
|
||||
kfree(vch);
|
||||
free_ctrldev:
|
||||
rpmsg_virtio_del_ctrl_dev(rpdev_ctrl);
|
||||
free_coherent:
|
||||
dma_free_coherent(vdev->dev.parent, total_buf_space,
|
||||
bufs_va, vrp->bufs_dma);
|
||||
vqs_del:
|
||||
|
|
|
@ -18,8 +18,7 @@
|
|||
#include <linux/mutex.h>
|
||||
#include <linux/poll.h>
|
||||
#include <linux/rpmsg/byteorder.h>
|
||||
|
||||
#define RPMSG_ADDR_ANY 0xFFFFFFFF
|
||||
#include <uapi/linux/rpmsg.h>
|
||||
|
||||
struct rpmsg_device;
|
||||
struct rpmsg_endpoint;
|
||||
|
|
|
@ -9,11 +9,13 @@
|
|||
#include <linux/ioctl.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#define RPMSG_ADDR_ANY 0xFFFFFFFF
|
||||
|
||||
/**
|
||||
* struct rpmsg_endpoint_info - endpoint info representation
|
||||
* @name: name of service
|
||||
* @src: local address
|
||||
* @dst: destination address
|
||||
* @src: local address. To set to RPMSG_ADDR_ANY if not used.
|
||||
* @dst: destination address. To set to RPMSG_ADDR_ANY if not used.
|
||||
*/
|
||||
struct rpmsg_endpoint_info {
|
||||
char name[32];
|
||||
|
@ -21,7 +23,14 @@ struct rpmsg_endpoint_info {
|
|||
__u32 dst;
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate a new rmpsg char device endpoint.
|
||||
*/
|
||||
#define RPMSG_CREATE_EPT_IOCTL _IOW(0xb5, 0x1, struct rpmsg_endpoint_info)
|
||||
|
||||
/**
|
||||
* Destroy a rpmsg char device endpoint created by the RPMSG_CREATE_EPT_IOCTL.
|
||||
*/
|
||||
#define RPMSG_DESTROY_EPT_IOCTL _IO(0xb5, 0x2)
|
||||
|
||||
#endif
|
||||
|
|
Загрузка…
Ссылка в новой задаче