Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  *  Based on meson_uart.c, by AMLOGIC, INC.
0004  *
0005  * Copyright (C) 2014 Carlo Caione <carlo@caione.org>
0006  */
0007 
0008 #include <linux/clk.h>
0009 #include <linux/console.h>
0010 #include <linux/delay.h>
0011 #include <linux/init.h>
0012 #include <linux/io.h>
0013 #include <linux/iopoll.h>
0014 #include <linux/module.h>
0015 #include <linux/kernel.h>
0016 #include <linux/of.h>
0017 #include <linux/platform_device.h>
0018 #include <linux/serial.h>
0019 #include <linux/serial_core.h>
0020 #include <linux/tty.h>
0021 #include <linux/tty_flip.h>
0022 
0023 /* Register offsets */
0024 #define AML_UART_WFIFO          0x00
0025 #define AML_UART_RFIFO          0x04
0026 #define AML_UART_CONTROL        0x08
0027 #define AML_UART_STATUS         0x0c
0028 #define AML_UART_MISC           0x10
0029 #define AML_UART_REG5           0x14
0030 
0031 /* AML_UART_CONTROL bits */
0032 #define AML_UART_TX_EN          BIT(12)
0033 #define AML_UART_RX_EN          BIT(13)
0034 #define AML_UART_TWO_WIRE_EN        BIT(15)
0035 #define AML_UART_STOP_BIT_LEN_MASK  (0x03 << 16)
0036 #define AML_UART_STOP_BIT_1SB       (0x00 << 16)
0037 #define AML_UART_STOP_BIT_2SB       (0x01 << 16)
0038 #define AML_UART_PARITY_TYPE        BIT(18)
0039 #define AML_UART_PARITY_EN      BIT(19)
0040 #define AML_UART_TX_RST         BIT(22)
0041 #define AML_UART_RX_RST         BIT(23)
0042 #define AML_UART_CLEAR_ERR      BIT(24)
0043 #define AML_UART_RX_INT_EN      BIT(27)
0044 #define AML_UART_TX_INT_EN      BIT(28)
0045 #define AML_UART_DATA_LEN_MASK      (0x03 << 20)
0046 #define AML_UART_DATA_LEN_8BIT      (0x00 << 20)
0047 #define AML_UART_DATA_LEN_7BIT      (0x01 << 20)
0048 #define AML_UART_DATA_LEN_6BIT      (0x02 << 20)
0049 #define AML_UART_DATA_LEN_5BIT      (0x03 << 20)
0050 
0051 /* AML_UART_STATUS bits */
0052 #define AML_UART_PARITY_ERR     BIT(16)
0053 #define AML_UART_FRAME_ERR      BIT(17)
0054 #define AML_UART_TX_FIFO_WERR       BIT(18)
0055 #define AML_UART_RX_EMPTY       BIT(20)
0056 #define AML_UART_TX_FULL        BIT(21)
0057 #define AML_UART_TX_EMPTY       BIT(22)
0058 #define AML_UART_XMIT_BUSY      BIT(25)
0059 #define AML_UART_ERR            (AML_UART_PARITY_ERR | \
0060                      AML_UART_FRAME_ERR  | \
0061                      AML_UART_TX_FIFO_WERR)
0062 
0063 /* AML_UART_MISC bits */
0064 #define AML_UART_XMIT_IRQ(c)        (((c) & 0xff) << 8)
0065 #define AML_UART_RECV_IRQ(c)        ((c) & 0xff)
0066 
0067 /* AML_UART_REG5 bits */
0068 #define AML_UART_BAUD_MASK      0x7fffff
0069 #define AML_UART_BAUD_USE       BIT(23)
0070 #define AML_UART_BAUD_XTAL      BIT(24)
0071 #define AML_UART_BAUD_XTAL_DIV2     BIT(27)
0072 
0073 #define AML_UART_PORT_NUM       12
0074 #define AML_UART_PORT_OFFSET        6
0075 #define AML_UART_DEV_NAME       "ttyAML"
0076 
0077 #define AML_UART_POLL_USEC      5
0078 #define AML_UART_TIMEOUT_USEC       10000
0079 
0080 static struct uart_driver meson_uart_driver;
0081 
0082 static struct uart_port *meson_ports[AML_UART_PORT_NUM];
0083 
0084 struct meson_uart_data {
0085     bool has_xtal_div2;
0086 };
0087 
0088 static void meson_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
0089 {
0090 }
0091 
0092 static unsigned int meson_uart_get_mctrl(struct uart_port *port)
0093 {
0094     return TIOCM_CTS;
0095 }
0096 
0097 static unsigned int meson_uart_tx_empty(struct uart_port *port)
0098 {
0099     u32 val;
0100 
0101     val = readl(port->membase + AML_UART_STATUS);
0102     val &= (AML_UART_TX_EMPTY | AML_UART_XMIT_BUSY);
0103     return (val == AML_UART_TX_EMPTY) ? TIOCSER_TEMT : 0;
0104 }
0105 
0106 static void meson_uart_stop_tx(struct uart_port *port)
0107 {
0108     u32 val;
0109 
0110     val = readl(port->membase + AML_UART_CONTROL);
0111     val &= ~AML_UART_TX_INT_EN;
0112     writel(val, port->membase + AML_UART_CONTROL);
0113 }
0114 
0115 static void meson_uart_stop_rx(struct uart_port *port)
0116 {
0117     u32 val;
0118 
0119     val = readl(port->membase + AML_UART_CONTROL);
0120     val &= ~AML_UART_RX_EN;
0121     writel(val, port->membase + AML_UART_CONTROL);
0122 }
0123 
0124 static void meson_uart_shutdown(struct uart_port *port)
0125 {
0126     unsigned long flags;
0127     u32 val;
0128 
0129     free_irq(port->irq, port);
0130 
0131     spin_lock_irqsave(&port->lock, flags);
0132 
0133     val = readl(port->membase + AML_UART_CONTROL);
0134     val &= ~AML_UART_RX_EN;
0135     val &= ~(AML_UART_RX_INT_EN | AML_UART_TX_INT_EN);
0136     writel(val, port->membase + AML_UART_CONTROL);
0137 
0138     spin_unlock_irqrestore(&port->lock, flags);
0139 }
0140 
0141 static void meson_uart_start_tx(struct uart_port *port)
0142 {
0143     struct circ_buf *xmit = &port->state->xmit;
0144     unsigned int ch;
0145     u32 val;
0146 
0147     if (uart_tx_stopped(port)) {
0148         meson_uart_stop_tx(port);
0149         return;
0150     }
0151 
0152     while (!(readl(port->membase + AML_UART_STATUS) & AML_UART_TX_FULL)) {
0153         if (port->x_char) {
0154             writel(port->x_char, port->membase + AML_UART_WFIFO);
0155             port->icount.tx++;
0156             port->x_char = 0;
0157             continue;
0158         }
0159 
0160         if (uart_circ_empty(xmit))
0161             break;
0162 
0163         ch = xmit->buf[xmit->tail];
0164         writel(ch, port->membase + AML_UART_WFIFO);
0165         xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
0166         port->icount.tx++;
0167     }
0168 
0169     if (!uart_circ_empty(xmit)) {
0170         val = readl(port->membase + AML_UART_CONTROL);
0171         val |= AML_UART_TX_INT_EN;
0172         writel(val, port->membase + AML_UART_CONTROL);
0173     }
0174 
0175     if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
0176         uart_write_wakeup(port);
0177 }
0178 
0179 static void meson_receive_chars(struct uart_port *port)
0180 {
0181     struct tty_port *tport = &port->state->port;
0182     char flag;
0183     u32 ostatus, status, ch, mode;
0184 
0185     do {
0186         flag = TTY_NORMAL;
0187         port->icount.rx++;
0188         ostatus = status = readl(port->membase + AML_UART_STATUS);
0189 
0190         if (status & AML_UART_ERR) {
0191             if (status & AML_UART_TX_FIFO_WERR)
0192                 port->icount.overrun++;
0193             else if (status & AML_UART_FRAME_ERR)
0194                 port->icount.frame++;
0195             else if (status & AML_UART_PARITY_ERR)
0196                 port->icount.frame++;
0197 
0198             mode = readl(port->membase + AML_UART_CONTROL);
0199             mode |= AML_UART_CLEAR_ERR;
0200             writel(mode, port->membase + AML_UART_CONTROL);
0201 
0202             /* It doesn't clear to 0 automatically */
0203             mode &= ~AML_UART_CLEAR_ERR;
0204             writel(mode, port->membase + AML_UART_CONTROL);
0205 
0206             status &= port->read_status_mask;
0207             if (status & AML_UART_FRAME_ERR)
0208                 flag = TTY_FRAME;
0209             else if (status & AML_UART_PARITY_ERR)
0210                 flag = TTY_PARITY;
0211         }
0212 
0213         ch = readl(port->membase + AML_UART_RFIFO);
0214         ch &= 0xff;
0215 
0216         if ((ostatus & AML_UART_FRAME_ERR) && (ch == 0)) {
0217             port->icount.brk++;
0218             flag = TTY_BREAK;
0219             if (uart_handle_break(port))
0220                 continue;
0221         }
0222 
0223         if (uart_handle_sysrq_char(port, ch))
0224             continue;
0225 
0226         if ((status & port->ignore_status_mask) == 0)
0227             tty_insert_flip_char(tport, ch, flag);
0228 
0229         if (status & AML_UART_TX_FIFO_WERR)
0230             tty_insert_flip_char(tport, 0, TTY_OVERRUN);
0231 
0232     } while (!(readl(port->membase + AML_UART_STATUS) & AML_UART_RX_EMPTY));
0233 
0234     tty_flip_buffer_push(tport);
0235 }
0236 
0237 static irqreturn_t meson_uart_interrupt(int irq, void *dev_id)
0238 {
0239     struct uart_port *port = (struct uart_port *)dev_id;
0240 
0241     spin_lock(&port->lock);
0242 
0243     if (!(readl(port->membase + AML_UART_STATUS) & AML_UART_RX_EMPTY))
0244         meson_receive_chars(port);
0245 
0246     if (!(readl(port->membase + AML_UART_STATUS) & AML_UART_TX_FULL)) {
0247         if (readl(port->membase + AML_UART_CONTROL) & AML_UART_TX_INT_EN)
0248             meson_uart_start_tx(port);
0249     }
0250 
0251     spin_unlock(&port->lock);
0252 
0253     return IRQ_HANDLED;
0254 }
0255 
0256 static const char *meson_uart_type(struct uart_port *port)
0257 {
0258     return (port->type == PORT_MESON) ? "meson_uart" : NULL;
0259 }
0260 
0261 /*
0262  * This function is called only from probe() using a temporary io mapping
0263  * in order to perform a reset before setting up the device. Since the
0264  * temporarily mapped region was successfully requested, there can be no
0265  * console on this port at this time. Hence it is not necessary for this
0266  * function to acquire the port->lock. (Since there is no console on this
0267  * port at this time, the port->lock is not initialized yet.)
0268  */
0269 static void meson_uart_reset(struct uart_port *port)
0270 {
0271     u32 val;
0272 
0273     val = readl(port->membase + AML_UART_CONTROL);
0274     val |= (AML_UART_RX_RST | AML_UART_TX_RST | AML_UART_CLEAR_ERR);
0275     writel(val, port->membase + AML_UART_CONTROL);
0276 
0277     val &= ~(AML_UART_RX_RST | AML_UART_TX_RST | AML_UART_CLEAR_ERR);
0278     writel(val, port->membase + AML_UART_CONTROL);
0279 }
0280 
0281 static int meson_uart_startup(struct uart_port *port)
0282 {
0283     unsigned long flags;
0284     u32 val;
0285     int ret = 0;
0286 
0287     spin_lock_irqsave(&port->lock, flags);
0288 
0289     val = readl(port->membase + AML_UART_CONTROL);
0290     val |= AML_UART_CLEAR_ERR;
0291     writel(val, port->membase + AML_UART_CONTROL);
0292     val &= ~AML_UART_CLEAR_ERR;
0293     writel(val, port->membase + AML_UART_CONTROL);
0294 
0295     val |= (AML_UART_RX_EN | AML_UART_TX_EN);
0296     writel(val, port->membase + AML_UART_CONTROL);
0297 
0298     val |= (AML_UART_RX_INT_EN | AML_UART_TX_INT_EN);
0299     writel(val, port->membase + AML_UART_CONTROL);
0300 
0301     val = (AML_UART_RECV_IRQ(1) | AML_UART_XMIT_IRQ(port->fifosize / 2));
0302     writel(val, port->membase + AML_UART_MISC);
0303 
0304     spin_unlock_irqrestore(&port->lock, flags);
0305 
0306     ret = request_irq(port->irq, meson_uart_interrupt, 0,
0307               port->name, port);
0308 
0309     return ret;
0310 }
0311 
0312 static void meson_uart_change_speed(struct uart_port *port, unsigned long baud)
0313 {
0314     const struct meson_uart_data *private_data = port->private_data;
0315     u32 val = 0;
0316 
0317     while (!meson_uart_tx_empty(port))
0318         cpu_relax();
0319 
0320     if (port->uartclk == 24000000) {
0321         unsigned int xtal_div = 3;
0322 
0323         if (private_data && private_data->has_xtal_div2) {
0324             xtal_div = 2;
0325             val |= AML_UART_BAUD_XTAL_DIV2;
0326         }
0327         val |= DIV_ROUND_CLOSEST(port->uartclk / xtal_div, baud) - 1;
0328         val |= AML_UART_BAUD_XTAL;
0329     } else {
0330         val =  DIV_ROUND_CLOSEST(port->uartclk / 4, baud) - 1;
0331     }
0332     val |= AML_UART_BAUD_USE;
0333     writel(val, port->membase + AML_UART_REG5);
0334 }
0335 
0336 static void meson_uart_set_termios(struct uart_port *port,
0337                    struct ktermios *termios,
0338                    struct ktermios *old)
0339 {
0340     unsigned int cflags, iflags, baud;
0341     unsigned long flags;
0342     u32 val;
0343 
0344     spin_lock_irqsave(&port->lock, flags);
0345 
0346     cflags = termios->c_cflag;
0347     iflags = termios->c_iflag;
0348 
0349     val = readl(port->membase + AML_UART_CONTROL);
0350 
0351     val &= ~AML_UART_DATA_LEN_MASK;
0352     switch (cflags & CSIZE) {
0353     case CS8:
0354         val |= AML_UART_DATA_LEN_8BIT;
0355         break;
0356     case CS7:
0357         val |= AML_UART_DATA_LEN_7BIT;
0358         break;
0359     case CS6:
0360         val |= AML_UART_DATA_LEN_6BIT;
0361         break;
0362     case CS5:
0363         val |= AML_UART_DATA_LEN_5BIT;
0364         break;
0365     }
0366 
0367     if (cflags & PARENB)
0368         val |= AML_UART_PARITY_EN;
0369     else
0370         val &= ~AML_UART_PARITY_EN;
0371 
0372     if (cflags & PARODD)
0373         val |= AML_UART_PARITY_TYPE;
0374     else
0375         val &= ~AML_UART_PARITY_TYPE;
0376 
0377     val &= ~AML_UART_STOP_BIT_LEN_MASK;
0378     if (cflags & CSTOPB)
0379         val |= AML_UART_STOP_BIT_2SB;
0380     else
0381         val |= AML_UART_STOP_BIT_1SB;
0382 
0383     if (cflags & CRTSCTS)
0384         val &= ~AML_UART_TWO_WIRE_EN;
0385     else
0386         val |= AML_UART_TWO_WIRE_EN;
0387 
0388     writel(val, port->membase + AML_UART_CONTROL);
0389 
0390     baud = uart_get_baud_rate(port, termios, old, 50, 4000000);
0391     meson_uart_change_speed(port, baud);
0392 
0393     port->read_status_mask = AML_UART_TX_FIFO_WERR;
0394     if (iflags & INPCK)
0395         port->read_status_mask |= AML_UART_PARITY_ERR |
0396                       AML_UART_FRAME_ERR;
0397 
0398     port->ignore_status_mask = 0;
0399     if (iflags & IGNPAR)
0400         port->ignore_status_mask |= AML_UART_PARITY_ERR |
0401                         AML_UART_FRAME_ERR;
0402 
0403     uart_update_timeout(port, termios->c_cflag, baud);
0404     spin_unlock_irqrestore(&port->lock, flags);
0405 }
0406 
0407 static int meson_uart_verify_port(struct uart_port *port,
0408                   struct serial_struct *ser)
0409 {
0410     int ret = 0;
0411 
0412     if (port->type != PORT_MESON)
0413         ret = -EINVAL;
0414     if (port->irq != ser->irq)
0415         ret = -EINVAL;
0416     if (ser->baud_base < 9600)
0417         ret = -EINVAL;
0418     return ret;
0419 }
0420 
0421 static void meson_uart_release_port(struct uart_port *port)
0422 {
0423     devm_iounmap(port->dev, port->membase);
0424     port->membase = NULL;
0425     devm_release_mem_region(port->dev, port->mapbase, port->mapsize);
0426 }
0427 
0428 static int meson_uart_request_port(struct uart_port *port)
0429 {
0430     if (!devm_request_mem_region(port->dev, port->mapbase, port->mapsize,
0431                      dev_name(port->dev))) {
0432         dev_err(port->dev, "Memory region busy\n");
0433         return -EBUSY;
0434     }
0435 
0436     port->membase = devm_ioremap(port->dev, port->mapbase,
0437                          port->mapsize);
0438     if (!port->membase)
0439         return -ENOMEM;
0440 
0441     return 0;
0442 }
0443 
0444 static void meson_uart_config_port(struct uart_port *port, int flags)
0445 {
0446     if (flags & UART_CONFIG_TYPE) {
0447         port->type = PORT_MESON;
0448         meson_uart_request_port(port);
0449     }
0450 }
0451 
0452 #ifdef CONFIG_CONSOLE_POLL
0453 /*
0454  * Console polling routines for writing and reading from the uart while
0455  * in an interrupt or debug context (i.e. kgdb).
0456  */
0457 
0458 static int meson_uart_poll_get_char(struct uart_port *port)
0459 {
0460     u32 c;
0461     unsigned long flags;
0462 
0463     spin_lock_irqsave(&port->lock, flags);
0464 
0465     if (readl(port->membase + AML_UART_STATUS) & AML_UART_RX_EMPTY)
0466         c = NO_POLL_CHAR;
0467     else
0468         c = readl(port->membase + AML_UART_RFIFO);
0469 
0470     spin_unlock_irqrestore(&port->lock, flags);
0471 
0472     return c;
0473 }
0474 
0475 static void meson_uart_poll_put_char(struct uart_port *port, unsigned char c)
0476 {
0477     unsigned long flags;
0478     u32 reg;
0479     int ret;
0480 
0481     spin_lock_irqsave(&port->lock, flags);
0482 
0483     /* Wait until FIFO is empty or timeout */
0484     ret = readl_poll_timeout_atomic(port->membase + AML_UART_STATUS, reg,
0485                     reg & AML_UART_TX_EMPTY,
0486                     AML_UART_POLL_USEC,
0487                     AML_UART_TIMEOUT_USEC);
0488     if (ret == -ETIMEDOUT) {
0489         dev_err(port->dev, "Timeout waiting for UART TX EMPTY\n");
0490         goto out;
0491     }
0492 
0493     /* Write the character */
0494     writel(c, port->membase + AML_UART_WFIFO);
0495 
0496     /* Wait until FIFO is empty or timeout */
0497     ret = readl_poll_timeout_atomic(port->membase + AML_UART_STATUS, reg,
0498                     reg & AML_UART_TX_EMPTY,
0499                     AML_UART_POLL_USEC,
0500                     AML_UART_TIMEOUT_USEC);
0501     if (ret == -ETIMEDOUT)
0502         dev_err(port->dev, "Timeout waiting for UART TX EMPTY\n");
0503 
0504 out:
0505     spin_unlock_irqrestore(&port->lock, flags);
0506 }
0507 
0508 #endif /* CONFIG_CONSOLE_POLL */
0509 
0510 static const struct uart_ops meson_uart_ops = {
0511     .set_mctrl      = meson_uart_set_mctrl,
0512     .get_mctrl      = meson_uart_get_mctrl,
0513     .tx_empty   = meson_uart_tx_empty,
0514     .start_tx   = meson_uart_start_tx,
0515     .stop_tx    = meson_uart_stop_tx,
0516     .stop_rx    = meson_uart_stop_rx,
0517     .startup    = meson_uart_startup,
0518     .shutdown   = meson_uart_shutdown,
0519     .set_termios    = meson_uart_set_termios,
0520     .type       = meson_uart_type,
0521     .config_port    = meson_uart_config_port,
0522     .request_port   = meson_uart_request_port,
0523     .release_port   = meson_uart_release_port,
0524     .verify_port    = meson_uart_verify_port,
0525 #ifdef CONFIG_CONSOLE_POLL
0526     .poll_get_char  = meson_uart_poll_get_char,
0527     .poll_put_char  = meson_uart_poll_put_char,
0528 #endif
0529 };
0530 
0531 #ifdef CONFIG_SERIAL_MESON_CONSOLE
0532 static void meson_uart_enable_tx_engine(struct uart_port *port)
0533 {
0534     u32 val;
0535 
0536     val = readl(port->membase + AML_UART_CONTROL);
0537     val |= AML_UART_TX_EN;
0538     writel(val, port->membase + AML_UART_CONTROL);
0539 }
0540 
0541 static void meson_console_putchar(struct uart_port *port, unsigned char ch)
0542 {
0543     if (!port->membase)
0544         return;
0545 
0546     while (readl(port->membase + AML_UART_STATUS) & AML_UART_TX_FULL)
0547         cpu_relax();
0548     writel(ch, port->membase + AML_UART_WFIFO);
0549 }
0550 
0551 static void meson_serial_port_write(struct uart_port *port, const char *s,
0552                     u_int count)
0553 {
0554     unsigned long flags;
0555     int locked;
0556     u32 val, tmp;
0557 
0558     local_irq_save(flags);
0559     if (port->sysrq) {
0560         locked = 0;
0561     } else if (oops_in_progress) {
0562         locked = spin_trylock(&port->lock);
0563     } else {
0564         spin_lock(&port->lock);
0565         locked = 1;
0566     }
0567 
0568     val = readl(port->membase + AML_UART_CONTROL);
0569     tmp = val & ~(AML_UART_TX_INT_EN | AML_UART_RX_INT_EN);
0570     writel(tmp, port->membase + AML_UART_CONTROL);
0571 
0572     uart_console_write(port, s, count, meson_console_putchar);
0573     writel(val, port->membase + AML_UART_CONTROL);
0574 
0575     if (locked)
0576         spin_unlock(&port->lock);
0577     local_irq_restore(flags);
0578 }
0579 
0580 static void meson_serial_console_write(struct console *co, const char *s,
0581                        u_int count)
0582 {
0583     struct uart_port *port;
0584 
0585     port = meson_ports[co->index];
0586     if (!port)
0587         return;
0588 
0589     meson_serial_port_write(port, s, count);
0590 }
0591 
0592 static int meson_serial_console_setup(struct console *co, char *options)
0593 {
0594     struct uart_port *port;
0595     int baud = 115200;
0596     int bits = 8;
0597     int parity = 'n';
0598     int flow = 'n';
0599 
0600     if (co->index < 0 || co->index >= AML_UART_PORT_NUM)
0601         return -EINVAL;
0602 
0603     port = meson_ports[co->index];
0604     if (!port || !port->membase)
0605         return -ENODEV;
0606 
0607     meson_uart_enable_tx_engine(port);
0608 
0609     if (options)
0610         uart_parse_options(options, &baud, &parity, &bits, &flow);
0611 
0612     return uart_set_options(port, co, baud, parity, bits, flow);
0613 }
0614 
0615 static struct console meson_serial_console = {
0616     .name       = AML_UART_DEV_NAME,
0617     .write      = meson_serial_console_write,
0618     .device     = uart_console_device,
0619     .setup      = meson_serial_console_setup,
0620     .flags      = CON_PRINTBUFFER,
0621     .index      = -1,
0622     .data       = &meson_uart_driver,
0623 };
0624 
0625 static int __init meson_serial_console_init(void)
0626 {
0627     register_console(&meson_serial_console);
0628     return 0;
0629 }
0630 
0631 static void meson_serial_early_console_write(struct console *co,
0632                          const char *s,
0633                          u_int count)
0634 {
0635     struct earlycon_device *dev = co->data;
0636 
0637     meson_serial_port_write(&dev->port, s, count);
0638 }
0639 
0640 static int __init
0641 meson_serial_early_console_setup(struct earlycon_device *device, const char *opt)
0642 {
0643     if (!device->port.membase)
0644         return -ENODEV;
0645 
0646     meson_uart_enable_tx_engine(&device->port);
0647     device->con->write = meson_serial_early_console_write;
0648     return 0;
0649 }
0650 
0651 OF_EARLYCON_DECLARE(meson, "amlogic,meson-ao-uart",
0652             meson_serial_early_console_setup);
0653 
0654 #define MESON_SERIAL_CONSOLE    (&meson_serial_console)
0655 #else
0656 static int __init meson_serial_console_init(void) {
0657     return 0;
0658 }
0659 #define MESON_SERIAL_CONSOLE    NULL
0660 #endif
0661 
0662 static struct uart_driver meson_uart_driver = {
0663     .owner      = THIS_MODULE,
0664     .driver_name    = "meson_uart",
0665     .dev_name   = AML_UART_DEV_NAME,
0666     .nr     = AML_UART_PORT_NUM,
0667     .cons       = MESON_SERIAL_CONSOLE,
0668 };
0669 
0670 static inline struct clk *meson_uart_probe_clock(struct device *dev,
0671                          const char *id)
0672 {
0673     struct clk *clk = NULL;
0674     int ret;
0675 
0676     clk = devm_clk_get(dev, id);
0677     if (IS_ERR(clk))
0678         return clk;
0679 
0680     ret = clk_prepare_enable(clk);
0681     if (ret) {
0682         dev_err(dev, "couldn't enable clk\n");
0683         return ERR_PTR(ret);
0684     }
0685 
0686     devm_add_action_or_reset(dev,
0687             (void(*)(void *))clk_disable_unprepare,
0688             clk);
0689 
0690     return clk;
0691 }
0692 
0693 static int meson_uart_probe_clocks(struct platform_device *pdev,
0694                    struct uart_port *port)
0695 {
0696     struct clk *clk_xtal = NULL;
0697     struct clk *clk_pclk = NULL;
0698     struct clk *clk_baud = NULL;
0699 
0700     clk_pclk = meson_uart_probe_clock(&pdev->dev, "pclk");
0701     if (IS_ERR(clk_pclk))
0702         return PTR_ERR(clk_pclk);
0703 
0704     clk_xtal = meson_uart_probe_clock(&pdev->dev, "xtal");
0705     if (IS_ERR(clk_xtal))
0706         return PTR_ERR(clk_xtal);
0707 
0708     clk_baud = meson_uart_probe_clock(&pdev->dev, "baud");
0709     if (IS_ERR(clk_baud))
0710         return PTR_ERR(clk_baud);
0711 
0712     port->uartclk = clk_get_rate(clk_baud);
0713 
0714     return 0;
0715 }
0716 
0717 static int meson_uart_probe(struct platform_device *pdev)
0718 {
0719     struct resource *res_mem;
0720     struct uart_port *port;
0721     u32 fifosize = 64; /* Default is 64, 128 for EE UART_0 */
0722     int ret = 0;
0723     int irq;
0724 
0725     if (pdev->dev.of_node)
0726         pdev->id = of_alias_get_id(pdev->dev.of_node, "serial");
0727 
0728     if (pdev->id < 0) {
0729         int id;
0730 
0731         for (id = AML_UART_PORT_OFFSET; id < AML_UART_PORT_NUM; id++) {
0732             if (!meson_ports[id]) {
0733                 pdev->id = id;
0734                 break;
0735             }
0736         }
0737     }
0738 
0739     if (pdev->id < 0 || pdev->id >= AML_UART_PORT_NUM)
0740         return -EINVAL;
0741 
0742     res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0743     if (!res_mem)
0744         return -ENODEV;
0745 
0746     irq = platform_get_irq(pdev, 0);
0747     if (irq < 0)
0748         return irq;
0749 
0750     of_property_read_u32(pdev->dev.of_node, "fifo-size", &fifosize);
0751 
0752     if (meson_ports[pdev->id]) {
0753         dev_err(&pdev->dev, "port %d already allocated\n", pdev->id);
0754         return -EBUSY;
0755     }
0756 
0757     port = devm_kzalloc(&pdev->dev, sizeof(struct uart_port), GFP_KERNEL);
0758     if (!port)
0759         return -ENOMEM;
0760 
0761     ret = meson_uart_probe_clocks(pdev, port);
0762     if (ret)
0763         return ret;
0764 
0765     port->iotype = UPIO_MEM;
0766     port->mapbase = res_mem->start;
0767     port->mapsize = resource_size(res_mem);
0768     port->irq = irq;
0769     port->flags = UPF_BOOT_AUTOCONF | UPF_LOW_LATENCY;
0770     port->has_sysrq = IS_ENABLED(CONFIG_SERIAL_MESON_CONSOLE);
0771     port->dev = &pdev->dev;
0772     port->line = pdev->id;
0773     port->type = PORT_MESON;
0774     port->x_char = 0;
0775     port->ops = &meson_uart_ops;
0776     port->fifosize = fifosize;
0777     port->private_data = (void *)device_get_match_data(&pdev->dev);
0778 
0779     meson_ports[pdev->id] = port;
0780     platform_set_drvdata(pdev, port);
0781 
0782     /* reset port before registering (and possibly registering console) */
0783     if (meson_uart_request_port(port) >= 0) {
0784         meson_uart_reset(port);
0785         meson_uart_release_port(port);
0786     }
0787 
0788     ret = uart_add_one_port(&meson_uart_driver, port);
0789     if (ret)
0790         meson_ports[pdev->id] = NULL;
0791 
0792     return ret;
0793 }
0794 
0795 static int meson_uart_remove(struct platform_device *pdev)
0796 {
0797     struct uart_port *port;
0798 
0799     port = platform_get_drvdata(pdev);
0800     uart_remove_one_port(&meson_uart_driver, port);
0801     meson_ports[pdev->id] = NULL;
0802 
0803     return 0;
0804 }
0805 
0806 static struct meson_uart_data s4_uart_data = {
0807     .has_xtal_div2 = true,
0808 };
0809 
0810 static const struct of_device_id meson_uart_dt_match[] = {
0811     { .compatible = "amlogic,meson6-uart" },
0812     { .compatible = "amlogic,meson8-uart" },
0813     { .compatible = "amlogic,meson8b-uart" },
0814     { .compatible = "amlogic,meson-gx-uart" },
0815     {
0816         .compatible = "amlogic,meson-s4-uart",
0817         .data = (void *)&s4_uart_data,
0818     },
0819     { /* sentinel */ },
0820 };
0821 MODULE_DEVICE_TABLE(of, meson_uart_dt_match);
0822 
0823 static  struct platform_driver meson_uart_platform_driver = {
0824     .probe      = meson_uart_probe,
0825     .remove     = meson_uart_remove,
0826     .driver     = {
0827         .name       = "meson_uart",
0828         .of_match_table = meson_uart_dt_match,
0829     },
0830 };
0831 
0832 static int __init meson_uart_init(void)
0833 {
0834     int ret;
0835 
0836     ret = meson_serial_console_init();
0837     if (ret)
0838         return ret;
0839     
0840     ret = uart_register_driver(&meson_uart_driver);
0841     if (ret)
0842         return ret;
0843 
0844     ret = platform_driver_register(&meson_uart_platform_driver);
0845     if (ret)
0846         uart_unregister_driver(&meson_uart_driver);
0847 
0848     return ret;
0849 }
0850 
0851 static void __exit meson_uart_exit(void)
0852 {
0853     platform_driver_unregister(&meson_uart_platform_driver);
0854     uart_unregister_driver(&meson_uart_driver);
0855 }
0856 
0857 module_init(meson_uart_init);
0858 module_exit(meson_uart_exit);
0859 
0860 MODULE_AUTHOR("Carlo Caione <carlo@caione.org>");
0861 MODULE_DESCRIPTION("Amlogic Meson serial port driver");
0862 MODULE_LICENSE("GPL v2");