| @@ -557,17 +557,6 @@ static void serial8250_clear_fifos(struct uart_8250_port *p) · 556 unmodified lines |
| 557 | 557 | } |
| 558 | 558 | } |
| 559 | 559 | |
| 560 | | −static inline void serial8250_em485_rts_after_send(struct uart_8250_port *p) |
| 561 | | −{ |
| 562 | | − unsigned char mcr = serial8250_in_MCR(p); |
| 563 | | − |
| 564 | | − if (p->port.rs485.flags & SER_RS485_RTS_AFTER_SEND) |
| 565 | | − mcr |= UART_MCR_RTS; |
| 566 | | − else |
| 567 | | − mcr &= ~UART_MCR_RTS; |
| 568 | | − serial8250_out_MCR(p, mcr); |
| 569 | | −} |
| 570 | | − |
| 571 | 560 | static enum hrtimer_restart serial8250_em485_handle_start_tx(struct hrtimer *t); |
| 572 | 561 | static enum hrtimer_restart serial8250_em485_handle_stop_tx(struct hrtimer *t); |
| 573 | 562 | |
| @@ -632,7 +621,9 @@ static int serial8250_em485_init(struct uart_8250_port *p) · 58 unmodified lines |
| 632 | 621 | p->em485->start_tx_timer.function = &serial8250_em485_handle_start_tx; |
| 633 | 622 | p->em485->port = p; |
| 634 | 623 | p->em485->active_timer = NULL; |
| 635 | | − serial8250_em485_rts_after_send(p); |
| 624 | + p->em485->tx_stopped = true; |
| 625 | + |
| 626 | + p->rs485_stop_tx(p); |
| 636 | 627 | |
| 637 | 628 | return 0; |
| 638 | 629 | } |
| @@ -1439,9 +1430,21 @@ static void serial8250_stop_rx(struct uart_port *port) · 800 unmodified lines |
| 1439 | 1430 | serial8250_rpm_put(up); |
| 1440 | 1431 | } |
| 1441 | 1432 | |
| 1442 | | −static void __do_stop_tx_rs485(struct uart_8250_port *p) |
| 1433 | +/** |
| 1434 | + * serial8250_em485_stop_tx() - generic ->rs485_stop_tx() callback |
| 1435 | + * @up: uart 8250 port |
| 1436 | + * |
| 1437 | + * Generic callback usable by 8250 uart drivers to stop rs485 transmission. |
| 1438 | + */ |
| 1439 | +void serial8250_em485_stop_tx(struct uart_8250_port *p) |
| 1443 | 1440 | { |
| 1444 | | − serial8250_em485_rts_after_send(p); |
| 1441 | + unsigned char mcr = serial8250_in_MCR(p); |
| 1442 | + |
| 1443 | + if (p->port.rs485.flags & SER_RS485_RTS_AFTER_SEND) |
| 1444 | + mcr |= UART_MCR_RTS; |
| 1445 | + else |
| 1446 | + mcr &= ~UART_MCR_RTS; |
| 1447 | + serial8250_out_MCR(p, mcr); |
| 1445 | 1448 | |
| 1446 | 1449 | /* |
| 1447 | 1450 | * Empty the RX FIFO, we are not interested in anything |
| @@ -1455,6 +1458,8 @@ static void __do_stop_tx_rs485(struct uart_8250_port *p) · 7 unmodified lines |
| 1455 | 1458 | serial_port_out(&p->port, UART_IER, p->ier); |
| 1456 | 1459 | } |
| 1457 | 1460 | } |
| 1461 | +EXPORT_SYMBOL_GPL(serial8250_em485_stop_tx); |
| 1462 | + |
| 1458 | 1463 | static enum hrtimer_restart serial8250_em485_handle_stop_tx(struct hrtimer *t) |
| 1459 | 1464 | { |
| 1460 | 1465 | struct uart_8250_em485 *em485; |
| @@ -1467,8 +1472,9 @@ static enum hrtimer_restart serial8250_em485_handle_stop_tx(struct hrtimer *t) · 6 unmodified lines |
| 1467 | 1472 | serial8250_rpm_get(p); |
| 1468 | 1473 | spin_lock_irqsave(&p->port.lock, flags); |
| 1469 | 1474 | if (em485->active_timer == &em485->stop_tx_timer) { |
| 1470 | | − __do_stop_tx_rs485(p); |
| 1475 | + p->rs485_stop_tx(p); |
| 1471 | 1476 | em485->active_timer = NULL; |
| 1477 | + em485->tx_stopped = true; |
| 1472 | 1478 | } |
| 1473 | 1479 | spin_unlock_irqrestore(&p->port.lock, flags); |
| 1474 | 1480 | serial8250_rpm_put(p); |
| @@ -1489,7 +1495,7 @@ static void __stop_tx_rs485(struct uart_8250_port *p) · 14 unmodified lines |
| 1489 | 1495 | struct uart_8250_em485 *em485 = p->em485; |
| 1490 | 1496 | |
| 1491 | 1497 | /* |
| 1492 | | − * __do_stop_tx_rs485 is going to set RTS according to config |
| 1498 | + * rs485_stop_tx() is going to set RTS according to config |
| 1493 | 1499 | * AND flush RX FIFO if required. |
| 1494 | 1500 | */ |
| 1495 | 1501 | if (p->port.rs485.delay_rts_after_send > 0) { |
| @@ -1497,8 +1503,9 @@ static void __stop_tx_rs485(struct uart_8250_port *p) · 1 unmodified line |
| 1497 | 1503 | start_hrtimer_ms(&em485->stop_tx_timer, |
| 1498 | 1504 | p->port.rs485.delay_rts_after_send); |
| 1499 | 1505 | } else { |
| 1500 | | − __do_stop_tx_rs485(p); |
| 1506 | + p->rs485_stop_tx(p); |
| 1501 | 1507 | em485->active_timer = NULL; |
| 1508 | + em485->tx_stopped = true; |
| 1502 | 1509 | } |
| 1503 | 1510 | } |
| 1504 | 1511 | |
| @@ -1572,25 +1579,42 @@ static inline void __start_tx(struct uart_port *port) · 67 unmodified lines |
| 1572 | 1579 | } |
| 1573 | 1580 | } |
| 1574 | 1581 | |
| 1575 | | −static inline void start_tx_rs485(struct uart_port *port) |
| 1582 | +/** |
| 1583 | + * serial8250_em485_start_tx() - generic ->rs485_start_tx() callback |
| 1584 | + * @up: uart 8250 port |
| 1585 | + * |
| 1586 | + * Generic callback usable by 8250 uart drivers to start rs485 transmission. |
| 1587 | + * Assumes that setting the RTS bit in the MCR register means RTS is high. |
| 1588 | + * (Some chips use inverse semantics.) Further assumes that reception is |
| 1589 | + * stoppable by disabling the UART_IER_RDI interrupt. (Some chips set the |
| 1590 | + * UART_LSR_DR bit even when UART_IER_RDI is disabled, foiling this approach.) |
| 1591 | + */ |
| 1592 | +void serial8250_em485_start_tx(struct uart_8250_port *up) |
| 1576 | 1593 | { |
| 1577 | | − struct uart_8250_port *up = up_to_u8250p(port); |
| 1578 | | − struct uart_8250_em485 *em485 = up->em485; |
| 1579 | | − unsigned char mcr; |
| 1594 | + unsigned char mcr = serial8250_in_MCR(up); |
| 1580 | 1595 | |
| 1581 | 1596 | if (!(up->port.rs485.flags & SER_RS485_RX_DURING_TX)) |
| 1582 | 1597 | serial8250_stop_rx(&up->port); |
| 1583 | 1598 | |
| 1599 | + if (up->port.rs485.flags & SER_RS485_RTS_ON_SEND) |
| 1600 | + mcr |= UART_MCR_RTS; |
| 1601 | + else |
| 1602 | + mcr &= ~UART_MCR_RTS; |
| 1603 | + serial8250_out_MCR(up, mcr); |
| 1604 | +} |
| 1605 | +EXPORT_SYMBOL_GPL(serial8250_em485_start_tx); |
| 1606 | + |
| 1607 | +static inline void start_tx_rs485(struct uart_port *port) |
| 1608 | +{ |
| 1609 | + struct uart_8250_port *up = up_to_u8250p(port); |
| 1610 | + struct uart_8250_em485 *em485 = up->em485; |
| 1611 | + |
| 1584 | 1612 | em485->active_timer = NULL; |
| 1585 | 1613 | |
| 1586 | | − mcr = serial8250_in_MCR(up); |
| 1587 | | − if (!!(up->port.rs485.flags & SER_RS485_RTS_ON_SEND) != |
| 1588 | | − !!(mcr & UART_MCR_RTS)) { |
| 1589 | | − if (up->port.rs485.flags & SER_RS485_RTS_ON_SEND) |
| 1590 | | − mcr |= UART_MCR_RTS; |
| 1591 | | − else |
| 1592 | | − mcr &= ~UART_MCR_RTS; |
| 1593 | | − serial8250_out_MCR(up, mcr); |
| 1614 | + if (em485->tx_stopped) { |
| 1615 | + em485->tx_stopped = false; |
| 1616 | + |
| 1617 | + up->rs485_start_tx(up); |
| 1594 | 1618 | |
| 1595 | 1619 | if (up->port.rs485.delay_rts_before_send > 0) { |
| 1596 | 1620 | em485->active_timer = &em485->start_tx_timer; |