diff options
Diffstat (limited to 'drivers/tty/serial/sh-sci.c')
-rw-r--r-- | drivers/tty/serial/sh-sci.c | 126 |
1 files changed, 24 insertions, 102 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 | */ |
306 | static unsigned int sci_serial_in(struct uart_port *p, int offset) | 308 | static 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 | ||
321 | static void sci_serial_out(struct uart_port *p, int offset, int value) | 322 | static 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) || \ | 436 | static 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) | ||
440 | static int scif_txfill(struct uart_port *port) | ||
441 | { | ||
442 | return sci_in(port, SCTFDR) & 0xff; | ||
443 | } | ||
444 | |||
445 | static 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 | ||
450 | static 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) | ||
455 | static 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 | ||
466 | static 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 | |||
477 | static 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) | ||
489 | static 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 | |||
497 | static int scif_txroom(struct uart_port *port) | ||
498 | { | ||
499 | return port->fifosize - scif_txfill(port); | ||
500 | } | ||
501 | 447 | ||
502 | static 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 | ||
510 | static int scif_txfill(struct uart_port *port) | ||
511 | { | ||
512 | return sci_in(port, SCFDR) >> 8; | ||
513 | } | ||
514 | |||
515 | static int scif_txroom(struct uart_port *port) | ||
516 | { | ||
517 | return SCIF_TXROOM_MAX - scif_txfill(port); | ||
518 | } | ||
519 | |||
520 | static int scif_rxfill(struct uart_port *port) | ||
521 | { | ||
522 | return sci_in(port, SCFDR) & SCIF_RFDC_MASK; | ||
523 | } | ||
524 | #endif | ||
525 | |||
526 | static 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 | ||
531 | static int sci_txroom(struct uart_port *port) | 451 | static 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 | ||
536 | static int sci_rxfill(struct uart_port *port) | 456 | static 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) | |||
1096 | static unsigned int sci_tx_empty(struct uart_port *port) | 1018 | static 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 | } |