aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuennadi Liakhovetski <g.liakhovetski@gmx.de>2010-05-23 12:39:09 -0400
committerPaul Mundt <lethal@linux-sh.org>2010-05-23 19:53:37 -0400
commitd1d4b10cdafb8dd4044a3b67b05f759047612fdc (patch)
tree3976e5921905e34a758eed86b08b83ea1ed5c1fd
parent75b93489b449db4a34f0424c72f51821d985f52f (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>
-rw-r--r--drivers/serial/sh-sci.c42
-rw-r--r--drivers/serial/sh-sci.h29
2 files changed, 57 insertions, 14 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)
350static 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
358static int scif_txroom(struct uart_port *port)
359{
360 return port->fifosize - scif_txfill(port);
361}
362
363static 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
350static int scif_txfill(struct uart_port *port) 371static 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;
diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h
index f70c49f915fa..9b52f77a9305 100644
--- a/drivers/serial/sh-sci.h
+++ b/drivers/serial/sh-sci.h
@@ -322,7 +322,7 @@
322#define CPU_SCIx_FNS(name, sci_offset, sci_size, scif_offset, scif_size)\ 322#define CPU_SCIx_FNS(name, sci_offset, sci_size, scif_offset, scif_size)\
323 static inline unsigned int sci_##name##_in(struct uart_port *port) \ 323 static inline unsigned int sci_##name##_in(struct uart_port *port) \
324 { \ 324 { \
325 if (port->type == PORT_SCIF) { \ 325 if (port->type == PORT_SCIF || port->type == PORT_SCIFB) { \
326 SCI_IN(scif_size, scif_offset) \ 326 SCI_IN(scif_size, scif_offset) \
327 } else { /* PORT_SCI or PORT_SCIFA */ \ 327 } else { /* PORT_SCI or PORT_SCIFA */ \
328 SCI_IN(sci_size, sci_offset); \ 328 SCI_IN(sci_size, sci_offset); \
@@ -330,7 +330,7 @@
330 } \ 330 } \
331 static inline void sci_##name##_out(struct uart_port *port, unsigned int value) \ 331 static inline void sci_##name##_out(struct uart_port *port, unsigned int value) \
332 { \ 332 { \
333 if (port->type == PORT_SCIF) { \ 333 if (port->type == PORT_SCIF || port->type == PORT_SCIFB) { \
334 SCI_OUT(scif_size, scif_offset, value) \ 334 SCI_OUT(scif_size, scif_offset, value) \
335 } else { /* PORT_SCI or PORT_SCIFA */ \ 335 } else { /* PORT_SCI or PORT_SCIFA */ \
336 SCI_OUT(sci_size, sci_offset, value); \ 336 SCI_OUT(sci_size, sci_offset, value); \
@@ -384,8 +384,12 @@
384 defined(CONFIG_CPU_SUBTYPE_SH7720) || \ 384 defined(CONFIG_CPU_SUBTYPE_SH7720) || \
385 defined(CONFIG_CPU_SUBTYPE_SH7721) || \ 385 defined(CONFIG_CPU_SUBTYPE_SH7721) || \
386 defined(CONFIG_ARCH_SH7367) || \ 386 defined(CONFIG_ARCH_SH7367) || \
387 defined(CONFIG_ARCH_SH7377) || \ 387 defined(CONFIG_ARCH_SH7377)
388 defined(CONFIG_ARCH_SH7372) 388#define SCIF_FNS(name, scif_offset, scif_size) \
389 CPU_SCIF_FNS(name, scif_offset, scif_size)
390#elif defined(CONFIG_ARCH_SH7372)
391#define SCIx_FNS(name, sh4_scifa_offset, sh4_scifa_size, sh4_scifb_offset, sh4_scifb_size) \
392 CPU_SCIx_FNS(name, sh4_scifa_offset, sh4_scifa_size, sh4_scifb_offset, sh4_scifb_size)
389#define SCIF_FNS(name, scif_offset, scif_size) \ 393#define SCIF_FNS(name, scif_offset, scif_size) \
390 CPU_SCIF_FNS(name, scif_offset, scif_size) 394 CPU_SCIF_FNS(name, scif_offset, scif_size)
391#else 395#else
@@ -422,8 +426,7 @@
422 defined(CONFIG_CPU_SUBTYPE_SH7720) || \ 426 defined(CONFIG_CPU_SUBTYPE_SH7720) || \
423 defined(CONFIG_CPU_SUBTYPE_SH7721) || \ 427 defined(CONFIG_CPU_SUBTYPE_SH7721) || \
424 defined(CONFIG_ARCH_SH7367) || \ 428 defined(CONFIG_ARCH_SH7367) || \
425 defined(CONFIG_ARCH_SH7377) || \ 429 defined(CONFIG_ARCH_SH7377)
426 defined(CONFIG_ARCH_SH7372)
427 430
428SCIF_FNS(SCSMR, 0x00, 16) 431SCIF_FNS(SCSMR, 0x00, 16)
429SCIF_FNS(SCBRR, 0x04, 8) 432SCIF_FNS(SCBRR, 0x04, 8)
@@ -436,6 +439,20 @@ SCIF_FNS(SCFDR, 0x1c, 16)
436SCIF_FNS(SCxTDR, 0x20, 8) 439SCIF_FNS(SCxTDR, 0x20, 8)
437SCIF_FNS(SCxRDR, 0x24, 8) 440SCIF_FNS(SCxRDR, 0x24, 8)
438SCIF_FNS(SCLSR, 0x00, 0) 441SCIF_FNS(SCLSR, 0x00, 0)
442#elif defined(CONFIG_ARCH_SH7372)
443SCIF_FNS(SCSMR, 0x00, 16)
444SCIF_FNS(SCBRR, 0x04, 8)
445SCIF_FNS(SCSCR, 0x08, 16)
446SCIF_FNS(SCTDSR, 0x0c, 16)
447SCIF_FNS(SCFER, 0x10, 16)
448SCIF_FNS(SCxSR, 0x14, 16)
449SCIF_FNS(SCFCR, 0x18, 16)
450SCIF_FNS(SCFDR, 0x1c, 16)
451SCIF_FNS(SCTFDR, 0x38, 16)
452SCIF_FNS(SCRFDR, 0x3c, 16)
453SCIx_FNS(SCxTDR, 0x20, 8, 0x40, 8)
454SCIx_FNS(SCxRDR, 0x24, 8, 0x60, 8)
455SCIF_FNS(SCLSR, 0x00, 0)
439#elif defined(CONFIG_CPU_SUBTYPE_SH7723) ||\ 456#elif defined(CONFIG_CPU_SUBTYPE_SH7723) ||\
440 defined(CONFIG_CPU_SUBTYPE_SH7724) 457 defined(CONFIG_CPU_SUBTYPE_SH7724)
441SCIx_FNS(SCSMR, 0x00, 16, 0x00, 16) 458SCIx_FNS(SCSMR, 0x00, 16, 0x00, 16)