aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/rpmsg/virtio_rpmsg_bus.c44
1 files changed, 30 insertions, 14 deletions
diff --git a/drivers/rpmsg/virtio_rpmsg_bus.c b/drivers/rpmsg/virtio_rpmsg_bus.c
index b6135d4d54eb..92f6af6da699 100644
--- a/drivers/rpmsg/virtio_rpmsg_bus.c
+++ b/drivers/rpmsg/virtio_rpmsg_bus.c
@@ -41,6 +41,7 @@
41 * @svq: tx virtqueue 41 * @svq: tx virtqueue
42 * @rbufs: kernel address of rx buffers 42 * @rbufs: kernel address of rx buffers
43 * @sbufs: kernel address of tx buffers 43 * @sbufs: kernel address of tx buffers
44 * @num_bufs: total number of buffers for rx and tx
44 * @last_sbuf: index of last tx buffer used 45 * @last_sbuf: index of last tx buffer used
45 * @bufs_dma: dma base addr of the buffers 46 * @bufs_dma: dma base addr of the buffers
46 * @tx_lock: protects svq, sbufs and sleepers, to allow concurrent senders. 47 * @tx_lock: protects svq, sbufs and sleepers, to allow concurrent senders.
@@ -60,6 +61,7 @@ struct virtproc_info {
60 struct virtio_device *vdev; 61 struct virtio_device *vdev;
61 struct virtqueue *rvq, *svq; 62 struct virtqueue *rvq, *svq;
62 void *rbufs, *sbufs; 63 void *rbufs, *sbufs;
64 unsigned int num_bufs;
63 int last_sbuf; 65 int last_sbuf;
64 dma_addr_t bufs_dma; 66 dma_addr_t bufs_dma;
65 struct mutex tx_lock; 67 struct mutex tx_lock;
@@ -86,13 +88,14 @@ struct rpmsg_channel_info {
86#define to_rpmsg_driver(d) container_of(d, struct rpmsg_driver, drv) 88#define to_rpmsg_driver(d) container_of(d, struct rpmsg_driver, drv)
87 89
88/* 90/*
89 * We're allocating 512 buffers of 512 bytes for communications, and then 91 * We're allocating buffers of 512 bytes each for communications. The
90 * using the first 256 buffers for RX, and the last 256 buffers for TX. 92 * number of buffers will be computed from the number of buffers supported
93 * by the vring, upto a maximum of 512 buffers (256 in each direction).
91 * 94 *
92 * Each buffer will have 16 bytes for the msg header and 496 bytes for 95 * Each buffer will have 16 bytes for the msg header and 496 bytes for
93 * the payload. 96 * the payload.
94 * 97 *
95 * This will require a total space of 256KB for the buffers. 98 * This will utilize a maximum total space of 256KB for the buffers.
96 * 99 *
97 * We might also want to add support for user-provided buffers in time. 100 * We might also want to add support for user-provided buffers in time.
98 * This will allow bigger buffer size flexibility, and can also be used 101 * This will allow bigger buffer size flexibility, and can also be used
@@ -102,9 +105,8 @@ struct rpmsg_channel_info {
102 * can change this without changing anything in the firmware of the remote 105 * can change this without changing anything in the firmware of the remote
103 * processor. 106 * processor.
104 */ 107 */
105#define RPMSG_NUM_BUFS (512) 108#define MAX_RPMSG_NUM_BUFS (512)
106#define RPMSG_BUF_SIZE (512) 109#define RPMSG_BUF_SIZE (512)
107#define RPMSG_TOTAL_BUF_SPACE (RPMSG_NUM_BUFS * RPMSG_BUF_SIZE)
108 110
109/* 111/*
110 * Local addresses are dynamically allocated on-demand. 112 * Local addresses are dynamically allocated on-demand.
@@ -579,7 +581,7 @@ static void *get_a_tx_buf(struct virtproc_info *vrp)
579 * either pick the next unused tx buffer 581 * either pick the next unused tx buffer
580 * (half of our buffers are used for sending messages) 582 * (half of our buffers are used for sending messages)
581 */ 583 */
582 if (vrp->last_sbuf < RPMSG_NUM_BUFS / 2) 584 if (vrp->last_sbuf < vrp->num_bufs / 2)
583 ret = vrp->sbufs + RPMSG_BUF_SIZE * vrp->last_sbuf++; 585 ret = vrp->sbufs + RPMSG_BUF_SIZE * vrp->last_sbuf++;
584 /* or recycle a used one */ 586 /* or recycle a used one */
585 else 587 else
@@ -948,6 +950,7 @@ static int rpmsg_probe(struct virtio_device *vdev)
948 struct virtproc_info *vrp; 950 struct virtproc_info *vrp;
949 void *bufs_va; 951 void *bufs_va;
950 int err = 0, i; 952 int err = 0, i;
953 size_t total_buf_space;
951 954
952 vrp = kzalloc(sizeof(*vrp), GFP_KERNEL); 955 vrp = kzalloc(sizeof(*vrp), GFP_KERNEL);
953 if (!vrp) 956 if (!vrp)
@@ -968,10 +971,22 @@ static int rpmsg_probe(struct virtio_device *vdev)
968 vrp->rvq = vqs[0]; 971 vrp->rvq = vqs[0];
969 vrp->svq = vqs[1]; 972 vrp->svq = vqs[1];
970 973
974 /* we expect symmetric tx/rx vrings */
975 WARN_ON(virtqueue_get_vring_size(vrp->rvq) !=
976 virtqueue_get_vring_size(vrp->svq));
977
978 /* we need less buffers if vrings are small */
979 if (virtqueue_get_vring_size(vrp->rvq) < MAX_RPMSG_NUM_BUFS / 2)
980 vrp->num_bufs = virtqueue_get_vring_size(vrp->rvq) * 2;
981 else
982 vrp->num_bufs = MAX_RPMSG_NUM_BUFS;
983
984 total_buf_space = vrp->num_bufs * RPMSG_BUF_SIZE;
985
971 /* allocate coherent memory for the buffers */ 986 /* allocate coherent memory for the buffers */
972 bufs_va = dma_alloc_coherent(vdev->dev.parent->parent, 987 bufs_va = dma_alloc_coherent(vdev->dev.parent->parent,
973 RPMSG_TOTAL_BUF_SPACE, 988 total_buf_space, &vrp->bufs_dma,
974 &vrp->bufs_dma, GFP_KERNEL); 989 GFP_KERNEL);
975 if (!bufs_va) { 990 if (!bufs_va) {
976 err = -ENOMEM; 991 err = -ENOMEM;
977 goto vqs_del; 992 goto vqs_del;
@@ -984,10 +999,10 @@ static int rpmsg_probe(struct virtio_device *vdev)
984 vrp->rbufs = bufs_va; 999 vrp->rbufs = bufs_va;
985 1000
986 /* and half is dedicated for TX */ 1001 /* and half is dedicated for TX */
987 vrp->sbufs = bufs_va + RPMSG_TOTAL_BUF_SPACE / 2; 1002 vrp->sbufs = bufs_va + total_buf_space / 2;
988 1003
989 /* set up the receive buffers */ 1004 /* set up the receive buffers */
990 for (i = 0; i < RPMSG_NUM_BUFS / 2; i++) { 1005 for (i = 0; i < vrp->num_bufs / 2; i++) {
991 struct scatterlist sg; 1006 struct scatterlist sg;
992 void *cpu_addr = vrp->rbufs + i * RPMSG_BUF_SIZE; 1007 void *cpu_addr = vrp->rbufs + i * RPMSG_BUF_SIZE;
993 1008
@@ -1023,8 +1038,8 @@ static int rpmsg_probe(struct virtio_device *vdev)
1023 return 0; 1038 return 0;
1024 1039
1025free_coherent: 1040free_coherent:
1026 dma_free_coherent(vdev->dev.parent->parent, RPMSG_TOTAL_BUF_SPACE, 1041 dma_free_coherent(vdev->dev.parent->parent, total_buf_space,
1027 bufs_va, vrp->bufs_dma); 1042 bufs_va, vrp->bufs_dma);
1028vqs_del: 1043vqs_del:
1029 vdev->config->del_vqs(vrp->vdev); 1044 vdev->config->del_vqs(vrp->vdev);
1030free_vrp: 1045free_vrp:
@@ -1042,6 +1057,7 @@ static int rpmsg_remove_device(struct device *dev, void *data)
1042static void rpmsg_remove(struct virtio_device *vdev) 1057static void rpmsg_remove(struct virtio_device *vdev)
1043{ 1058{
1044 struct virtproc_info *vrp = vdev->priv; 1059 struct virtproc_info *vrp = vdev->priv;
1060 size_t total_buf_space = vrp->num_bufs * RPMSG_BUF_SIZE;
1045 int ret; 1061 int ret;
1046 1062
1047 vdev->config->reset(vdev); 1063 vdev->config->reset(vdev);
@@ -1057,8 +1073,8 @@ static void rpmsg_remove(struct virtio_device *vdev)
1057 1073
1058 vdev->config->del_vqs(vrp->vdev); 1074 vdev->config->del_vqs(vrp->vdev);
1059 1075
1060 dma_free_coherent(vdev->dev.parent->parent, RPMSG_TOTAL_BUF_SPACE, 1076 dma_free_coherent(vdev->dev.parent->parent, total_buf_space,
1061 vrp->rbufs, vrp->bufs_dma); 1077 vrp->rbufs, vrp->bufs_dma);
1062 1078
1063 kfree(vrp); 1079 kfree(vrp);
1064} 1080}