diff options
Diffstat (limited to 'drivers/tty/serial/8250.c')
-rw-r--r-- | drivers/tty/serial/8250.c | 132 |
1 files changed, 57 insertions, 75 deletions
diff --git a/drivers/tty/serial/8250.c b/drivers/tty/serial/8250.c index 7f50999eebc2..a87a56cb5417 100644 --- a/drivers/tty/serial/8250.c +++ b/drivers/tty/serial/8250.c | |||
@@ -309,6 +309,13 @@ static const struct serial8250_config uart_config[] = { | |||
309 | UART_FCR_T_TRIG_01, | 309 | UART_FCR_T_TRIG_01, |
310 | .flags = UART_CAP_FIFO | UART_CAP_RTOIE, | 310 | .flags = UART_CAP_FIFO | UART_CAP_RTOIE, |
311 | }, | 311 | }, |
312 | [PORT_XR17D15X] = { | ||
313 | .name = "XR17D15X", | ||
314 | .fifo_size = 64, | ||
315 | .tx_loadsz = 64, | ||
316 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, | ||
317 | .flags = UART_CAP_FIFO | UART_CAP_AFE | UART_CAP_EFR, | ||
318 | }, | ||
312 | }; | 319 | }; |
313 | 320 | ||
314 | #if defined(CONFIG_MIPS_ALCHEMY) | 321 | #if defined(CONFIG_MIPS_ALCHEMY) |
@@ -461,42 +468,6 @@ static void tsi_serial_out(struct uart_port *p, int offset, int value) | |||
461 | writeb(value, p->membase + offset); | 468 | writeb(value, p->membase + offset); |
462 | } | 469 | } |
463 | 470 | ||
464 | /* Save the LCR value so it can be re-written when a Busy Detect IRQ occurs. */ | ||
465 | static inline void dwapb_save_out_value(struct uart_port *p, int offset, | ||
466 | int value) | ||
467 | { | ||
468 | struct uart_8250_port *up = | ||
469 | container_of(p, struct uart_8250_port, port); | ||
470 | |||
471 | if (offset == UART_LCR) | ||
472 | up->lcr = value; | ||
473 | } | ||
474 | |||
475 | /* Read the IER to ensure any interrupt is cleared before returning from ISR. */ | ||
476 | static inline void dwapb_check_clear_ier(struct uart_port *p, int offset) | ||
477 | { | ||
478 | if (offset == UART_TX || offset == UART_IER) | ||
479 | p->serial_in(p, UART_IER); | ||
480 | } | ||
481 | |||
482 | static void dwapb_serial_out(struct uart_port *p, int offset, int value) | ||
483 | { | ||
484 | int save_offset = offset; | ||
485 | offset = map_8250_out_reg(p, offset) << p->regshift; | ||
486 | dwapb_save_out_value(p, save_offset, value); | ||
487 | writeb(value, p->membase + offset); | ||
488 | dwapb_check_clear_ier(p, save_offset); | ||
489 | } | ||
490 | |||
491 | static void dwapb32_serial_out(struct uart_port *p, int offset, int value) | ||
492 | { | ||
493 | int save_offset = offset; | ||
494 | offset = map_8250_out_reg(p, offset) << p->regshift; | ||
495 | dwapb_save_out_value(p, save_offset, value); | ||
496 | writel(value, p->membase + offset); | ||
497 | dwapb_check_clear_ier(p, save_offset); | ||
498 | } | ||
499 | |||
500 | static unsigned int io_serial_in(struct uart_port *p, int offset) | 471 | static unsigned int io_serial_in(struct uart_port *p, int offset) |
501 | { | 472 | { |
502 | offset = map_8250_in_reg(p, offset) << p->regshift; | 473 | offset = map_8250_in_reg(p, offset) << p->regshift; |
@@ -509,6 +480,8 @@ static void io_serial_out(struct uart_port *p, int offset, int value) | |||
509 | outb(value, p->iobase + offset); | 480 | outb(value, p->iobase + offset); |
510 | } | 481 | } |
511 | 482 | ||
483 | static int serial8250_default_handle_irq(struct uart_port *port); | ||
484 | |||
512 | static void set_io_from_upio(struct uart_port *p) | 485 | static void set_io_from_upio(struct uart_port *p) |
513 | { | 486 | { |
514 | struct uart_8250_port *up = | 487 | struct uart_8250_port *up = |
@@ -540,16 +513,6 @@ static void set_io_from_upio(struct uart_port *p) | |||
540 | p->serial_out = tsi_serial_out; | 513 | p->serial_out = tsi_serial_out; |
541 | break; | 514 | break; |
542 | 515 | ||
543 | case UPIO_DWAPB: | ||
544 | p->serial_in = mem_serial_in; | ||
545 | p->serial_out = dwapb_serial_out; | ||
546 | break; | ||
547 | |||
548 | case UPIO_DWAPB32: | ||
549 | p->serial_in = mem32_serial_in; | ||
550 | p->serial_out = dwapb32_serial_out; | ||
551 | break; | ||
552 | |||
553 | default: | 516 | default: |
554 | p->serial_in = io_serial_in; | 517 | p->serial_in = io_serial_in; |
555 | p->serial_out = io_serial_out; | 518 | p->serial_out = io_serial_out; |
@@ -557,6 +520,7 @@ static void set_io_from_upio(struct uart_port *p) | |||
557 | } | 520 | } |
558 | /* Remember loaded iotype */ | 521 | /* Remember loaded iotype */ |
559 | up->cur_iotype = p->iotype; | 522 | up->cur_iotype = p->iotype; |
523 | p->handle_irq = serial8250_default_handle_irq; | ||
560 | } | 524 | } |
561 | 525 | ||
562 | static void | 526 | static void |
@@ -567,8 +531,6 @@ serial_out_sync(struct uart_8250_port *up, int offset, int value) | |||
567 | case UPIO_MEM: | 531 | case UPIO_MEM: |
568 | case UPIO_MEM32: | 532 | case UPIO_MEM32: |
569 | case UPIO_AU: | 533 | case UPIO_AU: |
570 | case UPIO_DWAPB: | ||
571 | case UPIO_DWAPB32: | ||
572 | p->serial_out(p, offset, value); | 534 | p->serial_out(p, offset, value); |
573 | p->serial_in(p, UART_LCR); /* safe, no side-effects */ | 535 | p->serial_in(p, UART_LCR); /* safe, no side-effects */ |
574 | break; | 536 | break; |
@@ -1120,6 +1082,14 @@ static void autoconfig_16550a(struct uart_8250_port *up) | |||
1120 | serial_outp(up, UART_IER, iersave); | 1082 | serial_outp(up, UART_IER, iersave); |
1121 | 1083 | ||
1122 | /* | 1084 | /* |
1085 | * Exar uarts have EFR in a weird location | ||
1086 | */ | ||
1087 | if (up->port.flags & UPF_EXAR_EFR) { | ||
1088 | up->port.type = PORT_XR17D15X; | ||
1089 | up->capabilities |= UART_CAP_AFE | UART_CAP_EFR; | ||
1090 | } | ||
1091 | |||
1092 | /* | ||
1123 | * We distinguish between 16550A and U6 16550A by counting | 1093 | * We distinguish between 16550A and U6 16550A by counting |
1124 | * how many bytes are in the FIFO. | 1094 | * how many bytes are in the FIFO. |
1125 | */ | 1095 | */ |
@@ -1621,6 +1591,29 @@ static void serial8250_handle_port(struct uart_8250_port *up) | |||
1621 | spin_unlock_irqrestore(&up->port.lock, flags); | 1591 | spin_unlock_irqrestore(&up->port.lock, flags); |
1622 | } | 1592 | } |
1623 | 1593 | ||
1594 | int serial8250_handle_irq(struct uart_port *port, unsigned int iir) | ||
1595 | { | ||
1596 | struct uart_8250_port *up = | ||
1597 | container_of(port, struct uart_8250_port, port); | ||
1598 | |||
1599 | if (!(iir & UART_IIR_NO_INT)) { | ||
1600 | serial8250_handle_port(up); | ||
1601 | return 1; | ||
1602 | } | ||
1603 | |||
1604 | return 0; | ||
1605 | } | ||
1606 | EXPORT_SYMBOL_GPL(serial8250_handle_irq); | ||
1607 | |||
1608 | static int serial8250_default_handle_irq(struct uart_port *port) | ||
1609 | { | ||
1610 | struct uart_8250_port *up = | ||
1611 | container_of(port, struct uart_8250_port, port); | ||
1612 | unsigned int iir = serial_in(up, UART_IIR); | ||
1613 | |||
1614 | return serial8250_handle_irq(port, iir); | ||
1615 | } | ||
1616 | |||
1624 | /* | 1617 | /* |
1625 | * This is the serial driver's interrupt routine. | 1618 | * This is the serial driver's interrupt routine. |
1626 | * | 1619 | * |
@@ -1648,30 +1641,13 @@ static irqreturn_t serial8250_interrupt(int irq, void *dev_id) | |||
1648 | l = i->head; | 1641 | l = i->head; |
1649 | do { | 1642 | do { |
1650 | struct uart_8250_port *up; | 1643 | struct uart_8250_port *up; |
1651 | unsigned int iir; | 1644 | struct uart_port *port; |
1652 | 1645 | ||
1653 | up = list_entry(l, struct uart_8250_port, list); | 1646 | up = list_entry(l, struct uart_8250_port, list); |
1647 | port = &up->port; | ||
1654 | 1648 | ||
1655 | iir = serial_in(up, UART_IIR); | 1649 | if (port->handle_irq(port)) { |
1656 | if (!(iir & UART_IIR_NO_INT)) { | ||
1657 | serial8250_handle_port(up); | ||
1658 | |||
1659 | handled = 1; | 1650 | handled = 1; |
1660 | |||
1661 | end = NULL; | ||
1662 | } else if ((up->port.iotype == UPIO_DWAPB || | ||
1663 | up->port.iotype == UPIO_DWAPB32) && | ||
1664 | (iir & UART_IIR_BUSY) == UART_IIR_BUSY) { | ||
1665 | /* The DesignWare APB UART has an Busy Detect (0x07) | ||
1666 | * interrupt meaning an LCR write attempt occurred while the | ||
1667 | * UART was busy. The interrupt must be cleared by reading | ||
1668 | * the UART status register (USR) and the LCR re-written. */ | ||
1669 | unsigned int status; | ||
1670 | status = *(volatile u32 *)up->port.private_data; | ||
1671 | serial_out(up, UART_LCR, up->lcr); | ||
1672 | |||
1673 | handled = 1; | ||
1674 | |||
1675 | end = NULL; | 1651 | end = NULL; |
1676 | } else if (end == NULL) | 1652 | } else if (end == NULL) |
1677 | end = l; | 1653 | end = l; |
@@ -2081,8 +2057,8 @@ static int serial8250_startup(struct uart_port *port) | |||
2081 | */ | 2057 | */ |
2082 | if (!(up->port.flags & UPF_BUGGY_UART) && | 2058 | if (!(up->port.flags & UPF_BUGGY_UART) && |
2083 | (serial_inp(up, UART_LSR) == 0xff)) { | 2059 | (serial_inp(up, UART_LSR) == 0xff)) { |
2084 | printk(KERN_INFO "ttyS%d: LSR safety check engaged!\n", | 2060 | printk_ratelimited(KERN_INFO "ttyS%d: LSR safety check engaged!\n", |
2085 | serial_index(&up->port)); | 2061 | serial_index(&up->port)); |
2086 | return -ENODEV; | 2062 | return -ENODEV; |
2087 | } | 2063 | } |
2088 | 2064 | ||
@@ -2458,7 +2434,10 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, | |||
2458 | efr |= UART_EFR_CTS; | 2434 | efr |= UART_EFR_CTS; |
2459 | 2435 | ||
2460 | serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B); | 2436 | serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B); |
2461 | serial_outp(up, UART_EFR, efr); | 2437 | if (up->port.flags & UPF_EXAR_EFR) |
2438 | serial_outp(up, UART_XR_EFR, efr); | ||
2439 | else | ||
2440 | serial_outp(up, UART_EFR, efr); | ||
2462 | } | 2441 | } |
2463 | 2442 | ||
2464 | #ifdef CONFIG_ARCH_OMAP | 2443 | #ifdef CONFIG_ARCH_OMAP |
@@ -2570,8 +2549,6 @@ static int serial8250_request_std_resource(struct uart_8250_port *up) | |||
2570 | case UPIO_TSI: | 2549 | case UPIO_TSI: |
2571 | case UPIO_MEM32: | 2550 | case UPIO_MEM32: |
2572 | case UPIO_MEM: | 2551 | case UPIO_MEM: |
2573 | case UPIO_DWAPB: | ||
2574 | case UPIO_DWAPB32: | ||
2575 | if (!up->port.mapbase) | 2552 | if (!up->port.mapbase) |
2576 | break; | 2553 | break; |
2577 | 2554 | ||
@@ -2608,8 +2585,6 @@ static void serial8250_release_std_resource(struct uart_8250_port *up) | |||
2608 | case UPIO_TSI: | 2585 | case UPIO_TSI: |
2609 | case UPIO_MEM32: | 2586 | case UPIO_MEM32: |
2610 | case UPIO_MEM: | 2587 | case UPIO_MEM: |
2611 | case UPIO_DWAPB: | ||
2612 | case UPIO_DWAPB32: | ||
2613 | if (!up->port.mapbase) | 2588 | if (!up->port.mapbase) |
2614 | break; | 2589 | break; |
2615 | 2590 | ||
@@ -3050,6 +3025,10 @@ int __init early_serial_setup(struct uart_port *port) | |||
3050 | p->serial_in = port->serial_in; | 3025 | p->serial_in = port->serial_in; |
3051 | if (port->serial_out) | 3026 | if (port->serial_out) |
3052 | p->serial_out = port->serial_out; | 3027 | p->serial_out = port->serial_out; |
3028 | if (port->handle_irq) | ||
3029 | p->handle_irq = port->handle_irq; | ||
3030 | else | ||
3031 | p->handle_irq = serial8250_default_handle_irq; | ||
3053 | 3032 | ||
3054 | return 0; | 3033 | return 0; |
3055 | } | 3034 | } |
@@ -3118,6 +3097,7 @@ static int __devinit serial8250_probe(struct platform_device *dev) | |||
3118 | port.type = p->type; | 3097 | port.type = p->type; |
3119 | port.serial_in = p->serial_in; | 3098 | port.serial_in = p->serial_in; |
3120 | port.serial_out = p->serial_out; | 3099 | port.serial_out = p->serial_out; |
3100 | port.handle_irq = p->handle_irq; | ||
3121 | port.set_termios = p->set_termios; | 3101 | port.set_termios = p->set_termios; |
3122 | port.pm = p->pm; | 3102 | port.pm = p->pm; |
3123 | port.dev = &dev->dev; | 3103 | port.dev = &dev->dev; |
@@ -3283,6 +3263,8 @@ int serial8250_register_port(struct uart_port *port) | |||
3283 | uart->port.serial_in = port->serial_in; | 3263 | uart->port.serial_in = port->serial_in; |
3284 | if (port->serial_out) | 3264 | if (port->serial_out) |
3285 | uart->port.serial_out = port->serial_out; | 3265 | uart->port.serial_out = port->serial_out; |
3266 | if (port->handle_irq) | ||
3267 | uart->port.handle_irq = port->handle_irq; | ||
3286 | /* Possibly override set_termios call */ | 3268 | /* Possibly override set_termios call */ |
3287 | if (port->set_termios) | 3269 | if (port->set_termios) |
3288 | uart->port.set_termios = port->set_termios; | 3270 | uart->port.set_termios = port->set_termios; |