3

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.

Damien
  • 785
  • 3
  • 8
  • 18
  • Oh, and isaset -y -f 0x3fA 0x07 (which directly pokes the FCR register of /dev/ttyS0) does not count! – Damien Aug 02 '16 at 05:15
  • If `isaset` does not count, why should other solutions count? – Erki Aring Aug 02 '16 at 08:45
  • Because the changes are lost whenever the port is re-opened. Moreover, it must be done by a privileged user - and poking random IO ports from userspace is generally not a safe option! – Damien Aug 03 '16 at 00:30
  • There is a sysfs method that must strictly be run as root: echo 4 > /sys/class/tty/ttyS6/rx_trig_bytes. It's safer that isaset, but not something to which privileges can be delegated to. It was [added to the kernel](https://kernel.googlesource.com/pub/scm/linux/kernel/git/rric/linux/+/aef9a7bd9b676f797dd5cefd43deb30d36b976a9) in 2014. – Damien Aug 03 '16 at 04:40

1 Answers1

0

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

Jimi
  • 29
  • 2
  • I'm not trying to change the UART type; I am trying to change the FIFO threshold level, i.e. the " UART_FCR_R_TRIG_10" flag in the original post. – Damien Feb 14 '18 at 01:59