LCOV - code coverage report
Current view: top level - drivers/tty/serial/8250 - 8250.h (source / functions) Hit Total Coverage
Test: combined.info Lines: 40 65 61.5 %
Date: 2022-04-01 14:17:54 Functions: 2 3 66.7 %
Branches: 13 43 30.2 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: GPL-2.0+
       2                 :            : /*
       3                 :            :  *  Driver for 8250/16550-type serial ports
       4                 :            :  *
       5                 :            :  *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
       6                 :            :  *
       7                 :            :  *  Copyright (C) 2001 Russell King.
       8                 :            :  */
       9                 :            : 
      10                 :            : #include <linux/serial_8250.h>
      11                 :            : #include <linux/serial_reg.h>
      12                 :            : #include <linux/dmaengine.h>
      13                 :            : 
      14                 :            : #include "../serial_mctrl_gpio.h"
      15                 :            : 
      16                 :            : struct uart_8250_dma {
      17                 :            :         int (*tx_dma)(struct uart_8250_port *p);
      18                 :            :         int (*rx_dma)(struct uart_8250_port *p);
      19                 :            : 
      20                 :            :         /* Filter function */
      21                 :            :         dma_filter_fn           fn;
      22                 :            :         /* Parameter to the filter function */
      23                 :            :         void                    *rx_param;
      24                 :            :         void                    *tx_param;
      25                 :            : 
      26                 :            :         struct dma_slave_config rxconf;
      27                 :            :         struct dma_slave_config txconf;
      28                 :            : 
      29                 :            :         struct dma_chan         *rxchan;
      30                 :            :         struct dma_chan         *txchan;
      31                 :            : 
      32                 :            :         /* Device address base for DMA operations */
      33                 :            :         phys_addr_t             rx_dma_addr;
      34                 :            :         phys_addr_t             tx_dma_addr;
      35                 :            : 
      36                 :            :         /* DMA address of the buffer in memory */
      37                 :            :         dma_addr_t              rx_addr;
      38                 :            :         dma_addr_t              tx_addr;
      39                 :            : 
      40                 :            :         dma_cookie_t            rx_cookie;
      41                 :            :         dma_cookie_t            tx_cookie;
      42                 :            : 
      43                 :            :         void                    *rx_buf;
      44                 :            : 
      45                 :            :         size_t                  rx_size;
      46                 :            :         size_t                  tx_size;
      47                 :            : 
      48                 :            :         unsigned char           tx_running;
      49                 :            :         unsigned char           tx_err;
      50                 :            :         unsigned char           rx_running;
      51                 :            : };
      52                 :            : 
      53                 :            : struct old_serial_port {
      54                 :            :         unsigned int uart;
      55                 :            :         unsigned int baud_base;
      56                 :            :         unsigned int port;
      57                 :            :         unsigned int irq;
      58                 :            :         upf_t        flags;
      59                 :            :         unsigned char io_type;
      60                 :            :         unsigned char __iomem *iomem_base;
      61                 :            :         unsigned short iomem_reg_shift;
      62                 :            : };
      63                 :            : 
      64                 :            : struct serial8250_config {
      65                 :            :         const char      *name;
      66                 :            :         unsigned short  fifo_size;
      67                 :            :         unsigned short  tx_loadsz;
      68                 :            :         unsigned char   fcr;
      69                 :            :         unsigned char   rxtrig_bytes[UART_FCR_R_TRIG_MAX_STATE];
      70                 :            :         unsigned int    flags;
      71                 :            : };
      72                 :            : 
      73                 :            : #define UART_CAP_FIFO   (1 << 8)  /* UART has FIFO */
      74                 :            : #define UART_CAP_EFR    (1 << 9)  /* UART has EFR */
      75                 :            : #define UART_CAP_SLEEP  (1 << 10) /* UART has IER sleep */
      76                 :            : #define UART_CAP_AFE    (1 << 11) /* MCR-based hw flow control */
      77                 :            : #define UART_CAP_UUE    (1 << 12) /* UART needs IER bit 6 set (Xscale) */
      78                 :            : #define UART_CAP_RTOIE  (1 << 13) /* UART needs IER bit 4 set (Xscale, Tegra) */
      79                 :            : #define UART_CAP_HFIFO  (1 << 14) /* UART has a "hidden" FIFO */
      80                 :            : #define UART_CAP_RPM    (1 << 15) /* Runtime PM is active while idle */
      81                 :            : #define UART_CAP_IRDA   (1 << 16) /* UART supports IrDA line discipline */
      82                 :            : #define UART_CAP_MINI   (1 << 17) /* Mini UART on BCM283X family lacks:
      83                 :            :                                          * STOP PARITY EPAR SPAR WLEN5 WLEN6
      84                 :            :                                          */
      85                 :            : 
      86                 :            : #define UART_BUG_QUOT   (1 << 0)  /* UART has buggy quot LSB */
      87                 :            : #define UART_BUG_TXEN   (1 << 1)  /* UART has buggy TX IIR status */
      88                 :            : #define UART_BUG_NOMSR  (1 << 2)  /* UART has buggy MSR status bits (Au1x00) */
      89                 :            : #define UART_BUG_THRE   (1 << 3)  /* UART has buggy THRE reassertion */
      90                 :            : #define UART_BUG_PARITY (1 << 4)  /* UART mishandles parity if FIFO enabled */
      91                 :            : 
      92                 :            : 
      93                 :            : #ifdef CONFIG_SERIAL_8250_SHARE_IRQ
      94                 :            : #define SERIAL8250_SHARE_IRQS 1
      95                 :            : #else
      96                 :            : #define SERIAL8250_SHARE_IRQS 0
      97                 :            : #endif
      98                 :            : 
      99                 :            : #define SERIAL8250_PORT_FLAGS(_base, _irq, _flags)              \
     100                 :            :         {                                                       \
     101                 :            :                 .iobase         = _base,                        \
     102                 :            :                 .irq            = _irq,                         \
     103                 :            :                 .uartclk        = 1843200,                      \
     104                 :            :                 .iotype         = UPIO_PORT,                    \
     105                 :            :                 .flags          = UPF_BOOT_AUTOCONF | (_flags), \
     106                 :            :         }
     107                 :            : 
     108                 :            : #define SERIAL8250_PORT(_base, _irq) SERIAL8250_PORT_FLAGS(_base, _irq, 0)
     109                 :            : 
     110                 :            : 
     111                 :     247379 : static inline int serial_in(struct uart_8250_port *up, int offset)
     112                 :            : {
     113   [ -  -  -  -  :     247368 :         return up->port.serial_in(&up->port, offset);
             -  -  -  +  
                      - ]
     114                 :            : }
     115                 :            : 
     116                 :      84832 : static inline void serial_out(struct uart_8250_port *up, int offset, int value)
     117                 :            : {
     118                 :      66055 :         up->port.serial_out(&up->port, offset, value);
     119                 :         33 : }
     120                 :            : 
     121                 :            : void serial8250_clear_and_reinit_fifos(struct uart_8250_port *p);
     122                 :            : 
     123                 :            : static inline int serial_dl_read(struct uart_8250_port *up)
     124                 :            : {
     125                 :            :         return up->dl_read(up);
     126                 :            : }
     127                 :            : 
     128                 :         22 : static inline void serial_dl_write(struct uart_8250_port *up, int value)
     129                 :            : {
     130                 :         22 :         up->dl_write(up, value);
     131                 :            : }
     132                 :            : 
     133                 :       9306 : static inline bool serial8250_set_THRI(struct uart_8250_port *up)
     134                 :            : {
     135         [ +  - ]:       9306 :         if (up->ier & UART_IER_THRI)
     136                 :            :                 return false;
     137                 :       9306 :         up->ier |= UART_IER_THRI;
     138                 :       9306 :         serial_out(up, UART_IER, up->ier);
     139         [ -  + ]:       9306 :         return true;
     140                 :            : }
     141                 :            : 
     142                 :       9306 : static inline bool serial8250_clear_THRI(struct uart_8250_port *up)
     143                 :            : {
     144         [ +  - ]:       9306 :         if (!(up->ier & UART_IER_THRI))
     145                 :            :                 return false;
     146                 :       9306 :         up->ier &= ~UART_IER_THRI;
     147                 :       9306 :         serial_out(up, UART_IER, up->ier);
     148                 :       9306 :         return true;
     149                 :            : }
     150                 :            : 
     151                 :            : struct uart_8250_port *serial8250_get_port(int line);
     152                 :            : 
     153                 :            : void serial8250_rpm_get(struct uart_8250_port *p);
     154                 :            : void serial8250_rpm_put(struct uart_8250_port *p);
     155                 :            : 
     156                 :            : void serial8250_rpm_get_tx(struct uart_8250_port *p);
     157                 :            : void serial8250_rpm_put_tx(struct uart_8250_port *p);
     158                 :            : 
     159                 :            : int serial8250_em485_init(struct uart_8250_port *p);
     160                 :            : void serial8250_em485_destroy(struct uart_8250_port *p);
     161                 :            : 
     162                 :            : /* MCR <-> TIOCM conversion */
     163                 :         55 : static inline int serial8250_TIOCM_to_MCR(int tiocm)
     164                 :            : {
     165                 :         55 :         int mcr = 0;
     166                 :            : 
     167         [ +  + ]:         55 :         if (tiocm & TIOCM_RTS)
     168                 :         11 :                 mcr |= UART_MCR_RTS;
     169         [ +  - ]:         55 :         if (tiocm & TIOCM_DTR)
     170                 :         55 :                 mcr |= UART_MCR_DTR;
     171         [ -  + ]:         55 :         if (tiocm & TIOCM_OUT1)
     172                 :          0 :                 mcr |= UART_MCR_OUT1;
     173         [ +  + ]:         55 :         if (tiocm & TIOCM_OUT2)
     174                 :         33 :                 mcr |= UART_MCR_OUT2;
     175         [ -  + ]:         55 :         if (tiocm & TIOCM_LOOP)
     176                 :          0 :                 mcr |= UART_MCR_LOOP;
     177                 :            : 
     178                 :         55 :         return mcr;
     179                 :            : }
     180                 :            : 
     181                 :            : static inline int serial8250_MCR_to_TIOCM(int mcr)
     182                 :            : {
     183                 :            :         int tiocm = 0;
     184                 :            : 
     185                 :            :         if (mcr & UART_MCR_RTS)
     186                 :            :                 tiocm |= TIOCM_RTS;
     187                 :            :         if (mcr & UART_MCR_DTR)
     188                 :            :                 tiocm |= TIOCM_DTR;
     189                 :            :         if (mcr & UART_MCR_OUT1)
     190                 :            :                 tiocm |= TIOCM_OUT1;
     191                 :            :         if (mcr & UART_MCR_OUT2)
     192                 :            :                 tiocm |= TIOCM_OUT2;
     193                 :            :         if (mcr & UART_MCR_LOOP)
     194                 :            :                 tiocm |= TIOCM_LOOP;
     195                 :            : 
     196                 :            :         return tiocm;
     197                 :            : }
     198                 :            : 
     199                 :            : /* MSR <-> TIOCM conversion */
     200                 :          0 : static inline int serial8250_MSR_to_TIOCM(int msr)
     201                 :            : {
     202                 :          0 :         int tiocm = 0;
     203                 :            : 
     204         [ #  # ]:          0 :         if (msr & UART_MSR_DCD)
     205                 :          0 :                 tiocm |= TIOCM_CAR;
     206         [ #  # ]:          0 :         if (msr & UART_MSR_RI)
     207                 :          0 :                 tiocm |= TIOCM_RNG;
     208         [ #  # ]:          0 :         if (msr & UART_MSR_DSR)
     209                 :          0 :                 tiocm |= TIOCM_DSR;
     210         [ #  # ]:          0 :         if (msr & UART_MSR_CTS)
     211                 :          0 :                 tiocm |= TIOCM_CTS;
     212                 :            : 
     213                 :          0 :         return tiocm;
     214                 :            : }
     215                 :            : 
     216                 :         66 : static inline void serial8250_out_MCR(struct uart_8250_port *up, int value)
     217                 :            : {
     218                 :         66 :         serial_out(up, UART_MCR, value);
     219                 :            : 
     220   [ -  -  -  - ]:         11 :         if (up->gpios)
     221                 :            :                 mctrl_gpio_set(up->gpios, serial8250_MCR_to_TIOCM(value));
     222                 :          0 : }
     223                 :            : 
     224                 :         11 : static inline int serial8250_in_MCR(struct uart_8250_port *up)
     225                 :            : {
     226                 :         11 :         int mctrl;
     227                 :            : 
     228                 :         11 :         mctrl = serial_in(up, UART_MCR);
     229                 :            : 
     230         [ -  + ]:         11 :         if (up->gpios) {
     231                 :          0 :                 unsigned int mctrl_gpio = 0;
     232                 :            : 
     233                 :          0 :                 mctrl_gpio = mctrl_gpio_get_outputs(up->gpios, &mctrl_gpio);
     234                 :          0 :                 mctrl |= serial8250_TIOCM_to_MCR(mctrl_gpio);
     235                 :            :         }
     236                 :            : 
     237                 :         11 :         return mctrl;
     238                 :            : }
     239                 :            : 
     240                 :            : #if defined(__alpha__) && !defined(CONFIG_PCI)
     241                 :            : /*
     242                 :            :  * Digital did something really horribly wrong with the OUT1 and OUT2
     243                 :            :  * lines on at least some ALPHA's.  The failure mode is that if either
     244                 :            :  * is cleared, the machine locks up with endless interrupts.
     245                 :            :  */
     246                 :            : #define ALPHA_KLUDGE_MCR  (UART_MCR_OUT2 | UART_MCR_OUT1)
     247                 :            : #else
     248                 :            : #define ALPHA_KLUDGE_MCR 0
     249                 :            : #endif
     250                 :            : 
     251                 :            : #ifdef CONFIG_SERIAL_8250_PNP
     252                 :            : int serial8250_pnp_init(void);
     253                 :            : void serial8250_pnp_exit(void);
     254                 :            : #else
     255                 :            : static inline int serial8250_pnp_init(void) { return 0; }
     256                 :            : static inline void serial8250_pnp_exit(void) { }
     257                 :            : #endif
     258                 :            : 
     259                 :            : #ifdef CONFIG_SERIAL_8250_FINTEK
     260                 :            : int fintek_8250_probe(struct uart_8250_port *uart);
     261                 :            : #else
     262                 :            : static inline int fintek_8250_probe(struct uart_8250_port *uart) { return 0; }
     263                 :            : #endif
     264                 :            : 
     265                 :            : #ifdef CONFIG_ARCH_OMAP1
     266                 :            : static inline int is_omap1_8250(struct uart_8250_port *pt)
     267                 :            : {
     268                 :            :         int res;
     269                 :            : 
     270                 :            :         switch (pt->port.mapbase) {
     271                 :            :         case OMAP1_UART1_BASE:
     272                 :            :         case OMAP1_UART2_BASE:
     273                 :            :         case OMAP1_UART3_BASE:
     274                 :            :                 res = 1;
     275                 :            :                 break;
     276                 :            :         default:
     277                 :            :                 res = 0;
     278                 :            :                 break;
     279                 :            :         }
     280                 :            : 
     281                 :            :         return res;
     282                 :            : }
     283                 :            : 
     284                 :            : static inline int is_omap1510_8250(struct uart_8250_port *pt)
     285                 :            : {
     286                 :            :         if (!cpu_is_omap1510())
     287                 :            :                 return 0;
     288                 :            : 
     289                 :            :         return is_omap1_8250(pt);
     290                 :            : }
     291                 :            : #else
     292                 :         77 : static inline int is_omap1_8250(struct uart_8250_port *pt)
     293                 :            : {
     294                 :         77 :         return 0;
     295                 :            : }
     296                 :         22 : static inline int is_omap1510_8250(struct uart_8250_port *pt)
     297                 :            : {
     298         [ -  + ]:         22 :         return 0;
     299                 :            : }
     300                 :            : #endif
     301                 :            : 
     302                 :            : #ifdef CONFIG_SERIAL_8250_DMA
     303                 :            : extern int serial8250_tx_dma(struct uart_8250_port *);
     304                 :            : extern int serial8250_rx_dma(struct uart_8250_port *);
     305                 :            : extern void serial8250_rx_dma_flush(struct uart_8250_port *);
     306                 :            : extern int serial8250_request_dma(struct uart_8250_port *);
     307                 :            : extern void serial8250_release_dma(struct uart_8250_port *);
     308                 :            : #else
     309                 :            : static inline int serial8250_tx_dma(struct uart_8250_port *p)
     310                 :            : {
     311                 :            :         return -1;
     312                 :            : }
     313                 :            : static inline int serial8250_rx_dma(struct uart_8250_port *p)
     314                 :            : {
     315                 :            :         return -1;
     316                 :            : }
     317                 :            : static inline void serial8250_rx_dma_flush(struct uart_8250_port *p) { }
     318                 :            : static inline int serial8250_request_dma(struct uart_8250_port *p)
     319                 :            : {
     320                 :            :         return -1;
     321                 :            : }
     322                 :            : static inline void serial8250_release_dma(struct uart_8250_port *p) { }
     323                 :            : #endif
     324                 :            : 
     325                 :          0 : static inline int ns16550a_goto_highspeed(struct uart_8250_port *up)
     326                 :            : {
     327                 :          0 :         unsigned char status;
     328                 :            : 
     329                 :          0 :         status = serial_in(up, 0x04); /* EXCR2 */
     330                 :            : #define PRESL(x) ((x) & 0x30)
     331         [ #  # ]:          0 :         if (PRESL(status) == 0x10) {
     332                 :            :                 /* already in high speed mode */
     333                 :            :                 return 0;
     334                 :            :         } else {
     335                 :          0 :                 status &= ~0xB0; /* Disable LOCK, mask out PRESL[01] */
     336                 :          0 :                 status |= 0x10;  /* 1.625 divisor for baud_base --> 921600 */
     337                 :          0 :                 serial_out(up, 0x04, status);
     338                 :            :         }
     339                 :          0 :         return 1;
     340                 :            : }
     341                 :            : 
     342                 :            : static inline int serial_index(struct uart_port *port)
     343                 :            : {
     344                 :            :         return port->minor - 64;
     345                 :            : }

Generated by: LCOV version 1.14