| .. | .. |
|---|
| 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) |
|---|
| .. | .. |
|---|
| 900 | 877 | |
|---|
| 901 | 878 | fifo_size = max(priv->fifo_size, 1); |
|---|
| 902 | 879 | tx_empty = 1; |
|---|
| 903 | | - if (pop_tx_x(priv, xmit->buf)) { |
|---|
| 904 | | - pch_uart_hal_write(priv, xmit->buf, 1); |
|---|
| 880 | + if (port->x_char) { |
|---|
| 881 | + pch_uart_hal_write(priv, &port->x_char, 1); |
|---|
| 905 | 882 | port->icount.tx++; |
|---|
| 883 | + port->x_char = 0; |
|---|
| 906 | 884 | tx_empty = 0; |
|---|
| 907 | 885 | fifo_size--; |
|---|
| 908 | 886 | } |
|---|
| .. | .. |
|---|
| 933 | 911 | struct scatterlist *sg; |
|---|
| 934 | 912 | int nent; |
|---|
| 935 | 913 | int fifo_size; |
|---|
| 936 | | - int tx_empty; |
|---|
| 937 | 914 | struct dma_async_tx_descriptor *desc; |
|---|
| 938 | 915 | int num; |
|---|
| 939 | 916 | int i; |
|---|
| .. | .. |
|---|
| 958 | 935 | } |
|---|
| 959 | 936 | |
|---|
| 960 | 937 | 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); |
|---|
| 938 | + |
|---|
| 939 | + if (port->x_char) { |
|---|
| 940 | + pch_uart_hal_write(priv, &port->x_char, 1); |
|---|
| 964 | 941 | port->icount.tx++; |
|---|
| 965 | | - tx_empty = 0; |
|---|
| 942 | + port->x_char = 0; |
|---|
| 966 | 943 | fifo_size--; |
|---|
| 967 | 944 | } |
|---|
| 968 | 945 | |
|---|
| .. | .. |
|---|
| 991 | 968 | |
|---|
| 992 | 969 | priv->tx_dma_use = 1; |
|---|
| 993 | 970 | |
|---|
| 994 | | - priv->sg_tx_p = kcalloc(num, sizeof(struct scatterlist), GFP_ATOMIC); |
|---|
| 971 | + priv->sg_tx_p = kmalloc_array(num, sizeof(struct scatterlist), GFP_ATOMIC); |
|---|
| 995 | 972 | if (!priv->sg_tx_p) { |
|---|
| 996 | 973 | dev_err(priv->port.dev, "%s:kzalloc Failed\n", __func__); |
|---|
| 997 | 974 | return 0; |
|---|
| .. | .. |
|---|
| 1799 | 1776 | priv->port.flags = UPF_BOOT_AUTOCONF; |
|---|
| 1800 | 1777 | priv->port.fifosize = fifosize; |
|---|
| 1801 | 1778 | priv->port.line = board->line_no; |
|---|
| 1779 | + priv->port.has_sysrq = IS_ENABLED(CONFIG_SERIAL_PCH_UART_CONSOLE); |
|---|
| 1802 | 1780 | priv->trigger = PCH_UART_HAL_TRIGGER_M; |
|---|
| 1803 | 1781 | |
|---|
| 1804 | 1782 | snprintf(priv->irq_name, IRQ_NAME_SIZE, |
|---|
| .. | .. |
|---|
| 1866 | 1844 | kfree(priv); |
|---|
| 1867 | 1845 | return; |
|---|
| 1868 | 1846 | } |
|---|
| 1869 | | -#ifdef CONFIG_PM |
|---|
| 1870 | | -static int pch_uart_pci_suspend(struct pci_dev *pdev, pm_message_t state) |
|---|
| 1847 | + |
|---|
| 1848 | +static int __maybe_unused pch_uart_pci_suspend(struct device *dev) |
|---|
| 1871 | 1849 | { |
|---|
| 1872 | | - struct eg20t_port *priv = pci_get_drvdata(pdev); |
|---|
| 1850 | + struct eg20t_port *priv = dev_get_drvdata(dev); |
|---|
| 1873 | 1851 | |
|---|
| 1874 | 1852 | uart_suspend_port(&pch_uart_driver, &priv->port); |
|---|
| 1875 | 1853 | |
|---|
| 1876 | | - pci_save_state(pdev); |
|---|
| 1877 | | - pci_set_power_state(pdev, pci_choose_state(pdev, state)); |
|---|
| 1878 | 1854 | return 0; |
|---|
| 1879 | 1855 | } |
|---|
| 1880 | 1856 | |
|---|
| 1881 | | -static int pch_uart_pci_resume(struct pci_dev *pdev) |
|---|
| 1857 | +static int __maybe_unused pch_uart_pci_resume(struct device *dev) |
|---|
| 1882 | 1858 | { |
|---|
| 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 | | - } |
|---|
| 1859 | + struct eg20t_port *priv = dev_get_drvdata(dev); |
|---|
| 1895 | 1860 | |
|---|
| 1896 | 1861 | uart_resume_port(&pch_uart_driver, &priv->port); |
|---|
| 1897 | 1862 | |
|---|
| 1898 | 1863 | return 0; |
|---|
| 1899 | 1864 | } |
|---|
| 1900 | | -#else |
|---|
| 1901 | | -#define pch_uart_pci_suspend NULL |
|---|
| 1902 | | -#define pch_uart_pci_resume NULL |
|---|
| 1903 | | -#endif |
|---|
| 1904 | 1865 | |
|---|
| 1905 | 1866 | static const struct pci_device_id pch_uart_pci_id[] = { |
|---|
| 1906 | 1867 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x8811), |
|---|
| .. | .. |
|---|
| 1954 | 1915 | return ret; |
|---|
| 1955 | 1916 | } |
|---|
| 1956 | 1917 | |
|---|
| 1918 | +static SIMPLE_DEV_PM_OPS(pch_uart_pci_pm_ops, |
|---|
| 1919 | + pch_uart_pci_suspend, |
|---|
| 1920 | + pch_uart_pci_resume); |
|---|
| 1921 | + |
|---|
| 1957 | 1922 | static struct pci_driver pch_uart_pci_driver = { |
|---|
| 1958 | 1923 | .name = "pch_uart", |
|---|
| 1959 | 1924 | .id_table = pch_uart_pci_id, |
|---|
| 1960 | 1925 | .probe = pch_uart_pci_probe, |
|---|
| 1961 | 1926 | .remove = pch_uart_pci_remove, |
|---|
| 1962 | | - .suspend = pch_uart_pci_suspend, |
|---|
| 1963 | | - .resume = pch_uart_pci_resume, |
|---|
| 1927 | + .driver.pm = &pch_uart_pci_pm_ops, |
|---|
| 1964 | 1928 | }; |
|---|
| 1965 | 1929 | |
|---|
| 1966 | 1930 | static int __init pch_uart_module_init(void) |
|---|