serial: sh-sci: implement FIFO threshold register setting
authorUlrich Hecht <ulrich.hecht+renesas@gmail.com>
Thu, 2 Feb 2017 17:10:16 +0000 (18:10 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 3 Feb 2017 09:14:10 +0000 (10:14 +0100)
Sets the closest match for a desired RX trigger level.

Signed-off-by: Ulrich Hecht <ulrich.hecht+renesas@gmail.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/tty/serial/sh-sci.c

index 5044a5e..050d028 100644 (file)
@@ -974,6 +974,65 @@ static int sci_handle_breaks(struct uart_port *port)
        return copied;
 }
 
+static int scif_set_rtrg(struct uart_port *port, int rx_trig)
+{
+       unsigned int bits;
+
+       if (rx_trig < 1)
+               rx_trig = 1;
+       if (rx_trig >= port->fifosize)
+               rx_trig = port->fifosize;
+
+       /* HSCIF can be set to an arbitrary level. */
+       if (sci_getreg(port, HSRTRGR)->size) {
+               serial_port_out(port, HSRTRGR, rx_trig);
+               return rx_trig;
+       }
+
+       switch (port->type) {
+       case PORT_SCIF:
+               if (rx_trig < 4) {
+                       bits = 0;
+                       rx_trig = 1;
+               } else if (rx_trig < 8) {
+                       bits = SCFCR_RTRG0;
+                       rx_trig = 4;
+               } else if (rx_trig < 14) {
+                       bits = SCFCR_RTRG1;
+                       rx_trig = 8;
+               } else {
+                       bits = SCFCR_RTRG0 | SCFCR_RTRG1;
+                       rx_trig = 14;
+               }
+               break;
+       case PORT_SCIFA:
+       case PORT_SCIFB:
+               if (rx_trig < 16) {
+                       bits = 0;
+                       rx_trig = 1;
+               } else if (rx_trig < 32) {
+                       bits = SCFCR_RTRG0;
+                       rx_trig = 16;
+               } else if (rx_trig < 48) {
+                       bits = SCFCR_RTRG1;
+                       rx_trig = 32;
+               } else {
+                       bits = SCFCR_RTRG0 | SCFCR_RTRG1;
+                       rx_trig = 48;
+               }
+               break;
+       default:
+               WARN(1, "unknown FIFO configuration");
+               return 1;
+       }
+
+       serial_port_out(port, SCFCR,
+               (serial_port_in(port, SCFCR) &
+               ~(SCFCR_RTRG1 | SCFCR_RTRG0)) | bits);
+
+       return rx_trig;
+}
+
 #ifdef CONFIG_SERIAL_SH_SCI_DMA
 static void sci_dma_tx_complete(void *arg)
 {