.. | .. |
---|
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) |
---|