diff options
-rw-r--r-- | MAINTAINERS | 8 | ||||
-rw-r--r-- | drivers/rpmsg/Kconfig | 1 | ||||
-rw-r--r-- | drivers/rpmsg/virtio_rpmsg_bus.c | 49 |
3 files changed, 44 insertions, 14 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index eeae5a7bdb88..e73c374483cb 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -6716,6 +6716,14 @@ F: drivers/remoteproc/ | |||
6716 | F: Documentation/remoteproc.txt | 6716 | F: Documentation/remoteproc.txt |
6717 | F: include/linux/remoteproc.h | 6717 | F: include/linux/remoteproc.h |
6718 | 6718 | ||
6719 | REMOTE PROCESSOR MESSAGING (RPMSG) SUBSYSTEM | ||
6720 | M: Ohad Ben-Cohen <ohad@wizery.com> | ||
6721 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/ohad/rpmsg.git | ||
6722 | S: Maintained | ||
6723 | F: drivers/rpmsg/ | ||
6724 | F: Documentation/rpmsg.txt | ||
6725 | F: include/linux/rpmsg.h | ||
6726 | |||
6719 | RFKILL | 6727 | RFKILL |
6720 | M: Johannes Berg <johannes@sipsolutions.net> | 6728 | M: Johannes Berg <johannes@sipsolutions.net> |
6721 | L: linux-wireless@vger.kernel.org | 6729 | L: linux-wireless@vger.kernel.org |
diff --git a/drivers/rpmsg/Kconfig b/drivers/rpmsg/Kconfig index f6e0ea6ffda5..69a219387582 100644 --- a/drivers/rpmsg/Kconfig +++ b/drivers/rpmsg/Kconfig | |||
@@ -4,5 +4,6 @@ menu "Rpmsg drivers" | |||
4 | config RPMSG | 4 | config RPMSG |
5 | tristate | 5 | tristate |
6 | select VIRTIO | 6 | select VIRTIO |
7 | select VIRTUALIZATION | ||
7 | 8 | ||
8 | endmenu | 9 | endmenu |
diff --git a/drivers/rpmsg/virtio_rpmsg_bus.c b/drivers/rpmsg/virtio_rpmsg_bus.c index 56fceafec9ec..b6135d4d54eb 100644 --- a/drivers/rpmsg/virtio_rpmsg_bus.c +++ b/drivers/rpmsg/virtio_rpmsg_bus.c | |||
@@ -776,23 +776,13 @@ out: | |||
776 | } | 776 | } |
777 | EXPORT_SYMBOL(rpmsg_send_offchannel_raw); | 777 | EXPORT_SYMBOL(rpmsg_send_offchannel_raw); |
778 | 778 | ||
779 | /* called when an rx buffer is used, and it's time to digest a message */ | 779 | static int rpmsg_recv_single(struct virtproc_info *vrp, struct device *dev, |
780 | static void rpmsg_recv_done(struct virtqueue *rvq) | 780 | struct rpmsg_hdr *msg, unsigned int len) |
781 | { | 781 | { |
782 | struct rpmsg_hdr *msg; | ||
783 | unsigned int len; | ||
784 | struct rpmsg_endpoint *ept; | 782 | struct rpmsg_endpoint *ept; |
785 | struct scatterlist sg; | 783 | struct scatterlist sg; |
786 | struct virtproc_info *vrp = rvq->vdev->priv; | ||
787 | struct device *dev = &rvq->vdev->dev; | ||
788 | int err; | 784 | int err; |
789 | 785 | ||
790 | msg = virtqueue_get_buf(rvq, &len); | ||
791 | if (!msg) { | ||
792 | dev_err(dev, "uhm, incoming signal, but no used buffer ?\n"); | ||
793 | return; | ||
794 | } | ||
795 | |||
796 | dev_dbg(dev, "From: 0x%x, To: 0x%x, Len: %d, Flags: %d, Reserved: %d\n", | 786 | dev_dbg(dev, "From: 0x%x, To: 0x%x, Len: %d, Flags: %d, Reserved: %d\n", |
797 | msg->src, msg->dst, msg->len, | 787 | msg->src, msg->dst, msg->len, |
798 | msg->flags, msg->reserved); | 788 | msg->flags, msg->reserved); |
@@ -806,7 +796,7 @@ static void rpmsg_recv_done(struct virtqueue *rvq) | |||
806 | if (len > RPMSG_BUF_SIZE || | 796 | if (len > RPMSG_BUF_SIZE || |
807 | msg->len > (len - sizeof(struct rpmsg_hdr))) { | 797 | msg->len > (len - sizeof(struct rpmsg_hdr))) { |
808 | dev_warn(dev, "inbound msg too big: (%d, %d)\n", len, msg->len); | 798 | dev_warn(dev, "inbound msg too big: (%d, %d)\n", len, msg->len); |
809 | return; | 799 | return -EINVAL; |
810 | } | 800 | } |
811 | 801 | ||
812 | /* use the dst addr to fetch the callback of the appropriate user */ | 802 | /* use the dst addr to fetch the callback of the appropriate user */ |
@@ -842,11 +832,42 @@ static void rpmsg_recv_done(struct virtqueue *rvq) | |||
842 | err = virtqueue_add_inbuf(vrp->rvq, &sg, 1, msg, GFP_KERNEL); | 832 | err = virtqueue_add_inbuf(vrp->rvq, &sg, 1, msg, GFP_KERNEL); |
843 | if (err < 0) { | 833 | if (err < 0) { |
844 | dev_err(dev, "failed to add a virtqueue buffer: %d\n", err); | 834 | dev_err(dev, "failed to add a virtqueue buffer: %d\n", err); |
835 | return err; | ||
836 | } | ||
837 | |||
838 | return 0; | ||
839 | } | ||
840 | |||
841 | /* called when an rx buffer is used, and it's time to digest a message */ | ||
842 | static void rpmsg_recv_done(struct virtqueue *rvq) | ||
843 | { | ||
844 | struct virtproc_info *vrp = rvq->vdev->priv; | ||
845 | struct device *dev = &rvq->vdev->dev; | ||
846 | struct rpmsg_hdr *msg; | ||
847 | unsigned int len, msgs_received = 0; | ||
848 | int err; | ||
849 | |||
850 | msg = virtqueue_get_buf(rvq, &len); | ||
851 | if (!msg) { | ||
852 | dev_err(dev, "uhm, incoming signal, but no used buffer ?\n"); | ||
845 | return; | 853 | return; |
846 | } | 854 | } |
847 | 855 | ||
856 | while (msg) { | ||
857 | err = rpmsg_recv_single(vrp, dev, msg, len); | ||
858 | if (err) | ||
859 | break; | ||
860 | |||
861 | msgs_received++; | ||
862 | |||
863 | msg = virtqueue_get_buf(rvq, &len); | ||
864 | }; | ||
865 | |||
866 | dev_dbg(dev, "Received %u messages\n", msgs_received); | ||
867 | |||
848 | /* tell the remote processor we added another available rx buffer */ | 868 | /* tell the remote processor we added another available rx buffer */ |
849 | virtqueue_kick(vrp->rvq); | 869 | if (msgs_received) |
870 | virtqueue_kick(vrp->rvq); | ||
850 | } | 871 | } |
851 | 872 | ||
852 | /* | 873 | /* |