Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

serial: fsl_lpuart: DMA support for 32-bit variant

Add DMA support for 32-bit variant of the LPUART, such as LS1021A.

Signed-off-by: Tomonori Sakita <tomonori.sakita@sord.co.jp>
Signed-off-by: Atsushi Nemoto <atsushi.nemoto@sord.co.jp>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Atsushi Nemoto and committed by
Greg Kroah-Hartman
42b68768 7c0cca7c

+163 -29
+163 -29
drivers/tty/serial/fsl_lpuart.c
··· 426 426 spin_unlock_irqrestore(&sport->port.lock, flags); 427 427 } 428 428 429 + static dma_addr_t lpuart_dma_datareg_addr(struct lpuart_port *sport) 430 + { 431 + switch (sport->port.iotype) { 432 + case UPIO_MEM32: 433 + return sport->port.mapbase + UARTDATA; 434 + case UPIO_MEM32BE: 435 + return sport->port.mapbase + UARTDATA + sizeof(u32) - 1; 436 + } 437 + return sport->port.mapbase + UARTDR; 438 + } 439 + 429 440 static int lpuart_dma_tx_request(struct uart_port *port) 430 441 { 431 442 struct lpuart_port *sport = container_of(port, ··· 444 433 struct dma_slave_config dma_tx_sconfig = {}; 445 434 int ret; 446 435 447 - dma_tx_sconfig.dst_addr = sport->port.mapbase + UARTDR; 436 + dma_tx_sconfig.dst_addr = lpuart_dma_datareg_addr(sport); 448 437 dma_tx_sconfig.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; 449 438 dma_tx_sconfig.dst_maxburst = 1; 450 439 dma_tx_sconfig.direction = DMA_MEM_TO_DEV; ··· 647 636 static void lpuart32_start_tx(struct uart_port *port) 648 637 { 649 638 struct lpuart_port *sport = container_of(port, struct lpuart_port, port); 639 + struct circ_buf *xmit = &sport->port.state->xmit; 650 640 unsigned long temp; 651 641 652 - temp = lpuart32_read(port, UARTCTRL); 653 - lpuart32_write(port, temp | UARTCTRL_TIE, UARTCTRL); 642 + if (sport->lpuart_dma_tx_use) { 643 + if (!uart_circ_empty(xmit) && !uart_tx_stopped(port)) 644 + lpuart_dma_tx(sport); 645 + } else { 646 + temp = lpuart32_read(port, UARTCTRL); 647 + lpuart32_write(port, temp | UARTCTRL_TIE, UARTCTRL); 654 648 655 - if (lpuart32_read(port, UARTSTAT) & UARTSTAT_TDRE) 656 - lpuart32_transmit_buffer(sport); 649 + if (lpuart32_read(port, UARTSTAT) & UARTSTAT_TDRE) 650 + lpuart32_transmit_buffer(sport); 651 + } 657 652 } 658 653 659 654 /* return TIOCSER_TEMT when transmitter is not busy */ ··· 889 872 rxcount = lpuart32_read(&sport->port, UARTWATER); 890 873 rxcount = rxcount >> UARTWATER_RXCNT_OFF; 891 874 892 - if (sts & UARTSTAT_RDRF || rxcount > 0) 875 + if ((sts & UARTSTAT_RDRF || rxcount > 0) && !sport->lpuart_dma_rx_use) 893 876 lpuart32_rxint(irq, dev_id); 894 877 895 - if ((sts & UARTSTAT_TDRE) && 896 - !(lpuart32_read(&sport->port, UARTBAUD) & UARTBAUD_TDMAE)) 878 + if ((sts & UARTSTAT_TDRE) && !sport->lpuart_dma_tx_use) 897 879 lpuart_txint(irq, dev_id); 898 880 899 881 lpuart32_write(&sport->port, sts, UARTSTAT); ··· 907 891 struct circ_buf *ring = &sport->rx_ring; 908 892 unsigned long flags; 909 893 int count = 0; 910 - unsigned char sr; 911 894 912 - sr = readb(sport->port.membase + UARTSR1); 895 + if (lpuart_is_32(sport)) { 896 + unsigned long sr = lpuart32_read(&sport->port, UARTSTAT); 913 897 914 - if (sr & (UARTSR1_PE | UARTSR1_FE)) { 915 - /* Read DR to clear the error flags */ 916 - readb(sport->port.membase + UARTDR); 898 + if (sr & (UARTSTAT_PE | UARTSTAT_FE)) { 899 + /* Read DR to clear the error flags */ 900 + lpuart32_read(&sport->port, UARTDATA); 917 901 918 - if (sr & UARTSR1_PE) 919 - sport->port.icount.parity++; 920 - else if (sr & UARTSR1_FE) 921 - sport->port.icount.frame++; 902 + if (sr & UARTSTAT_PE) 903 + sport->port.icount.parity++; 904 + else if (sr & UARTSTAT_FE) 905 + sport->port.icount.frame++; 906 + } 907 + } else { 908 + unsigned char sr = readb(sport->port.membase + UARTSR1); 909 + 910 + if (sr & (UARTSR1_PE | UARTSR1_FE)) { 911 + /* Read DR to clear the error flags */ 912 + readb(sport->port.membase + UARTDR); 913 + 914 + if (sr & UARTSR1_PE) 915 + sport->port.icount.parity++; 916 + else if (sr & UARTSR1_FE) 917 + sport->port.icount.frame++; 918 + } 922 919 } 923 920 924 921 async_tx_ack(sport->dma_rx_desc); ··· 1054 1025 return -EINVAL; 1055 1026 } 1056 1027 1057 - dma_rx_sconfig.src_addr = sport->port.mapbase + UARTDR; 1028 + dma_rx_sconfig.src_addr = lpuart_dma_datareg_addr(sport); 1058 1029 dma_rx_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; 1059 1030 dma_rx_sconfig.src_maxburst = 1; 1060 1031 dma_rx_sconfig.direction = DMA_DEV_TO_MEM; ··· 1082 1053 sport->dma_rx_cookie = dmaengine_submit(sport->dma_rx_desc); 1083 1054 dma_async_issue_pending(sport->dma_rx_chan); 1084 1055 1085 - writeb(readb(sport->port.membase + UARTCR5) | UARTCR5_RDMAS, 1086 - sport->port.membase + UARTCR5); 1056 + if (lpuart_is_32(sport)) { 1057 + unsigned long temp = lpuart32_read(&sport->port, UARTBAUD); 1058 + 1059 + lpuart32_write(&sport->port, temp | UARTBAUD_RDMAE, UARTBAUD); 1060 + } else { 1061 + writeb(readb(sport->port.membase + UARTCR5) | UARTCR5_RDMAS, 1062 + sport->port.membase + UARTCR5); 1063 + } 1087 1064 1088 1065 return 0; 1089 1066 } ··· 1389 1354 lpuart32_setup_watermark(sport); 1390 1355 1391 1356 temp = lpuart32_read(&sport->port, UARTCTRL); 1392 - temp |= (UARTCTRL_RIE | UARTCTRL_TIE | UARTCTRL_RE | UARTCTRL_TE); 1393 - temp |= UARTCTRL_ILIE; 1357 + temp |= UARTCTRL_RE | UARTCTRL_TE | UARTCTRL_ILIE; 1358 + lpuart32_write(&sport->port, temp, UARTCTRL); 1359 + 1360 + if (sport->dma_rx_chan && !lpuart_start_rx_dma(sport)) { 1361 + /* set Rx DMA timeout */ 1362 + sport->dma_rx_timeout = msecs_to_jiffies(DMA_RX_TIMEOUT); 1363 + if (!sport->dma_rx_timeout) 1364 + sport->dma_rx_timeout = 1; 1365 + 1366 + sport->lpuart_dma_rx_use = true; 1367 + rx_dma_timer_init(sport); 1368 + } else { 1369 + sport->lpuart_dma_rx_use = false; 1370 + } 1371 + 1372 + if (sport->dma_tx_chan && !lpuart_dma_tx_request(port)) { 1373 + init_waitqueue_head(&sport->dma_wait); 1374 + sport->lpuart_dma_tx_use = true; 1375 + temp = lpuart32_read(&sport->port, UARTBAUD); 1376 + lpuart32_write(&sport->port, temp | UARTBAUD_TDMAE, UARTBAUD); 1377 + } else { 1378 + sport->lpuart_dma_tx_use = false; 1379 + } 1380 + 1381 + if (sport->lpuart_dma_rx_use) { 1382 + /* RXWATER must be 0 */ 1383 + temp = lpuart32_read(&sport->port, UARTWATER); 1384 + temp &= ~(UARTWATER_WATER_MASK << UARTWATER_RXWATER_OFF); 1385 + lpuart32_write(&sport->port, temp, UARTWATER); 1386 + } 1387 + temp = lpuart32_read(&sport->port, UARTCTRL); 1388 + if (!sport->lpuart_dma_rx_use) 1389 + temp |= UARTCTRL_RIE; 1390 + if (!sport->lpuart_dma_tx_use) 1391 + temp |= UARTCTRL_TIE; 1394 1392 lpuart32_write(&sport->port, temp, UARTCTRL); 1395 1393 1396 1394 spin_unlock_irqrestore(&sport->port.lock, flags); ··· 1464 1396 1465 1397 static void lpuart32_shutdown(struct uart_port *port) 1466 1398 { 1399 + struct lpuart_port *sport = 1400 + container_of(port, struct lpuart_port, port); 1467 1401 unsigned long temp; 1468 1402 unsigned long flags; 1469 1403 ··· 1478 1408 lpuart32_write(port, temp, UARTCTRL); 1479 1409 1480 1410 spin_unlock_irqrestore(&port->lock, flags); 1411 + 1412 + if (sport->lpuart_dma_rx_use) { 1413 + del_timer_sync(&sport->lpuart_timer); 1414 + lpuart_dma_rx_free(&sport->port); 1415 + } 1416 + 1417 + if (sport->lpuart_dma_tx_use) { 1418 + if (wait_event_interruptible(sport->dma_wait, 1419 + !sport->dma_tx_in_progress)) { 1420 + sport->dma_tx_in_progress = false; 1421 + dmaengine_terminate_all(sport->dma_tx_chan); 1422 + } 1423 + 1424 + lpuart32_stop_tx(port); 1425 + } 1481 1426 } 1482 1427 1483 1428 static void ··· 1718 1633 tmp &= ~UARTBAUD_SBR_MASK; 1719 1634 tmp |= sbr & UARTBAUD_SBR_MASK; 1720 1635 1721 - tmp &= ~(UARTBAUD_TDMAE | UARTBAUD_RDMAE); 1636 + if (!sport->lpuart_dma_rx_use) 1637 + tmp &= ~UARTBAUD_RDMAE; 1638 + if (!sport->lpuart_dma_tx_use) 1639 + tmp &= ~UARTBAUD_TDMAE; 1722 1640 1723 1641 lpuart32_write(&sport->port, tmp, UARTBAUD); 1724 1642 } ··· 1799 1711 /* ask the core to calculate the divisor */ 1800 1712 baud = uart_get_baud_rate(port, termios, old, 50, port->uartclk / 4); 1801 1713 1714 + /* 1715 + * Need to update the Ring buffer length according to the selected 1716 + * baud rate and restart Rx DMA path. 1717 + * 1718 + * Since timer function acqures sport->port.lock, need to stop before 1719 + * acquring same lock because otherwise del_timer_sync() can deadlock. 1720 + */ 1721 + if (old && sport->lpuart_dma_rx_use) { 1722 + del_timer_sync(&sport->lpuart_timer); 1723 + lpuart_dma_rx_free(&sport->port); 1724 + } 1725 + 1802 1726 spin_lock_irqsave(&sport->port.lock, flags); 1803 1727 1804 1728 sport->port.read_status_mask = 0; ··· 1848 1748 lpuart32_write(&sport->port, modem, UARTMODIR); 1849 1749 lpuart32_write(&sport->port, ctrl, UARTCTRL); 1850 1750 /* restore control register */ 1751 + 1752 + if (old && sport->lpuart_dma_rx_use) { 1753 + if (!lpuart_start_rx_dma(sport)) 1754 + rx_dma_timer_init(sport); 1755 + else 1756 + sport->lpuart_dma_rx_use = false; 1757 + } 1851 1758 1852 1759 spin_unlock_irqrestore(&sport->port.lock, flags); 1853 1760 } ··· 2425 2318 } 2426 2319 2427 2320 /* Disable Rx DMA to use UART port as wakeup source */ 2428 - writeb(readb(sport->port.membase + UARTCR5) & ~UARTCR5_RDMAS, 2429 - sport->port.membase + UARTCR5); 2321 + if (lpuart_is_32(sport)) { 2322 + temp = lpuart32_read(&sport->port, UARTBAUD); 2323 + lpuart32_write(&sport->port, temp & ~UARTBAUD_RDMAE, 2324 + UARTBAUD); 2325 + } else { 2326 + writeb(readb(sport->port.membase + UARTCR5) & 2327 + ~UARTCR5_RDMAS, sport->port.membase + UARTCR5); 2328 + } 2430 2329 } 2431 2330 2432 2331 if (sport->lpuart_dma_tx_use) { ··· 2458 2345 if (lpuart_is_32(sport)) { 2459 2346 lpuart32_setup_watermark(sport); 2460 2347 temp = lpuart32_read(&sport->port, UARTCTRL); 2461 - temp |= (UARTCTRL_RIE | UARTCTRL_TIE | UARTCTRL_RE | 2462 - UARTCTRL_TE | UARTCTRL_ILIE); 2348 + temp |= UARTCTRL_RE | UARTCTRL_TE | UARTCTRL_ILIE; 2463 2349 lpuart32_write(&sport->port, temp, UARTCTRL); 2464 2350 } else { 2465 2351 lpuart_setup_watermark(sport); ··· 2477 2365 } 2478 2366 2479 2367 if (sport->dma_tx_chan && !lpuart_dma_tx_request(&sport->port)) { 2480 - init_waitqueue_head(&sport->dma_wait); 2481 - sport->lpuart_dma_tx_use = true; 2368 + init_waitqueue_head(&sport->dma_wait); 2369 + sport->lpuart_dma_tx_use = true; 2370 + if (lpuart_is_32(sport)) { 2371 + temp = lpuart32_read(&sport->port, UARTBAUD); 2372 + lpuart32_write(&sport->port, 2373 + temp | UARTBAUD_TDMAE, UARTBAUD); 2374 + } else { 2482 2375 writeb(readb(sport->port.membase + UARTCR5) | 2483 2376 UARTCR5_TDMAS, sport->port.membase + UARTCR5); 2377 + } 2484 2378 } else { 2485 2379 sport->lpuart_dma_tx_use = false; 2380 + } 2381 + 2382 + if (lpuart_is_32(sport)) { 2383 + if (sport->lpuart_dma_rx_use) { 2384 + /* RXWATER must be 0 */ 2385 + temp = lpuart32_read(&sport->port, UARTWATER); 2386 + temp &= ~(UARTWATER_WATER_MASK << 2387 + UARTWATER_RXWATER_OFF); 2388 + lpuart32_write(&sport->port, temp, UARTWATER); 2389 + } 2390 + temp = lpuart32_read(&sport->port, UARTCTRL); 2391 + if (!sport->lpuart_dma_rx_use) 2392 + temp |= UARTCTRL_RIE; 2393 + if (!sport->lpuart_dma_tx_use) 2394 + temp |= UARTCTRL_TIE; 2395 + lpuart32_write(&sport->port, temp, UARTCTRL); 2486 2396 } 2487 2397 2488 2398 uart_resume_port(&lpuart_reg, &sport->port);