aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorSjur Brændeland <sjur.brandeland@stericsson.com>2012-12-13 23:10:51 -0500
committerRusty Russell <rusty@rustcorp.com.au>2012-12-17 23:50:44 -0500
commit1b6370463e88b0c1c317de16d7b962acc1dab4f2 (patch)
tree778c4e46202565fb8797921d816861c587066f5b /drivers/char
parent276a3e954cfe4da7c492c9063741f99290d2973e (diff)
virtio_console: Add support for remoteproc serial
Add a simple serial connection driver called VIRTIO_ID_RPROC_SERIAL (11) for communicating with a remote processor in an asymmetric multi-processing configuration. This implementation reuses the existing virtio_console implementation, and adds support for DMA allocation of data buffers and disables use of tty console and the virtio control queue. Signed-off-by: Sjur Brændeland <sjur.brandeland@stericsson.com> Acked-by: Amit Shah <amit.shah@redhat.com> Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/virtio_console.c192
1 files changed, 169 insertions, 23 deletions
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
index 548224686963..55a89a4ae42f 100644
--- a/drivers/char/virtio_console.c
+++ b/drivers/char/virtio_console.c
@@ -37,8 +37,12 @@
37#include <linux/wait.h> 37#include <linux/wait.h>
38#include <linux/workqueue.h> 38#include <linux/workqueue.h>
39#include <linux/module.h> 39#include <linux/module.h>
40#include <linux/dma-mapping.h>
41#include <linux/kconfig.h>
40#include "../tty/hvc/hvc_console.h" 42#include "../tty/hvc/hvc_console.h"
41 43
44#define is_rproc_enabled IS_ENABLED(CONFIG_REMOTEPROC)
45
42/* 46/*
43 * This is a global struct for storing common data for all the devices 47 * This is a global struct for storing common data for all the devices
44 * this driver handles. 48 * this driver handles.
@@ -112,6 +116,15 @@ struct port_buffer {
112 /* offset in the buf from which to consume data */ 116 /* offset in the buf from which to consume data */
113 size_t offset; 117 size_t offset;
114 118
119 /* DMA address of buffer */
120 dma_addr_t dma;
121
122 /* Device we got DMA memory from */
123 struct device *dev;
124
125 /* List of pending dma buffers to free */
126 struct list_head list;
127
115 /* If sgpages == 0 then buf is used */ 128 /* If sgpages == 0 then buf is used */
116 unsigned int sgpages; 129 unsigned int sgpages;
117 130
@@ -331,6 +344,11 @@ static bool is_console_port(struct port *port)
331 return false; 344 return false;
332} 345}
333 346
347static bool is_rproc_serial(const struct virtio_device *vdev)
348{
349 return is_rproc_enabled && vdev->id.device == VIRTIO_ID_RPROC_SERIAL;
350}
351
334static inline bool use_multiport(struct ports_device *portdev) 352static inline bool use_multiport(struct ports_device *portdev)
335{ 353{
336 /* 354 /*
@@ -342,11 +360,13 @@ static inline bool use_multiport(struct ports_device *portdev)
342 return portdev->vdev->features[0] & (1 << VIRTIO_CONSOLE_F_MULTIPORT); 360 return portdev->vdev->features[0] & (1 << VIRTIO_CONSOLE_F_MULTIPORT);
343} 361}
344 362
345static void free_buf(struct port_buffer *buf) 363static DEFINE_SPINLOCK(dma_bufs_lock);
364static LIST_HEAD(pending_free_dma_bufs);
365
366static void free_buf(struct port_buffer *buf, bool can_sleep)
346{ 367{
347 unsigned int i; 368 unsigned int i;
348 369
349 kfree(buf->buf);
350 for (i = 0; i < buf->sgpages; i++) { 370 for (i = 0; i < buf->sgpages; i++) {
351 struct page *page = sg_page(&buf->sg[i]); 371 struct page *page = sg_page(&buf->sg[i]);
352 if (!page) 372 if (!page)
@@ -354,14 +374,57 @@ static void free_buf(struct port_buffer *buf)
354 put_page(page); 374 put_page(page);
355 } 375 }
356 376
377 if (!buf->dev) {
378 kfree(buf->buf);
379 } else if (is_rproc_enabled) {
380 unsigned long flags;
381
382 /* dma_free_coherent requires interrupts to be enabled. */
383 if (!can_sleep) {
384 /* queue up dma-buffers to be freed later */
385 spin_lock_irqsave(&dma_bufs_lock, flags);
386 list_add_tail(&buf->list, &pending_free_dma_bufs);
387 spin_unlock_irqrestore(&dma_bufs_lock, flags);
388 return;
389 }
390 dma_free_coherent(buf->dev, buf->size, buf->buf, buf->dma);
391
392 /* Release device refcnt and allow it to be freed */
393 put_device(buf->dev);
394 }
395
357 kfree(buf); 396 kfree(buf);
358} 397}
359 398
399static void reclaim_dma_bufs(void)
400{
401 unsigned long flags;
402 struct port_buffer *buf, *tmp;
403 LIST_HEAD(tmp_list);
404
405 if (list_empty(&pending_free_dma_bufs))
406 return;
407
408 /* Create a copy of the pending_free_dma_bufs while holding the lock */
409 spin_lock_irqsave(&dma_bufs_lock, flags);
410 list_cut_position(&tmp_list, &pending_free_dma_bufs,
411 pending_free_dma_bufs.prev);
412 spin_unlock_irqrestore(&dma_bufs_lock, flags);
413
414 /* Release the dma buffers, without irqs enabled */
415 list_for_each_entry_safe(buf, tmp, &tmp_list, list) {
416 list_del(&buf->list);
417 free_buf(buf, true);
418 }
419}
420
360static struct port_buffer *alloc_buf(struct virtqueue *vq, size_t buf_size, 421static struct port_buffer *alloc_buf(struct virtqueue *vq, size_t buf_size,
361 int pages) 422 int pages)
362{ 423{
363 struct port_buffer *buf; 424 struct port_buffer *buf;
364 425
426 reclaim_dma_bufs();
427
365 /* 428 /*
366 * Allocate buffer and the sg list. The sg list array is allocated 429 * Allocate buffer and the sg list. The sg list array is allocated
367 * directly after the port_buffer struct. 430 * directly after the port_buffer struct.
@@ -373,11 +436,34 @@ static struct port_buffer *alloc_buf(struct virtqueue *vq, size_t buf_size,
373 436
374 buf->sgpages = pages; 437 buf->sgpages = pages;
375 if (pages > 0) { 438 if (pages > 0) {
439 buf->dev = NULL;
376 buf->buf = NULL; 440 buf->buf = NULL;
377 return buf; 441 return buf;
378 } 442 }
379 443
380 buf->buf = kmalloc(buf_size, GFP_KERNEL); 444 if (is_rproc_serial(vq->vdev)) {
445 /*
446 * Allocate DMA memory from ancestor. When a virtio
447 * device is created by remoteproc, the DMA memory is
448 * associated with the grandparent device:
449 * vdev => rproc => platform-dev.
450 * The code here would have been less quirky if
451 * DMA_MEMORY_INCLUDES_CHILDREN had been supported
452 * in dma-coherent.c
453 */
454 if (!vq->vdev->dev.parent || !vq->vdev->dev.parent->parent)
455 goto free_buf;
456 buf->dev = vq->vdev->dev.parent->parent;
457
458 /* Increase device refcnt to avoid freeing it */
459 get_device(buf->dev);
460 buf->buf = dma_alloc_coherent(buf->dev, buf_size, &buf->dma,
461 GFP_KERNEL);
462 } else {
463 buf->dev = NULL;
464 buf->buf = kmalloc(buf_size, GFP_KERNEL);
465 }
466
381 if (!buf->buf) 467 if (!buf->buf)
382 goto free_buf; 468 goto free_buf;
383 buf->len = 0; 469 buf->len = 0;
@@ -446,7 +532,7 @@ static void discard_port_data(struct port *port)
446 port->stats.bytes_discarded += buf->len - buf->offset; 532 port->stats.bytes_discarded += buf->len - buf->offset;
447 if (add_inbuf(port->in_vq, buf) < 0) { 533 if (add_inbuf(port->in_vq, buf) < 0) {
448 err++; 534 err++;
449 free_buf(buf); 535 free_buf(buf, false);
450 } 536 }
451 port->inbuf = NULL; 537 port->inbuf = NULL;
452 buf = get_inbuf(port); 538 buf = get_inbuf(port);
@@ -518,7 +604,7 @@ static void reclaim_consumed_buffers(struct port *port)
518 return; 604 return;
519 } 605 }
520 while ((buf = virtqueue_get_buf(port->out_vq, &len))) { 606 while ((buf = virtqueue_get_buf(port->out_vq, &len))) {
521 free_buf(buf); 607 free_buf(buf, false);
522 port->outvq_full = false; 608 port->outvq_full = false;
523 } 609 }
524} 610}
@@ -765,7 +851,7 @@ static ssize_t port_fops_write(struct file *filp, const char __user *ubuf,
765 goto out; 851 goto out;
766 852
767free_buf: 853free_buf:
768 free_buf(buf); 854 free_buf(buf, true);
769out: 855out:
770 return ret; 856 return ret;
771} 857}
@@ -839,6 +925,15 @@ static ssize_t port_fops_splice_write(struct pipe_inode_info *pipe,
839 .u.data = &sgl, 925 .u.data = &sgl,
840 }; 926 };
841 927
928 /*
929 * Rproc_serial does not yet support splice. To support splice
930 * pipe_to_sg() must allocate dma-buffers and copy content from
931 * regular pages to dma pages. And alloc_buf and free_buf must
932 * support allocating and freeing such a list of dma-buffers.
933 */
934 if (is_rproc_serial(port->out_vq->vdev))
935 return -EINVAL;
936
842 ret = wait_port_writable(port, filp->f_flags & O_NONBLOCK); 937 ret = wait_port_writable(port, filp->f_flags & O_NONBLOCK);
843 if (ret < 0) 938 if (ret < 0)
844 return ret; 939 return ret;
@@ -857,7 +952,7 @@ static ssize_t port_fops_splice_write(struct pipe_inode_info *pipe,
857 ret = __send_to_port(port, buf->sg, sgl.n, sgl.len, buf, true); 952 ret = __send_to_port(port, buf->sg, sgl.n, sgl.len, buf, true);
858 953
859 if (unlikely(ret <= 0)) 954 if (unlikely(ret <= 0))
860 kfree(sgl.sg); 955 free_buf(buf, true);
861 return ret; 956 return ret;
862} 957}
863 958
@@ -906,6 +1001,7 @@ static int port_fops_release(struct inode *inode, struct file *filp)
906 reclaim_consumed_buffers(port); 1001 reclaim_consumed_buffers(port);
907 spin_unlock_irq(&port->outvq_lock); 1002 spin_unlock_irq(&port->outvq_lock);
908 1003
1004 reclaim_dma_bufs();
909 /* 1005 /*
910 * Locks aren't necessary here as a port can't be opened after 1006 * Locks aren't necessary here as a port can't be opened after
911 * unplug, and if a port isn't unplugged, a kref would already 1007 * unplug, and if a port isn't unplugged, a kref would already
@@ -1057,7 +1153,10 @@ static void resize_console(struct port *port)
1057 return; 1153 return;
1058 1154
1059 vdev = port->portdev->vdev; 1155 vdev = port->portdev->vdev;
1060 if (virtio_has_feature(vdev, VIRTIO_CONSOLE_F_SIZE)) 1156
1157 /* Don't test F_SIZE at all if we're rproc: not a valid feature! */
1158 if (!is_rproc_serial(vdev) &&
1159 virtio_has_feature(vdev, VIRTIO_CONSOLE_F_SIZE))
1061 hvc_resize(port->cons.hvc, port->cons.ws); 1160 hvc_resize(port->cons.hvc, port->cons.ws);
1062} 1161}
1063 1162
@@ -1249,7 +1348,7 @@ static unsigned int fill_queue(struct virtqueue *vq, spinlock_t *lock)
1249 ret = add_inbuf(vq, buf); 1348 ret = add_inbuf(vq, buf);
1250 if (ret < 0) { 1349 if (ret < 0) {
1251 spin_unlock_irq(lock); 1350 spin_unlock_irq(lock);
1252 free_buf(buf); 1351 free_buf(buf, true);
1253 break; 1352 break;
1254 } 1353 }
1255 nr_added_bufs++; 1354 nr_added_bufs++;
@@ -1337,10 +1436,18 @@ static int add_port(struct ports_device *portdev, u32 id)
1337 goto free_device; 1436 goto free_device;
1338 } 1437 }
1339 1438
1340 /* 1439 if (is_rproc_serial(port->portdev->vdev))
1341 * If we're not using multiport support, this has to be a console port 1440 /*
1342 */ 1441 * For rproc_serial assume remote processor is connected.
1343 if (!use_multiport(port->portdev)) { 1442 * rproc_serial does not want the console port, only
1443 * the generic port implementation.
1444 */
1445 port->host_connected = true;
1446 else if (!use_multiport(port->portdev)) {
1447 /*
1448 * If we're not using multiport support,
1449 * this has to be a console port.
1450 */
1344 err = init_port_console(port); 1451 err = init_port_console(port);
1345 if (err) 1452 if (err)
1346 goto free_inbufs; 1453 goto free_inbufs;
@@ -1373,7 +1480,7 @@ static int add_port(struct ports_device *portdev, u32 id)
1373 1480
1374free_inbufs: 1481free_inbufs:
1375 while ((buf = virtqueue_detach_unused_buf(port->in_vq))) 1482 while ((buf = virtqueue_detach_unused_buf(port->in_vq)))
1376 free_buf(buf); 1483 free_buf(buf, true);
1377free_device: 1484free_device:
1378 device_destroy(pdrvdata.class, port->dev->devt); 1485 device_destroy(pdrvdata.class, port->dev->devt);
1379free_cdev: 1486free_cdev:
@@ -1415,11 +1522,11 @@ static void remove_port_data(struct port *port)
1415 1522
1416 /* Remove buffers we queued up for the Host to send us data in. */ 1523 /* Remove buffers we queued up for the Host to send us data in. */
1417 while ((buf = virtqueue_detach_unused_buf(port->in_vq))) 1524 while ((buf = virtqueue_detach_unused_buf(port->in_vq)))
1418 free_buf(buf); 1525 free_buf(buf, true);
1419 1526
1420 /* Free pending buffers from the out-queue. */ 1527 /* Free pending buffers from the out-queue. */
1421 while ((buf = virtqueue_detach_unused_buf(port->out_vq))) 1528 while ((buf = virtqueue_detach_unused_buf(port->out_vq)))
1422 free_buf(buf); 1529 free_buf(buf, true);
1423} 1530}
1424 1531
1425/* 1532/*
@@ -1621,7 +1728,7 @@ static void control_work_handler(struct work_struct *work)
1621 if (add_inbuf(portdev->c_ivq, buf) < 0) { 1728 if (add_inbuf(portdev->c_ivq, buf) < 0) {
1622 dev_warn(&portdev->vdev->dev, 1729 dev_warn(&portdev->vdev->dev,
1623 "Error adding buffer to queue\n"); 1730 "Error adding buffer to queue\n");
1624 free_buf(buf); 1731 free_buf(buf, false);
1625 } 1732 }
1626 } 1733 }
1627 spin_unlock(&portdev->cvq_lock); 1734 spin_unlock(&portdev->cvq_lock);
@@ -1817,10 +1924,10 @@ static void remove_controlq_data(struct ports_device *portdev)
1817 return; 1924 return;
1818 1925
1819 while ((buf = virtqueue_get_buf(portdev->c_ivq, &len))) 1926 while ((buf = virtqueue_get_buf(portdev->c_ivq, &len)))
1820 free_buf(buf); 1927 free_buf(buf, true);
1821 1928
1822 while ((buf = virtqueue_detach_unused_buf(portdev->c_ivq))) 1929 while ((buf = virtqueue_detach_unused_buf(portdev->c_ivq)))
1823 free_buf(buf); 1930 free_buf(buf, true);
1824} 1931}
1825 1932
1826/* 1933/*
@@ -1867,11 +1974,15 @@ static int __devinit virtcons_probe(struct virtio_device *vdev)
1867 1974
1868 multiport = false; 1975 multiport = false;
1869 portdev->config.max_nr_ports = 1; 1976 portdev->config.max_nr_ports = 1;
1870 if (virtio_config_val(vdev, VIRTIO_CONSOLE_F_MULTIPORT, 1977
1871 offsetof(struct virtio_console_config, 1978 /* Don't test MULTIPORT at all if we're rproc: not a valid feature! */
1872 max_nr_ports), 1979 if (!is_rproc_serial(vdev) &&
1873 &portdev->config.max_nr_ports) == 0) 1980 virtio_config_val(vdev, VIRTIO_CONSOLE_F_MULTIPORT,
1981 offsetof(struct virtio_console_config,
1982 max_nr_ports),
1983 &portdev->config.max_nr_ports) == 0) {
1874 multiport = true; 1984 multiport = true;
1985 }
1875 1986
1876 err = init_vqs(portdev); 1987 err = init_vqs(portdev);
1877 if (err < 0) { 1988 if (err < 0) {
@@ -1981,6 +2092,16 @@ static unsigned int features[] = {
1981 VIRTIO_CONSOLE_F_MULTIPORT, 2092 VIRTIO_CONSOLE_F_MULTIPORT,
1982}; 2093};
1983 2094
2095static struct virtio_device_id rproc_serial_id_table[] = {
2096#if IS_ENABLED(CONFIG_REMOTEPROC)
2097 { VIRTIO_ID_RPROC_SERIAL, VIRTIO_DEV_ANY_ID },
2098#endif
2099 { 0 },
2100};
2101
2102static unsigned int rproc_serial_features[] = {
2103};
2104
1984#ifdef CONFIG_PM 2105#ifdef CONFIG_PM
1985static int virtcons_freeze(struct virtio_device *vdev) 2106static int virtcons_freeze(struct virtio_device *vdev)
1986{ 2107{
@@ -2065,6 +2186,20 @@ static struct virtio_driver virtio_console = {
2065#endif 2186#endif
2066}; 2187};
2067 2188
2189/*
2190 * virtio_rproc_serial refers to __devinit function which causes
2191 * section mismatch warnings. So use __refdata to silence warnings.
2192 */
2193static struct virtio_driver __refdata virtio_rproc_serial = {
2194 .feature_table = rproc_serial_features,
2195 .feature_table_size = ARRAY_SIZE(rproc_serial_features),
2196 .driver.name = "virtio_rproc_serial",
2197 .driver.owner = THIS_MODULE,
2198 .id_table = rproc_serial_id_table,
2199 .probe = virtcons_probe,
2200 .remove = virtcons_remove,
2201};
2202
2068static int __init init(void) 2203static int __init init(void)
2069{ 2204{
2070 int err; 2205 int err;
@@ -2089,7 +2224,15 @@ static int __init init(void)
2089 pr_err("Error %d registering virtio driver\n", err); 2224 pr_err("Error %d registering virtio driver\n", err);
2090 goto free; 2225 goto free;
2091 } 2226 }
2227 err = register_virtio_driver(&virtio_rproc_serial);
2228 if (err < 0) {
2229 pr_err("Error %d registering virtio rproc serial driver\n",
2230 err);
2231 goto unregister;
2232 }
2092 return 0; 2233 return 0;
2234unregister:
2235 unregister_virtio_driver(&virtio_console);
2093free: 2236free:
2094 if (pdrvdata.debugfs_dir) 2237 if (pdrvdata.debugfs_dir)
2095 debugfs_remove_recursive(pdrvdata.debugfs_dir); 2238 debugfs_remove_recursive(pdrvdata.debugfs_dir);
@@ -2099,7 +2242,10 @@ free:
2099 2242
2100static void __exit fini(void) 2243static void __exit fini(void)
2101{ 2244{
2245 reclaim_dma_bufs();
2246
2102 unregister_virtio_driver(&virtio_console); 2247 unregister_virtio_driver(&virtio_console);
2248 unregister_virtio_driver(&virtio_rproc_serial);
2103 2249
2104 class_destroy(pdrvdata.class); 2250 class_destroy(pdrvdata.class);
2105 if (pdrvdata.debugfs_dir) 2251 if (pdrvdata.debugfs_dir)