| .. | .. |
|---|
| 8 | 8 | * Copyright (C) 2004 Pengutronix |
|---|
| 9 | 9 | */ |
|---|
| 10 | 10 | |
|---|
| 11 | | -#if defined(CONFIG_SERIAL_IMX_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) |
|---|
| 12 | | -#define SUPPORT_SYSRQ |
|---|
| 13 | | -#endif |
|---|
| 14 | | - |
|---|
| 15 | 11 | #include <linux/module.h> |
|---|
| 16 | 12 | #include <linux/ioport.h> |
|---|
| 17 | 13 | #include <linux/init.h> |
|---|
| .. | .. |
|---|
| 24 | 20 | #include <linux/serial.h> |
|---|
| 25 | 21 | #include <linux/clk.h> |
|---|
| 26 | 22 | #include <linux/delay.h> |
|---|
| 23 | +#include <linux/ktime.h> |
|---|
| 24 | +#include <linux/pinctrl/consumer.h> |
|---|
| 27 | 25 | #include <linux/rational.h> |
|---|
| 28 | 26 | #include <linux/slab.h> |
|---|
| 29 | 27 | #include <linux/of.h> |
|---|
| .. | .. |
|---|
| 191 | 189 | enum imx_uart_type devtype; |
|---|
| 192 | 190 | }; |
|---|
| 193 | 191 | |
|---|
| 192 | +enum imx_tx_state { |
|---|
| 193 | + OFF, |
|---|
| 194 | + WAIT_AFTER_RTS, |
|---|
| 195 | + SEND, |
|---|
| 196 | + WAIT_AFTER_SEND, |
|---|
| 197 | +}; |
|---|
| 198 | + |
|---|
| 194 | 199 | struct imx_port { |
|---|
| 195 | 200 | struct uart_port port; |
|---|
| 196 | 201 | struct timer_list timer; |
|---|
| .. | .. |
|---|
| 198 | 203 | unsigned int have_rtscts:1; |
|---|
| 199 | 204 | unsigned int have_rtsgpio:1; |
|---|
| 200 | 205 | unsigned int dte_mode:1; |
|---|
| 206 | + unsigned int inverted_tx:1; |
|---|
| 207 | + unsigned int inverted_rx:1; |
|---|
| 201 | 208 | struct clk *clk_ipg; |
|---|
| 202 | 209 | struct clk *clk_per; |
|---|
| 203 | 210 | const struct imx_uart_data *devdata; |
|---|
| .. | .. |
|---|
| 225 | 232 | unsigned int dma_tx_nents; |
|---|
| 226 | 233 | unsigned int saved_reg[10]; |
|---|
| 227 | 234 | bool context_saved; |
|---|
| 235 | + |
|---|
| 236 | + enum imx_tx_state tx_state; |
|---|
| 237 | + struct hrtimer trigger_start_tx; |
|---|
| 238 | + struct hrtimer trigger_stop_tx; |
|---|
| 228 | 239 | }; |
|---|
| 229 | 240 | |
|---|
| 230 | 241 | struct imx_port_ucrs { |
|---|
| .. | .. |
|---|
| 362 | 373 | /* |
|---|
| 363 | 374 | * Save and restore functions for UCR1, UCR2 and UCR3 registers |
|---|
| 364 | 375 | */ |
|---|
| 365 | | -#if defined(CONFIG_SERIAL_IMX_CONSOLE) |
|---|
| 376 | +#if IS_ENABLED(CONFIG_SERIAL_IMX_CONSOLE) |
|---|
| 366 | 377 | static void imx_uart_ucrs_save(struct imx_port *sport, |
|---|
| 367 | 378 | struct imx_port_ucrs *ucr) |
|---|
| 368 | 379 | { |
|---|
| .. | .. |
|---|
| 387 | 398 | { |
|---|
| 388 | 399 | *ucr2 &= ~(UCR2_CTSC | UCR2_CTS); |
|---|
| 389 | 400 | |
|---|
| 390 | | - sport->port.mctrl |= TIOCM_RTS; |
|---|
| 391 | | - mctrl_gpio_set(sport->gpios, sport->port.mctrl); |
|---|
| 401 | + mctrl_gpio_set(sport->gpios, sport->port.mctrl | TIOCM_RTS); |
|---|
| 392 | 402 | } |
|---|
| 393 | 403 | |
|---|
| 394 | 404 | /* called with port.lock taken and irqs caller dependent */ |
|---|
| .. | .. |
|---|
| 397 | 407 | *ucr2 &= ~UCR2_CTSC; |
|---|
| 398 | 408 | *ucr2 |= UCR2_CTS; |
|---|
| 399 | 409 | |
|---|
| 400 | | - sport->port.mctrl &= ~TIOCM_RTS; |
|---|
| 401 | | - mctrl_gpio_set(sport->gpios, sport->port.mctrl); |
|---|
| 410 | + mctrl_gpio_set(sport->gpios, sport->port.mctrl & ~TIOCM_RTS); |
|---|
| 402 | 411 | } |
|---|
| 403 | 412 | |
|---|
| 404 | | -/* called with port.lock taken and irqs caller dependent */ |
|---|
| 405 | | -static void imx_uart_rts_auto(struct imx_port *sport, u32 *ucr2) |
|---|
| 413 | +static void start_hrtimer_ms(struct hrtimer *hrt, unsigned long msec) |
|---|
| 406 | 414 | { |
|---|
| 407 | | - *ucr2 |= UCR2_CTSC; |
|---|
| 415 | + long sec = msec / MSEC_PER_SEC; |
|---|
| 416 | + long nsec = (msec % MSEC_PER_SEC) * 1000000; |
|---|
| 417 | + ktime_t t = ktime_set(sec, nsec); |
|---|
| 418 | + |
|---|
| 419 | + hrtimer_start(hrt, t, HRTIMER_MODE_REL); |
|---|
| 408 | 420 | } |
|---|
| 409 | 421 | |
|---|
| 410 | 422 | /* called with port.lock taken and irqs off */ |
|---|
| .. | .. |
|---|
| 434 | 446 | static void imx_uart_stop_tx(struct uart_port *port) |
|---|
| 435 | 447 | { |
|---|
| 436 | 448 | struct imx_port *sport = (struct imx_port *)port; |
|---|
| 437 | | - u32 ucr1; |
|---|
| 449 | + u32 ucr1, ucr4, usr2; |
|---|
| 450 | + |
|---|
| 451 | + if (sport->tx_state == OFF) |
|---|
| 452 | + return; |
|---|
| 438 | 453 | |
|---|
| 439 | 454 | /* |
|---|
| 440 | 455 | * We are maybe in the SMP context, so if the DMA TX thread is running |
|---|
| .. | .. |
|---|
| 444 | 459 | return; |
|---|
| 445 | 460 | |
|---|
| 446 | 461 | ucr1 = imx_uart_readl(sport, UCR1); |
|---|
| 447 | | - imx_uart_writel(sport, ucr1 & ~UCR1_TXMPTYEN, UCR1); |
|---|
| 462 | + imx_uart_writel(sport, ucr1 & ~UCR1_TRDYEN, UCR1); |
|---|
| 448 | 463 | |
|---|
| 449 | | - /* in rs485 mode disable transmitter if shifter is empty */ |
|---|
| 450 | | - if (port->rs485.flags & SER_RS485_ENABLED && |
|---|
| 451 | | - imx_uart_readl(sport, USR2) & USR2_TXDC) { |
|---|
| 452 | | - u32 ucr2 = imx_uart_readl(sport, UCR2), ucr4; |
|---|
| 453 | | - if (port->rs485.flags & SER_RS485_RTS_AFTER_SEND) |
|---|
| 454 | | - imx_uart_rts_active(sport, &ucr2); |
|---|
| 455 | | - else |
|---|
| 456 | | - imx_uart_rts_inactive(sport, &ucr2); |
|---|
| 457 | | - imx_uart_writel(sport, ucr2, UCR2); |
|---|
| 464 | + usr2 = imx_uart_readl(sport, USR2); |
|---|
| 465 | + if (!(usr2 & USR2_TXDC)) { |
|---|
| 466 | + /* The shifter is still busy, so retry once TC triggers */ |
|---|
| 467 | + return; |
|---|
| 468 | + } |
|---|
| 458 | 469 | |
|---|
| 459 | | - imx_uart_start_rx(port); |
|---|
| 470 | + ucr4 = imx_uart_readl(sport, UCR4); |
|---|
| 471 | + ucr4 &= ~UCR4_TCEN; |
|---|
| 472 | + imx_uart_writel(sport, ucr4, UCR4); |
|---|
| 460 | 473 | |
|---|
| 461 | | - ucr4 = imx_uart_readl(sport, UCR4); |
|---|
| 462 | | - ucr4 &= ~UCR4_TCEN; |
|---|
| 463 | | - imx_uart_writel(sport, ucr4, UCR4); |
|---|
| 474 | + /* in rs485 mode disable transmitter */ |
|---|
| 475 | + if (port->rs485.flags & SER_RS485_ENABLED) { |
|---|
| 476 | + if (sport->tx_state == SEND) { |
|---|
| 477 | + sport->tx_state = WAIT_AFTER_SEND; |
|---|
| 478 | + start_hrtimer_ms(&sport->trigger_stop_tx, |
|---|
| 479 | + port->rs485.delay_rts_after_send); |
|---|
| 480 | + return; |
|---|
| 481 | + } |
|---|
| 482 | + |
|---|
| 483 | + if (sport->tx_state == WAIT_AFTER_RTS || |
|---|
| 484 | + sport->tx_state == WAIT_AFTER_SEND) { |
|---|
| 485 | + u32 ucr2; |
|---|
| 486 | + |
|---|
| 487 | + hrtimer_try_to_cancel(&sport->trigger_start_tx); |
|---|
| 488 | + |
|---|
| 489 | + ucr2 = imx_uart_readl(sport, UCR2); |
|---|
| 490 | + if (port->rs485.flags & SER_RS485_RTS_AFTER_SEND) |
|---|
| 491 | + imx_uart_rts_active(sport, &ucr2); |
|---|
| 492 | + else |
|---|
| 493 | + imx_uart_rts_inactive(sport, &ucr2); |
|---|
| 494 | + imx_uart_writel(sport, ucr2, UCR2); |
|---|
| 495 | + |
|---|
| 496 | + imx_uart_start_rx(port); |
|---|
| 497 | + |
|---|
| 498 | + sport->tx_state = OFF; |
|---|
| 499 | + } |
|---|
| 500 | + } else { |
|---|
| 501 | + sport->tx_state = OFF; |
|---|
| 464 | 502 | } |
|---|
| 465 | 503 | } |
|---|
| 466 | 504 | |
|---|
| .. | .. |
|---|
| 468 | 506 | static void imx_uart_stop_rx(struct uart_port *port) |
|---|
| 469 | 507 | { |
|---|
| 470 | 508 | struct imx_port *sport = (struct imx_port *)port; |
|---|
| 471 | | - u32 ucr1, ucr2; |
|---|
| 509 | + u32 ucr1, ucr2, ucr4; |
|---|
| 472 | 510 | |
|---|
| 473 | 511 | ucr1 = imx_uart_readl(sport, UCR1); |
|---|
| 474 | 512 | ucr2 = imx_uart_readl(sport, UCR2); |
|---|
| 513 | + ucr4 = imx_uart_readl(sport, UCR4); |
|---|
| 475 | 514 | |
|---|
| 476 | 515 | if (sport->dma_is_enabled) { |
|---|
| 477 | 516 | ucr1 &= ~(UCR1_RXDMAEN | UCR1_ATDMAEN); |
|---|
| 478 | 517 | } else { |
|---|
| 479 | 518 | ucr1 &= ~UCR1_RRDYEN; |
|---|
| 480 | 519 | ucr2 &= ~UCR2_ATEN; |
|---|
| 520 | + ucr4 &= ~UCR4_OREN; |
|---|
| 481 | 521 | } |
|---|
| 482 | 522 | imx_uart_writel(sport, ucr1, UCR1); |
|---|
| 523 | + imx_uart_writel(sport, ucr4, UCR4); |
|---|
| 483 | 524 | |
|---|
| 484 | 525 | ucr2 &= ~UCR2_RXEN; |
|---|
| 485 | 526 | imx_uart_writel(sport, ucr2, UCR2); |
|---|
| .. | .. |
|---|
| 522 | 563 | * and the TX IRQ is disabled. |
|---|
| 523 | 564 | **/ |
|---|
| 524 | 565 | ucr1 = imx_uart_readl(sport, UCR1); |
|---|
| 525 | | - ucr1 &= ~UCR1_TXMPTYEN; |
|---|
| 566 | + ucr1 &= ~UCR1_TRDYEN; |
|---|
| 526 | 567 | if (sport->dma_is_txing) { |
|---|
| 527 | 568 | ucr1 |= UCR1_TXDMAEN; |
|---|
| 528 | 569 | imx_uart_writel(sport, ucr1, UCR1); |
|---|
| .. | .. |
|---|
| 658 | 699 | if (!sport->port.x_char && uart_circ_empty(&port->state->xmit)) |
|---|
| 659 | 700 | return; |
|---|
| 660 | 701 | |
|---|
| 702 | + /* |
|---|
| 703 | + * We cannot simply do nothing here if sport->tx_state == SEND already |
|---|
| 704 | + * because UCR1_TXMPTYEN might already have been cleared in |
|---|
| 705 | + * imx_uart_stop_tx(), but tx_state is still SEND. |
|---|
| 706 | + */ |
|---|
| 707 | + |
|---|
| 661 | 708 | if (port->rs485.flags & SER_RS485_ENABLED) { |
|---|
| 662 | | - u32 ucr2; |
|---|
| 709 | + if (sport->tx_state == OFF) { |
|---|
| 710 | + u32 ucr2 = imx_uart_readl(sport, UCR2); |
|---|
| 711 | + if (port->rs485.flags & SER_RS485_RTS_ON_SEND) |
|---|
| 712 | + imx_uart_rts_active(sport, &ucr2); |
|---|
| 713 | + else |
|---|
| 714 | + imx_uart_rts_inactive(sport, &ucr2); |
|---|
| 715 | + imx_uart_writel(sport, ucr2, UCR2); |
|---|
| 663 | 716 | |
|---|
| 664 | | - ucr2 = imx_uart_readl(sport, UCR2); |
|---|
| 665 | | - if (port->rs485.flags & SER_RS485_RTS_ON_SEND) |
|---|
| 666 | | - imx_uart_rts_active(sport, &ucr2); |
|---|
| 667 | | - else |
|---|
| 668 | | - imx_uart_rts_inactive(sport, &ucr2); |
|---|
| 669 | | - imx_uart_writel(sport, ucr2, UCR2); |
|---|
| 717 | + if (!(port->rs485.flags & SER_RS485_RX_DURING_TX)) |
|---|
| 718 | + imx_uart_stop_rx(port); |
|---|
| 670 | 719 | |
|---|
| 671 | | - if (!(port->rs485.flags & SER_RS485_RX_DURING_TX)) |
|---|
| 672 | | - imx_uart_stop_rx(port); |
|---|
| 673 | | - |
|---|
| 674 | | - /* |
|---|
| 675 | | - * Enable transmitter and shifter empty irq only if DMA is off. |
|---|
| 676 | | - * In the DMA case this is done in the tx-callback. |
|---|
| 677 | | - */ |
|---|
| 678 | | - if (!sport->dma_is_enabled) { |
|---|
| 679 | | - u32 ucr4 = imx_uart_readl(sport, UCR4); |
|---|
| 680 | | - ucr4 |= UCR4_TCEN; |
|---|
| 681 | | - imx_uart_writel(sport, ucr4, UCR4); |
|---|
| 720 | + sport->tx_state = WAIT_AFTER_RTS; |
|---|
| 721 | + start_hrtimer_ms(&sport->trigger_start_tx, |
|---|
| 722 | + port->rs485.delay_rts_before_send); |
|---|
| 723 | + return; |
|---|
| 682 | 724 | } |
|---|
| 725 | + |
|---|
| 726 | + if (sport->tx_state == WAIT_AFTER_SEND |
|---|
| 727 | + || sport->tx_state == WAIT_AFTER_RTS) { |
|---|
| 728 | + |
|---|
| 729 | + hrtimer_try_to_cancel(&sport->trigger_stop_tx); |
|---|
| 730 | + |
|---|
| 731 | + /* |
|---|
| 732 | + * Enable transmitter and shifter empty irq only if DMA |
|---|
| 733 | + * is off. In the DMA case this is done in the |
|---|
| 734 | + * tx-callback. |
|---|
| 735 | + */ |
|---|
| 736 | + if (!sport->dma_is_enabled) { |
|---|
| 737 | + u32 ucr4 = imx_uart_readl(sport, UCR4); |
|---|
| 738 | + ucr4 |= UCR4_TCEN; |
|---|
| 739 | + imx_uart_writel(sport, ucr4, UCR4); |
|---|
| 740 | + } |
|---|
| 741 | + |
|---|
| 742 | + sport->tx_state = SEND; |
|---|
| 743 | + } |
|---|
| 744 | + } else { |
|---|
| 745 | + sport->tx_state = SEND; |
|---|
| 683 | 746 | } |
|---|
| 684 | 747 | |
|---|
| 685 | 748 | if (!sport->dma_is_enabled) { |
|---|
| 686 | 749 | ucr1 = imx_uart_readl(sport, UCR1); |
|---|
| 687 | | - imx_uart_writel(sport, ucr1 | UCR1_TXMPTYEN, UCR1); |
|---|
| 750 | + imx_uart_writel(sport, ucr1 | UCR1_TRDYEN, UCR1); |
|---|
| 688 | 751 | } |
|---|
| 689 | 752 | |
|---|
| 690 | 753 | if (sport->dma_is_enabled) { |
|---|
| .. | .. |
|---|
| 693 | 756 | * disable TX DMA to let TX interrupt to send X-char */ |
|---|
| 694 | 757 | ucr1 = imx_uart_readl(sport, UCR1); |
|---|
| 695 | 758 | ucr1 &= ~UCR1_TXDMAEN; |
|---|
| 696 | | - ucr1 |= UCR1_TXMPTYEN; |
|---|
| 759 | + ucr1 |= UCR1_TRDYEN; |
|---|
| 697 | 760 | imx_uart_writel(sport, ucr1, UCR1); |
|---|
| 698 | 761 | return; |
|---|
| 699 | 762 | } |
|---|
| .. | .. |
|---|
| 705 | 768 | } |
|---|
| 706 | 769 | } |
|---|
| 707 | 770 | |
|---|
| 708 | | -static irqreturn_t imx_uart_rtsint(int irq, void *dev_id) |
|---|
| 771 | +static irqreturn_t __imx_uart_rtsint(int irq, void *dev_id) |
|---|
| 709 | 772 | { |
|---|
| 710 | 773 | struct imx_port *sport = dev_id; |
|---|
| 711 | 774 | u32 usr1; |
|---|
| 712 | | - unsigned long flags; |
|---|
| 713 | | - |
|---|
| 714 | | - spin_lock_irqsave(&sport->port.lock, flags); |
|---|
| 715 | 775 | |
|---|
| 716 | 776 | imx_uart_writel(sport, USR1_RTSD, USR1); |
|---|
| 717 | 777 | usr1 = imx_uart_readl(sport, USR1) & USR1_RTSS; |
|---|
| 718 | 778 | uart_handle_cts_change(&sport->port, !!usr1); |
|---|
| 719 | 779 | wake_up_interruptible(&sport->port.state->port.delta_msr_wait); |
|---|
| 720 | 780 | |
|---|
| 721 | | - spin_unlock_irqrestore(&sport->port.lock, flags); |
|---|
| 722 | 781 | return IRQ_HANDLED; |
|---|
| 782 | +} |
|---|
| 783 | + |
|---|
| 784 | +static irqreturn_t imx_uart_rtsint(int irq, void *dev_id) |
|---|
| 785 | +{ |
|---|
| 786 | + struct imx_port *sport = dev_id; |
|---|
| 787 | + irqreturn_t ret; |
|---|
| 788 | + |
|---|
| 789 | + spin_lock(&sport->port.lock); |
|---|
| 790 | + |
|---|
| 791 | + ret = __imx_uart_rtsint(irq, dev_id); |
|---|
| 792 | + |
|---|
| 793 | + spin_unlock(&sport->port.lock); |
|---|
| 794 | + |
|---|
| 795 | + return ret; |
|---|
| 723 | 796 | } |
|---|
| 724 | 797 | |
|---|
| 725 | 798 | static irqreturn_t imx_uart_txint(int irq, void *dev_id) |
|---|
| 726 | 799 | { |
|---|
| 727 | 800 | struct imx_port *sport = dev_id; |
|---|
| 728 | | - unsigned long flags; |
|---|
| 729 | 801 | |
|---|
| 730 | | - spin_lock_irqsave(&sport->port.lock, flags); |
|---|
| 802 | + spin_lock(&sport->port.lock); |
|---|
| 731 | 803 | imx_uart_transmit_buffer(sport); |
|---|
| 732 | | - spin_unlock_irqrestore(&sport->port.lock, flags); |
|---|
| 804 | + spin_unlock(&sport->port.lock); |
|---|
| 733 | 805 | return IRQ_HANDLED; |
|---|
| 734 | 806 | } |
|---|
| 735 | 807 | |
|---|
| 736 | | -static irqreturn_t imx_uart_rxint(int irq, void *dev_id) |
|---|
| 808 | +static irqreturn_t __imx_uart_rxint(int irq, void *dev_id) |
|---|
| 737 | 809 | { |
|---|
| 738 | 810 | struct imx_port *sport = dev_id; |
|---|
| 739 | 811 | unsigned int rx, flg, ignored = 0; |
|---|
| 740 | 812 | struct tty_port *port = &sport->port.state->port; |
|---|
| 741 | | - unsigned long flags; |
|---|
| 742 | | - |
|---|
| 743 | | - spin_lock_irqsave(&sport->port.lock, flags); |
|---|
| 744 | 813 | |
|---|
| 745 | 814 | while (imx_uart_readl(sport, USR2) & USR2_RDR) { |
|---|
| 746 | 815 | u32 usr2; |
|---|
| .. | .. |
|---|
| 787 | 856 | if (rx & URXD_OVRRUN) |
|---|
| 788 | 857 | flg = TTY_OVERRUN; |
|---|
| 789 | 858 | |
|---|
| 790 | | -#ifdef SUPPORT_SYSRQ |
|---|
| 791 | 859 | sport->port.sysrq = 0; |
|---|
| 792 | | -#endif |
|---|
| 793 | 860 | } |
|---|
| 794 | 861 | |
|---|
| 795 | 862 | if (sport->port.ignore_status_mask & URXD_DUMMY_READ) |
|---|
| .. | .. |
|---|
| 800 | 867 | } |
|---|
| 801 | 868 | |
|---|
| 802 | 869 | out: |
|---|
| 803 | | - spin_unlock_irqrestore(&sport->port.lock, flags); |
|---|
| 804 | 870 | tty_flip_buffer_push(port); |
|---|
| 871 | + |
|---|
| 805 | 872 | return IRQ_HANDLED; |
|---|
| 873 | +} |
|---|
| 874 | + |
|---|
| 875 | +static irqreturn_t imx_uart_rxint(int irq, void *dev_id) |
|---|
| 876 | +{ |
|---|
| 877 | + struct imx_port *sport = dev_id; |
|---|
| 878 | + irqreturn_t ret; |
|---|
| 879 | + |
|---|
| 880 | + spin_lock(&sport->port.lock); |
|---|
| 881 | + |
|---|
| 882 | + ret = __imx_uart_rxint(irq, dev_id); |
|---|
| 883 | + |
|---|
| 884 | + spin_unlock(&sport->port.lock); |
|---|
| 885 | + |
|---|
| 886 | + return ret; |
|---|
| 806 | 887 | } |
|---|
| 807 | 888 | |
|---|
| 808 | 889 | static void imx_uart_clear_rx_errors(struct imx_port *sport); |
|---|
| .. | .. |
|---|
| 862 | 943 | struct imx_port *sport = dev_id; |
|---|
| 863 | 944 | unsigned int usr1, usr2, ucr1, ucr2, ucr3, ucr4; |
|---|
| 864 | 945 | irqreturn_t ret = IRQ_NONE; |
|---|
| 946 | + unsigned long flags = 0; |
|---|
| 947 | + |
|---|
| 948 | + /* |
|---|
| 949 | + * IRQs might not be disabled upon entering this interrupt handler, |
|---|
| 950 | + * e.g. when interrupt handlers are forced to be threaded. To support |
|---|
| 951 | + * this scenario as well, disable IRQs when acquiring the spinlock. |
|---|
| 952 | + */ |
|---|
| 953 | + spin_lock_irqsave(&sport->port.lock, flags); |
|---|
| 865 | 954 | |
|---|
| 866 | 955 | usr1 = imx_uart_readl(sport, USR1); |
|---|
| 867 | 956 | usr2 = imx_uart_readl(sport, USR2); |
|---|
| .. | .. |
|---|
| 882 | 971 | usr1 &= ~USR1_RRDY; |
|---|
| 883 | 972 | if ((ucr2 & UCR2_ATEN) == 0) |
|---|
| 884 | 973 | usr1 &= ~USR1_AGTIM; |
|---|
| 885 | | - if ((ucr1 & UCR1_TXMPTYEN) == 0) |
|---|
| 974 | + if ((ucr1 & UCR1_TRDYEN) == 0) |
|---|
| 886 | 975 | usr1 &= ~USR1_TRDY; |
|---|
| 887 | 976 | if ((ucr4 & UCR4_TCEN) == 0) |
|---|
| 888 | 977 | usr2 &= ~USR2_TXDC; |
|---|
| .. | .. |
|---|
| 896 | 985 | usr2 &= ~USR2_ORE; |
|---|
| 897 | 986 | |
|---|
| 898 | 987 | if (usr1 & (USR1_RRDY | USR1_AGTIM)) { |
|---|
| 899 | | - imx_uart_rxint(irq, dev_id); |
|---|
| 988 | + imx_uart_writel(sport, USR1_AGTIM, USR1); |
|---|
| 989 | + |
|---|
| 990 | + __imx_uart_rxint(irq, dev_id); |
|---|
| 900 | 991 | ret = IRQ_HANDLED; |
|---|
| 901 | 992 | } |
|---|
| 902 | 993 | |
|---|
| 903 | 994 | if ((usr1 & USR1_TRDY) || (usr2 & USR2_TXDC)) { |
|---|
| 904 | | - imx_uart_txint(irq, dev_id); |
|---|
| 995 | + imx_uart_transmit_buffer(sport); |
|---|
| 905 | 996 | ret = IRQ_HANDLED; |
|---|
| 906 | 997 | } |
|---|
| 907 | 998 | |
|---|
| 908 | 999 | if (usr1 & USR1_DTRD) { |
|---|
| 909 | | - unsigned long flags; |
|---|
| 910 | | - |
|---|
| 911 | 1000 | imx_uart_writel(sport, USR1_DTRD, USR1); |
|---|
| 912 | 1001 | |
|---|
| 913 | | - spin_lock_irqsave(&sport->port.lock, flags); |
|---|
| 914 | 1002 | imx_uart_mctrl_check(sport); |
|---|
| 915 | | - spin_unlock_irqrestore(&sport->port.lock, flags); |
|---|
| 916 | 1003 | |
|---|
| 917 | 1004 | ret = IRQ_HANDLED; |
|---|
| 918 | 1005 | } |
|---|
| 919 | 1006 | |
|---|
| 920 | 1007 | if (usr1 & USR1_RTSD) { |
|---|
| 921 | | - imx_uart_rtsint(irq, dev_id); |
|---|
| 1008 | + __imx_uart_rtsint(irq, dev_id); |
|---|
| 922 | 1009 | ret = IRQ_HANDLED; |
|---|
| 923 | 1010 | } |
|---|
| 924 | 1011 | |
|---|
| .. | .. |
|---|
| 932 | 1019 | imx_uart_writel(sport, USR2_ORE, USR2); |
|---|
| 933 | 1020 | ret = IRQ_HANDLED; |
|---|
| 934 | 1021 | } |
|---|
| 1022 | + |
|---|
| 1023 | + spin_unlock_irqrestore(&sport->port.lock, flags); |
|---|
| 935 | 1024 | |
|---|
| 936 | 1025 | return ret; |
|---|
| 937 | 1026 | } |
|---|
| .. | .. |
|---|
| 973 | 1062 | if (!(port->rs485.flags & SER_RS485_ENABLED)) { |
|---|
| 974 | 1063 | u32 ucr2; |
|---|
| 975 | 1064 | |
|---|
| 1065 | + /* |
|---|
| 1066 | + * Turn off autoRTS if RTS is lowered and restore autoRTS |
|---|
| 1067 | + * setting if RTS is raised. |
|---|
| 1068 | + */ |
|---|
| 976 | 1069 | ucr2 = imx_uart_readl(sport, UCR2); |
|---|
| 977 | 1070 | ucr2 &= ~(UCR2_CTS | UCR2_CTSC); |
|---|
| 978 | | - if (mctrl & TIOCM_RTS) |
|---|
| 979 | | - ucr2 |= UCR2_CTS | UCR2_CTSC; |
|---|
| 1071 | + if (mctrl & TIOCM_RTS) { |
|---|
| 1072 | + ucr2 |= UCR2_CTS; |
|---|
| 1073 | + /* |
|---|
| 1074 | + * UCR2_IRTS is unset if and only if the port is |
|---|
| 1075 | + * configured for CRTSCTS, so we use inverted UCR2_IRTS |
|---|
| 1076 | + * to get the state to restore to. |
|---|
| 1077 | + */ |
|---|
| 1078 | + if (!(ucr2 & UCR2_IRTS)) |
|---|
| 1079 | + ucr2 |= UCR2_CTSC; |
|---|
| 1080 | + } |
|---|
| 980 | 1081 | imx_uart_writel(sport, ucr2, UCR2); |
|---|
| 981 | 1082 | } |
|---|
| 982 | 1083 | |
|---|
| .. | .. |
|---|
| 1031 | 1132 | mod_timer(&sport->timer, jiffies + MCTRL_TIMEOUT); |
|---|
| 1032 | 1133 | } |
|---|
| 1033 | 1134 | } |
|---|
| 1034 | | - |
|---|
| 1035 | | -#define RX_BUF_SIZE (PAGE_SIZE) |
|---|
| 1036 | 1135 | |
|---|
| 1037 | 1136 | /* |
|---|
| 1038 | 1137 | * There are two kinds of RX DMA interrupts(such as in the MX6Q): |
|---|
| .. | .. |
|---|
| 1116 | 1215 | } |
|---|
| 1117 | 1216 | |
|---|
| 1118 | 1217 | /* RX DMA buffer periods */ |
|---|
| 1119 | | -#define RX_DMA_PERIODS 4 |
|---|
| 1218 | +#define RX_DMA_PERIODS 16 |
|---|
| 1219 | +#define RX_BUF_SIZE (RX_DMA_PERIODS * PAGE_SIZE / 4) |
|---|
| 1120 | 1220 | |
|---|
| 1121 | 1221 | static int imx_uart_start_rx_dma(struct imx_port *sport) |
|---|
| 1122 | 1222 | { |
|---|
| .. | .. |
|---|
| 1172 | 1272 | sport->port.icount.buf_overrun++; |
|---|
| 1173 | 1273 | tty_flip_buffer_push(port); |
|---|
| 1174 | 1274 | } else { |
|---|
| 1175 | | - dev_err(sport->port.dev, "DMA transaction error.\n"); |
|---|
| 1176 | 1275 | if (usr1 & USR1_FRAMERR) { |
|---|
| 1177 | 1276 | sport->port.icount.frame++; |
|---|
| 1178 | 1277 | imx_uart_writel(sport, USR1_FRAMERR, USR1); |
|---|
| .. | .. |
|---|
| 1316 | 1415 | int retval, i; |
|---|
| 1317 | 1416 | unsigned long flags; |
|---|
| 1318 | 1417 | int dma_is_inited = 0; |
|---|
| 1319 | | - u32 ucr1, ucr2, ucr4; |
|---|
| 1418 | + u32 ucr1, ucr2, ucr3, ucr4; |
|---|
| 1320 | 1419 | |
|---|
| 1321 | 1420 | retval = clk_prepare_enable(sport->clk_per); |
|---|
| 1322 | 1421 | if (retval) |
|---|
| .. | .. |
|---|
| 1368 | 1467 | |
|---|
| 1369 | 1468 | imx_uart_writel(sport, ucr1, UCR1); |
|---|
| 1370 | 1469 | |
|---|
| 1371 | | - ucr4 = imx_uart_readl(sport, UCR4) & ~UCR4_OREN; |
|---|
| 1372 | | - if (!sport->dma_is_enabled) |
|---|
| 1470 | + ucr4 = imx_uart_readl(sport, UCR4) & ~(UCR4_OREN | UCR4_INVR); |
|---|
| 1471 | + if (!dma_is_inited) |
|---|
| 1373 | 1472 | ucr4 |= UCR4_OREN; |
|---|
| 1473 | + if (sport->inverted_rx) |
|---|
| 1474 | + ucr4 |= UCR4_INVR; |
|---|
| 1374 | 1475 | imx_uart_writel(sport, ucr4, UCR4); |
|---|
| 1476 | + |
|---|
| 1477 | + ucr3 = imx_uart_readl(sport, UCR3) & ~UCR3_INVT; |
|---|
| 1478 | + /* |
|---|
| 1479 | + * configure tx polarity before enabling tx |
|---|
| 1480 | + */ |
|---|
| 1481 | + if (sport->inverted_tx) |
|---|
| 1482 | + ucr3 |= UCR3_INVT; |
|---|
| 1483 | + |
|---|
| 1484 | + if (!imx_uart_is_imx1(sport)) { |
|---|
| 1485 | + ucr3 |= UCR3_DTRDEN | UCR3_RI | UCR3_DCD; |
|---|
| 1486 | + |
|---|
| 1487 | + if (sport->dte_mode) |
|---|
| 1488 | + /* disable broken interrupts */ |
|---|
| 1489 | + ucr3 &= ~(UCR3_RI | UCR3_DCD); |
|---|
| 1490 | + } |
|---|
| 1491 | + imx_uart_writel(sport, ucr3, UCR3); |
|---|
| 1375 | 1492 | |
|---|
| 1376 | 1493 | ucr2 = imx_uart_readl(sport, UCR2) & ~UCR2_ATEN; |
|---|
| 1377 | 1494 | ucr2 |= (UCR2_RXEN | UCR2_TXEN); |
|---|
| .. | .. |
|---|
| 1384 | 1501 | if (!imx_uart_is_imx1(sport)) |
|---|
| 1385 | 1502 | ucr2 &= ~UCR2_RTSEN; |
|---|
| 1386 | 1503 | imx_uart_writel(sport, ucr2, UCR2); |
|---|
| 1387 | | - |
|---|
| 1388 | | - if (!imx_uart_is_imx1(sport)) { |
|---|
| 1389 | | - u32 ucr3; |
|---|
| 1390 | | - |
|---|
| 1391 | | - ucr3 = imx_uart_readl(sport, UCR3); |
|---|
| 1392 | | - |
|---|
| 1393 | | - ucr3 |= UCR3_DTRDEN | UCR3_RI | UCR3_DCD; |
|---|
| 1394 | | - |
|---|
| 1395 | | - if (sport->dte_mode) |
|---|
| 1396 | | - /* disable broken interrupts */ |
|---|
| 1397 | | - ucr3 &= ~(UCR3_RI | UCR3_DCD); |
|---|
| 1398 | | - |
|---|
| 1399 | | - imx_uart_writel(sport, ucr3, UCR3); |
|---|
| 1400 | | - } |
|---|
| 1401 | 1504 | |
|---|
| 1402 | 1505 | /* |
|---|
| 1403 | 1506 | * Enable modem status interrupts |
|---|
| .. | .. |
|---|
| 1456 | 1559 | ucr2 = imx_uart_readl(sport, UCR2); |
|---|
| 1457 | 1560 | ucr2 &= ~(UCR2_TXEN | UCR2_ATEN); |
|---|
| 1458 | 1561 | imx_uart_writel(sport, ucr2, UCR2); |
|---|
| 1459 | | - |
|---|
| 1460 | | - ucr4 = imx_uart_readl(sport, UCR4); |
|---|
| 1461 | | - ucr4 &= ~UCR4_OREN; |
|---|
| 1462 | | - imx_uart_writel(sport, ucr4, UCR4); |
|---|
| 1463 | 1562 | spin_unlock_irqrestore(&sport->port.lock, flags); |
|---|
| 1464 | 1563 | |
|---|
| 1465 | 1564 | /* |
|---|
| .. | .. |
|---|
| 1472 | 1571 | */ |
|---|
| 1473 | 1572 | |
|---|
| 1474 | 1573 | spin_lock_irqsave(&sport->port.lock, flags); |
|---|
| 1475 | | - ucr1 = imx_uart_readl(sport, UCR1); |
|---|
| 1476 | | - ucr1 &= ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN | UCR1_RXDMAEN | UCR1_ATDMAEN); |
|---|
| 1477 | 1574 | |
|---|
| 1575 | + ucr1 = imx_uart_readl(sport, UCR1); |
|---|
| 1576 | + ucr1 &= ~(UCR1_TRDYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN | UCR1_RXDMAEN | UCR1_ATDMAEN); |
|---|
| 1478 | 1577 | imx_uart_writel(sport, ucr1, UCR1); |
|---|
| 1578 | + |
|---|
| 1579 | + ucr4 = imx_uart_readl(sport, UCR4); |
|---|
| 1580 | + ucr4 &= ~UCR4_TCEN; |
|---|
| 1581 | + imx_uart_writel(sport, ucr4, UCR4); |
|---|
| 1582 | + |
|---|
| 1479 | 1583 | spin_unlock_irqrestore(&sport->port.lock, flags); |
|---|
| 1480 | 1584 | |
|---|
| 1481 | 1585 | clk_disable_unprepare(sport->clk_per); |
|---|
| .. | .. |
|---|
| 1540 | 1644 | { |
|---|
| 1541 | 1645 | struct imx_port *sport = (struct imx_port *)port; |
|---|
| 1542 | 1646 | unsigned long flags; |
|---|
| 1543 | | - u32 ucr2, old_ucr1, old_ucr2, ufcr; |
|---|
| 1647 | + u32 ucr2, old_ucr2, ufcr; |
|---|
| 1544 | 1648 | unsigned int baud, quot; |
|---|
| 1545 | 1649 | unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8; |
|---|
| 1546 | 1650 | unsigned long div; |
|---|
| 1547 | | - unsigned long num, denom; |
|---|
| 1651 | + unsigned long num, denom, old_ubir, old_ubmr; |
|---|
| 1548 | 1652 | uint64_t tdiv64; |
|---|
| 1549 | 1653 | |
|---|
| 1550 | 1654 | /* |
|---|
| .. | .. |
|---|
| 1567 | 1671 | |
|---|
| 1568 | 1672 | spin_lock_irqsave(&sport->port.lock, flags); |
|---|
| 1569 | 1673 | |
|---|
| 1674 | + /* |
|---|
| 1675 | + * Read current UCR2 and save it for future use, then clear all the bits |
|---|
| 1676 | + * except those we will or may need to preserve. |
|---|
| 1677 | + */ |
|---|
| 1678 | + old_ucr2 = imx_uart_readl(sport, UCR2); |
|---|
| 1679 | + ucr2 = old_ucr2 & (UCR2_TXEN | UCR2_RXEN | UCR2_ATEN | UCR2_CTS); |
|---|
| 1680 | + |
|---|
| 1681 | + ucr2 |= UCR2_SRST | UCR2_IRTS; |
|---|
| 1570 | 1682 | if ((termios->c_cflag & CSIZE) == CS8) |
|---|
| 1571 | | - ucr2 = UCR2_WS | UCR2_SRST | UCR2_IRTS; |
|---|
| 1572 | | - else |
|---|
| 1573 | | - ucr2 = UCR2_SRST | UCR2_IRTS; |
|---|
| 1683 | + ucr2 |= UCR2_WS; |
|---|
| 1574 | 1684 | |
|---|
| 1575 | | - if (termios->c_cflag & CRTSCTS) { |
|---|
| 1576 | | - if (sport->have_rtscts) { |
|---|
| 1577 | | - ucr2 &= ~UCR2_IRTS; |
|---|
| 1685 | + if (!sport->have_rtscts) |
|---|
| 1686 | + termios->c_cflag &= ~CRTSCTS; |
|---|
| 1578 | 1687 | |
|---|
| 1579 | | - if (port->rs485.flags & SER_RS485_ENABLED) { |
|---|
| 1580 | | - /* |
|---|
| 1581 | | - * RTS is mandatory for rs485 operation, so keep |
|---|
| 1582 | | - * it under manual control and keep transmitter |
|---|
| 1583 | | - * disabled. |
|---|
| 1584 | | - */ |
|---|
| 1585 | | - if (port->rs485.flags & |
|---|
| 1586 | | - SER_RS485_RTS_AFTER_SEND) |
|---|
| 1587 | | - imx_uart_rts_active(sport, &ucr2); |
|---|
| 1588 | | - else |
|---|
| 1589 | | - imx_uart_rts_inactive(sport, &ucr2); |
|---|
| 1590 | | - } else { |
|---|
| 1591 | | - imx_uart_rts_auto(sport, &ucr2); |
|---|
| 1592 | | - } |
|---|
| 1593 | | - } else { |
|---|
| 1594 | | - termios->c_cflag &= ~CRTSCTS; |
|---|
| 1595 | | - } |
|---|
| 1596 | | - } else if (port->rs485.flags & SER_RS485_ENABLED) { |
|---|
| 1597 | | - /* disable transmitter */ |
|---|
| 1688 | + if (port->rs485.flags & SER_RS485_ENABLED) { |
|---|
| 1689 | + /* |
|---|
| 1690 | + * RTS is mandatory for rs485 operation, so keep |
|---|
| 1691 | + * it under manual control and keep transmitter |
|---|
| 1692 | + * disabled. |
|---|
| 1693 | + */ |
|---|
| 1598 | 1694 | if (port->rs485.flags & SER_RS485_RTS_AFTER_SEND) |
|---|
| 1599 | 1695 | imx_uart_rts_active(sport, &ucr2); |
|---|
| 1600 | 1696 | else |
|---|
| 1601 | 1697 | imx_uart_rts_inactive(sport, &ucr2); |
|---|
| 1698 | + |
|---|
| 1699 | + } else if (termios->c_cflag & CRTSCTS) { |
|---|
| 1700 | + /* |
|---|
| 1701 | + * Only let receiver control RTS output if we were not requested |
|---|
| 1702 | + * to have RTS inactive (which then should take precedence). |
|---|
| 1703 | + */ |
|---|
| 1704 | + if (ucr2 & UCR2_CTS) |
|---|
| 1705 | + ucr2 |= UCR2_CTSC; |
|---|
| 1602 | 1706 | } |
|---|
| 1603 | 1707 | |
|---|
| 1604 | | - |
|---|
| 1708 | + if (termios->c_cflag & CRTSCTS) |
|---|
| 1709 | + ucr2 &= ~UCR2_IRTS; |
|---|
| 1605 | 1710 | if (termios->c_cflag & CSTOPB) |
|---|
| 1606 | 1711 | ucr2 |= UCR2_STPB; |
|---|
| 1607 | 1712 | if (termios->c_cflag & PARENB) { |
|---|
| .. | .. |
|---|
| 1640 | 1745 | */ |
|---|
| 1641 | 1746 | uart_update_timeout(port, termios->c_cflag, baud); |
|---|
| 1642 | 1747 | |
|---|
| 1643 | | - /* |
|---|
| 1644 | | - * disable interrupts and drain transmitter |
|---|
| 1645 | | - */ |
|---|
| 1646 | | - old_ucr1 = imx_uart_readl(sport, UCR1); |
|---|
| 1647 | | - imx_uart_writel(sport, |
|---|
| 1648 | | - old_ucr1 & ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN), |
|---|
| 1649 | | - UCR1); |
|---|
| 1650 | | - old_ucr2 = imx_uart_readl(sport, UCR2); |
|---|
| 1651 | | - imx_uart_writel(sport, old_ucr2 & ~UCR2_ATEN, UCR2); |
|---|
| 1652 | | - |
|---|
| 1653 | | - while (!(imx_uart_readl(sport, USR2) & USR2_TXDC)) |
|---|
| 1654 | | - barrier(); |
|---|
| 1655 | | - |
|---|
| 1656 | | - /* then, disable everything */ |
|---|
| 1657 | | - imx_uart_writel(sport, old_ucr2 & ~(UCR2_TXEN | UCR2_RXEN | UCR2_ATEN), UCR2); |
|---|
| 1658 | | - old_ucr2 &= (UCR2_TXEN | UCR2_RXEN | UCR2_ATEN); |
|---|
| 1659 | | - |
|---|
| 1660 | 1748 | /* custom-baudrate handling */ |
|---|
| 1661 | 1749 | div = sport->port.uartclk / (baud * 16); |
|---|
| 1662 | 1750 | if (baud == 38400 && quot != div) |
|---|
| .. | .. |
|---|
| 1684 | 1772 | ufcr = (ufcr & (~UFCR_RFDIV)) | UFCR_RFDIV_REG(div); |
|---|
| 1685 | 1773 | imx_uart_writel(sport, ufcr, UFCR); |
|---|
| 1686 | 1774 | |
|---|
| 1687 | | - imx_uart_writel(sport, num, UBIR); |
|---|
| 1688 | | - imx_uart_writel(sport, denom, UBMR); |
|---|
| 1775 | + /* |
|---|
| 1776 | + * Two registers below should always be written both and in this |
|---|
| 1777 | + * particular order. One consequence is that we need to check if any of |
|---|
| 1778 | + * them changes and then update both. We do need the check for change |
|---|
| 1779 | + * as even writing the same values seem to "restart" |
|---|
| 1780 | + * transmission/receiving logic in the hardware, that leads to data |
|---|
| 1781 | + * breakage even when rate doesn't in fact change. E.g., user switches |
|---|
| 1782 | + * RTS/CTS handshake and suddenly gets broken bytes. |
|---|
| 1783 | + */ |
|---|
| 1784 | + old_ubir = imx_uart_readl(sport, UBIR); |
|---|
| 1785 | + old_ubmr = imx_uart_readl(sport, UBMR); |
|---|
| 1786 | + if (old_ubir != num || old_ubmr != denom) { |
|---|
| 1787 | + imx_uart_writel(sport, num, UBIR); |
|---|
| 1788 | + imx_uart_writel(sport, denom, UBMR); |
|---|
| 1789 | + } |
|---|
| 1689 | 1790 | |
|---|
| 1690 | 1791 | if (!imx_uart_is_imx1(sport)) |
|---|
| 1691 | 1792 | imx_uart_writel(sport, sport->port.uartclk / div / 1000, |
|---|
| 1692 | 1793 | IMX21_ONEMS); |
|---|
| 1693 | 1794 | |
|---|
| 1694 | | - imx_uart_writel(sport, old_ucr1, UCR1); |
|---|
| 1695 | | - |
|---|
| 1696 | | - /* set the parity, stop bits and data size */ |
|---|
| 1697 | | - imx_uart_writel(sport, ucr2 | old_ucr2, UCR2); |
|---|
| 1795 | + imx_uart_writel(sport, ucr2, UCR2); |
|---|
| 1698 | 1796 | |
|---|
| 1699 | 1797 | if (UART_ENABLE_MS(&sport->port, termios->c_cflag)) |
|---|
| 1700 | 1798 | imx_uart_enable_ms(&sport->port); |
|---|
| .. | .. |
|---|
| 1782 | 1880 | ucr1 |= IMX1_UCR1_UARTCLKEN; |
|---|
| 1783 | 1881 | |
|---|
| 1784 | 1882 | ucr1 |= UCR1_UARTEN; |
|---|
| 1785 | | - ucr1 &= ~(UCR1_TXMPTYEN | UCR1_RTSDEN | UCR1_RRDYEN); |
|---|
| 1883 | + ucr1 &= ~(UCR1_TRDYEN | UCR1_RTSDEN | UCR1_RRDYEN); |
|---|
| 1786 | 1884 | |
|---|
| 1787 | 1885 | ucr2 |= UCR2_RXEN; |
|---|
| 1788 | 1886 | ucr2 &= ~UCR2_ATEN; |
|---|
| .. | .. |
|---|
| 1834 | 1932 | { |
|---|
| 1835 | 1933 | struct imx_port *sport = (struct imx_port *)port; |
|---|
| 1836 | 1934 | u32 ucr2; |
|---|
| 1837 | | - |
|---|
| 1838 | | - /* unimplemented */ |
|---|
| 1839 | | - rs485conf->delay_rts_before_send = 0; |
|---|
| 1840 | | - rs485conf->delay_rts_after_send = 0; |
|---|
| 1841 | 1935 | |
|---|
| 1842 | 1936 | /* RTS is required to control the transmitter */ |
|---|
| 1843 | 1937 | if (!sport->have_rtscts && !sport->have_rtsgpio) |
|---|
| .. | .. |
|---|
| 1893 | 1987 | |
|---|
| 1894 | 1988 | static struct imx_port *imx_uart_ports[UART_NR]; |
|---|
| 1895 | 1989 | |
|---|
| 1896 | | -#ifdef CONFIG_SERIAL_IMX_CONSOLE |
|---|
| 1990 | +#if IS_ENABLED(CONFIG_SERIAL_IMX_CONSOLE) |
|---|
| 1897 | 1991 | static void imx_uart_console_putchar(struct uart_port *port, int ch) |
|---|
| 1898 | 1992 | { |
|---|
| 1899 | 1993 | struct imx_port *sport = (struct imx_port *)port; |
|---|
| .. | .. |
|---|
| 1932 | 2026 | if (imx_uart_is_imx1(sport)) |
|---|
| 1933 | 2027 | ucr1 |= IMX1_UCR1_UARTCLKEN; |
|---|
| 1934 | 2028 | ucr1 |= UCR1_UARTEN; |
|---|
| 1935 | | - ucr1 &= ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN); |
|---|
| 2029 | + ucr1 &= ~(UCR1_TRDYEN | UCR1_RRDYEN | UCR1_RTSDEN); |
|---|
| 1936 | 2030 | |
|---|
| 1937 | 2031 | imx_uart_writel(sport, ucr1, UCR1); |
|---|
| 1938 | 2032 | |
|---|
| .. | .. |
|---|
| 1956 | 2050 | * If the port was already initialised (eg, by a boot loader), |
|---|
| 1957 | 2051 | * try to determine the current setup. |
|---|
| 1958 | 2052 | */ |
|---|
| 1959 | | -static void __init |
|---|
| 2053 | +static void |
|---|
| 1960 | 2054 | imx_uart_console_get_options(struct imx_port *sport, int *baud, |
|---|
| 1961 | 2055 | int *parity, int *bits) |
|---|
| 1962 | 2056 | { |
|---|
| .. | .. |
|---|
| 2010 | 2104 | } |
|---|
| 2011 | 2105 | |
|---|
| 2012 | 2106 | if (*baud != baud_raw) |
|---|
| 2013 | | - pr_info("Console IMX rounded baud rate from %d to %d\n", |
|---|
| 2107 | + dev_info(sport->port.dev, "Console IMX rounded baud rate from %d to %d\n", |
|---|
| 2014 | 2108 | baud_raw, *baud); |
|---|
| 2015 | 2109 | } |
|---|
| 2016 | 2110 | } |
|---|
| 2017 | 2111 | |
|---|
| 2018 | | -static int __init |
|---|
| 2112 | +static int |
|---|
| 2019 | 2113 | imx_uart_console_setup(struct console *co, char *options) |
|---|
| 2020 | 2114 | { |
|---|
| 2021 | 2115 | struct imx_port *sport; |
|---|
| .. | .. |
|---|
| 2076 | 2170 | |
|---|
| 2077 | 2171 | #define IMX_CONSOLE &imx_uart_console |
|---|
| 2078 | 2172 | |
|---|
| 2079 | | -#ifdef CONFIG_OF |
|---|
| 2080 | | -static void imx_uart_console_early_putchar(struct uart_port *port, int ch) |
|---|
| 2081 | | -{ |
|---|
| 2082 | | - struct imx_port *sport = (struct imx_port *)port; |
|---|
| 2083 | | - |
|---|
| 2084 | | - while (imx_uart_readl(sport, IMX21_UTS) & UTS_TXFULL) |
|---|
| 2085 | | - cpu_relax(); |
|---|
| 2086 | | - |
|---|
| 2087 | | - imx_uart_writel(sport, ch, URTX0); |
|---|
| 2088 | | -} |
|---|
| 2089 | | - |
|---|
| 2090 | | -static void imx_uart_console_early_write(struct console *con, const char *s, |
|---|
| 2091 | | - unsigned count) |
|---|
| 2092 | | -{ |
|---|
| 2093 | | - struct earlycon_device *dev = con->data; |
|---|
| 2094 | | - |
|---|
| 2095 | | - uart_console_write(&dev->port, s, count, imx_uart_console_early_putchar); |
|---|
| 2096 | | -} |
|---|
| 2097 | | - |
|---|
| 2098 | | -static int __init |
|---|
| 2099 | | -imx_console_early_setup(struct earlycon_device *dev, const char *opt) |
|---|
| 2100 | | -{ |
|---|
| 2101 | | - if (!dev->port.membase) |
|---|
| 2102 | | - return -ENODEV; |
|---|
| 2103 | | - |
|---|
| 2104 | | - dev->con->write = imx_uart_console_early_write; |
|---|
| 2105 | | - |
|---|
| 2106 | | - return 0; |
|---|
| 2107 | | -} |
|---|
| 2108 | | -OF_EARLYCON_DECLARE(ec_imx6q, "fsl,imx6q-uart", imx_console_early_setup); |
|---|
| 2109 | | -OF_EARLYCON_DECLARE(ec_imx21, "fsl,imx21-uart", imx_console_early_setup); |
|---|
| 2110 | | -#endif |
|---|
| 2111 | | - |
|---|
| 2112 | 2173 | #else |
|---|
| 2113 | 2174 | #define IMX_CONSOLE NULL |
|---|
| 2114 | 2175 | #endif |
|---|
| .. | .. |
|---|
| 2156 | 2217 | if (of_get_property(np, "rts-gpios", NULL)) |
|---|
| 2157 | 2218 | sport->have_rtsgpio = 1; |
|---|
| 2158 | 2219 | |
|---|
| 2220 | + if (of_get_property(np, "fsl,inverted-tx", NULL)) |
|---|
| 2221 | + sport->inverted_tx = 1; |
|---|
| 2222 | + |
|---|
| 2223 | + if (of_get_property(np, "fsl,inverted-rx", NULL)) |
|---|
| 2224 | + sport->inverted_rx = 1; |
|---|
| 2225 | + |
|---|
| 2159 | 2226 | return 0; |
|---|
| 2160 | 2227 | } |
|---|
| 2161 | 2228 | #else |
|---|
| .. | .. |
|---|
| 2179 | 2246 | |
|---|
| 2180 | 2247 | if (pdata->flags & IMXUART_HAVE_RTSCTS) |
|---|
| 2181 | 2248 | sport->have_rtscts = 1; |
|---|
| 2249 | +} |
|---|
| 2250 | + |
|---|
| 2251 | +static enum hrtimer_restart imx_trigger_start_tx(struct hrtimer *t) |
|---|
| 2252 | +{ |
|---|
| 2253 | + struct imx_port *sport = container_of(t, struct imx_port, trigger_start_tx); |
|---|
| 2254 | + unsigned long flags; |
|---|
| 2255 | + |
|---|
| 2256 | + spin_lock_irqsave(&sport->port.lock, flags); |
|---|
| 2257 | + if (sport->tx_state == WAIT_AFTER_RTS) |
|---|
| 2258 | + imx_uart_start_tx(&sport->port); |
|---|
| 2259 | + spin_unlock_irqrestore(&sport->port.lock, flags); |
|---|
| 2260 | + |
|---|
| 2261 | + return HRTIMER_NORESTART; |
|---|
| 2262 | +} |
|---|
| 2263 | + |
|---|
| 2264 | +static enum hrtimer_restart imx_trigger_stop_tx(struct hrtimer *t) |
|---|
| 2265 | +{ |
|---|
| 2266 | + struct imx_port *sport = container_of(t, struct imx_port, trigger_stop_tx); |
|---|
| 2267 | + unsigned long flags; |
|---|
| 2268 | + |
|---|
| 2269 | + spin_lock_irqsave(&sport->port.lock, flags); |
|---|
| 2270 | + if (sport->tx_state == WAIT_AFTER_SEND) |
|---|
| 2271 | + imx_uart_stop_tx(&sport->port); |
|---|
| 2272 | + spin_unlock_irqrestore(&sport->port.lock, flags); |
|---|
| 2273 | + |
|---|
| 2274 | + return HRTIMER_NORESTART; |
|---|
| 2182 | 2275 | } |
|---|
| 2183 | 2276 | |
|---|
| 2184 | 2277 | static int imx_uart_probe(struct platform_device *pdev) |
|---|
| .. | .. |
|---|
| 2212 | 2305 | return PTR_ERR(base); |
|---|
| 2213 | 2306 | |
|---|
| 2214 | 2307 | rxirq = platform_get_irq(pdev, 0); |
|---|
| 2215 | | - txirq = platform_get_irq(pdev, 1); |
|---|
| 2216 | | - rtsirq = platform_get_irq(pdev, 2); |
|---|
| 2308 | + if (rxirq < 0) |
|---|
| 2309 | + return rxirq; |
|---|
| 2310 | + txirq = platform_get_irq_optional(pdev, 1); |
|---|
| 2311 | + rtsirq = platform_get_irq_optional(pdev, 2); |
|---|
| 2217 | 2312 | |
|---|
| 2218 | 2313 | sport->port.dev = &pdev->dev; |
|---|
| 2219 | 2314 | sport->port.mapbase = res->start; |
|---|
| .. | .. |
|---|
| 2222 | 2317 | sport->port.iotype = UPIO_MEM; |
|---|
| 2223 | 2318 | sport->port.irq = rxirq; |
|---|
| 2224 | 2319 | sport->port.fifosize = 32; |
|---|
| 2320 | + sport->port.has_sysrq = IS_ENABLED(CONFIG_SERIAL_IMX_CONSOLE); |
|---|
| 2225 | 2321 | sport->port.ops = &imx_uart_pops; |
|---|
| 2226 | 2322 | sport->port.rs485_config = imx_uart_rs485_config; |
|---|
| 2227 | 2323 | sport->port.flags = UPF_BOOT_AUTOCONF; |
|---|
| .. | .. |
|---|
| 2261 | 2357 | sport->ucr4 = readl(sport->port.membase + UCR4); |
|---|
| 2262 | 2358 | sport->ufcr = readl(sport->port.membase + UFCR); |
|---|
| 2263 | 2359 | |
|---|
| 2264 | | - uart_get_rs485_mode(&pdev->dev, &sport->port.rs485); |
|---|
| 2360 | + ret = uart_get_rs485_mode(&sport->port); |
|---|
| 2361 | + if (ret) { |
|---|
| 2362 | + clk_disable_unprepare(sport->clk_ipg); |
|---|
| 2363 | + return ret; |
|---|
| 2364 | + } |
|---|
| 2265 | 2365 | |
|---|
| 2266 | 2366 | if (sport->port.rs485.flags & SER_RS485_ENABLED && |
|---|
| 2267 | 2367 | (!sport->have_rtscts && !sport->have_rtsgpio)) |
|---|
| .. | .. |
|---|
| 2279 | 2379 | dev_err(&pdev->dev, |
|---|
| 2280 | 2380 | "low-active RTS not possible when receiver is off, enabling receiver\n"); |
|---|
| 2281 | 2381 | |
|---|
| 2282 | | - imx_uart_rs485_config(&sport->port, &sport->port.rs485); |
|---|
| 2283 | | - |
|---|
| 2284 | 2382 | /* Disable interrupts before requesting them */ |
|---|
| 2285 | 2383 | ucr1 = imx_uart_readl(sport, UCR1); |
|---|
| 2286 | | - ucr1 &= ~(UCR1_ADEN | UCR1_TRDYEN | UCR1_IDEN | UCR1_RRDYEN | |
|---|
| 2287 | | - UCR1_TXMPTYEN | UCR1_RTSDEN); |
|---|
| 2384 | + ucr1 &= ~(UCR1_ADEN | UCR1_TRDYEN | UCR1_IDEN | UCR1_RRDYEN | UCR1_RTSDEN); |
|---|
| 2288 | 2385 | imx_uart_writel(sport, ucr1, UCR1); |
|---|
| 2289 | 2386 | |
|---|
| 2290 | 2387 | if (!imx_uart_is_imx1(sport) && sport->dte_mode) { |
|---|
| .. | .. |
|---|
| 2319 | 2416 | } |
|---|
| 2320 | 2417 | |
|---|
| 2321 | 2418 | clk_disable_unprepare(sport->clk_ipg); |
|---|
| 2419 | + |
|---|
| 2420 | + hrtimer_init(&sport->trigger_start_tx, CLOCK_MONOTONIC, HRTIMER_MODE_REL); |
|---|
| 2421 | + hrtimer_init(&sport->trigger_stop_tx, CLOCK_MONOTONIC, HRTIMER_MODE_REL); |
|---|
| 2422 | + sport->trigger_start_tx.function = imx_trigger_start_tx; |
|---|
| 2423 | + sport->trigger_stop_tx.function = imx_trigger_stop_tx; |
|---|
| 2322 | 2424 | |
|---|
| 2323 | 2425 | /* |
|---|
| 2324 | 2426 | * Allocate the IRQ(s) i.MX1 has three interrupts whereas later |
|---|
| .. | .. |
|---|
| 2373 | 2475 | |
|---|
| 2374 | 2476 | static void imx_uart_restore_context(struct imx_port *sport) |
|---|
| 2375 | 2477 | { |
|---|
| 2376 | | - if (!sport->context_saved) |
|---|
| 2478 | + unsigned long flags; |
|---|
| 2479 | + |
|---|
| 2480 | + spin_lock_irqsave(&sport->port.lock, flags); |
|---|
| 2481 | + if (!sport->context_saved) { |
|---|
| 2482 | + spin_unlock_irqrestore(&sport->port.lock, flags); |
|---|
| 2377 | 2483 | return; |
|---|
| 2484 | + } |
|---|
| 2378 | 2485 | |
|---|
| 2379 | 2486 | imx_uart_writel(sport, sport->saved_reg[4], UFCR); |
|---|
| 2380 | 2487 | imx_uart_writel(sport, sport->saved_reg[5], UESC); |
|---|
| .. | .. |
|---|
| 2387 | 2494 | imx_uart_writel(sport, sport->saved_reg[2], UCR3); |
|---|
| 2388 | 2495 | imx_uart_writel(sport, sport->saved_reg[3], UCR4); |
|---|
| 2389 | 2496 | sport->context_saved = false; |
|---|
| 2497 | + spin_unlock_irqrestore(&sport->port.lock, flags); |
|---|
| 2390 | 2498 | } |
|---|
| 2391 | 2499 | |
|---|
| 2392 | 2500 | static void imx_uart_save_context(struct imx_port *sport) |
|---|
| 2393 | 2501 | { |
|---|
| 2502 | + unsigned long flags; |
|---|
| 2503 | + |
|---|
| 2394 | 2504 | /* Save necessary regs */ |
|---|
| 2505 | + spin_lock_irqsave(&sport->port.lock, flags); |
|---|
| 2395 | 2506 | sport->saved_reg[0] = imx_uart_readl(sport, UCR1); |
|---|
| 2396 | 2507 | sport->saved_reg[1] = imx_uart_readl(sport, UCR2); |
|---|
| 2397 | 2508 | sport->saved_reg[2] = imx_uart_readl(sport, UCR3); |
|---|
| .. | .. |
|---|
| 2403 | 2514 | sport->saved_reg[8] = imx_uart_readl(sport, UBMR); |
|---|
| 2404 | 2515 | sport->saved_reg[9] = imx_uart_readl(sport, IMX21_UTS); |
|---|
| 2405 | 2516 | sport->context_saved = true; |
|---|
| 2517 | + spin_unlock_irqrestore(&sport->port.lock, flags); |
|---|
| 2406 | 2518 | } |
|---|
| 2407 | 2519 | |
|---|
| 2408 | 2520 | static void imx_uart_enable_wakeup(struct imx_port *sport, bool on) |
|---|
| .. | .. |
|---|
| 2436 | 2548 | |
|---|
| 2437 | 2549 | clk_disable(sport->clk_ipg); |
|---|
| 2438 | 2550 | |
|---|
| 2551 | + pinctrl_pm_select_sleep_state(dev); |
|---|
| 2552 | + |
|---|
| 2439 | 2553 | return 0; |
|---|
| 2440 | 2554 | } |
|---|
| 2441 | 2555 | |
|---|
| .. | .. |
|---|
| 2443 | 2557 | { |
|---|
| 2444 | 2558 | struct imx_port *sport = dev_get_drvdata(dev); |
|---|
| 2445 | 2559 | int ret; |
|---|
| 2560 | + |
|---|
| 2561 | + pinctrl_pm_select_default_state(dev); |
|---|
| 2446 | 2562 | |
|---|
| 2447 | 2563 | ret = clk_enable(sport->clk_ipg); |
|---|
| 2448 | 2564 | if (ret) |
|---|
| .. | .. |
|---|
| 2510 | 2626 | .suspend_noirq = imx_uart_suspend_noirq, |
|---|
| 2511 | 2627 | .resume_noirq = imx_uart_resume_noirq, |
|---|
| 2512 | 2628 | .freeze_noirq = imx_uart_suspend_noirq, |
|---|
| 2629 | + .thaw_noirq = imx_uart_resume_noirq, |
|---|
| 2513 | 2630 | .restore_noirq = imx_uart_resume_noirq, |
|---|
| 2514 | 2631 | .suspend = imx_uart_suspend, |
|---|
| 2515 | 2632 | .resume = imx_uart_resume, |
|---|