Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

serial: sh-sci: Support for variable HSCIF hardware RX timeout

HSCIF has facilities that allow changing the timeout after which an RX
interrupt is triggered even if the FIFO is not filled. This patch allows
changing the default (15 bits of silence) using the existing sysfs
attribute "rx_fifo_timeout".

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>

authored by

Ulrich Hecht and committed by
Greg Kroah-Hartman
fa2abb03 62fadbd8

+40 -15
+37 -15
drivers/tty/serial/sh-sci.c
··· 152 152 int rx_trigger; 153 153 struct timer_list rx_fifo_timer; 154 154 int rx_fifo_timeout; 155 + u16 hscif_tot; 155 156 156 157 bool has_rtscts; 157 158 bool autorts; ··· 1108 1107 { 1109 1108 struct uart_port *port = dev_get_drvdata(dev); 1110 1109 struct sci_port *sci = to_sci_port(port); 1110 + int v; 1111 1111 1112 - return sprintf(buf, "%d\n", sci->rx_fifo_timeout); 1112 + if (port->type == PORT_HSCIF) 1113 + v = sci->hscif_tot >> HSSCR_TOT_SHIFT; 1114 + else 1115 + v = sci->rx_fifo_timeout; 1116 + 1117 + return sprintf(buf, "%d\n", v); 1113 1118 } 1114 1119 1115 1120 static ssize_t rx_fifo_timeout_store(struct device *dev, ··· 1131 1124 ret = kstrtol(buf, 0, &r); 1132 1125 if (ret) 1133 1126 return ret; 1134 - sci->rx_fifo_timeout = r; 1135 - scif_set_rtrg(port, 1); 1136 - if (r > 0) 1137 - setup_timer(&sci->rx_fifo_timer, rx_fifo_timer_fn, 1138 - (unsigned long)sci); 1127 + 1128 + if (port->type == PORT_HSCIF) { 1129 + if (r < 0 || r > 3) 1130 + return -EINVAL; 1131 + sci->hscif_tot = r << HSSCR_TOT_SHIFT; 1132 + } else { 1133 + sci->rx_fifo_timeout = r; 1134 + scif_set_rtrg(port, 1); 1135 + if (r > 0) 1136 + setup_timer(&sci->rx_fifo_timer, rx_fifo_timer_fn, 1137 + (unsigned long)sci); 1138 + } 1139 + 1139 1140 return count; 1140 1141 } 1141 1142 ··· 2052 2037 spin_lock_irqsave(&port->lock, flags); 2053 2038 sci_stop_rx(port); 2054 2039 sci_stop_tx(port); 2055 - /* Stop RX and TX, disable related interrupts, keep clock source */ 2040 + /* 2041 + * Stop RX and TX, disable related interrupts, keep clock source 2042 + * and HSCIF TOT bits 2043 + */ 2056 2044 scr = serial_port_in(port, SCSCR); 2057 - serial_port_out(port, SCSCR, scr & (SCSCR_CKE1 | SCSCR_CKE0)); 2045 + serial_port_out(port, SCSCR, scr & 2046 + (SCSCR_CKE1 | SCSCR_CKE0 | s->hscif_tot)); 2058 2047 spin_unlock_irqrestore(&port->lock, flags); 2059 2048 2060 2049 #ifdef CONFIG_SERIAL_SH_SCI_DMA ··· 2205 2186 unsigned int status; 2206 2187 struct sci_port *s = to_sci_port(port); 2207 2188 2208 - serial_port_out(port, SCSCR, 0x00); /* TE=0, RE=0, CKE1=0 */ 2189 + serial_port_out(port, SCSCR, s->hscif_tot); /* TE=0, RE=0, CKE1=0 */ 2209 2190 2210 2191 reg = sci_getreg(port, SCFCR); 2211 2192 if (reg->size) ··· 2375 2356 dev_dbg(port->dev, 2376 2357 "SCR 0x%x SMR 0x%x BRR %u CKS 0x%x DL %u SRR %u\n", 2377 2358 scr_val, smr_val, brr, sccks, dl, srr); 2378 - serial_port_out(port, SCSCR, scr_val); 2359 + serial_port_out(port, SCSCR, scr_val | s->hscif_tot); 2379 2360 serial_port_out(port, SCSMR, smr_val); 2380 2361 serial_port_out(port, SCBRR, brr); 2381 2362 if (sci_getreg(port, HSSRR)->size) ··· 2389 2370 smr_val |= serial_port_in(port, SCSMR) & 2390 2371 (SCSMR_CKEDG | SCSMR_SRC_MASK | SCSMR_CKS); 2391 2372 dev_dbg(port->dev, "SCR 0x%x SMR 0x%x\n", scr_val, smr_val); 2392 - serial_port_out(port, SCSCR, scr_val); 2373 + serial_port_out(port, SCSCR, scr_val | s->hscif_tot); 2393 2374 serial_port_out(port, SCSMR, smr_val); 2394 2375 } 2395 2376 ··· 2426 2407 scr_val |= SCSCR_RE | SCSCR_TE | 2427 2408 (s->cfg->scscr & ~(SCSCR_CKE1 | SCSCR_CKE0)); 2428 2409 dev_dbg(port->dev, "SCSCR 0x%x\n", scr_val); 2429 - serial_port_out(port, SCSCR, scr_val); 2410 + serial_port_out(port, SCSCR, scr_val | s->hscif_tot); 2430 2411 if ((srr + 1 == 5) && 2431 2412 (port->type == PORT_SCIFA || port->type == PORT_SCIFB)) { 2432 2413 /* ··· 2792 2773 } 2793 2774 2794 2775 sci_port->rx_fifo_timeout = 0; 2776 + sci_port->hscif_tot = 0; 2795 2777 2796 2778 /* SCIFA on sh7723 and sh7724 need a custom sampling rate that doesn't 2797 2779 * match the SoC datasheet, this should be investigated. Let platform ··· 2880 2860 ctrl_temp = SCSCR_RE | SCSCR_TE | 2881 2861 (sci_port->cfg->scscr & ~(SCSCR_CKE1 | SCSCR_CKE0)) | 2882 2862 (ctrl & (SCSCR_CKE1 | SCSCR_CKE0)); 2883 - serial_port_out(port, SCSCR, ctrl_temp); 2863 + serial_port_out(port, SCSCR, ctrl_temp | sci_port->hscif_tot); 2884 2864 2885 2865 uart_console_write(port, s, count, serial_console_putchar); 2886 2866 ··· 3008 2988 sysfs_remove_file(&dev->dev.kobj, 3009 2989 &dev_attr_rx_fifo_trigger.attr); 3010 2990 } 3011 - if (port->port.type == PORT_SCIFA || port->port.type == PORT_SCIFB) { 2991 + if (port->port.type == PORT_SCIFA || port->port.type == PORT_SCIFB || 2992 + port->port.type == PORT_HSCIF) { 3012 2993 sysfs_remove_file(&dev->dev.kobj, 3013 2994 &dev_attr_rx_fifo_timeout.attr); 3014 2995 } ··· 3194 3173 if (ret) 3195 3174 return ret; 3196 3175 } 3197 - if (sp->port.type == PORT_SCIFA || sp->port.type == PORT_SCIFB) { 3176 + if (sp->port.type == PORT_SCIFA || sp->port.type == PORT_SCIFB || 3177 + sp->port.type == PORT_HSCIF) { 3198 3178 ret = sysfs_create_file(&dev->dev.kobj, 3199 3179 &dev_attr_rx_fifo_timeout.attr); 3200 3180 if (ret) {
+3
drivers/tty/serial/sh-sci.h
··· 62 62 #define SCSCR_TDRQE BIT(15) /* Tx Data Transfer Request Enable */ 63 63 #define SCSCR_RDRQE BIT(14) /* Rx Data Transfer Request Enable */ 64 64 65 + /* Serial Control Register, HSCIF-only bits */ 66 + #define HSSCR_TOT_SHIFT 14 67 + 65 68 /* SCxSR (Serial Status Register) on SCI */ 66 69 #define SCI_TDRE BIT(7) /* Transmit Data Register Empty */ 67 70 #define SCI_RDRF BIT(6) /* Receive Data Register Full */