I am currently using a 16550-compatible UART, and I want to be able to change the FIFO interrupt trigger level (I am dropping bytes under high UART loads and I want to reduce the threshold - it's an underpowered embedded system). Of course, I can change it in the 8250_port.c driver if I want:
[PORT_NS16550A] = {
.name = "NS16550A",
.fifo_size = 16,
.tx_loadsz = 16,
.fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
.flags = UART_CAP_FIFO | UART_NATSEMI,
},
But it would be far more convenient to change it from userspace without having to recompile a kernel.
I am hoping that the following documentation is out of date:
As of late 2000 there was no way the Linux user could set these directly (setserial can't do it). While many PC's only have a 16550 with 16-byte buffers, better UARTS have even larger buffers.
If there is a means to doing so (e.g. some new-ish ioctl), then seterial (8) and stty (1) do not yet expose the interface.
I think the general solution to this problem is to use setserial to make the uart change modes. For instance with the pericom PI7C9X7958, you have multiple modes of operation such as the "550" and the 950 modes. These correspond to a 16550 or a 16950 standard uart type. Each mode has a certain fifo size associated with it and some other features.
So, if your device supports it you can try
setserial -v /dev/ttyS1 uart 16950
and then to verify
setserial -g /dev/ttyS1 /dev/ttyS1, UART: 16950/954, Port: 0xc800, IRQ: 16
来源:https://stackoverflow.com/questions/38712137/set-16550a-uart-hardware-fifo-interrupt-level-from-linux-userspace