Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  * High Speed Serial Ports on NXP LPC32xx SoC
0004  *
0005  * Authors: Kevin Wells <kevin.wells@nxp.com>
0006  *          Roland Stigge <stigge@antcom.de>
0007  *
0008  * Copyright (C) 2010 NXP Semiconductors
0009  * Copyright (C) 2012 Roland Stigge
0010  */
0011 
0012 #include <linux/module.h>
0013 #include <linux/ioport.h>
0014 #include <linux/init.h>
0015 #include <linux/console.h>
0016 #include <linux/sysrq.h>
0017 #include <linux/tty.h>
0018 #include <linux/tty_flip.h>
0019 #include <linux/serial_core.h>
0020 #include <linux/serial.h>
0021 #include <linux/platform_device.h>
0022 #include <linux/delay.h>
0023 #include <linux/nmi.h>
0024 #include <linux/io.h>
0025 #include <linux/irq.h>
0026 #include <linux/of.h>
0027 #include <linux/sizes.h>
0028 #include <linux/soc/nxp/lpc32xx-misc.h>
0029 
0030 /*
0031  * High Speed UART register offsets
0032  */
0033 #define LPC32XX_HSUART_FIFO(x)          ((x) + 0x00)
0034 #define LPC32XX_HSUART_LEVEL(x)         ((x) + 0x04)
0035 #define LPC32XX_HSUART_IIR(x)           ((x) + 0x08)
0036 #define LPC32XX_HSUART_CTRL(x)          ((x) + 0x0C)
0037 #define LPC32XX_HSUART_RATE(x)          ((x) + 0x10)
0038 
0039 #define LPC32XX_HSU_BREAK_DATA          (1 << 10)
0040 #define LPC32XX_HSU_ERROR_DATA          (1 << 9)
0041 #define LPC32XX_HSU_RX_EMPTY            (1 << 8)
0042 
0043 #define LPC32XX_HSU_TX_LEV(n)           (((n) >> 8) & 0xFF)
0044 #define LPC32XX_HSU_RX_LEV(n)           ((n) & 0xFF)
0045 
0046 #define LPC32XX_HSU_TX_INT_SET          (1 << 6)
0047 #define LPC32XX_HSU_RX_OE_INT           (1 << 5)
0048 #define LPC32XX_HSU_BRK_INT         (1 << 4)
0049 #define LPC32XX_HSU_FE_INT          (1 << 3)
0050 #define LPC32XX_HSU_RX_TIMEOUT_INT      (1 << 2)
0051 #define LPC32XX_HSU_RX_TRIG_INT         (1 << 1)
0052 #define LPC32XX_HSU_TX_INT          (1 << 0)
0053 
0054 #define LPC32XX_HSU_HRTS_INV            (1 << 21)
0055 #define LPC32XX_HSU_HRTS_TRIG_8B        (0x0 << 19)
0056 #define LPC32XX_HSU_HRTS_TRIG_16B       (0x1 << 19)
0057 #define LPC32XX_HSU_HRTS_TRIG_32B       (0x2 << 19)
0058 #define LPC32XX_HSU_HRTS_TRIG_48B       (0x3 << 19)
0059 #define LPC32XX_HSU_HRTS_EN         (1 << 18)
0060 #define LPC32XX_HSU_TMO_DISABLED        (0x0 << 16)
0061 #define LPC32XX_HSU_TMO_INACT_4B        (0x1 << 16)
0062 #define LPC32XX_HSU_TMO_INACT_8B        (0x2 << 16)
0063 #define LPC32XX_HSU_TMO_INACT_16B       (0x3 << 16)
0064 #define LPC32XX_HSU_HCTS_INV            (1 << 15)
0065 #define LPC32XX_HSU_HCTS_EN         (1 << 14)
0066 #define LPC32XX_HSU_OFFSET(n)           ((n) << 9)
0067 #define LPC32XX_HSU_BREAK           (1 << 8)
0068 #define LPC32XX_HSU_ERR_INT_EN          (1 << 7)
0069 #define LPC32XX_HSU_RX_INT_EN           (1 << 6)
0070 #define LPC32XX_HSU_TX_INT_EN           (1 << 5)
0071 #define LPC32XX_HSU_RX_TL1B         (0x0 << 2)
0072 #define LPC32XX_HSU_RX_TL4B         (0x1 << 2)
0073 #define LPC32XX_HSU_RX_TL8B         (0x2 << 2)
0074 #define LPC32XX_HSU_RX_TL16B            (0x3 << 2)
0075 #define LPC32XX_HSU_RX_TL32B            (0x4 << 2)
0076 #define LPC32XX_HSU_RX_TL48B            (0x5 << 2)
0077 #define LPC32XX_HSU_TX_TLEMPTY          (0x0 << 0)
0078 #define LPC32XX_HSU_TX_TL0B         (0x0 << 0)
0079 #define LPC32XX_HSU_TX_TL4B         (0x1 << 0)
0080 #define LPC32XX_HSU_TX_TL8B         (0x2 << 0)
0081 #define LPC32XX_HSU_TX_TL16B            (0x3 << 0)
0082 
0083 #define LPC32XX_MAIN_OSC_FREQ           13000000
0084 
0085 #define MODNAME "lpc32xx_hsuart"
0086 
0087 struct lpc32xx_hsuart_port {
0088     struct uart_port port;
0089 };
0090 
0091 #define FIFO_READ_LIMIT 128
0092 #define MAX_PORTS 3
0093 #define LPC32XX_TTY_NAME "ttyTX"
0094 static struct lpc32xx_hsuart_port lpc32xx_hs_ports[MAX_PORTS];
0095 
0096 #ifdef CONFIG_SERIAL_HS_LPC32XX_CONSOLE
0097 static void wait_for_xmit_empty(struct uart_port *port)
0098 {
0099     unsigned int timeout = 10000;
0100 
0101     do {
0102         if (LPC32XX_HSU_TX_LEV(readl(LPC32XX_HSUART_LEVEL(
0103                             port->membase))) == 0)
0104             break;
0105         if (--timeout == 0)
0106             break;
0107         udelay(1);
0108     } while (1);
0109 }
0110 
0111 static void wait_for_xmit_ready(struct uart_port *port)
0112 {
0113     unsigned int timeout = 10000;
0114 
0115     while (1) {
0116         if (LPC32XX_HSU_TX_LEV(readl(LPC32XX_HSUART_LEVEL(
0117                             port->membase))) < 32)
0118             break;
0119         if (--timeout == 0)
0120             break;
0121         udelay(1);
0122     }
0123 }
0124 
0125 static void lpc32xx_hsuart_console_putchar(struct uart_port *port, unsigned char ch)
0126 {
0127     wait_for_xmit_ready(port);
0128     writel((u32)ch, LPC32XX_HSUART_FIFO(port->membase));
0129 }
0130 
0131 static void lpc32xx_hsuart_console_write(struct console *co, const char *s,
0132                      unsigned int count)
0133 {
0134     struct lpc32xx_hsuart_port *up = &lpc32xx_hs_ports[co->index];
0135     unsigned long flags;
0136     int locked = 1;
0137 
0138     touch_nmi_watchdog();
0139     local_irq_save(flags);
0140     if (up->port.sysrq)
0141         locked = 0;
0142     else if (oops_in_progress)
0143         locked = spin_trylock(&up->port.lock);
0144     else
0145         spin_lock(&up->port.lock);
0146 
0147     uart_console_write(&up->port, s, count, lpc32xx_hsuart_console_putchar);
0148     wait_for_xmit_empty(&up->port);
0149 
0150     if (locked)
0151         spin_unlock(&up->port.lock);
0152     local_irq_restore(flags);
0153 }
0154 
0155 static int __init lpc32xx_hsuart_console_setup(struct console *co,
0156                            char *options)
0157 {
0158     struct uart_port *port;
0159     int baud = 115200;
0160     int bits = 8;
0161     int parity = 'n';
0162     int flow = 'n';
0163 
0164     if (co->index >= MAX_PORTS)
0165         co->index = 0;
0166 
0167     port = &lpc32xx_hs_ports[co->index].port;
0168     if (!port->membase)
0169         return -ENODEV;
0170 
0171     if (options)
0172         uart_parse_options(options, &baud, &parity, &bits, &flow);
0173 
0174     lpc32xx_loopback_set(port->mapbase, 0); /* get out of loopback mode */
0175 
0176     return uart_set_options(port, co, baud, parity, bits, flow);
0177 }
0178 
0179 static struct uart_driver lpc32xx_hsuart_reg;
0180 static struct console lpc32xx_hsuart_console = {
0181     .name       = LPC32XX_TTY_NAME,
0182     .write      = lpc32xx_hsuart_console_write,
0183     .device     = uart_console_device,
0184     .setup      = lpc32xx_hsuart_console_setup,
0185     .flags      = CON_PRINTBUFFER,
0186     .index      = -1,
0187     .data       = &lpc32xx_hsuart_reg,
0188 };
0189 
0190 static int __init lpc32xx_hsuart_console_init(void)
0191 {
0192     register_console(&lpc32xx_hsuart_console);
0193     return 0;
0194 }
0195 console_initcall(lpc32xx_hsuart_console_init);
0196 
0197 #define LPC32XX_HSUART_CONSOLE (&lpc32xx_hsuart_console)
0198 #else
0199 #define LPC32XX_HSUART_CONSOLE NULL
0200 #endif
0201 
0202 static struct uart_driver lpc32xx_hs_reg = {
0203     .owner      = THIS_MODULE,
0204     .driver_name    = MODNAME,
0205     .dev_name   = LPC32XX_TTY_NAME,
0206     .nr     = MAX_PORTS,
0207     .cons       = LPC32XX_HSUART_CONSOLE,
0208 };
0209 static int uarts_registered;
0210 
0211 static unsigned int __serial_get_clock_div(unsigned long uartclk,
0212                        unsigned long rate)
0213 {
0214     u32 div, goodrate, hsu_rate, l_hsu_rate, comprate;
0215     u32 rate_diff;
0216 
0217     /* Find the closest divider to get the desired clock rate */
0218     div = uartclk / rate;
0219     goodrate = hsu_rate = (div / 14) - 1;
0220     if (hsu_rate != 0)
0221         hsu_rate--;
0222 
0223     /* Tweak divider */
0224     l_hsu_rate = hsu_rate + 3;
0225     rate_diff = 0xFFFFFFFF;
0226 
0227     while (hsu_rate < l_hsu_rate) {
0228         comprate = uartclk / ((hsu_rate + 1) * 14);
0229         if (abs(comprate - rate) < rate_diff) {
0230             goodrate = hsu_rate;
0231             rate_diff = abs(comprate - rate);
0232         }
0233 
0234         hsu_rate++;
0235     }
0236     if (hsu_rate > 0xFF)
0237         hsu_rate = 0xFF;
0238 
0239     return goodrate;
0240 }
0241 
0242 static void __serial_uart_flush(struct uart_port *port)
0243 {
0244     int cnt = 0;
0245 
0246     while ((readl(LPC32XX_HSUART_LEVEL(port->membase)) > 0) &&
0247            (cnt++ < FIFO_READ_LIMIT))
0248         readl(LPC32XX_HSUART_FIFO(port->membase));
0249 }
0250 
0251 static void __serial_lpc32xx_rx(struct uart_port *port)
0252 {
0253     struct tty_port *tport = &port->state->port;
0254     unsigned int tmp, flag;
0255 
0256     /* Read data from FIFO and push into terminal */
0257     tmp = readl(LPC32XX_HSUART_FIFO(port->membase));
0258     while (!(tmp & LPC32XX_HSU_RX_EMPTY)) {
0259         flag = TTY_NORMAL;
0260         port->icount.rx++;
0261 
0262         if (tmp & LPC32XX_HSU_ERROR_DATA) {
0263             /* Framing error */
0264             writel(LPC32XX_HSU_FE_INT,
0265                    LPC32XX_HSUART_IIR(port->membase));
0266             port->icount.frame++;
0267             flag = TTY_FRAME;
0268             tty_insert_flip_char(tport, 0, TTY_FRAME);
0269         }
0270 
0271         tty_insert_flip_char(tport, (tmp & 0xFF), flag);
0272 
0273         tmp = readl(LPC32XX_HSUART_FIFO(port->membase));
0274     }
0275 
0276     tty_flip_buffer_push(tport);
0277 }
0278 
0279 static void serial_lpc32xx_stop_tx(struct uart_port *port);
0280 
0281 static void __serial_lpc32xx_tx(struct uart_port *port)
0282 {
0283     struct circ_buf *xmit = &port->state->xmit;
0284 
0285     if (port->x_char) {
0286         writel((u32)port->x_char, LPC32XX_HSUART_FIFO(port->membase));
0287         port->icount.tx++;
0288         port->x_char = 0;
0289         return;
0290     }
0291 
0292     if (uart_circ_empty(xmit) || uart_tx_stopped(port))
0293         goto exit_tx;
0294 
0295     /* Transfer data */
0296     while (LPC32XX_HSU_TX_LEV(readl(
0297         LPC32XX_HSUART_LEVEL(port->membase))) < 64) {
0298         writel((u32) xmit->buf[xmit->tail],
0299                LPC32XX_HSUART_FIFO(port->membase));
0300         xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
0301         port->icount.tx++;
0302         if (uart_circ_empty(xmit))
0303             break;
0304     }
0305 
0306     if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
0307         uart_write_wakeup(port);
0308 
0309 exit_tx:
0310     if (uart_circ_empty(xmit))
0311         serial_lpc32xx_stop_tx(port);
0312 }
0313 
0314 static irqreturn_t serial_lpc32xx_interrupt(int irq, void *dev_id)
0315 {
0316     struct uart_port *port = dev_id;
0317     struct tty_port *tport = &port->state->port;
0318     u32 status;
0319 
0320     spin_lock(&port->lock);
0321 
0322     /* Read UART status and clear latched interrupts */
0323     status = readl(LPC32XX_HSUART_IIR(port->membase));
0324 
0325     if (status & LPC32XX_HSU_BRK_INT) {
0326         /* Break received */
0327         writel(LPC32XX_HSU_BRK_INT, LPC32XX_HSUART_IIR(port->membase));
0328         port->icount.brk++;
0329         uart_handle_break(port);
0330     }
0331 
0332     /* Framing error */
0333     if (status & LPC32XX_HSU_FE_INT)
0334         writel(LPC32XX_HSU_FE_INT, LPC32XX_HSUART_IIR(port->membase));
0335 
0336     if (status & LPC32XX_HSU_RX_OE_INT) {
0337         /* Receive FIFO overrun */
0338         writel(LPC32XX_HSU_RX_OE_INT,
0339                LPC32XX_HSUART_IIR(port->membase));
0340         port->icount.overrun++;
0341         tty_insert_flip_char(tport, 0, TTY_OVERRUN);
0342         tty_flip_buffer_push(tport);
0343     }
0344 
0345     /* Data received? */
0346     if (status & (LPC32XX_HSU_RX_TIMEOUT_INT | LPC32XX_HSU_RX_TRIG_INT))
0347         __serial_lpc32xx_rx(port);
0348 
0349     /* Transmit data request? */
0350     if ((status & LPC32XX_HSU_TX_INT) && (!uart_tx_stopped(port))) {
0351         writel(LPC32XX_HSU_TX_INT, LPC32XX_HSUART_IIR(port->membase));
0352         __serial_lpc32xx_tx(port);
0353     }
0354 
0355     spin_unlock(&port->lock);
0356 
0357     return IRQ_HANDLED;
0358 }
0359 
0360 /* port->lock is not held.  */
0361 static unsigned int serial_lpc32xx_tx_empty(struct uart_port *port)
0362 {
0363     unsigned int ret = 0;
0364 
0365     if (LPC32XX_HSU_TX_LEV(readl(LPC32XX_HSUART_LEVEL(port->membase))) == 0)
0366         ret = TIOCSER_TEMT;
0367 
0368     return ret;
0369 }
0370 
0371 /* port->lock held by caller.  */
0372 static void serial_lpc32xx_set_mctrl(struct uart_port *port,
0373                      unsigned int mctrl)
0374 {
0375     /* No signals are supported on HS UARTs */
0376 }
0377 
0378 /* port->lock is held by caller and interrupts are disabled.  */
0379 static unsigned int serial_lpc32xx_get_mctrl(struct uart_port *port)
0380 {
0381     /* No signals are supported on HS UARTs */
0382     return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS;
0383 }
0384 
0385 /* port->lock held by caller.  */
0386 static void serial_lpc32xx_stop_tx(struct uart_port *port)
0387 {
0388     u32 tmp;
0389 
0390     tmp = readl(LPC32XX_HSUART_CTRL(port->membase));
0391     tmp &= ~LPC32XX_HSU_TX_INT_EN;
0392     writel(tmp, LPC32XX_HSUART_CTRL(port->membase));
0393 }
0394 
0395 /* port->lock held by caller.  */
0396 static void serial_lpc32xx_start_tx(struct uart_port *port)
0397 {
0398     u32 tmp;
0399 
0400     __serial_lpc32xx_tx(port);
0401     tmp = readl(LPC32XX_HSUART_CTRL(port->membase));
0402     tmp |= LPC32XX_HSU_TX_INT_EN;
0403     writel(tmp, LPC32XX_HSUART_CTRL(port->membase));
0404 }
0405 
0406 /* port->lock held by caller.  */
0407 static void serial_lpc32xx_stop_rx(struct uart_port *port)
0408 {
0409     u32 tmp;
0410 
0411     tmp = readl(LPC32XX_HSUART_CTRL(port->membase));
0412     tmp &= ~(LPC32XX_HSU_RX_INT_EN | LPC32XX_HSU_ERR_INT_EN);
0413     writel(tmp, LPC32XX_HSUART_CTRL(port->membase));
0414 
0415     writel((LPC32XX_HSU_BRK_INT | LPC32XX_HSU_RX_OE_INT |
0416         LPC32XX_HSU_FE_INT), LPC32XX_HSUART_IIR(port->membase));
0417 }
0418 
0419 /* port->lock is not held.  */
0420 static void serial_lpc32xx_break_ctl(struct uart_port *port,
0421                      int break_state)
0422 {
0423     unsigned long flags;
0424     u32 tmp;
0425 
0426     spin_lock_irqsave(&port->lock, flags);
0427     tmp = readl(LPC32XX_HSUART_CTRL(port->membase));
0428     if (break_state != 0)
0429         tmp |= LPC32XX_HSU_BREAK;
0430     else
0431         tmp &= ~LPC32XX_HSU_BREAK;
0432     writel(tmp, LPC32XX_HSUART_CTRL(port->membase));
0433     spin_unlock_irqrestore(&port->lock, flags);
0434 }
0435 
0436 /* port->lock is not held.  */
0437 static int serial_lpc32xx_startup(struct uart_port *port)
0438 {
0439     int retval;
0440     unsigned long flags;
0441     u32 tmp;
0442 
0443     spin_lock_irqsave(&port->lock, flags);
0444 
0445     __serial_uart_flush(port);
0446 
0447     writel((LPC32XX_HSU_TX_INT | LPC32XX_HSU_FE_INT |
0448         LPC32XX_HSU_BRK_INT | LPC32XX_HSU_RX_OE_INT),
0449            LPC32XX_HSUART_IIR(port->membase));
0450 
0451     writel(0xFF, LPC32XX_HSUART_RATE(port->membase));
0452 
0453     /*
0454      * Set receiver timeout, HSU offset of 20, no break, no interrupts,
0455      * and default FIFO trigger levels
0456      */
0457     tmp = LPC32XX_HSU_TX_TL8B | LPC32XX_HSU_RX_TL32B |
0458         LPC32XX_HSU_OFFSET(20) | LPC32XX_HSU_TMO_INACT_4B;
0459     writel(tmp, LPC32XX_HSUART_CTRL(port->membase));
0460 
0461     lpc32xx_loopback_set(port->mapbase, 0); /* get out of loopback mode */
0462 
0463     spin_unlock_irqrestore(&port->lock, flags);
0464 
0465     retval = request_irq(port->irq, serial_lpc32xx_interrupt,
0466                  0, MODNAME, port);
0467     if (!retval)
0468         writel((tmp | LPC32XX_HSU_RX_INT_EN | LPC32XX_HSU_ERR_INT_EN),
0469                LPC32XX_HSUART_CTRL(port->membase));
0470 
0471     return retval;
0472 }
0473 
0474 /* port->lock is not held.  */
0475 static void serial_lpc32xx_shutdown(struct uart_port *port)
0476 {
0477     u32 tmp;
0478     unsigned long flags;
0479 
0480     spin_lock_irqsave(&port->lock, flags);
0481 
0482     tmp = LPC32XX_HSU_TX_TL8B | LPC32XX_HSU_RX_TL32B |
0483         LPC32XX_HSU_OFFSET(20) | LPC32XX_HSU_TMO_INACT_4B;
0484     writel(tmp, LPC32XX_HSUART_CTRL(port->membase));
0485 
0486     lpc32xx_loopback_set(port->mapbase, 1); /* go to loopback mode */
0487 
0488     spin_unlock_irqrestore(&port->lock, flags);
0489 
0490     free_irq(port->irq, port);
0491 }
0492 
0493 /* port->lock is not held.  */
0494 static void serial_lpc32xx_set_termios(struct uart_port *port,
0495                        struct ktermios *termios,
0496                        struct ktermios *old)
0497 {
0498     unsigned long flags;
0499     unsigned int baud, quot;
0500     u32 tmp;
0501 
0502     /* Always 8-bit, no parity, 1 stop bit */
0503     termios->c_cflag &= ~(CSIZE | CSTOPB | PARENB | PARODD);
0504     termios->c_cflag |= CS8;
0505 
0506     termios->c_cflag &= ~(HUPCL | CMSPAR | CLOCAL | CRTSCTS);
0507 
0508     baud = uart_get_baud_rate(port, termios, old, 0,
0509                   port->uartclk / 14);
0510 
0511     quot = __serial_get_clock_div(port->uartclk, baud);
0512 
0513     spin_lock_irqsave(&port->lock, flags);
0514 
0515     /* Ignore characters? */
0516     tmp = readl(LPC32XX_HSUART_CTRL(port->membase));
0517     if ((termios->c_cflag & CREAD) == 0)
0518         tmp &= ~(LPC32XX_HSU_RX_INT_EN | LPC32XX_HSU_ERR_INT_EN);
0519     else
0520         tmp |= LPC32XX_HSU_RX_INT_EN | LPC32XX_HSU_ERR_INT_EN;
0521     writel(tmp, LPC32XX_HSUART_CTRL(port->membase));
0522 
0523     writel(quot, LPC32XX_HSUART_RATE(port->membase));
0524 
0525     uart_update_timeout(port, termios->c_cflag, baud);
0526 
0527     spin_unlock_irqrestore(&port->lock, flags);
0528 
0529     /* Don't rewrite B0 */
0530     if (tty_termios_baud_rate(termios))
0531         tty_termios_encode_baud_rate(termios, baud, baud);
0532 }
0533 
0534 static const char *serial_lpc32xx_type(struct uart_port *port)
0535 {
0536     return MODNAME;
0537 }
0538 
0539 static void serial_lpc32xx_release_port(struct uart_port *port)
0540 {
0541     if ((port->iotype == UPIO_MEM32) && (port->mapbase)) {
0542         if (port->flags & UPF_IOREMAP) {
0543             iounmap(port->membase);
0544             port->membase = NULL;
0545         }
0546 
0547         release_mem_region(port->mapbase, SZ_4K);
0548     }
0549 }
0550 
0551 static int serial_lpc32xx_request_port(struct uart_port *port)
0552 {
0553     int ret = -ENODEV;
0554 
0555     if ((port->iotype == UPIO_MEM32) && (port->mapbase)) {
0556         ret = 0;
0557 
0558         if (!request_mem_region(port->mapbase, SZ_4K, MODNAME))
0559             ret = -EBUSY;
0560         else if (port->flags & UPF_IOREMAP) {
0561             port->membase = ioremap(port->mapbase, SZ_4K);
0562             if (!port->membase) {
0563                 release_mem_region(port->mapbase, SZ_4K);
0564                 ret = -ENOMEM;
0565             }
0566         }
0567     }
0568 
0569     return ret;
0570 }
0571 
0572 static void serial_lpc32xx_config_port(struct uart_port *port, int uflags)
0573 {
0574     int ret;
0575 
0576     ret = serial_lpc32xx_request_port(port);
0577     if (ret < 0)
0578         return;
0579     port->type = PORT_UART00;
0580     port->fifosize = 64;
0581 
0582     __serial_uart_flush(port);
0583 
0584     writel((LPC32XX_HSU_TX_INT | LPC32XX_HSU_FE_INT |
0585         LPC32XX_HSU_BRK_INT | LPC32XX_HSU_RX_OE_INT),
0586            LPC32XX_HSUART_IIR(port->membase));
0587 
0588     writel(0xFF, LPC32XX_HSUART_RATE(port->membase));
0589 
0590     /* Set receiver timeout, HSU offset of 20, no break, no interrupts,
0591        and default FIFO trigger levels */
0592     writel(LPC32XX_HSU_TX_TL8B | LPC32XX_HSU_RX_TL32B |
0593            LPC32XX_HSU_OFFSET(20) | LPC32XX_HSU_TMO_INACT_4B,
0594            LPC32XX_HSUART_CTRL(port->membase));
0595 }
0596 
0597 static int serial_lpc32xx_verify_port(struct uart_port *port,
0598                       struct serial_struct *ser)
0599 {
0600     int ret = 0;
0601 
0602     if (ser->type != PORT_UART00)
0603         ret = -EINVAL;
0604 
0605     return ret;
0606 }
0607 
0608 static const struct uart_ops serial_lpc32xx_pops = {
0609     .tx_empty   = serial_lpc32xx_tx_empty,
0610     .set_mctrl  = serial_lpc32xx_set_mctrl,
0611     .get_mctrl  = serial_lpc32xx_get_mctrl,
0612     .stop_tx    = serial_lpc32xx_stop_tx,
0613     .start_tx   = serial_lpc32xx_start_tx,
0614     .stop_rx    = serial_lpc32xx_stop_rx,
0615     .break_ctl  = serial_lpc32xx_break_ctl,
0616     .startup    = serial_lpc32xx_startup,
0617     .shutdown   = serial_lpc32xx_shutdown,
0618     .set_termios    = serial_lpc32xx_set_termios,
0619     .type       = serial_lpc32xx_type,
0620     .release_port   = serial_lpc32xx_release_port,
0621     .request_port   = serial_lpc32xx_request_port,
0622     .config_port    = serial_lpc32xx_config_port,
0623     .verify_port    = serial_lpc32xx_verify_port,
0624 };
0625 
0626 /*
0627  * Register a set of serial devices attached to a platform device
0628  */
0629 static int serial_hs_lpc32xx_probe(struct platform_device *pdev)
0630 {
0631     struct lpc32xx_hsuart_port *p = &lpc32xx_hs_ports[uarts_registered];
0632     int ret = 0;
0633     struct resource *res;
0634 
0635     if (uarts_registered >= MAX_PORTS) {
0636         dev_err(&pdev->dev,
0637             "Error: Number of possible ports exceeded (%d)!\n",
0638             uarts_registered + 1);
0639         return -ENXIO;
0640     }
0641 
0642     memset(p, 0, sizeof(*p));
0643 
0644     res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0645     if (!res) {
0646         dev_err(&pdev->dev,
0647             "Error getting mem resource for HS UART port %d\n",
0648             uarts_registered);
0649         return -ENXIO;
0650     }
0651     p->port.mapbase = res->start;
0652     p->port.membase = NULL;
0653 
0654     ret = platform_get_irq(pdev, 0);
0655     if (ret < 0)
0656         return ret;
0657     p->port.irq = ret;
0658 
0659     p->port.iotype = UPIO_MEM32;
0660     p->port.uartclk = LPC32XX_MAIN_OSC_FREQ;
0661     p->port.regshift = 2;
0662     p->port.flags = UPF_BOOT_AUTOCONF | UPF_FIXED_PORT | UPF_IOREMAP;
0663     p->port.dev = &pdev->dev;
0664     p->port.ops = &serial_lpc32xx_pops;
0665     p->port.line = uarts_registered++;
0666     spin_lock_init(&p->port.lock);
0667 
0668     /* send port to loopback mode by default */
0669     lpc32xx_loopback_set(p->port.mapbase, 1);
0670 
0671     ret = uart_add_one_port(&lpc32xx_hs_reg, &p->port);
0672 
0673     platform_set_drvdata(pdev, p);
0674 
0675     return ret;
0676 }
0677 
0678 /*
0679  * Remove serial ports registered against a platform device.
0680  */
0681 static int serial_hs_lpc32xx_remove(struct platform_device *pdev)
0682 {
0683     struct lpc32xx_hsuart_port *p = platform_get_drvdata(pdev);
0684 
0685     uart_remove_one_port(&lpc32xx_hs_reg, &p->port);
0686 
0687     return 0;
0688 }
0689 
0690 
0691 #ifdef CONFIG_PM
0692 static int serial_hs_lpc32xx_suspend(struct platform_device *pdev,
0693                      pm_message_t state)
0694 {
0695     struct lpc32xx_hsuart_port *p = platform_get_drvdata(pdev);
0696 
0697     uart_suspend_port(&lpc32xx_hs_reg, &p->port);
0698 
0699     return 0;
0700 }
0701 
0702 static int serial_hs_lpc32xx_resume(struct platform_device *pdev)
0703 {
0704     struct lpc32xx_hsuart_port *p = platform_get_drvdata(pdev);
0705 
0706     uart_resume_port(&lpc32xx_hs_reg, &p->port);
0707 
0708     return 0;
0709 }
0710 #else
0711 #define serial_hs_lpc32xx_suspend   NULL
0712 #define serial_hs_lpc32xx_resume    NULL
0713 #endif
0714 
0715 static const struct of_device_id serial_hs_lpc32xx_dt_ids[] = {
0716     { .compatible = "nxp,lpc3220-hsuart" },
0717     { /* sentinel */ }
0718 };
0719 
0720 MODULE_DEVICE_TABLE(of, serial_hs_lpc32xx_dt_ids);
0721 
0722 static struct platform_driver serial_hs_lpc32xx_driver = {
0723     .probe      = serial_hs_lpc32xx_probe,
0724     .remove     = serial_hs_lpc32xx_remove,
0725     .suspend    = serial_hs_lpc32xx_suspend,
0726     .resume     = serial_hs_lpc32xx_resume,
0727     .driver     = {
0728         .name   = MODNAME,
0729         .of_match_table = serial_hs_lpc32xx_dt_ids,
0730     },
0731 };
0732 
0733 static int __init lpc32xx_hsuart_init(void)
0734 {
0735     int ret;
0736 
0737     ret = uart_register_driver(&lpc32xx_hs_reg);
0738     if (ret)
0739         return ret;
0740 
0741     ret = platform_driver_register(&serial_hs_lpc32xx_driver);
0742     if (ret)
0743         uart_unregister_driver(&lpc32xx_hs_reg);
0744 
0745     return ret;
0746 }
0747 
0748 static void __exit lpc32xx_hsuart_exit(void)
0749 {
0750     platform_driver_unregister(&serial_hs_lpc32xx_driver);
0751     uart_unregister_driver(&lpc32xx_hs_reg);
0752 }
0753 
0754 module_init(lpc32xx_hsuart_init);
0755 module_exit(lpc32xx_hsuart_exit);
0756 
0757 MODULE_AUTHOR("Kevin Wells <kevin.wells@nxp.com>");
0758 MODULE_AUTHOR("Roland Stigge <stigge@antcom.de>");
0759 MODULE_DESCRIPTION("NXP LPC32XX High Speed UART driver");
0760 MODULE_LICENSE("GPL");