diff options
author | Guennadi Liakhovetski <g.liakhovetski@gmx.de> | 2010-05-23 12:39:09 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2010-05-23 19:53:37 -0400 |
commit | d1d4b10cdafb8dd4044a3b67b05f759047612fdc (patch) | |
tree | 3976e5921905e34a758eed86b08b83ea1ed5c1fd /drivers/serial/sh-sci.c | |
parent | 75b93489b449db4a34f0424c72f51821d985f52f (diff) |
serial: sh-sci: fix handling of SCIFB sh-mobile ports
SCIFB ports have a slightly different register layout and a different FIFO
size from SCIFA ports, in DMA mode they have to be treated just like SCIFA.
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.c | 42 |
1 files changed, 34 insertions, 8 deletions
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 4f73fb756745..aaef223df676 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c | |||
@@ -346,6 +346,27 @@ static int scif_rxfill(struct uart_port *port) | |||
346 | return sci_in(port, SCFDR) & SCIF2_RFDC_MASK; | 346 | return sci_in(port, SCFDR) & SCIF2_RFDC_MASK; |
347 | } | 347 | } |
348 | } | 348 | } |
349 | #elif defined(CONFIG_ARCH_SH7372) | ||
350 | static int scif_txfill(struct uart_port *port) | ||
351 | { | ||
352 | if (port->type == PORT_SCIFA) | ||
353 | return sci_in(port, SCFDR) >> 8; | ||
354 | else | ||
355 | return sci_in(port, SCTFDR); | ||
356 | } | ||
357 | |||
358 | static int scif_txroom(struct uart_port *port) | ||
359 | { | ||
360 | return port->fifosize - scif_txfill(port); | ||
361 | } | ||
362 | |||
363 | static int scif_rxfill(struct uart_port *port) | ||
364 | { | ||
365 | if (port->type == PORT_SCIFA) | ||
366 | return sci_in(port, SCFDR) & SCIF_RFDC_MASK; | ||
367 | else | ||
368 | return sci_in(port, SCRFDR); | ||
369 | } | ||
349 | #else | 370 | #else |
350 | static int scif_txfill(struct uart_port *port) | 371 | static int scif_txfill(struct uart_port *port) |
351 | { | 372 | { |
@@ -683,7 +704,7 @@ static irqreturn_t sci_rx_interrupt(int irq, void *ptr) | |||
683 | u16 ssr = sci_in(port, SCxSR); | 704 | u16 ssr = sci_in(port, SCxSR); |
684 | 705 | ||
685 | /* Disable future Rx interrupts */ | 706 | /* Disable future Rx interrupts */ |
686 | if (port->type == PORT_SCIFA) { | 707 | if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) { |
687 | disable_irq_nosync(irq); | 708 | disable_irq_nosync(irq); |
688 | scr |= 0x4000; | 709 | scr |= 0x4000; |
689 | } else { | 710 | } else { |
@@ -928,7 +949,7 @@ static void sci_dma_tx_complete(void *arg) | |||
928 | 949 | ||
929 | if (!uart_circ_empty(xmit)) { | 950 | if (!uart_circ_empty(xmit)) { |
930 | schedule_work(&s->work_tx); | 951 | schedule_work(&s->work_tx); |
931 | } else if (port->type == PORT_SCIFA) { | 952 | } else if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) { |
932 | u16 ctrl = sci_in(port, SCSCR); | 953 | u16 ctrl = sci_in(port, SCSCR); |
933 | sci_out(port, SCSCR, ctrl & ~SCI_CTRL_FLAGS_TIE); | 954 | sci_out(port, SCSCR, ctrl & ~SCI_CTRL_FLAGS_TIE); |
934 | } | 955 | } |
@@ -1183,7 +1204,7 @@ static void sci_start_tx(struct uart_port *port) | |||
1183 | unsigned short ctrl; | 1204 | unsigned short ctrl; |
1184 | 1205 | ||
1185 | #ifdef CONFIG_SERIAL_SH_SCI_DMA | 1206 | #ifdef CONFIG_SERIAL_SH_SCI_DMA |
1186 | if (port->type == PORT_SCIFA) { | 1207 | if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) { |
1187 | u16 new, scr = sci_in(port, SCSCR); | 1208 | u16 new, scr = sci_in(port, SCSCR); |
1188 | if (s->chan_tx) | 1209 | if (s->chan_tx) |
1189 | new = scr | 0x8000; | 1210 | new = scr | 0x8000; |
@@ -1196,7 +1217,7 @@ static void sci_start_tx(struct uart_port *port) | |||
1196 | s->cookie_tx < 0) | 1217 | s->cookie_tx < 0) |
1197 | schedule_work(&s->work_tx); | 1218 | schedule_work(&s->work_tx); |
1198 | #endif | 1219 | #endif |
1199 | if (!s->chan_tx || port->type == PORT_SCIFA) { | 1220 | if (!s->chan_tx || port->type == PORT_SCIFA || port->type == PORT_SCIFB) { |
1200 | /* Set TIE (Transmit Interrupt Enable) bit in SCSCR */ | 1221 | /* Set TIE (Transmit Interrupt Enable) bit in SCSCR */ |
1201 | ctrl = sci_in(port, SCSCR); | 1222 | ctrl = sci_in(port, SCSCR); |
1202 | sci_out(port, SCSCR, ctrl | SCI_CTRL_FLAGS_TIE); | 1223 | sci_out(port, SCSCR, ctrl | SCI_CTRL_FLAGS_TIE); |
@@ -1209,7 +1230,7 @@ static void sci_stop_tx(struct uart_port *port) | |||
1209 | 1230 | ||
1210 | /* Clear TIE (Transmit Interrupt Enable) bit in SCSCR */ | 1231 | /* Clear TIE (Transmit Interrupt Enable) bit in SCSCR */ |
1211 | ctrl = sci_in(port, SCSCR); | 1232 | ctrl = sci_in(port, SCSCR); |
1212 | if (port->type == PORT_SCIFA) | 1233 | if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) |
1213 | ctrl &= ~0x8000; | 1234 | ctrl &= ~0x8000; |
1214 | ctrl &= ~SCI_CTRL_FLAGS_TIE; | 1235 | ctrl &= ~SCI_CTRL_FLAGS_TIE; |
1215 | sci_out(port, SCSCR, ctrl); | 1236 | sci_out(port, SCSCR, ctrl); |
@@ -1221,7 +1242,7 @@ static void sci_start_rx(struct uart_port *port) | |||
1221 | 1242 | ||
1222 | /* Set RIE (Receive Interrupt Enable) bit in SCSCR */ | 1243 | /* Set RIE (Receive Interrupt Enable) bit in SCSCR */ |
1223 | ctrl |= sci_in(port, SCSCR); | 1244 | ctrl |= sci_in(port, SCSCR); |
1224 | if (port->type == PORT_SCIFA) | 1245 | if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) |
1225 | ctrl &= ~0x4000; | 1246 | ctrl &= ~0x4000; |
1226 | sci_out(port, SCSCR, ctrl); | 1247 | sci_out(port, SCSCR, ctrl); |
1227 | } | 1248 | } |
@@ -1232,7 +1253,7 @@ static void sci_stop_rx(struct uart_port *port) | |||
1232 | 1253 | ||
1233 | /* Clear RIE (Receive Interrupt Enable) bit in SCSCR */ | 1254 | /* Clear RIE (Receive Interrupt Enable) bit in SCSCR */ |
1234 | ctrl = sci_in(port, SCSCR); | 1255 | ctrl = sci_in(port, SCSCR); |
1235 | if (port->type == PORT_SCIFA) | 1256 | if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) |
1236 | ctrl &= ~0x4000; | 1257 | ctrl &= ~0x4000; |
1237 | ctrl &= ~(SCI_CTRL_FLAGS_RIE | SCI_CTRL_FLAGS_REIE); | 1258 | ctrl &= ~(SCI_CTRL_FLAGS_RIE | SCI_CTRL_FLAGS_REIE); |
1238 | sci_out(port, SCSCR, ctrl); | 1259 | sci_out(port, SCSCR, ctrl); |
@@ -1270,7 +1291,7 @@ static void rx_timer_fn(unsigned long arg) | |||
1270 | struct uart_port *port = &s->port; | 1291 | struct uart_port *port = &s->port; |
1271 | u16 scr = sci_in(port, SCSCR); | 1292 | u16 scr = sci_in(port, SCSCR); |
1272 | 1293 | ||
1273 | if (port->type == PORT_SCIFA) { | 1294 | if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) { |
1274 | scr &= ~0x4000; | 1295 | scr &= ~0x4000; |
1275 | enable_irq(s->irqs[1]); | 1296 | enable_irq(s->irqs[1]); |
1276 | } | 1297 | } |
@@ -1523,6 +1544,8 @@ static const char *sci_type(struct uart_port *port) | |||
1523 | return "scif"; | 1544 | return "scif"; |
1524 | case PORT_SCIFA: | 1545 | case PORT_SCIFA: |
1525 | return "scifa"; | 1546 | return "scifa"; |
1547 | case PORT_SCIFB: | ||
1548 | return "scifb"; | ||
1526 | } | 1549 | } |
1527 | 1550 | ||
1528 | return NULL; | 1551 | return NULL; |
@@ -1611,6 +1634,9 @@ static int __devinit sci_init_single(struct platform_device *dev, | |||
1611 | port->line = index; | 1634 | port->line = index; |
1612 | 1635 | ||
1613 | switch (p->type) { | 1636 | switch (p->type) { |
1637 | case PORT_SCIFB: | ||
1638 | port->fifosize = 256; | ||
1639 | break; | ||
1614 | case PORT_SCIFA: | 1640 | case PORT_SCIFA: |
1615 | port->fifosize = 64; | 1641 | port->fifosize = 64; |
1616 | break; | 1642 | break; |