In >=3.10.5 the "serial FIFO" that you refer to is called a uart_port
. These are defined in drivers/tty/serial
.
I assume that what you want to do is to copy the driver for your UART to a new file, then instead of using uart_insert_char
to insert characters from the UART RX FIFO, you want to insert the characters into a buffer that you can access from user space.
The way to do this is to create a second driver, a misc
class device driver that has file operations, including mmap
, and that allocates kernel memory that the driver's mmap
file operation function associates with the userspace mapped memory. There is a good example of code for this written by Maxime Ripard. This example was written for a FIQ handled device, but you can use just the probe routine's dma_zalloc_coherent
call and the mmap routine, with it's call to remap_pfn_range
, to do the trick, that is, to associate a user space mmap on the misc
device file with the alloc'ed memory.
You need to connect the memory that you allocated in your misc
driver to the buffer that you write to in your UART driver using either a global void pointer, or else by using an exported symbol, if your misc
driver is a module. Initialize the pointer to a known invalid value in the UART driver and test it to make sure the misc
driver has assigned it before you try to insert characters to the address to which it points.
Note that you can't add an mmap
function to the UART driver directly because the UART driver class does not support an mmap
file operation. It only supports the operations defined in the include/linux/serial_core.h
struct uart_ops
.
Admittedly this is a cumbersome solution - two device drivers, but the alternative is to write a new device class, a UART device that has an mmap
operation, and that would be a lot of work compared with the above solution although it would be elegant. No one has done this to date because as Jonathan Corbet say's "...not every device lends itself to the mmap abstraction; it makes no sense, for instance, for serial ports and other stream-oriented devices", though this is exactly what you are asking for.
I implemented this solution for a polling mode UART driver based on the mxs-auart.c
code and Maxime's example. It was non-trivial effort but mostly because I am using a FIQ handler for the polling timer. You should allow two to three weeks to get the whole thing up and running.
The DMA aspect of your question depends on whether the UART supports DMA transfer mode. If so, then you should be able to set it using the serial flags
. The i.MX28's PrimeCell auarts support DMA transfer but for my application there was no advantage over simply reading bytes directly from the UART RX FIFO.