| .. | .. |
|---|
| 2 | 2 | /* |
|---|
| 3 | 3 | *Copyright (C) 2011 LAPIS Semiconductor Co., Ltd. |
|---|
| 4 | 4 | */ |
|---|
| 5 | | -#if defined(CONFIG_SERIAL_PCH_UART_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) |
|---|
| 6 | | -#define SUPPORT_SYSRQ |
|---|
| 7 | | -#endif |
|---|
| 8 | 5 | #include <linux/kernel.h> |
|---|
| 9 | 6 | #include <linux/serial_reg.h> |
|---|
| 10 | 7 | #include <linux/slab.h> |
|---|
| .. | .. |
|---|
| 313 | 310 | if (!buf) |
|---|
| 314 | 311 | return 0; |
|---|
| 315 | 312 | |
|---|
| 316 | | - len += snprintf(buf + len, PCH_REGS_BUFSIZE - len, |
|---|
| 313 | + len += scnprintf(buf + len, PCH_REGS_BUFSIZE - len, |
|---|
| 317 | 314 | "PCH EG20T port[%d] regs:\n", priv->port.line); |
|---|
| 318 | 315 | |
|---|
| 319 | | - len += snprintf(buf + len, PCH_REGS_BUFSIZE - len, |
|---|
| 316 | + len += scnprintf(buf + len, PCH_REGS_BUFSIZE - len, |
|---|
| 320 | 317 | "=================================\n"); |
|---|
| 321 | | - len += snprintf(buf + len, PCH_REGS_BUFSIZE - len, |
|---|
| 318 | + len += scnprintf(buf + len, PCH_REGS_BUFSIZE - len, |
|---|
| 322 | 319 | "IER: \t0x%02x\n", ioread8(priv->membase + UART_IER)); |
|---|
| 323 | | - len += snprintf(buf + len, PCH_REGS_BUFSIZE - len, |
|---|
| 320 | + len += scnprintf(buf + len, PCH_REGS_BUFSIZE - len, |
|---|
| 324 | 321 | "IIR: \t0x%02x\n", ioread8(priv->membase + UART_IIR)); |
|---|
| 325 | | - len += snprintf(buf + len, PCH_REGS_BUFSIZE - len, |
|---|
| 322 | + len += scnprintf(buf + len, PCH_REGS_BUFSIZE - len, |
|---|
| 326 | 323 | "LCR: \t0x%02x\n", ioread8(priv->membase + UART_LCR)); |
|---|
| 327 | | - len += snprintf(buf + len, PCH_REGS_BUFSIZE - len, |
|---|
| 324 | + len += scnprintf(buf + len, PCH_REGS_BUFSIZE - len, |
|---|
| 328 | 325 | "MCR: \t0x%02x\n", ioread8(priv->membase + UART_MCR)); |
|---|
| 329 | | - len += snprintf(buf + len, PCH_REGS_BUFSIZE - len, |
|---|
| 326 | + len += scnprintf(buf + len, PCH_REGS_BUFSIZE - len, |
|---|
| 330 | 327 | "LSR: \t0x%02x\n", ioread8(priv->membase + UART_LSR)); |
|---|
| 331 | | - len += snprintf(buf + len, PCH_REGS_BUFSIZE - len, |
|---|
| 328 | + len += scnprintf(buf + len, PCH_REGS_BUFSIZE - len, |
|---|
| 332 | 329 | "MSR: \t0x%02x\n", ioread8(priv->membase + UART_MSR)); |
|---|
| 333 | | - len += snprintf(buf + len, PCH_REGS_BUFSIZE - len, |
|---|
| 330 | + len += scnprintf(buf + len, PCH_REGS_BUFSIZE - len, |
|---|
| 334 | 331 | "BRCSR: \t0x%02x\n", |
|---|
| 335 | 332 | ioread8(priv->membase + PCH_UART_BRCSR)); |
|---|
| 336 | 333 | |
|---|
| 337 | 334 | lcr = ioread8(priv->membase + UART_LCR); |
|---|
| 338 | 335 | iowrite8(PCH_UART_LCR_DLAB, priv->membase + UART_LCR); |
|---|
| 339 | | - len += snprintf(buf + len, PCH_REGS_BUFSIZE - len, |
|---|
| 336 | + len += scnprintf(buf + len, PCH_REGS_BUFSIZE - len, |
|---|
| 340 | 337 | "DLL: \t0x%02x\n", ioread8(priv->membase + UART_DLL)); |
|---|
| 341 | | - len += snprintf(buf + len, PCH_REGS_BUFSIZE - len, |
|---|
| 338 | + len += scnprintf(buf + len, PCH_REGS_BUFSIZE - len, |
|---|
| 342 | 339 | "DLM: \t0x%02x\n", ioread8(priv->membase + UART_DLM)); |
|---|
| 343 | 340 | iowrite8(lcr, priv->membase + UART_LCR); |
|---|
| 344 | 341 | |
|---|
| .. | .. |
|---|
| 587 | 584 | if (uart_handle_break(port)) |
|---|
| 588 | 585 | continue; |
|---|
| 589 | 586 | } |
|---|
| 590 | | -#ifdef SUPPORT_SYSRQ |
|---|
| 591 | | - if (port->sysrq) { |
|---|
| 592 | | - if (uart_handle_sysrq_char(port, rbr)) |
|---|
| 593 | | - continue; |
|---|
| 594 | | - } |
|---|
| 595 | | -#endif |
|---|
| 587 | + if (uart_handle_sysrq_char(port, rbr)) |
|---|
| 588 | + continue; |
|---|
| 596 | 589 | |
|---|
| 597 | 590 | buf[i++] = rbr; |
|---|
| 598 | 591 | } |
|---|
| .. | .. |
|---|
| 633 | 626 | tty_flip_buffer_push(tport); |
|---|
| 634 | 627 | |
|---|
| 635 | 628 | return 0; |
|---|
| 636 | | -} |
|---|
| 637 | | - |
|---|
| 638 | | -static int pop_tx_x(struct eg20t_port *priv, unsigned char *buf) |
|---|
| 639 | | -{ |
|---|
| 640 | | - int ret = 0; |
|---|
| 641 | | - struct uart_port *port = &priv->port; |
|---|
| 642 | | - |
|---|
| 643 | | - if (port->x_char) { |
|---|
| 644 | | - dev_dbg(priv->port.dev, "%s:X character send %02x (%lu)\n", |
|---|
| 645 | | - __func__, port->x_char, jiffies); |
|---|
| 646 | | - buf[0] = port->x_char; |
|---|
| 647 | | - port->x_char = 0; |
|---|
| 648 | | - ret = 1; |
|---|
| 649 | | - } |
|---|
| 650 | | - |
|---|
| 651 | | - return ret; |
|---|
| 652 | 629 | } |
|---|
| 653 | 630 | |
|---|
| 654 | 631 | static int dma_push_rx(struct eg20t_port *priv, int size) |
|---|
| .. | .. |
|---|
| 734 | 711 | if (!chan) { |
|---|
| 735 | 712 | dev_err(priv->port.dev, "%s:dma_request_channel FAILS(Tx)\n", |
|---|
| 736 | 713 | __func__); |
|---|
| 714 | + pci_dev_put(dma_dev); |
|---|
| 737 | 715 | return; |
|---|
| 738 | 716 | } |
|---|
| 739 | 717 | priv->chan_tx = chan; |
|---|
| .. | .. |
|---|
| 750 | 728 | __func__); |
|---|
| 751 | 729 | dma_release_channel(priv->chan_tx); |
|---|
| 752 | 730 | priv->chan_tx = NULL; |
|---|
| 731 | + pci_dev_put(dma_dev); |
|---|
| 753 | 732 | return; |
|---|
| 754 | 733 | } |
|---|
| 755 | 734 | |
|---|
| .. | .. |
|---|
| 757 | 736 | priv->rx_buf_virt = dma_alloc_coherent(port->dev, port->fifosize, |
|---|
| 758 | 737 | &priv->rx_buf_dma, GFP_KERNEL); |
|---|
| 759 | 738 | priv->chan_rx = chan; |
|---|
| 739 | + |
|---|
| 740 | + pci_dev_put(dma_dev); |
|---|
| 760 | 741 | } |
|---|
| 761 | 742 | |
|---|
| 762 | 743 | static void pch_dma_rx_complete(void *arg) |
|---|
| .. | .. |
|---|
| 788 | 769 | } |
|---|
| 789 | 770 | xmit->tail &= UART_XMIT_SIZE - 1; |
|---|
| 790 | 771 | async_tx_ack(priv->desc_tx); |
|---|
| 791 | | - dma_unmap_sg(port->dev, sg, priv->orig_nent, DMA_TO_DEVICE); |
|---|
| 772 | + dma_unmap_sg(port->dev, priv->sg_tx_p, priv->orig_nent, DMA_TO_DEVICE); |
|---|
| 792 | 773 | priv->tx_dma_use = 0; |
|---|
| 793 | 774 | priv->nent = 0; |
|---|
| 794 | 775 | priv->orig_nent = 0; |
|---|
| .. | .. |
|---|
| 900 | 881 | |
|---|
| 901 | 882 | fifo_size = max(priv->fifo_size, 1); |
|---|
| 902 | 883 | tx_empty = 1; |
|---|
| 903 | | - if (pop_tx_x(priv, xmit->buf)) { |
|---|
| 904 | | - pch_uart_hal_write(priv, xmit->buf, 1); |
|---|
| 884 | + if (port->x_char) { |
|---|
| 885 | + pch_uart_hal_write(priv, &port->x_char, 1); |
|---|
| 905 | 886 | port->icount.tx++; |
|---|
| 887 | + port->x_char = 0; |
|---|
| 906 | 888 | tx_empty = 0; |
|---|
| 907 | 889 | fifo_size--; |
|---|
| 908 | 890 | } |
|---|
| .. | .. |
|---|
| 933 | 915 | struct scatterlist *sg; |
|---|
| 934 | 916 | int nent; |
|---|
| 935 | 917 | int fifo_size; |
|---|
| 936 | | - int tx_empty; |
|---|
| 937 | 918 | struct dma_async_tx_descriptor *desc; |
|---|
| 938 | 919 | int num; |
|---|
| 939 | 920 | int i; |
|---|
| .. | .. |
|---|
| 958 | 939 | } |
|---|
| 959 | 940 | |
|---|
| 960 | 941 | fifo_size = max(priv->fifo_size, 1); |
|---|
| 961 | | - tx_empty = 1; |
|---|
| 962 | | - if (pop_tx_x(priv, xmit->buf)) { |
|---|
| 963 | | - pch_uart_hal_write(priv, xmit->buf, 1); |
|---|
| 942 | + |
|---|
| 943 | + if (port->x_char) { |
|---|
| 944 | + pch_uart_hal_write(priv, &port->x_char, 1); |
|---|
| 964 | 945 | port->icount.tx++; |
|---|
| 965 | | - tx_empty = 0; |
|---|
| 946 | + port->x_char = 0; |
|---|
| 966 | 947 | fifo_size--; |
|---|
| 967 | 948 | } |
|---|
| 968 | 949 | |
|---|
| .. | .. |
|---|
| 991 | 972 | |
|---|
| 992 | 973 | priv->tx_dma_use = 1; |
|---|
| 993 | 974 | |
|---|
| 994 | | - priv->sg_tx_p = kcalloc(num, sizeof(struct scatterlist), GFP_ATOMIC); |
|---|
| 975 | + priv->sg_tx_p = kmalloc_array(num, sizeof(struct scatterlist), GFP_ATOMIC); |
|---|
| 995 | 976 | if (!priv->sg_tx_p) { |
|---|
| 996 | 977 | dev_err(priv->port.dev, "%s:kzalloc Failed\n", __func__); |
|---|
| 997 | 978 | return 0; |
|---|
| .. | .. |
|---|
| 1799 | 1780 | priv->port.flags = UPF_BOOT_AUTOCONF; |
|---|
| 1800 | 1781 | priv->port.fifosize = fifosize; |
|---|
| 1801 | 1782 | priv->port.line = board->line_no; |
|---|
| 1783 | + priv->port.has_sysrq = IS_ENABLED(CONFIG_SERIAL_PCH_UART_CONSOLE); |
|---|
| 1802 | 1784 | priv->trigger = PCH_UART_HAL_TRIGGER_M; |
|---|
| 1803 | 1785 | |
|---|
| 1804 | 1786 | snprintf(priv->irq_name, IRQ_NAME_SIZE, |
|---|
| .. | .. |
|---|
| 1866 | 1848 | kfree(priv); |
|---|
| 1867 | 1849 | return; |
|---|
| 1868 | 1850 | } |
|---|
| 1869 | | -#ifdef CONFIG_PM |
|---|
| 1870 | | -static int pch_uart_pci_suspend(struct pci_dev *pdev, pm_message_t state) |
|---|
| 1851 | + |
|---|
| 1852 | +static int __maybe_unused pch_uart_pci_suspend(struct device *dev) |
|---|
| 1871 | 1853 | { |
|---|
| 1872 | | - struct eg20t_port *priv = pci_get_drvdata(pdev); |
|---|
| 1854 | + struct eg20t_port *priv = dev_get_drvdata(dev); |
|---|
| 1873 | 1855 | |
|---|
| 1874 | 1856 | uart_suspend_port(&pch_uart_driver, &priv->port); |
|---|
| 1875 | 1857 | |
|---|
| 1876 | | - pci_save_state(pdev); |
|---|
| 1877 | | - pci_set_power_state(pdev, pci_choose_state(pdev, state)); |
|---|
| 1878 | 1858 | return 0; |
|---|
| 1879 | 1859 | } |
|---|
| 1880 | 1860 | |
|---|
| 1881 | | -static int pch_uart_pci_resume(struct pci_dev *pdev) |
|---|
| 1861 | +static int __maybe_unused pch_uart_pci_resume(struct device *dev) |
|---|
| 1882 | 1862 | { |
|---|
| 1883 | | - struct eg20t_port *priv = pci_get_drvdata(pdev); |
|---|
| 1884 | | - int ret; |
|---|
| 1885 | | - |
|---|
| 1886 | | - pci_set_power_state(pdev, PCI_D0); |
|---|
| 1887 | | - pci_restore_state(pdev); |
|---|
| 1888 | | - |
|---|
| 1889 | | - ret = pci_enable_device(pdev); |
|---|
| 1890 | | - if (ret) { |
|---|
| 1891 | | - dev_err(&pdev->dev, |
|---|
| 1892 | | - "%s-pci_enable_device failed(ret=%d) ", __func__, ret); |
|---|
| 1893 | | - return ret; |
|---|
| 1894 | | - } |
|---|
| 1863 | + struct eg20t_port *priv = dev_get_drvdata(dev); |
|---|
| 1895 | 1864 | |
|---|
| 1896 | 1865 | uart_resume_port(&pch_uart_driver, &priv->port); |
|---|
| 1897 | 1866 | |
|---|
| 1898 | 1867 | return 0; |
|---|
| 1899 | 1868 | } |
|---|
| 1900 | | -#else |
|---|
| 1901 | | -#define pch_uart_pci_suspend NULL |
|---|
| 1902 | | -#define pch_uart_pci_resume NULL |
|---|
| 1903 | | -#endif |
|---|
| 1904 | 1869 | |
|---|
| 1905 | 1870 | static const struct pci_device_id pch_uart_pci_id[] = { |
|---|
| 1906 | 1871 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x8811), |
|---|
| .. | .. |
|---|
| 1954 | 1919 | return ret; |
|---|
| 1955 | 1920 | } |
|---|
| 1956 | 1921 | |
|---|
| 1922 | +static SIMPLE_DEV_PM_OPS(pch_uart_pci_pm_ops, |
|---|
| 1923 | + pch_uart_pci_suspend, |
|---|
| 1924 | + pch_uart_pci_resume); |
|---|
| 1925 | + |
|---|
| 1957 | 1926 | static struct pci_driver pch_uart_pci_driver = { |
|---|
| 1958 | 1927 | .name = "pch_uart", |
|---|
| 1959 | 1928 | .id_table = pch_uart_pci_id, |
|---|
| 1960 | 1929 | .probe = pch_uart_pci_probe, |
|---|
| 1961 | 1930 | .remove = pch_uart_pci_remove, |
|---|
| 1962 | | - .suspend = pch_uart_pci_suspend, |
|---|
| 1963 | | - .resume = pch_uart_pci_resume, |
|---|
| 1931 | + .driver.pm = &pch_uart_pci_pm_ops, |
|---|
| 1964 | 1932 | }; |
|---|
| 1965 | 1933 | |
|---|
| 1966 | 1934 | static int __init pch_uart_module_init(void) |
|---|