From: Stephen Rothwell Date: Wed, 20 Feb 2013 05:41:16 +0000 (+1100) Subject: Merge remote-tracking branch 'modem_shm/remoteproc-next' X-Git-Tag: next-20130220~3 X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=6fe91138ae36dc22ec395d9d79a9e55f73ca4baf;p=karo-tx-linux.git Merge remote-tracking branch 'modem_shm/remoteproc-next' --- 6fe91138ae36dc22ec395d9d79a9e55f73ca4baf diff --cc drivers/remoteproc/remoteproc_virtio.c index 750b21818e27,d98cdd86b9a8..dba33ff59b9f --- a/drivers/remoteproc/remoteproc_virtio.c +++ b/drivers/remoteproc/remoteproc_virtio.c @@@ -186,106 -173,6 +186,106 @@@ error return ret; } +/** + * rproc_virtio_new_vringh() - create a reversed virtio ring. + * @vdev: the virtio device + * @index: the virtio ring index + * @cb: callback for the reversed virtio ring + * + * This function should be called by the virtio-driver + * before calling find_vqs(). It returns a struct vringh for + * accessing the virtio ring. + * + * Return: struct vhost, or NULL upon error. + */ +struct vringh * +rproc_virtio_new_vringh(struct virtio_device *vdev, unsigned index, + irqreturn_t (*cb)(struct virtio_device *vdev, + struct vringh *vring)) +{ + struct rproc_vdev *rvdev = vdev_to_rvdev(vdev); + struct rproc_vring *rvring; + struct vringh *vrh; + int err; + + if (index > ARRAY_SIZE(rvdev->vring)) { + dev_err(&rvdev->vdev.dev, "bad vring index: %d\n", index); + return NULL; + } + + vrh = kzalloc(sizeof(*vrh), GFP_KERNEL); + if (!vrh) + return NULL; + + err = rproc_alloc_vring(rvdev, index); + if (err) + goto free_vring; + + + rvring = &rvdev->vring[index]; + /* zero vring */ + memset(rvring->va, 0, vring_size(rvring->len, rvring->align)); + vring_init(&vrh->vring, rvring->len, rvring->va, rvring->align); + + rvring->vringh_cb = cb; + rvring->vringh = vrh; + + err = vringh_init_kern(vrh, - rvdev->dfeatures, ++ rvdev->rsc->dfeatures, + rvring->len, + false, + vrh->vring.desc, + vrh->vring.avail, + vrh->vring.used); + if (!err) + return vrh; + + dev_err(&vdev->dev, "failed to create vhost: %d\n", err); + rproc_free_vring(rvring); +free_vring: + kfree(vrh); + return NULL; +} +EXPORT_SYMBOL(rproc_virtio_new_vringh); + +/** + * rproc_virtio_del_vringh() - release a reversed virtio ring. + * @vdev: the virtio device + * @index: the virtio ring index + * + * This function release the reversed virtio ring. + */ +void rproc_virtio_del_vringh(struct virtio_device *vdev, unsigned index) +{ + struct rproc_vdev *rvdev = vdev_to_rvdev(vdev); + struct rproc_vring *rvring = &rvdev->vring[index]; + kfree(rvring->vringh); + rproc_free_vring(rvring); + rvring->vringh_cb = NULL; + rvring->vringh = NULL; +} +EXPORT_SYMBOL(rproc_virtio_del_vringh); + +/** + * rproc_virtio_kick_vringh() - kick the remote processor. + * @vdev: the virtio device + * @index: the virtio ring index + * + * kick the remote processor, and let it know which vring to poke at + */ +void rproc_virtio_kick_vringh(struct virtio_device *vdev, unsigned index) +{ + struct rproc_vdev *rvdev = vdev_to_rvdev(vdev); + struct rproc_vring *rvring = &rvdev->vring[index]; + struct rproc *rproc = rvring->rvdev->rproc; + int notifyid = rvring->notifyid; + + dev_dbg(&rproc->dev, "kicking vq index: %d\n", notifyid); + + rproc->ops->kick(rproc, notifyid); +} +EXPORT_SYMBOL(rproc_virtio_kick_vringh); + /* * We don't support yet real virtio status semantics. * @@@ -332,10 -224,34 +337,34 @@@ static void rproc_virtio_finalize_featu * fixed as part of a small resource table overhaul and then an * extension of the virtio resource entries. */ - rvdev->gfeatures = vdev->features[0]; + rvdev->rsc->gfeatures = vdev->features[0]; + } + + void rproc_virtio_get(struct virtio_device *vdev, unsigned offset, + void *buf, unsigned len) + { + struct rproc_vdev *rvdev = vdev_to_rvdev(vdev); + void *cfg = &rvdev->rsc->vring[rvdev->rsc->num_of_vrings]; + if (offset + len > rvdev->rsc->config_len) + dev_err(&vdev->dev, + "rproc_virtio_get: access out of bounds\n"); + else + memcpy(buf, cfg + offset, len); + } + + void rproc_virtio_set(struct virtio_device *vdev, unsigned offset, + const void *buf, unsigned len) + { + struct rproc_vdev *rvdev = vdev_to_rvdev(vdev); + void *cfg = &rvdev->rsc->vring[rvdev->rsc->num_of_vrings]; + if (offset + len > rvdev->rsc->config_len) + dev_err(&vdev->dev, + "rproc_virtio_set: access out of bounds\n"); + else + memcpy(cfg + offset, buf, len); } -static struct virtio_config_ops rproc_virtio_config_ops = { +static const struct virtio_config_ops rproc_virtio_config_ops = { .get_features = rproc_virtio_get_features, .finalize_features = rproc_virtio_finalize_features, .find_vqs = rproc_virtio_find_vqs, diff --cc include/linux/remoteproc.h index 414a1fda828b,07deff4982d0..eed19b2f8829 --- a/include/linux/remoteproc.h +++ b/include/linux/remoteproc.h @@@ -39,10 -39,9 +39,11 @@@ #include #include #include +#include #include +#include #include + #include /** * struct resource_table - firmware resource table header