aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial/sh-sci.c
diff options
context:
space:
mode:
authorGuennadi Liakhovetski <g.liakhovetski@gmx.de>2010-03-19 09:53:04 -0400
committerPaul Mundt <lethal@linux-sh.org>2010-03-23 04:39:30 -0400
commit3089f381fbaf53560dcbcb4aef6ef17fe44e347c (patch)
treeb5e5fdb29fbe27d87343d127314bb8feed36f50d /drivers/serial/sh-sci.c
parentb2623a61cfd3c6badb8396dc85ab5a70f4a05f61 (diff)
SH: extend SCI DMA support to work on SCIFA ports
SCIFA ports have additional bits to control DMA requests and they must have respective interrupt sources enabled, as the datasheet suggests, the only way to avoid actually taking interrupts in addition to DMA events is by masking the IRQ on the CPU. Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'drivers/serial/sh-sci.c')
-rw-r--r--drivers/serial/sh-sci.c114
1 files changed, 81 insertions, 33 deletions
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c
index cd52dd64edf0..304a877d083d 100644
--- a/drivers/serial/sh-sci.c
+++ b/drivers/serial/sh-sci.c
@@ -106,6 +106,7 @@ struct sci_port {
106 struct work_struct work_tx; 106 struct work_struct work_tx;
107 struct work_struct work_rx; 107 struct work_struct work_rx;
108 struct timer_list rx_timer; 108 struct timer_list rx_timer;
109 unsigned int rx_timeout;
109#endif 110#endif
110}; 111};
111 112
@@ -673,22 +674,22 @@ static irqreturn_t sci_rx_interrupt(int irq, void *ptr)
673 struct sci_port *s = to_sci_port(port); 674 struct sci_port *s = to_sci_port(port);
674 675
675 if (s->chan_rx) { 676 if (s->chan_rx) {
676 unsigned long tout;
677 u16 scr = sci_in(port, SCSCR); 677 u16 scr = sci_in(port, SCSCR);
678 u16 ssr = sci_in(port, SCxSR); 678 u16 ssr = sci_in(port, SCxSR);
679 679
680 /* Disable future Rx interrupts */ 680 /* Disable future Rx interrupts */
681 sci_out(port, SCSCR, scr & ~SCI_CTRL_FLAGS_RIE); 681 if (port->type == PORT_SCIFA) {
682 disable_irq_nosync(irq);
683 scr |= 0x4000;
684 } else {
685 scr &= ~SCI_CTRL_FLAGS_RIE;
686 }
687 sci_out(port, SCSCR, scr);
682 /* Clear current interrupt */ 688 /* Clear current interrupt */
683 sci_out(port, SCxSR, ssr & ~(1 | SCxSR_RDxF(port))); 689 sci_out(port, SCxSR, ssr & ~(1 | SCxSR_RDxF(port)));
684 /* Calculate delay for 1.5 DMA buffers */ 690 dev_dbg(port->dev, "Rx IRQ %lu: setup t-out in %u jiffies\n",
685 tout = (port->timeout - HZ / 50) * s->buf_len_rx * 3 / 691 jiffies, s->rx_timeout);
686 port->fifosize / 2; 692 mod_timer(&s->rx_timer, jiffies + s->rx_timeout);
687 dev_dbg(port->dev, "Rx IRQ: setup timeout in %lu ms\n",
688 tout * 1000 / HZ);
689 if (tout < 2)
690 tout = 2;
691 mod_timer(&s->rx_timer, jiffies + tout);
692 693
693 return IRQ_HANDLED; 694 return IRQ_HANDLED;
694 } 695 }
@@ -925,13 +926,17 @@ static void sci_dma_tx_complete(void *arg)
925 s->cookie_tx = -EINVAL; 926 s->cookie_tx = -EINVAL;
926 s->desc_tx = NULL; 927 s->desc_tx = NULL;
927 928
928 spin_unlock_irqrestore(&port->lock, flags);
929
930 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) 929 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
931 uart_write_wakeup(port); 930 uart_write_wakeup(port);
932 931
933 if (uart_circ_chars_pending(xmit)) 932 if (!uart_circ_empty(xmit)) {
934 schedule_work(&s->work_tx); 933 schedule_work(&s->work_tx);
934 } else if (port->type == PORT_SCIFA) {
935 u16 ctrl = sci_in(port, SCSCR);
936 sci_out(port, SCSCR, ctrl & ~SCI_CTRL_FLAGS_TIE);
937 }
938
939 spin_unlock_irqrestore(&port->lock, flags);
935} 940}
936 941
937/* Locking: called with port lock held */ 942/* Locking: called with port lock held */
@@ -975,13 +980,13 @@ static void sci_dma_rx_complete(void *arg)
975 unsigned long flags; 980 unsigned long flags;
976 int count; 981 int count;
977 982
978 dev_dbg(port->dev, "%s(%d)\n", __func__, port->line); 983 dev_dbg(port->dev, "%s(%d) active #%d\n", __func__, port->line, s->active_rx);
979 984
980 spin_lock_irqsave(&port->lock, flags); 985 spin_lock_irqsave(&port->lock, flags);
981 986
982 count = sci_dma_rx_push(s, tty, s->buf_len_rx); 987 count = sci_dma_rx_push(s, tty, s->buf_len_rx);
983 988
984 mod_timer(&s->rx_timer, jiffies + msecs_to_jiffies(5)); 989 mod_timer(&s->rx_timer, jiffies + s->rx_timeout);
985 990
986 spin_unlock_irqrestore(&port->lock, flags); 991 spin_unlock_irqrestore(&port->lock, flags);
987 992
@@ -1053,6 +1058,8 @@ static void sci_submit_rx(struct sci_port *s)
1053 sci_rx_dma_release(s, true); 1058 sci_rx_dma_release(s, true);
1054 return; 1059 return;
1055 } 1060 }
1061 dev_dbg(s->port.dev, "%s(): cookie %d to #%d\n", __func__,
1062 s->cookie_rx[i], i);
1056 } 1063 }
1057 1064
1058 s->active_rx = s->cookie_rx[0]; 1065 s->active_rx = s->cookie_rx[0];
@@ -1110,10 +1117,10 @@ static void work_fn_rx(struct work_struct *work)
1110 return; 1117 return;
1111 } 1118 }
1112 1119
1113 dev_dbg(port->dev, "%s: cookie %d #%d\n", __func__,
1114 s->cookie_rx[new], new);
1115
1116 s->active_rx = s->cookie_rx[!new]; 1120 s->active_rx = s->cookie_rx[!new];
1121
1122 dev_dbg(port->dev, "%s: cookie %d #%d, new active #%d\n", __func__,
1123 s->cookie_rx[new], new, s->active_rx);
1117} 1124}
1118 1125
1119static void work_fn_tx(struct work_struct *work) 1126static void work_fn_tx(struct work_struct *work)
@@ -1175,23 +1182,28 @@ static void work_fn_tx(struct work_struct *work)
1175 1182
1176static void sci_start_tx(struct uart_port *port) 1183static void sci_start_tx(struct uart_port *port)
1177{ 1184{
1185 struct sci_port *s = to_sci_port(port);
1178 unsigned short ctrl; 1186 unsigned short ctrl;
1179 1187
1180#ifdef CONFIG_SERIAL_SH_SCI_DMA 1188#ifdef CONFIG_SERIAL_SH_SCI_DMA
1181 struct sci_port *s = to_sci_port(port); 1189 if (port->type == PORT_SCIFA) {
1182 1190 u16 new, scr = sci_in(port, SCSCR);
1183 if (s->chan_tx) { 1191 if (s->chan_tx)
1184 if (!uart_circ_empty(&s->port.state->xmit) && s->cookie_tx < 0) 1192 new = scr | 0x8000;
1185 schedule_work(&s->work_tx); 1193 else
1186 1194 new = scr & ~0x8000;
1187 return; 1195 if (new != scr)
1196 sci_out(port, SCSCR, new);
1188 } 1197 }
1198 if (s->chan_tx && !uart_circ_empty(&s->port.state->xmit) &&
1199 s->cookie_tx < 0)
1200 schedule_work(&s->work_tx);
1189#endif 1201#endif
1190 1202 if (!s->chan_tx || port->type == PORT_SCIFA) {
1191 /* Set TIE (Transmit Interrupt Enable) bit in SCSCR */ 1203 /* Set TIE (Transmit Interrupt Enable) bit in SCSCR */
1192 ctrl = sci_in(port, SCSCR); 1204 ctrl = sci_in(port, SCSCR);
1193 ctrl |= SCI_CTRL_FLAGS_TIE; 1205 sci_out(port, SCSCR, ctrl | SCI_CTRL_FLAGS_TIE);
1194 sci_out(port, SCSCR, ctrl); 1206 }
1195} 1207}
1196 1208
1197static void sci_stop_tx(struct uart_port *port) 1209static void sci_stop_tx(struct uart_port *port)
@@ -1200,6 +1212,8 @@ static void sci_stop_tx(struct uart_port *port)
1200 1212
1201 /* Clear TIE (Transmit Interrupt Enable) bit in SCSCR */ 1213 /* Clear TIE (Transmit Interrupt Enable) bit in SCSCR */
1202 ctrl = sci_in(port, SCSCR); 1214 ctrl = sci_in(port, SCSCR);
1215 if (port->type == PORT_SCIFA)
1216 ctrl &= ~0x8000;
1203 ctrl &= ~SCI_CTRL_FLAGS_TIE; 1217 ctrl &= ~SCI_CTRL_FLAGS_TIE;
1204 sci_out(port, SCSCR, ctrl); 1218 sci_out(port, SCSCR, ctrl);
1205} 1219}
@@ -1210,6 +1224,8 @@ static void sci_start_rx(struct uart_port *port)
1210 1224
1211 /* Set RIE (Receive Interrupt Enable) bit in SCSCR */ 1225 /* Set RIE (Receive Interrupt Enable) bit in SCSCR */
1212 ctrl |= sci_in(port, SCSCR); 1226 ctrl |= sci_in(port, SCSCR);
1227 if (port->type == PORT_SCIFA)
1228 ctrl &= ~0x4000;
1213 sci_out(port, SCSCR, ctrl); 1229 sci_out(port, SCSCR, ctrl);
1214} 1230}
1215 1231
@@ -1219,6 +1235,8 @@ static void sci_stop_rx(struct uart_port *port)
1219 1235
1220 /* Clear RIE (Receive Interrupt Enable) bit in SCSCR */ 1236 /* Clear RIE (Receive Interrupt Enable) bit in SCSCR */
1221 ctrl = sci_in(port, SCSCR); 1237 ctrl = sci_in(port, SCSCR);
1238 if (port->type == PORT_SCIFA)
1239 ctrl &= ~0x4000;
1222 ctrl &= ~(SCI_CTRL_FLAGS_RIE | SCI_CTRL_FLAGS_REIE); 1240 ctrl &= ~(SCI_CTRL_FLAGS_RIE | SCI_CTRL_FLAGS_REIE);
1223 sci_out(port, SCSCR, ctrl); 1241 sci_out(port, SCSCR, ctrl);
1224} 1242}
@@ -1253,8 +1271,12 @@ static void rx_timer_fn(unsigned long arg)
1253{ 1271{
1254 struct sci_port *s = (struct sci_port *)arg; 1272 struct sci_port *s = (struct sci_port *)arg;
1255 struct uart_port *port = &s->port; 1273 struct uart_port *port = &s->port;
1256
1257 u16 scr = sci_in(port, SCSCR); 1274 u16 scr = sci_in(port, SCSCR);
1275
1276 if (port->type == PORT_SCIFA) {
1277 scr &= ~0x4000;
1278 enable_irq(s->irqs[1]);
1279 }
1258 sci_out(port, SCSCR, scr | SCI_CTRL_FLAGS_RIE); 1280 sci_out(port, SCSCR, scr | SCI_CTRL_FLAGS_RIE);
1259 dev_dbg(port->dev, "DMA Rx timed out\n"); 1281 dev_dbg(port->dev, "DMA Rx timed out\n");
1260 schedule_work(&s->work_rx); 1282 schedule_work(&s->work_rx);
@@ -1404,8 +1426,12 @@ static void sci_shutdown(struct uart_port *port)
1404static void sci_set_termios(struct uart_port *port, struct ktermios *termios, 1426static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
1405 struct ktermios *old) 1427 struct ktermios *old)
1406{ 1428{
1429#ifdef CONFIG_SERIAL_SH_SCI_DMA
1430 struct sci_port *s = to_sci_port(port);
1431#endif
1407 unsigned int status, baud, smr_val, max_baud; 1432 unsigned int status, baud, smr_val, max_baud;
1408 int t = -1; 1433 int t = -1;
1434 u16 scfcr = 0;
1409 1435
1410 /* 1436 /*
1411 * earlyprintk comes here early on with port->uartclk set to zero. 1437 * earlyprintk comes here early on with port->uartclk set to zero.
@@ -1428,7 +1454,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
1428 sci_out(port, SCSCR, 0x00); /* TE=0, RE=0, CKE1=0 */ 1454 sci_out(port, SCSCR, 0x00); /* TE=0, RE=0, CKE1=0 */
1429 1455
1430 if (port->type != PORT_SCI) 1456 if (port->type != PORT_SCI)
1431 sci_out(port, SCFCR, SCFCR_RFRST | SCFCR_TFRST); 1457 sci_out(port, SCFCR, scfcr | SCFCR_RFRST | SCFCR_TFRST);
1432 1458
1433 smr_val = sci_in(port, SCSMR) & 3; 1459 smr_val = sci_in(port, SCSMR) & 3;
1434 if ((termios->c_cflag & CSIZE) == CS7) 1460 if ((termios->c_cflag & CSIZE) == CS7)
@@ -1459,10 +1485,32 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
1459 } 1485 }
1460 1486
1461 sci_init_pins(port, termios->c_cflag); 1487 sci_init_pins(port, termios->c_cflag);
1462 sci_out(port, SCFCR, (termios->c_cflag & CRTSCTS) ? SCFCR_MCE : 0); 1488 sci_out(port, SCFCR, scfcr | ((termios->c_cflag & CRTSCTS) ? SCFCR_MCE : 0));
1463 1489
1464 sci_out(port, SCSCR, SCSCR_INIT(port)); 1490 sci_out(port, SCSCR, SCSCR_INIT(port));
1465 1491
1492#ifdef CONFIG_SERIAL_SH_SCI_DMA
1493 /*
1494 * Calculate delay for 1.5 DMA buffers: see
1495 * drivers/serial/serial_core.c::uart_update_timeout(). With 10 bits
1496 * (CS8), 250Hz, 115200 baud and 64 bytes FIFO, the above function
1497 * calculates 1 jiffie for the data plus 5 jiffies for the "slop(e)."
1498 * Then below we calculate 3 jiffies (12ms) for 1.5 DMA buffers (3 FIFO
1499 * sizes), but it has been found out experimentally, that this is not
1500 * enough: the driver too often needlessly runs on a DMA timeout. 20ms
1501 * as a minimum seem to work perfectly.
1502 */
1503 if (s->chan_rx) {
1504 s->rx_timeout = (port->timeout - HZ / 50) * s->buf_len_rx * 3 /
1505 port->fifosize / 2;
1506 dev_dbg(port->dev,
1507 "DMA Rx t-out %ums, tty t-out %u jiffies\n",
1508 s->rx_timeout * 1000 / HZ, port->timeout);
1509 if (s->rx_timeout < msecs_to_jiffies(20))
1510 s->rx_timeout = msecs_to_jiffies(20);
1511 }
1512#endif
1513
1466 if ((termios->c_cflag & CREAD) != 0) 1514 if ((termios->c_cflag & CREAD) != 0)
1467 sci_start_rx(port); 1515 sci_start_rx(port);
1468} 1516}