3737#include <linux/wait.h>
3838#include <linux/workqueue.h>
3939#include <linux/module.h>
40+ #include <linux/dma-mapping.h>
41+ #include <linux/kconfig.h>
4042#include "../tty/hvc/hvc_console.h"
4143
44+ #define is_rproc_enabled IS_ENABLED(CONFIG_REMOTEPROC)
45+
4246/*
4347 * This is a global struct for storing common data for all the devices
4448 * this driver handles.
@@ -112,6 +116,15 @@ struct port_buffer {
112116 /* offset in the buf from which to consume data */
113117 size_t offset ;
114118
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+
115128 /* If sgpages == 0 then buf is used */
116129 unsigned int sgpages ;
117130
@@ -331,6 +344,11 @@ static bool is_console_port(struct port *port)
331344 return false;
332345}
333346
347+ static bool is_rproc_serial (const struct virtio_device * vdev )
348+ {
349+ return is_rproc_enabled && vdev -> id .device == VIRTIO_ID_RPROC_SERIAL ;
350+ }
351+
334352static inline bool use_multiport (struct ports_device * portdev )
335353{
336354 /*
@@ -342,26 +360,71 @@ static inline bool use_multiport(struct ports_device *portdev)
342360 return portdev -> vdev -> features [0 ] & (1 << VIRTIO_CONSOLE_F_MULTIPORT );
343361}
344362
345- static void free_buf (struct port_buffer * buf )
363+ static DEFINE_SPINLOCK (dma_bufs_lock );
364+ static LIST_HEAD (pending_free_dma_bufs );
365+
366+ static void free_buf (struct port_buffer * buf , bool can_sleep )
346367{
347368 unsigned int i ;
348369
349- kfree (buf -> buf );
350370 for (i = 0 ; i < buf -> sgpages ; i ++ ) {
351371 struct page * page = sg_page (& buf -> sg [i ]);
352372 if (!page )
353373 break ;
354374 put_page (page );
355375 }
356376
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+
357396 kfree (buf );
358397}
359398
399+ static 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+
360421static struct port_buffer * alloc_buf (struct virtqueue * vq , size_t buf_size ,
361422 int pages )
362423{
363424 struct port_buffer * buf ;
364425
426+ reclaim_dma_bufs ();
427+
365428 /*
366429 * Allocate buffer and the sg list. The sg list array is allocated
367430 * directly after the port_buffer struct.
@@ -373,11 +436,34 @@ static struct port_buffer *alloc_buf(struct virtqueue *vq, size_t buf_size,
373436
374437 buf -> sgpages = pages ;
375438 if (pages > 0 ) {
439+ buf -> dev = NULL ;
376440 buf -> buf = NULL ;
377441 return buf ;
378442 }
379443
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+
381467 if (!buf -> buf )
382468 goto free_buf ;
383469 buf -> len = 0 ;
@@ -446,7 +532,7 @@ static void discard_port_data(struct port *port)
446532 port -> stats .bytes_discarded += buf -> len - buf -> offset ;
447533 if (add_inbuf (port -> in_vq , buf ) < 0 ) {
448534 err ++ ;
449- free_buf (buf );
535+ free_buf (buf , false );
450536 }
451537 port -> inbuf = NULL ;
452538 buf = get_inbuf (port );
@@ -518,7 +604,7 @@ static void reclaim_consumed_buffers(struct port *port)
518604 return ;
519605 }
520606 while ((buf = virtqueue_get_buf (port -> out_vq , & len ))) {
521- free_buf (buf );
607+ free_buf (buf , false );
522608 port -> outvq_full = false;
523609 }
524610}
@@ -765,7 +851,7 @@ static ssize_t port_fops_write(struct file *filp, const char __user *ubuf,
765851 goto out ;
766852
767853free_buf :
768- free_buf (buf );
854+ free_buf (buf , true );
769855out :
770856 return ret ;
771857}
@@ -839,6 +925,15 @@ static ssize_t port_fops_splice_write(struct pipe_inode_info *pipe,
839925 .u .data = & sgl ,
840926 };
841927
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+
842937 ret = wait_port_writable (port , filp -> f_flags & O_NONBLOCK );
843938 if (ret < 0 )
844939 return ret ;
@@ -857,7 +952,7 @@ static ssize_t port_fops_splice_write(struct pipe_inode_info *pipe,
857952 ret = __send_to_port (port , buf -> sg , sgl .n , sgl .len , buf , true);
858953
859954 if (unlikely (ret <= 0 ))
860- kfree ( sgl . sg );
955+ free_buf ( buf , true );
861956 return ret ;
862957}
863958
@@ -906,6 +1001,7 @@ static int port_fops_release(struct inode *inode, struct file *filp)
9061001 reclaim_consumed_buffers (port );
9071002 spin_unlock_irq (& port -> outvq_lock );
9081003
1004+ reclaim_dma_bufs ();
9091005 /*
9101006 * Locks aren't necessary here as a port can't be opened after
9111007 * unplug, and if a port isn't unplugged, a kref would already
@@ -1057,7 +1153,10 @@ static void resize_console(struct port *port)
10571153 return ;
10581154
10591155 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 ))
10611160 hvc_resize (port -> cons .hvc , port -> cons .ws );
10621161}
10631162
@@ -1249,7 +1348,7 @@ static unsigned int fill_queue(struct virtqueue *vq, spinlock_t *lock)
12491348 ret = add_inbuf (vq , buf );
12501349 if (ret < 0 ) {
12511350 spin_unlock_irq (lock );
1252- free_buf (buf );
1351+ free_buf (buf , true );
12531352 break ;
12541353 }
12551354 nr_added_bufs ++ ;
@@ -1337,10 +1436,18 @@ static int add_port(struct ports_device *portdev, u32 id)
13371436 goto free_device ;
13381437 }
13391438
1340- /*
1341- * If we're not using multiport support, this has to be a console port
1342- */
1343- if (!use_multiport (port -> portdev )) {
1439+ if (is_rproc_serial (port -> portdev -> vdev ))
1440+ /*
1441+ * For rproc_serial assume remote processor is connected.
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+ */
13441451 err = init_port_console (port );
13451452 if (err )
13461453 goto free_inbufs ;
@@ -1373,7 +1480,7 @@ static int add_port(struct ports_device *portdev, u32 id)
13731480
13741481free_inbufs :
13751482 while ((buf = virtqueue_detach_unused_buf (port -> in_vq )))
1376- free_buf (buf );
1483+ free_buf (buf , true );
13771484free_device :
13781485 device_destroy (pdrvdata .class , port -> dev -> devt );
13791486free_cdev :
@@ -1415,11 +1522,11 @@ static void remove_port_data(struct port *port)
14151522
14161523 /* Remove buffers we queued up for the Host to send us data in. */
14171524 while ((buf = virtqueue_detach_unused_buf (port -> in_vq )))
1418- free_buf (buf );
1525+ free_buf (buf , true );
14191526
14201527 /* Free pending buffers from the out-queue. */
14211528 while ((buf = virtqueue_detach_unused_buf (port -> out_vq )))
1422- free_buf (buf );
1529+ free_buf (buf , true );
14231530}
14241531
14251532/*
@@ -1621,7 +1728,7 @@ static void control_work_handler(struct work_struct *work)
16211728 if (add_inbuf (portdev -> c_ivq , buf ) < 0 ) {
16221729 dev_warn (& portdev -> vdev -> dev ,
16231730 "Error adding buffer to queue\n" );
1624- free_buf (buf );
1731+ free_buf (buf , false );
16251732 }
16261733 }
16271734 spin_unlock (& portdev -> cvq_lock );
@@ -1817,10 +1924,10 @@ static void remove_controlq_data(struct ports_device *portdev)
18171924 return ;
18181925
18191926 while ((buf = virtqueue_get_buf (portdev -> c_ivq , & len )))
1820- free_buf (buf );
1927+ free_buf (buf , true );
18211928
18221929 while ((buf = virtqueue_detach_unused_buf (portdev -> c_ivq )))
1823- free_buf (buf );
1930+ free_buf (buf , true );
18241931}
18251932
18261933/*
@@ -1867,11 +1974,15 @@ static int __devinit virtcons_probe(struct virtio_device *vdev)
18671974
18681975 multiport = false;
18691976 portdev -> config .max_nr_ports = 1 ;
1870- if (virtio_config_val (vdev , VIRTIO_CONSOLE_F_MULTIPORT ,
1871- offsetof(struct virtio_console_config ,
1872- max_nr_ports ),
1873- & portdev -> config .max_nr_ports ) == 0 )
1977+
1978+ /* Don't test MULTIPORT at all if we're rproc: not a valid feature! */
1979+ if (!is_rproc_serial (vdev ) &&
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 ) {
18741984 multiport = true;
1985+ }
18751986
18761987 err = init_vqs (portdev );
18771988 if (err < 0 ) {
@@ -1981,6 +2092,16 @@ static unsigned int features[] = {
19812092 VIRTIO_CONSOLE_F_MULTIPORT ,
19822093};
19832094
2095+ static 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+
2102+ static unsigned int rproc_serial_features [] = {
2103+ };
2104+
19842105#ifdef CONFIG_PM
19852106static int virtcons_freeze (struct virtio_device * vdev )
19862107{
@@ -2065,6 +2186,20 @@ static struct virtio_driver virtio_console = {
20652186#endif
20662187};
20672188
2189+ /*
2190+ * virtio_rproc_serial refers to __devinit function which causes
2191+ * section mismatch warnings. So use __refdata to silence warnings.
2192+ */
2193+ static 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+
20682203static int __init init (void )
20692204{
20702205 int err ;
@@ -2089,7 +2224,15 @@ static int __init init(void)
20892224 pr_err ("Error %d registering virtio driver\n" , err );
20902225 goto free ;
20912226 }
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+ }
20922233 return 0 ;
2234+ unregister :
2235+ unregister_virtio_driver (& virtio_console );
20932236free :
20942237 if (pdrvdata .debugfs_dir )
20952238 debugfs_remove_recursive (pdrvdata .debugfs_dir );
@@ -2099,7 +2242,10 @@ static int __init init(void)
20992242
21002243static void __exit fini (void )
21012244{
2245+ reclaim_dma_bufs ();
2246+
21022247 unregister_virtio_driver (& virtio_console );
2248+ unregister_virtio_driver (& virtio_rproc_serial );
21032249
21042250 class_destroy (pdrvdata .class );
21052251 if (pdrvdata .debugfs_dir )
0 commit comments