aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2011-06-14 04:38:19 -0400
committerPaul Mundt <lethal@linux-sh.org>2011-06-14 04:38:19 -0400
commit72b294cf76dcd6d37891387049ddbe3c25043cb8 (patch)
treee19eaab5e23bba04b1f0f9ef244764ae73656764 /drivers/tty
parent61a6976bf19a6cf5dfcf37c3536665b316f22d49 (diff)
serial: sh-sci: FIFO sizing helper consolidation.
This consolidates all of the TX/RX fill/room nonsense in to a single set of fairly heavyweight definitions. The implementation goes in descending order of complexity, testing the register map for capabilities until we run out of options and do it the legacy SCI way. Masks are derived directly from the per-port FIFO size, meaning that platforms with FIFO sizes not matching the standard port types will still need to manually fix them up. This also fixes up a number of issues such as tx_empty being completely bogus for SCI and IrDA ports, some ports using masks smaller or greater than their FIFO size, and so forth. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'drivers/tty')
-rw-r--r--drivers/tty/serial/sh-sci.c126
-rw-r--r--drivers/tty/serial/sh-sci.h20
2 files changed, 24 insertions, 122 deletions
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 14e1bae50392..60027d51bb51 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -297,6 +297,8 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = {
297 }, 297 },
298}; 298};
299 299
300#define sci_getreg(up, offset) (sci_regmap[to_sci_port(up)->cfg->regtype] + offset)
301
300/* 302/*
301 * The "offset" here is rather misleading, in that it refers to an enum 303 * The "offset" here is rather misleading, in that it refers to an enum
302 * value relative to the port mapping rather than the fixed offset 304 * value relative to the port mapping rather than the fixed offset
@@ -305,8 +307,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = {
305 */ 307 */
306static unsigned int sci_serial_in(struct uart_port *p, int offset) 308static unsigned int sci_serial_in(struct uart_port *p, int offset)
307{ 309{
308 struct sci_port *s = to_sci_port(p); 310 struct plat_sci_reg *reg = sci_getreg(p, offset);
309 struct plat_sci_reg *reg = sci_regmap[s->cfg->regtype] + offset;
310 311
311 if (reg->size == 8) 312 if (reg->size == 8)
312 return ioread8(p->membase + (reg->offset << p->regshift)); 313 return ioread8(p->membase + (reg->offset << p->regshift));
@@ -320,8 +321,7 @@ static unsigned int sci_serial_in(struct uart_port *p, int offset)
320 321
321static void sci_serial_out(struct uart_port *p, int offset, int value) 322static void sci_serial_out(struct uart_port *p, int offset, int value)
322{ 323{
323 struct sci_port *s = to_sci_port(p); 324 struct plat_sci_reg *reg = sci_getreg(p, offset);
324 struct plat_sci_reg *reg = sci_regmap[s->cfg->regtype] + offset;
325 325
326 if (reg->size == 8) 326 if (reg->size == 8)
327 iowrite8(value, p->membase + (reg->offset << p->regshift)); 327 iowrite8(value, p->membase + (reg->offset << p->regshift));
@@ -433,108 +433,38 @@ static void sci_init_pins(struct uart_port *port, unsigned int cflag)
433 sci_out(port, SCSPTR, 0x0080); /* Set RTS = 1 */ 433 sci_out(port, SCSPTR, 0x0080); /* Set RTS = 1 */
434} 434}
435 435
436#if defined(CONFIG_CPU_SUBTYPE_SH7760) || \ 436static int sci_txfill(struct uart_port *port)
437 defined(CONFIG_CPU_SUBTYPE_SH7780) || \
438 defined(CONFIG_CPU_SUBTYPE_SH7785) || \
439 defined(CONFIG_CPU_SUBTYPE_SH7786)
440static int scif_txfill(struct uart_port *port)
441{
442 return sci_in(port, SCTFDR) & 0xff;
443}
444
445static int scif_txroom(struct uart_port *port)
446{ 437{
447 return SCIF_TXROOM_MAX - scif_txfill(port); 438 struct plat_sci_reg *reg;
448}
449 439
450static int scif_rxfill(struct uart_port *port) 440 reg = sci_getreg(port, SCTFDR);
451{ 441 if (reg->size)
452 return sci_in(port, SCRFDR) & 0xff;
453}
454#elif defined(CONFIG_CPU_SUBTYPE_SH7763)
455static int scif_txfill(struct uart_port *port)
456{
457 if (port->mapbase == 0xffe00000 ||
458 port->mapbase == 0xffe08000)
459 /* SCIF0/1*/
460 return sci_in(port, SCTFDR) & 0xff; 442 return sci_in(port, SCTFDR) & 0xff;
461 else
462 /* SCIF2 */
463 return sci_in(port, SCFDR) >> 8;
464}
465 443
466static int scif_txroom(struct uart_port *port) 444 reg = sci_getreg(port, SCFDR);
467{ 445 if (reg->size)
468 if (port->mapbase == 0xffe00000 ||
469 port->mapbase == 0xffe08000)
470 /* SCIF0/1*/
471 return SCIF_TXROOM_MAX - scif_txfill(port);
472 else
473 /* SCIF2 */
474 return SCIF2_TXROOM_MAX - scif_txfill(port);
475}
476
477static int scif_rxfill(struct uart_port *port)
478{
479 if ((port->mapbase == 0xffe00000) ||
480 (port->mapbase == 0xffe08000)) {
481 /* SCIF0/1*/
482 return sci_in(port, SCRFDR) & 0xff;
483 } else {
484 /* SCIF2 */
485 return sci_in(port, SCFDR) & SCIF2_RFDC_MASK;
486 }
487}
488#elif defined(CONFIG_ARCH_SH7372)
489static int scif_txfill(struct uart_port *port)
490{
491 if (port->type == PORT_SCIFA)
492 return sci_in(port, SCFDR) >> 8; 446 return sci_in(port, SCFDR) >> 8;
493 else
494 return sci_in(port, SCTFDR);
495}
496
497static int scif_txroom(struct uart_port *port)
498{
499 return port->fifosize - scif_txfill(port);
500}
501 447
502static int scif_rxfill(struct uart_port *port)
503{
504 if (port->type == PORT_SCIFA)
505 return sci_in(port, SCFDR) & SCIF_RFDC_MASK;
506 else
507 return sci_in(port, SCRFDR);
508}
509#else
510static int scif_txfill(struct uart_port *port)
511{
512 return sci_in(port, SCFDR) >> 8;
513}
514
515static int scif_txroom(struct uart_port *port)
516{
517 return SCIF_TXROOM_MAX - scif_txfill(port);
518}
519
520static int scif_rxfill(struct uart_port *port)
521{
522 return sci_in(port, SCFDR) & SCIF_RFDC_MASK;
523}
524#endif
525
526static int sci_txfill(struct uart_port *port)
527{
528 return !(sci_in(port, SCxSR) & SCI_TDRE); 448 return !(sci_in(port, SCxSR) & SCI_TDRE);
529} 449}
530 450
531static int sci_txroom(struct uart_port *port) 451static int sci_txroom(struct uart_port *port)
532{ 452{
533 return !sci_txfill(port); 453 return port->fifosize - sci_txfill(port);
534} 454}
535 455
536static int sci_rxfill(struct uart_port *port) 456static int sci_rxfill(struct uart_port *port)
537{ 457{
458 struct plat_sci_reg *reg;
459
460 reg = sci_getreg(port, SCRFDR);
461 if (reg->size)
462 return sci_in(port, SCRFDR) & 0xff;
463
464 reg = sci_getreg(port, SCFDR);
465 if (reg->size)
466 return sci_in(port, SCFDR) & ((port->fifosize << 1) - 1);
467
538 return (sci_in(port, SCxSR) & SCxSR_RDxF(port)) != 0; 468 return (sci_in(port, SCxSR) & SCxSR_RDxF(port)) != 0;
539} 469}
540 470
@@ -574,10 +504,7 @@ static void sci_transmit_chars(struct uart_port *port)
574 return; 504 return;
575 } 505 }
576 506
577 if (port->type == PORT_SCI) 507 count = sci_txroom(port);
578 count = sci_txroom(port);
579 else
580 count = scif_txroom(port);
581 508
582 do { 509 do {
583 unsigned char c; 510 unsigned char c;
@@ -632,13 +559,8 @@ static void sci_receive_chars(struct uart_port *port)
632 return; 559 return;
633 560
634 while (1) { 561 while (1) {
635 if (port->type == PORT_SCI)
636 count = sci_rxfill(port);
637 else
638 count = scif_rxfill(port);
639
640 /* Don't copy more bytes than there is room for in the buffer */ 562 /* Don't copy more bytes than there is room for in the buffer */
641 count = tty_buffer_request_room(tty, count); 563 count = tty_buffer_request_room(tty, sci_rxfill(port));
642 564
643 /* If for any reason we can't copy more data, we're done! */ 565 /* If for any reason we can't copy more data, we're done! */
644 if (count == 0) 566 if (count == 0)
@@ -1096,7 +1018,7 @@ static void sci_free_irq(struct sci_port *port)
1096static unsigned int sci_tx_empty(struct uart_port *port) 1018static unsigned int sci_tx_empty(struct uart_port *port)
1097{ 1019{
1098 unsigned short status = sci_in(port, SCxSR); 1020 unsigned short status = sci_in(port, SCxSR);
1099 unsigned short in_tx_fifo = scif_txfill(port); 1021 unsigned short in_tx_fifo = sci_txfill(port);
1100 1022
1101 return (status & SCxSR_TEND(port)) && !in_tx_fifo ? TIOCSER_TEMT : 0; 1023 return (status & SCxSR_TEND(port)) && !in_tx_fifo ? TIOCSER_TEMT : 0;
1102} 1024}
diff --git a/drivers/tty/serial/sh-sci.h b/drivers/tty/serial/sh-sci.h
index 26de640a9d01..e9bed038aa1f 100644
--- a/drivers/tty/serial/sh-sci.h
+++ b/drivers/tty/serial/sh-sci.h
@@ -2,26 +2,6 @@
2#include <linux/io.h> 2#include <linux/io.h>
3#include <linux/gpio.h> 3#include <linux/gpio.h>
4 4
5#if defined(CONFIG_CPU_SUBTYPE_SH7705) || \
6 defined(CONFIG_CPU_SUBTYPE_SH7720) || \
7 defined(CONFIG_CPU_SUBTYPE_SH7721) || \
8 defined(CONFIG_ARCH_SH73A0) || \
9 defined(CONFIG_ARCH_SH7367) || \
10 defined(CONFIG_ARCH_SH7377) || \
11 defined(CONFIG_ARCH_SH7372)
12# define SCIF_RFDC_MASK 0x007f
13# define SCIF_TXROOM_MAX 64
14#elif defined(CONFIG_CPU_SUBTYPE_SH7763)
15# define SCIF_RFDC_MASK 0x007f
16# define SCIF_TXROOM_MAX 64
17/* SH7763 SCIF2 support */
18# define SCIF2_RFDC_MASK 0x001f
19# define SCIF2_TXROOM_MAX 16
20#else
21# define SCIF_RFDC_MASK 0x001f
22# define SCIF_TXROOM_MAX 16
23#endif
24
25#define SCxSR_TEND(port) (((port)->type == PORT_SCI) ? SCI_TEND : SCIF_TEND) 5#define SCxSR_TEND(port) (((port)->type == PORT_SCI) ? SCI_TEND : SCIF_TEND)
26#define SCxSR_RDxF(port) (((port)->type == PORT_SCI) ? SCI_RDRF : SCIF_RDF) 6#define SCxSR_RDxF(port) (((port)->type == PORT_SCI) ? SCI_RDRF : SCIF_RDF)
27#define SCxSR_TDxE(port) (((port)->type == PORT_SCI) ? SCI_TDRE : SCIF_TDFE) 7#define SCxSR_TDxE(port) (((port)->type == PORT_SCI) ? SCI_TDRE : SCIF_TDFE)