Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Driver core for Samsung SoC onboard UARTs.
0004  *
0005  * Ben Dooks, Copyright (c) 2003-2008 Simtec Electronics
0006  *  http://armlinux.simtec.co.uk/
0007  */
0008 
0009 /* Note on 2410 error handling
0010  *
0011  * The s3c2410 manual has a love/hate affair with the contents of the
0012  * UERSTAT register in the UART blocks, and keeps marking some of the
0013  * error bits as reserved. Having checked with the s3c2410x01,
0014  * it copes with BREAKs properly, so I am happy to ignore the RESERVED
0015  * feature from the latter versions of the manual.
0016  *
0017  * If it becomes aparrent that latter versions of the 2410 remove these
0018  * bits, then action will have to be taken to differentiate the versions
0019  * and change the policy on BREAK
0020  *
0021  * BJD, 04-Nov-2004
0022  */
0023 
0024 #include <linux/dmaengine.h>
0025 #include <linux/dma-mapping.h>
0026 #include <linux/slab.h>
0027 #include <linux/module.h>
0028 #include <linux/ioport.h>
0029 #include <linux/io.h>
0030 #include <linux/platform_device.h>
0031 #include <linux/init.h>
0032 #include <linux/sysrq.h>
0033 #include <linux/console.h>
0034 #include <linux/tty.h>
0035 #include <linux/tty_flip.h>
0036 #include <linux/serial_core.h>
0037 #include <linux/serial.h>
0038 #include <linux/serial_s3c.h>
0039 #include <linux/delay.h>
0040 #include <linux/clk.h>
0041 #include <linux/cpufreq.h>
0042 #include <linux/of.h>
0043 #include <asm/irq.h>
0044 
0045 /* UART name and device definitions */
0046 
0047 #define S3C24XX_SERIAL_NAME "ttySAC"
0048 #define S3C24XX_SERIAL_MAJOR    204
0049 #define S3C24XX_SERIAL_MINOR    64
0050 
0051 #ifdef CONFIG_ARM64
0052 #define UART_NR         12
0053 #else
0054 #define UART_NR         CONFIG_SERIAL_SAMSUNG_UARTS
0055 #endif
0056 
0057 #define S3C24XX_TX_PIO          1
0058 #define S3C24XX_TX_DMA          2
0059 #define S3C24XX_RX_PIO          1
0060 #define S3C24XX_RX_DMA          2
0061 
0062 /* flag to ignore all characters coming in */
0063 #define RXSTAT_DUMMY_READ (0x10000000)
0064 
0065 enum s3c24xx_port_type {
0066     TYPE_S3C24XX,
0067     TYPE_S3C6400,
0068     TYPE_APPLE_S5L,
0069 };
0070 
0071 struct s3c24xx_uart_info {
0072     const char      *name;
0073     enum s3c24xx_port_type  type;
0074     unsigned int        port_type;
0075     unsigned int        fifosize;
0076     unsigned long       rx_fifomask;
0077     unsigned long       rx_fifoshift;
0078     unsigned long       rx_fifofull;
0079     unsigned long       tx_fifomask;
0080     unsigned long       tx_fifoshift;
0081     unsigned long       tx_fifofull;
0082     unsigned int        def_clk_sel;
0083     unsigned long       num_clks;
0084     unsigned long       clksel_mask;
0085     unsigned long       clksel_shift;
0086     unsigned long       ucon_mask;
0087 
0088     /* uart port features */
0089 
0090     unsigned int        has_divslot:1;
0091 };
0092 
0093 struct s3c24xx_serial_drv_data {
0094     const struct s3c24xx_uart_info  info;
0095     const struct s3c2410_uartcfg    def_cfg;
0096     const unsigned int      fifosize[UART_NR];
0097 };
0098 
0099 struct s3c24xx_uart_dma {
0100     unsigned int            rx_chan_id;
0101     unsigned int            tx_chan_id;
0102 
0103     struct dma_slave_config     rx_conf;
0104     struct dma_slave_config     tx_conf;
0105 
0106     struct dma_chan         *rx_chan;
0107     struct dma_chan         *tx_chan;
0108 
0109     dma_addr_t          rx_addr;
0110     dma_addr_t          tx_addr;
0111 
0112     dma_cookie_t            rx_cookie;
0113     dma_cookie_t            tx_cookie;
0114 
0115     char                *rx_buf;
0116 
0117     dma_addr_t          tx_transfer_addr;
0118 
0119     size_t              rx_size;
0120     size_t              tx_size;
0121 
0122     struct dma_async_tx_descriptor  *tx_desc;
0123     struct dma_async_tx_descriptor  *rx_desc;
0124 
0125     int             tx_bytes_requested;
0126     int             rx_bytes_requested;
0127 };
0128 
0129 struct s3c24xx_uart_port {
0130     unsigned char           rx_claimed;
0131     unsigned char           tx_claimed;
0132     unsigned char           rx_enabled;
0133     unsigned char           tx_enabled;
0134     unsigned int            pm_level;
0135     unsigned long           baudclk_rate;
0136     unsigned int            min_dma_size;
0137 
0138     unsigned int            rx_irq;
0139     unsigned int            tx_irq;
0140 
0141     unsigned int            tx_in_progress;
0142     unsigned int            tx_mode;
0143     unsigned int            rx_mode;
0144 
0145     const struct s3c24xx_uart_info  *info;
0146     struct clk          *clk;
0147     struct clk          *baudclk;
0148     struct uart_port        port;
0149     const struct s3c24xx_serial_drv_data    *drv_data;
0150 
0151     /* reference to platform data */
0152     const struct s3c2410_uartcfg    *cfg;
0153 
0154     struct s3c24xx_uart_dma     *dma;
0155 
0156 #ifdef CONFIG_ARM_S3C24XX_CPUFREQ
0157     struct notifier_block       freq_transition;
0158 #endif
0159 };
0160 
0161 static void s3c24xx_serial_tx_chars(struct s3c24xx_uart_port *ourport);
0162 
0163 /* conversion functions */
0164 
0165 #define s3c24xx_dev_to_port(__dev) dev_get_drvdata(__dev)
0166 
0167 /* register access controls */
0168 
0169 #define portaddr(port, reg) ((port)->membase + (reg))
0170 #define portaddrl(port, reg) \
0171     ((unsigned long *)(unsigned long)((port)->membase + (reg)))
0172 
0173 static u32 rd_reg(const struct uart_port *port, u32 reg)
0174 {
0175     switch (port->iotype) {
0176     case UPIO_MEM:
0177         return readb_relaxed(portaddr(port, reg));
0178     case UPIO_MEM32:
0179         return readl_relaxed(portaddr(port, reg));
0180     default:
0181         return 0;
0182     }
0183     return 0;
0184 }
0185 
0186 #define rd_regl(port, reg) (readl_relaxed(portaddr(port, reg)))
0187 
0188 static void wr_reg(const struct uart_port *port, u32 reg, u32 val)
0189 {
0190     switch (port->iotype) {
0191     case UPIO_MEM:
0192         writeb_relaxed(val, portaddr(port, reg));
0193         break;
0194     case UPIO_MEM32:
0195         writel_relaxed(val, portaddr(port, reg));
0196         break;
0197     }
0198 }
0199 
0200 #define wr_regl(port, reg, val) writel_relaxed(val, portaddr(port, reg))
0201 
0202 /* Byte-order aware bit setting/clearing functions. */
0203 
0204 static inline void s3c24xx_set_bit(const struct uart_port *port, int idx,
0205                    unsigned int reg)
0206 {
0207     unsigned long flags;
0208     u32 val;
0209 
0210     local_irq_save(flags);
0211     val = rd_regl(port, reg);
0212     val |= (1 << idx);
0213     wr_regl(port, reg, val);
0214     local_irq_restore(flags);
0215 }
0216 
0217 static inline void s3c24xx_clear_bit(const struct uart_port *port, int idx,
0218                      unsigned int reg)
0219 {
0220     unsigned long flags;
0221     u32 val;
0222 
0223     local_irq_save(flags);
0224     val = rd_regl(port, reg);
0225     val &= ~(1 << idx);
0226     wr_regl(port, reg, val);
0227     local_irq_restore(flags);
0228 }
0229 
0230 static inline struct s3c24xx_uart_port *to_ourport(struct uart_port *port)
0231 {
0232     return container_of(port, struct s3c24xx_uart_port, port);
0233 }
0234 
0235 /* translate a port to the device name */
0236 
0237 static inline const char *s3c24xx_serial_portname(const struct uart_port *port)
0238 {
0239     return to_platform_device(port->dev)->name;
0240 }
0241 
0242 static int s3c24xx_serial_txempty_nofifo(const struct uart_port *port)
0243 {
0244     return rd_regl(port, S3C2410_UTRSTAT) & S3C2410_UTRSTAT_TXE;
0245 }
0246 
0247 static void s3c24xx_serial_rx_enable(struct uart_port *port)
0248 {
0249     struct s3c24xx_uart_port *ourport = to_ourport(port);
0250     unsigned long flags;
0251     unsigned int ucon, ufcon;
0252     int count = 10000;
0253 
0254     spin_lock_irqsave(&port->lock, flags);
0255 
0256     while (--count && !s3c24xx_serial_txempty_nofifo(port))
0257         udelay(100);
0258 
0259     ufcon = rd_regl(port, S3C2410_UFCON);
0260     ufcon |= S3C2410_UFCON_RESETRX;
0261     wr_regl(port, S3C2410_UFCON, ufcon);
0262 
0263     ucon = rd_regl(port, S3C2410_UCON);
0264     ucon |= S3C2410_UCON_RXIRQMODE;
0265     wr_regl(port, S3C2410_UCON, ucon);
0266 
0267     ourport->rx_enabled = 1;
0268     spin_unlock_irqrestore(&port->lock, flags);
0269 }
0270 
0271 static void s3c24xx_serial_rx_disable(struct uart_port *port)
0272 {
0273     struct s3c24xx_uart_port *ourport = to_ourport(port);
0274     unsigned long flags;
0275     unsigned int ucon;
0276 
0277     spin_lock_irqsave(&port->lock, flags);
0278 
0279     ucon = rd_regl(port, S3C2410_UCON);
0280     ucon &= ~S3C2410_UCON_RXIRQMODE;
0281     wr_regl(port, S3C2410_UCON, ucon);
0282 
0283     ourport->rx_enabled = 0;
0284     spin_unlock_irqrestore(&port->lock, flags);
0285 }
0286 
0287 static void s3c24xx_serial_stop_tx(struct uart_port *port)
0288 {
0289     struct s3c24xx_uart_port *ourport = to_ourport(port);
0290     struct s3c24xx_uart_dma *dma = ourport->dma;
0291     struct circ_buf *xmit = &port->state->xmit;
0292     struct dma_tx_state state;
0293     int count;
0294 
0295     if (!ourport->tx_enabled)
0296         return;
0297 
0298     switch (ourport->info->type) {
0299     case TYPE_S3C6400:
0300         s3c24xx_set_bit(port, S3C64XX_UINTM_TXD, S3C64XX_UINTM);
0301         break;
0302     case TYPE_APPLE_S5L:
0303         s3c24xx_clear_bit(port, APPLE_S5L_UCON_TXTHRESH_ENA, S3C2410_UCON);
0304         break;
0305     default:
0306         disable_irq_nosync(ourport->tx_irq);
0307         break;
0308     }
0309 
0310     if (dma && dma->tx_chan && ourport->tx_in_progress == S3C24XX_TX_DMA) {
0311         dmaengine_pause(dma->tx_chan);
0312         dmaengine_tx_status(dma->tx_chan, dma->tx_cookie, &state);
0313         dmaengine_terminate_all(dma->tx_chan);
0314         dma_sync_single_for_cpu(dma->tx_chan->device->dev,
0315                     dma->tx_transfer_addr, dma->tx_size,
0316                     DMA_TO_DEVICE);
0317         async_tx_ack(dma->tx_desc);
0318         count = dma->tx_bytes_requested - state.residue;
0319         xmit->tail = (xmit->tail + count) & (UART_XMIT_SIZE - 1);
0320         port->icount.tx += count;
0321     }
0322 
0323     ourport->tx_enabled = 0;
0324     ourport->tx_in_progress = 0;
0325 
0326     if (port->flags & UPF_CONS_FLOW)
0327         s3c24xx_serial_rx_enable(port);
0328 
0329     ourport->tx_mode = 0;
0330 }
0331 
0332 static void s3c24xx_serial_start_next_tx(struct s3c24xx_uart_port *ourport);
0333 
0334 static void s3c24xx_serial_tx_dma_complete(void *args)
0335 {
0336     struct s3c24xx_uart_port *ourport = args;
0337     struct uart_port *port = &ourport->port;
0338     struct circ_buf *xmit = &port->state->xmit;
0339     struct s3c24xx_uart_dma *dma = ourport->dma;
0340     struct dma_tx_state state;
0341     unsigned long flags;
0342     int count;
0343 
0344     dmaengine_tx_status(dma->tx_chan, dma->tx_cookie, &state);
0345     count = dma->tx_bytes_requested - state.residue;
0346     async_tx_ack(dma->tx_desc);
0347 
0348     dma_sync_single_for_cpu(dma->tx_chan->device->dev,
0349                 dma->tx_transfer_addr, dma->tx_size,
0350                 DMA_TO_DEVICE);
0351 
0352     spin_lock_irqsave(&port->lock, flags);
0353 
0354     xmit->tail = (xmit->tail + count) & (UART_XMIT_SIZE - 1);
0355     port->icount.tx += count;
0356     ourport->tx_in_progress = 0;
0357 
0358     if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
0359         uart_write_wakeup(port);
0360 
0361     s3c24xx_serial_start_next_tx(ourport);
0362     spin_unlock_irqrestore(&port->lock, flags);
0363 }
0364 
0365 static void enable_tx_dma(struct s3c24xx_uart_port *ourport)
0366 {
0367     const struct uart_port *port = &ourport->port;
0368     u32 ucon;
0369 
0370     /* Mask Tx interrupt */
0371     switch (ourport->info->type) {
0372     case TYPE_S3C6400:
0373         s3c24xx_set_bit(port, S3C64XX_UINTM_TXD, S3C64XX_UINTM);
0374         break;
0375     case TYPE_APPLE_S5L:
0376         WARN_ON(1); // No DMA
0377         break;
0378     default:
0379         disable_irq_nosync(ourport->tx_irq);
0380         break;
0381     }
0382 
0383     /* Enable tx dma mode */
0384     ucon = rd_regl(port, S3C2410_UCON);
0385     ucon &= ~(S3C64XX_UCON_TXBURST_MASK | S3C64XX_UCON_TXMODE_MASK);
0386     ucon |= S3C64XX_UCON_TXBURST_1;
0387     ucon |= S3C64XX_UCON_TXMODE_DMA;
0388     wr_regl(port,  S3C2410_UCON, ucon);
0389 
0390     ourport->tx_mode = S3C24XX_TX_DMA;
0391 }
0392 
0393 static void enable_tx_pio(struct s3c24xx_uart_port *ourport)
0394 {
0395     const struct uart_port *port = &ourport->port;
0396     u32 ucon, ufcon;
0397 
0398     /* Set ufcon txtrig */
0399     ourport->tx_in_progress = S3C24XX_TX_PIO;
0400     ufcon = rd_regl(port, S3C2410_UFCON);
0401     wr_regl(port,  S3C2410_UFCON, ufcon);
0402 
0403     /* Enable tx pio mode */
0404     ucon = rd_regl(port, S3C2410_UCON);
0405     ucon &= ~(S3C64XX_UCON_TXMODE_MASK);
0406     ucon |= S3C64XX_UCON_TXMODE_CPU;
0407     wr_regl(port,  S3C2410_UCON, ucon);
0408 
0409     /* Unmask Tx interrupt */
0410     switch (ourport->info->type) {
0411     case TYPE_S3C6400:
0412         s3c24xx_clear_bit(port, S3C64XX_UINTM_TXD,
0413                   S3C64XX_UINTM);
0414         break;
0415     case TYPE_APPLE_S5L:
0416         ucon |= APPLE_S5L_UCON_TXTHRESH_ENA_MSK;
0417         wr_regl(port, S3C2410_UCON, ucon);
0418         break;
0419     default:
0420         enable_irq(ourport->tx_irq);
0421         break;
0422     }
0423 
0424     ourport->tx_mode = S3C24XX_TX_PIO;
0425 
0426     /*
0427      * The Apple version only has edge triggered TX IRQs, so we need
0428      * to kick off the process by sending some characters here.
0429      */
0430     if (ourport->info->type == TYPE_APPLE_S5L)
0431         s3c24xx_serial_tx_chars(ourport);
0432 }
0433 
0434 static void s3c24xx_serial_start_tx_pio(struct s3c24xx_uart_port *ourport)
0435 {
0436     if (ourport->tx_mode != S3C24XX_TX_PIO)
0437         enable_tx_pio(ourport);
0438 }
0439 
0440 static int s3c24xx_serial_start_tx_dma(struct s3c24xx_uart_port *ourport,
0441                       unsigned int count)
0442 {
0443     struct uart_port *port = &ourport->port;
0444     struct circ_buf *xmit = &port->state->xmit;
0445     struct s3c24xx_uart_dma *dma = ourport->dma;
0446 
0447     if (ourport->tx_mode != S3C24XX_TX_DMA)
0448         enable_tx_dma(ourport);
0449 
0450     dma->tx_size = count & ~(dma_get_cache_alignment() - 1);
0451     dma->tx_transfer_addr = dma->tx_addr + xmit->tail;
0452 
0453     dma_sync_single_for_device(dma->tx_chan->device->dev,
0454                    dma->tx_transfer_addr, dma->tx_size,
0455                    DMA_TO_DEVICE);
0456 
0457     dma->tx_desc = dmaengine_prep_slave_single(dma->tx_chan,
0458                 dma->tx_transfer_addr, dma->tx_size,
0459                 DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT);
0460     if (!dma->tx_desc) {
0461         dev_err(ourport->port.dev, "Unable to get desc for Tx\n");
0462         return -EIO;
0463     }
0464 
0465     dma->tx_desc->callback = s3c24xx_serial_tx_dma_complete;
0466     dma->tx_desc->callback_param = ourport;
0467     dma->tx_bytes_requested = dma->tx_size;
0468 
0469     ourport->tx_in_progress = S3C24XX_TX_DMA;
0470     dma->tx_cookie = dmaengine_submit(dma->tx_desc);
0471     dma_async_issue_pending(dma->tx_chan);
0472     return 0;
0473 }
0474 
0475 static void s3c24xx_serial_start_next_tx(struct s3c24xx_uart_port *ourport)
0476 {
0477     struct uart_port *port = &ourport->port;
0478     struct circ_buf *xmit = &port->state->xmit;
0479     unsigned long count;
0480 
0481     /* Get data size up to the end of buffer */
0482     count = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE);
0483 
0484     if (!count) {
0485         s3c24xx_serial_stop_tx(port);
0486         return;
0487     }
0488 
0489     if (!ourport->dma || !ourport->dma->tx_chan ||
0490         count < ourport->min_dma_size ||
0491         xmit->tail & (dma_get_cache_alignment() - 1))
0492         s3c24xx_serial_start_tx_pio(ourport);
0493     else
0494         s3c24xx_serial_start_tx_dma(ourport, count);
0495 }
0496 
0497 static void s3c24xx_serial_start_tx(struct uart_port *port)
0498 {
0499     struct s3c24xx_uart_port *ourport = to_ourport(port);
0500     struct circ_buf *xmit = &port->state->xmit;
0501 
0502     if (!ourport->tx_enabled) {
0503         if (port->flags & UPF_CONS_FLOW)
0504             s3c24xx_serial_rx_disable(port);
0505 
0506         ourport->tx_enabled = 1;
0507         if (!ourport->dma || !ourport->dma->tx_chan)
0508             s3c24xx_serial_start_tx_pio(ourport);
0509     }
0510 
0511     if (ourport->dma && ourport->dma->tx_chan) {
0512         if (!uart_circ_empty(xmit) && !ourport->tx_in_progress)
0513             s3c24xx_serial_start_next_tx(ourport);
0514     }
0515 }
0516 
0517 static void s3c24xx_uart_copy_rx_to_tty(struct s3c24xx_uart_port *ourport,
0518         struct tty_port *tty, int count)
0519 {
0520     struct s3c24xx_uart_dma *dma = ourport->dma;
0521     int copied;
0522 
0523     if (!count)
0524         return;
0525 
0526     dma_sync_single_for_cpu(dma->rx_chan->device->dev, dma->rx_addr,
0527                 dma->rx_size, DMA_FROM_DEVICE);
0528 
0529     ourport->port.icount.rx += count;
0530     if (!tty) {
0531         dev_err(ourport->port.dev, "No tty port\n");
0532         return;
0533     }
0534     copied = tty_insert_flip_string(tty,
0535             ((unsigned char *)(ourport->dma->rx_buf)), count);
0536     if (copied != count) {
0537         WARN_ON(1);
0538         dev_err(ourport->port.dev, "RxData copy to tty layer failed\n");
0539     }
0540 }
0541 
0542 static void s3c24xx_serial_stop_rx(struct uart_port *port)
0543 {
0544     struct s3c24xx_uart_port *ourport = to_ourport(port);
0545     struct s3c24xx_uart_dma *dma = ourport->dma;
0546     struct tty_port *t = &port->state->port;
0547     struct dma_tx_state state;
0548     enum dma_status dma_status;
0549     unsigned int received;
0550 
0551     if (ourport->rx_enabled) {
0552         dev_dbg(port->dev, "stopping rx\n");
0553         switch (ourport->info->type) {
0554         case TYPE_S3C6400:
0555             s3c24xx_set_bit(port, S3C64XX_UINTM_RXD,
0556                     S3C64XX_UINTM);
0557             break;
0558         case TYPE_APPLE_S5L:
0559             s3c24xx_clear_bit(port, APPLE_S5L_UCON_RXTHRESH_ENA, S3C2410_UCON);
0560             s3c24xx_clear_bit(port, APPLE_S5L_UCON_RXTO_ENA, S3C2410_UCON);
0561             break;
0562         default:
0563             disable_irq_nosync(ourport->rx_irq);
0564             break;
0565         }
0566         ourport->rx_enabled = 0;
0567     }
0568     if (dma && dma->rx_chan) {
0569         dmaengine_pause(dma->tx_chan);
0570         dma_status = dmaengine_tx_status(dma->rx_chan,
0571                 dma->rx_cookie, &state);
0572         if (dma_status == DMA_IN_PROGRESS ||
0573             dma_status == DMA_PAUSED) {
0574             received = dma->rx_bytes_requested - state.residue;
0575             dmaengine_terminate_all(dma->rx_chan);
0576             s3c24xx_uart_copy_rx_to_tty(ourport, t, received);
0577         }
0578     }
0579 }
0580 
0581 static inline const struct s3c24xx_uart_info
0582     *s3c24xx_port_to_info(struct uart_port *port)
0583 {
0584     return to_ourport(port)->info;
0585 }
0586 
0587 static inline const struct s3c2410_uartcfg
0588     *s3c24xx_port_to_cfg(const struct uart_port *port)
0589 {
0590     const struct s3c24xx_uart_port *ourport;
0591 
0592     if (port->dev == NULL)
0593         return NULL;
0594 
0595     ourport = container_of(port, struct s3c24xx_uart_port, port);
0596     return ourport->cfg;
0597 }
0598 
0599 static int s3c24xx_serial_rx_fifocnt(const struct s3c24xx_uart_port *ourport,
0600                      unsigned long ufstat)
0601 {
0602     const struct s3c24xx_uart_info *info = ourport->info;
0603 
0604     if (ufstat & info->rx_fifofull)
0605         return ourport->port.fifosize;
0606 
0607     return (ufstat & info->rx_fifomask) >> info->rx_fifoshift;
0608 }
0609 
0610 static void s3c64xx_start_rx_dma(struct s3c24xx_uart_port *ourport);
0611 static void s3c24xx_serial_rx_dma_complete(void *args)
0612 {
0613     struct s3c24xx_uart_port *ourport = args;
0614     struct uart_port *port = &ourport->port;
0615 
0616     struct s3c24xx_uart_dma *dma = ourport->dma;
0617     struct tty_port *t = &port->state->port;
0618     struct tty_struct *tty = tty_port_tty_get(&ourport->port.state->port);
0619 
0620     struct dma_tx_state state;
0621     unsigned long flags;
0622     int received;
0623 
0624     dmaengine_tx_status(dma->rx_chan,  dma->rx_cookie, &state);
0625     received  = dma->rx_bytes_requested - state.residue;
0626     async_tx_ack(dma->rx_desc);
0627 
0628     spin_lock_irqsave(&port->lock, flags);
0629 
0630     if (received)
0631         s3c24xx_uart_copy_rx_to_tty(ourport, t, received);
0632 
0633     if (tty) {
0634         tty_flip_buffer_push(t);
0635         tty_kref_put(tty);
0636     }
0637 
0638     s3c64xx_start_rx_dma(ourport);
0639 
0640     spin_unlock_irqrestore(&port->lock, flags);
0641 }
0642 
0643 static void s3c64xx_start_rx_dma(struct s3c24xx_uart_port *ourport)
0644 {
0645     struct s3c24xx_uart_dma *dma = ourport->dma;
0646 
0647     dma_sync_single_for_device(dma->rx_chan->device->dev, dma->rx_addr,
0648                    dma->rx_size, DMA_FROM_DEVICE);
0649 
0650     dma->rx_desc = dmaengine_prep_slave_single(dma->rx_chan,
0651                 dma->rx_addr, dma->rx_size, DMA_DEV_TO_MEM,
0652                 DMA_PREP_INTERRUPT);
0653     if (!dma->rx_desc) {
0654         dev_err(ourport->port.dev, "Unable to get desc for Rx\n");
0655         return;
0656     }
0657 
0658     dma->rx_desc->callback = s3c24xx_serial_rx_dma_complete;
0659     dma->rx_desc->callback_param = ourport;
0660     dma->rx_bytes_requested = dma->rx_size;
0661 
0662     dma->rx_cookie = dmaengine_submit(dma->rx_desc);
0663     dma_async_issue_pending(dma->rx_chan);
0664 }
0665 
0666 /* ? - where has parity gone?? */
0667 #define S3C2410_UERSTAT_PARITY (0x1000)
0668 
0669 static void enable_rx_dma(struct s3c24xx_uart_port *ourport)
0670 {
0671     struct uart_port *port = &ourport->port;
0672     unsigned int ucon;
0673 
0674     /* set Rx mode to DMA mode */
0675     ucon = rd_regl(port, S3C2410_UCON);
0676     ucon &= ~(S3C64XX_UCON_RXBURST_MASK |
0677             S3C64XX_UCON_TIMEOUT_MASK |
0678             S3C64XX_UCON_EMPTYINT_EN |
0679             S3C64XX_UCON_DMASUS_EN |
0680             S3C64XX_UCON_TIMEOUT_EN |
0681             S3C64XX_UCON_RXMODE_MASK);
0682     ucon |= S3C64XX_UCON_RXBURST_1 |
0683             0xf << S3C64XX_UCON_TIMEOUT_SHIFT |
0684             S3C64XX_UCON_EMPTYINT_EN |
0685             S3C64XX_UCON_TIMEOUT_EN |
0686             S3C64XX_UCON_RXMODE_DMA;
0687     wr_regl(port, S3C2410_UCON, ucon);
0688 
0689     ourport->rx_mode = S3C24XX_RX_DMA;
0690 }
0691 
0692 static void enable_rx_pio(struct s3c24xx_uart_port *ourport)
0693 {
0694     struct uart_port *port = &ourport->port;
0695     unsigned int ucon;
0696 
0697     /* set Rx mode to DMA mode */
0698     ucon = rd_regl(port, S3C2410_UCON);
0699     ucon &= ~S3C64XX_UCON_RXMODE_MASK;
0700     ucon |= S3C64XX_UCON_RXMODE_CPU;
0701 
0702     /* Apple types use these bits for IRQ masks */
0703     if (ourport->info->type != TYPE_APPLE_S5L) {
0704         ucon &= ~(S3C64XX_UCON_TIMEOUT_MASK |
0705                 S3C64XX_UCON_EMPTYINT_EN |
0706                 S3C64XX_UCON_DMASUS_EN |
0707                 S3C64XX_UCON_TIMEOUT_EN);
0708         ucon |= 0xf << S3C64XX_UCON_TIMEOUT_SHIFT |
0709                 S3C64XX_UCON_TIMEOUT_EN;
0710     }
0711     wr_regl(port, S3C2410_UCON, ucon);
0712 
0713     ourport->rx_mode = S3C24XX_RX_PIO;
0714 }
0715 
0716 static void s3c24xx_serial_rx_drain_fifo(struct s3c24xx_uart_port *ourport);
0717 
0718 static irqreturn_t s3c24xx_serial_rx_chars_dma(void *dev_id)
0719 {
0720     unsigned int utrstat, received;
0721     struct s3c24xx_uart_port *ourport = dev_id;
0722     struct uart_port *port = &ourport->port;
0723     struct s3c24xx_uart_dma *dma = ourport->dma;
0724     struct tty_struct *tty = tty_port_tty_get(&ourport->port.state->port);
0725     struct tty_port *t = &port->state->port;
0726     struct dma_tx_state state;
0727 
0728     utrstat = rd_regl(port, S3C2410_UTRSTAT);
0729     rd_regl(port, S3C2410_UFSTAT);
0730 
0731     spin_lock(&port->lock);
0732 
0733     if (!(utrstat & S3C2410_UTRSTAT_TIMEOUT)) {
0734         s3c64xx_start_rx_dma(ourport);
0735         if (ourport->rx_mode == S3C24XX_RX_PIO)
0736             enable_rx_dma(ourport);
0737         goto finish;
0738     }
0739 
0740     if (ourport->rx_mode == S3C24XX_RX_DMA) {
0741         dmaengine_pause(dma->rx_chan);
0742         dmaengine_tx_status(dma->rx_chan, dma->rx_cookie, &state);
0743         dmaengine_terminate_all(dma->rx_chan);
0744         received = dma->rx_bytes_requested - state.residue;
0745         s3c24xx_uart_copy_rx_to_tty(ourport, t, received);
0746 
0747         enable_rx_pio(ourport);
0748     }
0749 
0750     s3c24xx_serial_rx_drain_fifo(ourport);
0751 
0752     if (tty) {
0753         tty_flip_buffer_push(t);
0754         tty_kref_put(tty);
0755     }
0756 
0757     wr_regl(port, S3C2410_UTRSTAT, S3C2410_UTRSTAT_TIMEOUT);
0758 
0759 finish:
0760     spin_unlock(&port->lock);
0761 
0762     return IRQ_HANDLED;
0763 }
0764 
0765 static void s3c24xx_serial_rx_drain_fifo(struct s3c24xx_uart_port *ourport)
0766 {
0767     struct uart_port *port = &ourport->port;
0768     unsigned int ufcon, ch, flag, ufstat, uerstat;
0769     unsigned int fifocnt = 0;
0770     int max_count = port->fifosize;
0771 
0772     while (max_count-- > 0) {
0773         /*
0774          * Receive all characters known to be in FIFO
0775          * before reading FIFO level again
0776          */
0777         if (fifocnt == 0) {
0778             ufstat = rd_regl(port, S3C2410_UFSTAT);
0779             fifocnt = s3c24xx_serial_rx_fifocnt(ourport, ufstat);
0780             if (fifocnt == 0)
0781                 break;
0782         }
0783         fifocnt--;
0784 
0785         uerstat = rd_regl(port, S3C2410_UERSTAT);
0786         ch = rd_reg(port, S3C2410_URXH);
0787 
0788         if (port->flags & UPF_CONS_FLOW) {
0789             int txe = s3c24xx_serial_txempty_nofifo(port);
0790 
0791             if (ourport->rx_enabled) {
0792                 if (!txe) {
0793                     ourport->rx_enabled = 0;
0794                     continue;
0795                 }
0796             } else {
0797                 if (txe) {
0798                     ufcon = rd_regl(port, S3C2410_UFCON);
0799                     ufcon |= S3C2410_UFCON_RESETRX;
0800                     wr_regl(port, S3C2410_UFCON, ufcon);
0801                     ourport->rx_enabled = 1;
0802                     return;
0803                 }
0804                 continue;
0805             }
0806         }
0807 
0808         /* insert the character into the buffer */
0809 
0810         flag = TTY_NORMAL;
0811         port->icount.rx++;
0812 
0813         if (unlikely(uerstat & S3C2410_UERSTAT_ANY)) {
0814             dev_dbg(port->dev,
0815                 "rxerr: port ch=0x%02x, rxs=0x%08x\n",
0816                 ch, uerstat);
0817 
0818             /* check for break */
0819             if (uerstat & S3C2410_UERSTAT_BREAK) {
0820                 dev_dbg(port->dev, "break!\n");
0821                 port->icount.brk++;
0822                 if (uart_handle_break(port))
0823                     continue; /* Ignore character */
0824             }
0825 
0826             if (uerstat & S3C2410_UERSTAT_FRAME)
0827                 port->icount.frame++;
0828             if (uerstat & S3C2410_UERSTAT_OVERRUN)
0829                 port->icount.overrun++;
0830 
0831             uerstat &= port->read_status_mask;
0832 
0833             if (uerstat & S3C2410_UERSTAT_BREAK)
0834                 flag = TTY_BREAK;
0835             else if (uerstat & S3C2410_UERSTAT_PARITY)
0836                 flag = TTY_PARITY;
0837             else if (uerstat & (S3C2410_UERSTAT_FRAME |
0838                         S3C2410_UERSTAT_OVERRUN))
0839                 flag = TTY_FRAME;
0840         }
0841 
0842         if (uart_handle_sysrq_char(port, ch))
0843             continue; /* Ignore character */
0844 
0845         uart_insert_char(port, uerstat, S3C2410_UERSTAT_OVERRUN,
0846                  ch, flag);
0847     }
0848 
0849     tty_flip_buffer_push(&port->state->port);
0850 }
0851 
0852 static irqreturn_t s3c24xx_serial_rx_chars_pio(void *dev_id)
0853 {
0854     struct s3c24xx_uart_port *ourport = dev_id;
0855     struct uart_port *port = &ourport->port;
0856 
0857     spin_lock(&port->lock);
0858     s3c24xx_serial_rx_drain_fifo(ourport);
0859     spin_unlock(&port->lock);
0860 
0861     return IRQ_HANDLED;
0862 }
0863 
0864 static irqreturn_t s3c24xx_serial_rx_irq(int irq, void *dev_id)
0865 {
0866     struct s3c24xx_uart_port *ourport = dev_id;
0867 
0868     if (ourport->dma && ourport->dma->rx_chan)
0869         return s3c24xx_serial_rx_chars_dma(dev_id);
0870     return s3c24xx_serial_rx_chars_pio(dev_id);
0871 }
0872 
0873 static void s3c24xx_serial_tx_chars(struct s3c24xx_uart_port *ourport)
0874 {
0875     struct uart_port *port = &ourport->port;
0876     struct circ_buf *xmit = &port->state->xmit;
0877     int count, dma_count = 0;
0878 
0879     count = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE);
0880 
0881     if (ourport->dma && ourport->dma->tx_chan &&
0882         count >= ourport->min_dma_size) {
0883         int align = dma_get_cache_alignment() -
0884             (xmit->tail & (dma_get_cache_alignment() - 1));
0885         if (count - align >= ourport->min_dma_size) {
0886             dma_count = count - align;
0887             count = align;
0888         }
0889     }
0890 
0891     if (port->x_char) {
0892         wr_reg(port, S3C2410_UTXH, port->x_char);
0893         port->icount.tx++;
0894         port->x_char = 0;
0895         return;
0896     }
0897 
0898     /* if there isn't anything more to transmit, or the uart is now
0899      * stopped, disable the uart and exit
0900      */
0901 
0902     if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
0903         s3c24xx_serial_stop_tx(port);
0904         return;
0905     }
0906 
0907     /* try and drain the buffer... */
0908 
0909     if (count > port->fifosize) {
0910         count = port->fifosize;
0911         dma_count = 0;
0912     }
0913 
0914     while (!uart_circ_empty(xmit) && count > 0) {
0915         if (rd_regl(port, S3C2410_UFSTAT) & ourport->info->tx_fifofull)
0916             break;
0917 
0918         wr_reg(port, S3C2410_UTXH, xmit->buf[xmit->tail]);
0919         xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
0920         port->icount.tx++;
0921         count--;
0922     }
0923 
0924     if (!count && dma_count) {
0925         s3c24xx_serial_start_tx_dma(ourport, dma_count);
0926         return;
0927     }
0928 
0929     if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
0930         uart_write_wakeup(port);
0931 
0932     if (uart_circ_empty(xmit))
0933         s3c24xx_serial_stop_tx(port);
0934 }
0935 
0936 static irqreturn_t s3c24xx_serial_tx_irq(int irq, void *id)
0937 {
0938     struct s3c24xx_uart_port *ourport = id;
0939     struct uart_port *port = &ourport->port;
0940 
0941     spin_lock(&port->lock);
0942 
0943     s3c24xx_serial_tx_chars(ourport);
0944 
0945     spin_unlock(&port->lock);
0946     return IRQ_HANDLED;
0947 }
0948 
0949 /* interrupt handler for s3c64xx and later SoC's.*/
0950 static irqreturn_t s3c64xx_serial_handle_irq(int irq, void *id)
0951 {
0952     const struct s3c24xx_uart_port *ourport = id;
0953     const struct uart_port *port = &ourport->port;
0954     unsigned int pend = rd_regl(port, S3C64XX_UINTP);
0955     irqreturn_t ret = IRQ_HANDLED;
0956 
0957     if (pend & S3C64XX_UINTM_RXD_MSK) {
0958         ret = s3c24xx_serial_rx_irq(irq, id);
0959         wr_regl(port, S3C64XX_UINTP, S3C64XX_UINTM_RXD_MSK);
0960     }
0961     if (pend & S3C64XX_UINTM_TXD_MSK) {
0962         ret = s3c24xx_serial_tx_irq(irq, id);
0963         wr_regl(port, S3C64XX_UINTP, S3C64XX_UINTM_TXD_MSK);
0964     }
0965     return ret;
0966 }
0967 
0968 /* interrupt handler for Apple SoC's.*/
0969 static irqreturn_t apple_serial_handle_irq(int irq, void *id)
0970 {
0971     const struct s3c24xx_uart_port *ourport = id;
0972     const struct uart_port *port = &ourport->port;
0973     unsigned int pend = rd_regl(port, S3C2410_UTRSTAT);
0974     irqreturn_t ret = IRQ_NONE;
0975 
0976     if (pend & (APPLE_S5L_UTRSTAT_RXTHRESH | APPLE_S5L_UTRSTAT_RXTO)) {
0977         wr_regl(port, S3C2410_UTRSTAT,
0978             APPLE_S5L_UTRSTAT_RXTHRESH | APPLE_S5L_UTRSTAT_RXTO);
0979         ret = s3c24xx_serial_rx_irq(irq, id);
0980     }
0981     if (pend & APPLE_S5L_UTRSTAT_TXTHRESH) {
0982         wr_regl(port, S3C2410_UTRSTAT, APPLE_S5L_UTRSTAT_TXTHRESH);
0983         ret = s3c24xx_serial_tx_irq(irq, id);
0984     }
0985 
0986     return ret;
0987 }
0988 
0989 static unsigned int s3c24xx_serial_tx_empty(struct uart_port *port)
0990 {
0991     const struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
0992     unsigned long ufstat = rd_regl(port, S3C2410_UFSTAT);
0993     unsigned long ufcon = rd_regl(port, S3C2410_UFCON);
0994 
0995     if (ufcon & S3C2410_UFCON_FIFOMODE) {
0996         if ((ufstat & info->tx_fifomask) != 0 ||
0997             (ufstat & info->tx_fifofull))
0998             return 0;
0999 
1000         return 1;
1001     }
1002 
1003     return s3c24xx_serial_txempty_nofifo(port);
1004 }
1005 
1006 /* no modem control lines */
1007 static unsigned int s3c24xx_serial_get_mctrl(struct uart_port *port)
1008 {
1009     unsigned int umstat = rd_reg(port, S3C2410_UMSTAT);
1010 
1011     if (umstat & S3C2410_UMSTAT_CTS)
1012         return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS;
1013     else
1014         return TIOCM_CAR | TIOCM_DSR;
1015 }
1016 
1017 static void s3c24xx_serial_set_mctrl(struct uart_port *port, unsigned int mctrl)
1018 {
1019     unsigned int umcon = rd_regl(port, S3C2410_UMCON);
1020     unsigned int ucon = rd_regl(port, S3C2410_UCON);
1021 
1022     if (mctrl & TIOCM_RTS)
1023         umcon |= S3C2410_UMCOM_RTS_LOW;
1024     else
1025         umcon &= ~S3C2410_UMCOM_RTS_LOW;
1026 
1027     wr_regl(port, S3C2410_UMCON, umcon);
1028 
1029     if (mctrl & TIOCM_LOOP)
1030         ucon |= S3C2410_UCON_LOOPBACK;
1031     else
1032         ucon &= ~S3C2410_UCON_LOOPBACK;
1033 
1034     wr_regl(port, S3C2410_UCON, ucon);
1035 }
1036 
1037 static void s3c24xx_serial_break_ctl(struct uart_port *port, int break_state)
1038 {
1039     unsigned long flags;
1040     unsigned int ucon;
1041 
1042     spin_lock_irqsave(&port->lock, flags);
1043 
1044     ucon = rd_regl(port, S3C2410_UCON);
1045 
1046     if (break_state)
1047         ucon |= S3C2410_UCON_SBREAK;
1048     else
1049         ucon &= ~S3C2410_UCON_SBREAK;
1050 
1051     wr_regl(port, S3C2410_UCON, ucon);
1052 
1053     spin_unlock_irqrestore(&port->lock, flags);
1054 }
1055 
1056 static int s3c24xx_serial_request_dma(struct s3c24xx_uart_port *p)
1057 {
1058     struct s3c24xx_uart_dma *dma = p->dma;
1059     struct dma_slave_caps dma_caps;
1060     const char *reason = NULL;
1061     int ret;
1062 
1063     /* Default slave configuration parameters */
1064     dma->rx_conf.direction      = DMA_DEV_TO_MEM;
1065     dma->rx_conf.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
1066     dma->rx_conf.src_addr       = p->port.mapbase + S3C2410_URXH;
1067     dma->rx_conf.src_maxburst   = 1;
1068 
1069     dma->tx_conf.direction      = DMA_MEM_TO_DEV;
1070     dma->tx_conf.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
1071     dma->tx_conf.dst_addr       = p->port.mapbase + S3C2410_UTXH;
1072     dma->tx_conf.dst_maxburst   = 1;
1073 
1074     dma->rx_chan = dma_request_chan(p->port.dev, "rx");
1075 
1076     if (IS_ERR(dma->rx_chan)) {
1077         reason = "DMA RX channel request failed";
1078         ret = PTR_ERR(dma->rx_chan);
1079         goto err_warn;
1080     }
1081 
1082     ret = dma_get_slave_caps(dma->rx_chan, &dma_caps);
1083     if (ret < 0 ||
1084         dma_caps.residue_granularity < DMA_RESIDUE_GRANULARITY_BURST) {
1085         reason = "insufficient DMA RX engine capabilities";
1086         ret = -EOPNOTSUPP;
1087         goto err_release_rx;
1088     }
1089 
1090     dmaengine_slave_config(dma->rx_chan, &dma->rx_conf);
1091 
1092     dma->tx_chan = dma_request_chan(p->port.dev, "tx");
1093     if (IS_ERR(dma->tx_chan)) {
1094         reason = "DMA TX channel request failed";
1095         ret = PTR_ERR(dma->tx_chan);
1096         goto err_release_rx;
1097     }
1098 
1099     ret = dma_get_slave_caps(dma->tx_chan, &dma_caps);
1100     if (ret < 0 ||
1101         dma_caps.residue_granularity < DMA_RESIDUE_GRANULARITY_BURST) {
1102         reason = "insufficient DMA TX engine capabilities";
1103         ret = -EOPNOTSUPP;
1104         goto err_release_tx;
1105     }
1106 
1107     dmaengine_slave_config(dma->tx_chan, &dma->tx_conf);
1108 
1109     /* RX buffer */
1110     dma->rx_size = PAGE_SIZE;
1111 
1112     dma->rx_buf = kmalloc(dma->rx_size, GFP_KERNEL);
1113     if (!dma->rx_buf) {
1114         ret = -ENOMEM;
1115         goto err_release_tx;
1116     }
1117 
1118     dma->rx_addr = dma_map_single(dma->rx_chan->device->dev, dma->rx_buf,
1119                       dma->rx_size, DMA_FROM_DEVICE);
1120     if (dma_mapping_error(dma->rx_chan->device->dev, dma->rx_addr)) {
1121         reason = "DMA mapping error for RX buffer";
1122         ret = -EIO;
1123         goto err_free_rx;
1124     }
1125 
1126     /* TX buffer */
1127     dma->tx_addr = dma_map_single(dma->tx_chan->device->dev,
1128                       p->port.state->xmit.buf, UART_XMIT_SIZE,
1129                       DMA_TO_DEVICE);
1130     if (dma_mapping_error(dma->tx_chan->device->dev, dma->tx_addr)) {
1131         reason = "DMA mapping error for TX buffer";
1132         ret = -EIO;
1133         goto err_unmap_rx;
1134     }
1135 
1136     return 0;
1137 
1138 err_unmap_rx:
1139     dma_unmap_single(dma->rx_chan->device->dev, dma->rx_addr,
1140              dma->rx_size, DMA_FROM_DEVICE);
1141 err_free_rx:
1142     kfree(dma->rx_buf);
1143 err_release_tx:
1144     dma_release_channel(dma->tx_chan);
1145 err_release_rx:
1146     dma_release_channel(dma->rx_chan);
1147 err_warn:
1148     if (reason)
1149         dev_warn(p->port.dev, "%s, DMA will not be used\n", reason);
1150     return ret;
1151 }
1152 
1153 static void s3c24xx_serial_release_dma(struct s3c24xx_uart_port *p)
1154 {
1155     struct s3c24xx_uart_dma *dma = p->dma;
1156 
1157     if (dma->rx_chan) {
1158         dmaengine_terminate_all(dma->rx_chan);
1159         dma_unmap_single(dma->rx_chan->device->dev, dma->rx_addr,
1160                  dma->rx_size, DMA_FROM_DEVICE);
1161         kfree(dma->rx_buf);
1162         dma_release_channel(dma->rx_chan);
1163         dma->rx_chan = NULL;
1164     }
1165 
1166     if (dma->tx_chan) {
1167         dmaengine_terminate_all(dma->tx_chan);
1168         dma_unmap_single(dma->tx_chan->device->dev, dma->tx_addr,
1169                  UART_XMIT_SIZE, DMA_TO_DEVICE);
1170         dma_release_channel(dma->tx_chan);
1171         dma->tx_chan = NULL;
1172     }
1173 }
1174 
1175 static void s3c24xx_serial_shutdown(struct uart_port *port)
1176 {
1177     struct s3c24xx_uart_port *ourport = to_ourport(port);
1178 
1179     if (ourport->tx_claimed) {
1180         free_irq(ourport->tx_irq, ourport);
1181         ourport->tx_enabled = 0;
1182         ourport->tx_claimed = 0;
1183         ourport->tx_mode = 0;
1184     }
1185 
1186     if (ourport->rx_claimed) {
1187         free_irq(ourport->rx_irq, ourport);
1188         ourport->rx_claimed = 0;
1189         ourport->rx_enabled = 0;
1190     }
1191 
1192     if (ourport->dma)
1193         s3c24xx_serial_release_dma(ourport);
1194 
1195     ourport->tx_in_progress = 0;
1196 }
1197 
1198 static void s3c64xx_serial_shutdown(struct uart_port *port)
1199 {
1200     struct s3c24xx_uart_port *ourport = to_ourport(port);
1201 
1202     ourport->tx_enabled = 0;
1203     ourport->tx_mode = 0;
1204     ourport->rx_enabled = 0;
1205 
1206     free_irq(port->irq, ourport);
1207 
1208     wr_regl(port, S3C64XX_UINTP, 0xf);
1209     wr_regl(port, S3C64XX_UINTM, 0xf);
1210 
1211     if (ourport->dma)
1212         s3c24xx_serial_release_dma(ourport);
1213 
1214     ourport->tx_in_progress = 0;
1215 }
1216 
1217 static void apple_s5l_serial_shutdown(struct uart_port *port)
1218 {
1219     struct s3c24xx_uart_port *ourport = to_ourport(port);
1220 
1221     unsigned int ucon;
1222 
1223     ucon = rd_regl(port, S3C2410_UCON);
1224     ucon &= ~(APPLE_S5L_UCON_TXTHRESH_ENA_MSK |
1225           APPLE_S5L_UCON_RXTHRESH_ENA_MSK |
1226           APPLE_S5L_UCON_RXTO_ENA_MSK);
1227     wr_regl(port, S3C2410_UCON, ucon);
1228 
1229     wr_regl(port, S3C2410_UTRSTAT, APPLE_S5L_UTRSTAT_ALL_FLAGS);
1230 
1231     free_irq(port->irq, ourport);
1232 
1233     ourport->tx_enabled = 0;
1234     ourport->tx_mode = 0;
1235     ourport->rx_enabled = 0;
1236 
1237     if (ourport->dma)
1238         s3c24xx_serial_release_dma(ourport);
1239 
1240     ourport->tx_in_progress = 0;
1241 }
1242 
1243 static int s3c24xx_serial_startup(struct uart_port *port)
1244 {
1245     struct s3c24xx_uart_port *ourport = to_ourport(port);
1246     int ret;
1247 
1248     ourport->rx_enabled = 1;
1249 
1250     ret = request_irq(ourport->rx_irq, s3c24xx_serial_rx_irq, 0,
1251               s3c24xx_serial_portname(port), ourport);
1252 
1253     if (ret != 0) {
1254         dev_err(port->dev, "cannot get irq %d\n", ourport->rx_irq);
1255         return ret;
1256     }
1257 
1258     ourport->rx_claimed = 1;
1259 
1260     dev_dbg(port->dev, "requesting tx irq...\n");
1261 
1262     ourport->tx_enabled = 1;
1263 
1264     ret = request_irq(ourport->tx_irq, s3c24xx_serial_tx_irq, 0,
1265               s3c24xx_serial_portname(port), ourport);
1266 
1267     if (ret) {
1268         dev_err(port->dev, "cannot get irq %d\n", ourport->tx_irq);
1269         goto err;
1270     }
1271 
1272     ourport->tx_claimed = 1;
1273 
1274     /* the port reset code should have done the correct
1275      * register setup for the port controls
1276      */
1277 
1278     return ret;
1279 
1280 err:
1281     s3c24xx_serial_shutdown(port);
1282     return ret;
1283 }
1284 
1285 static int s3c64xx_serial_startup(struct uart_port *port)
1286 {
1287     struct s3c24xx_uart_port *ourport = to_ourport(port);
1288     unsigned long flags;
1289     unsigned int ufcon;
1290     int ret;
1291 
1292     wr_regl(port, S3C64XX_UINTM, 0xf);
1293     if (ourport->dma) {
1294         ret = s3c24xx_serial_request_dma(ourport);
1295         if (ret < 0) {
1296             devm_kfree(port->dev, ourport->dma);
1297             ourport->dma = NULL;
1298         }
1299     }
1300 
1301     ret = request_irq(port->irq, s3c64xx_serial_handle_irq, IRQF_SHARED,
1302               s3c24xx_serial_portname(port), ourport);
1303     if (ret) {
1304         dev_err(port->dev, "cannot get irq %d\n", port->irq);
1305         return ret;
1306     }
1307 
1308     /* For compatibility with s3c24xx Soc's */
1309     ourport->rx_enabled = 1;
1310     ourport->tx_enabled = 0;
1311 
1312     spin_lock_irqsave(&port->lock, flags);
1313 
1314     ufcon = rd_regl(port, S3C2410_UFCON);
1315     ufcon |= S3C2410_UFCON_RESETRX | S5PV210_UFCON_RXTRIG8;
1316     if (!uart_console(port))
1317         ufcon |= S3C2410_UFCON_RESETTX;
1318     wr_regl(port, S3C2410_UFCON, ufcon);
1319 
1320     enable_rx_pio(ourport);
1321 
1322     spin_unlock_irqrestore(&port->lock, flags);
1323 
1324     /* Enable Rx Interrupt */
1325     s3c24xx_clear_bit(port, S3C64XX_UINTM_RXD, S3C64XX_UINTM);
1326 
1327     return ret;
1328 }
1329 
1330 static int apple_s5l_serial_startup(struct uart_port *port)
1331 {
1332     struct s3c24xx_uart_port *ourport = to_ourport(port);
1333     unsigned long flags;
1334     unsigned int ufcon;
1335     int ret;
1336 
1337     wr_regl(port, S3C2410_UTRSTAT, APPLE_S5L_UTRSTAT_ALL_FLAGS);
1338 
1339     ret = request_irq(port->irq, apple_serial_handle_irq, 0,
1340               s3c24xx_serial_portname(port), ourport);
1341     if (ret) {
1342         dev_err(port->dev, "cannot get irq %d\n", port->irq);
1343         return ret;
1344     }
1345 
1346     /* For compatibility with s3c24xx Soc's */
1347     ourport->rx_enabled = 1;
1348     ourport->tx_enabled = 0;
1349 
1350     spin_lock_irqsave(&port->lock, flags);
1351 
1352     ufcon = rd_regl(port, S3C2410_UFCON);
1353     ufcon |= S3C2410_UFCON_RESETRX | S5PV210_UFCON_RXTRIG8;
1354     if (!uart_console(port))
1355         ufcon |= S3C2410_UFCON_RESETTX;
1356     wr_regl(port, S3C2410_UFCON, ufcon);
1357 
1358     enable_rx_pio(ourport);
1359 
1360     spin_unlock_irqrestore(&port->lock, flags);
1361 
1362     /* Enable Rx Interrupt */
1363     s3c24xx_set_bit(port, APPLE_S5L_UCON_RXTHRESH_ENA, S3C2410_UCON);
1364     s3c24xx_set_bit(port, APPLE_S5L_UCON_RXTO_ENA, S3C2410_UCON);
1365 
1366     return ret;
1367 }
1368 
1369 /* power power management control */
1370 
1371 static void s3c24xx_serial_pm(struct uart_port *port, unsigned int level,
1372                   unsigned int old)
1373 {
1374     struct s3c24xx_uart_port *ourport = to_ourport(port);
1375     int timeout = 10000;
1376 
1377     ourport->pm_level = level;
1378 
1379     switch (level) {
1380     case 3:
1381         while (--timeout && !s3c24xx_serial_txempty_nofifo(port))
1382             udelay(100);
1383 
1384         if (!IS_ERR(ourport->baudclk))
1385             clk_disable_unprepare(ourport->baudclk);
1386 
1387         clk_disable_unprepare(ourport->clk);
1388         break;
1389 
1390     case 0:
1391         clk_prepare_enable(ourport->clk);
1392 
1393         if (!IS_ERR(ourport->baudclk))
1394             clk_prepare_enable(ourport->baudclk);
1395         break;
1396     default:
1397         dev_err(port->dev, "s3c24xx_serial: unknown pm %d\n", level);
1398     }
1399 }
1400 
1401 /* baud rate calculation
1402  *
1403  * The UARTs on the S3C2410/S3C2440 can take their clocks from a number
1404  * of different sources, including the peripheral clock ("pclk") and an
1405  * external clock ("uclk"). The S3C2440 also adds the core clock ("fclk")
1406  * with a programmable extra divisor.
1407  *
1408  * The following code goes through the clock sources, and calculates the
1409  * baud clocks (and the resultant actual baud rates) and then tries to
1410  * pick the closest one and select that.
1411  *
1412  */
1413 
1414 #define MAX_CLK_NAME_LENGTH 15
1415 
1416 static inline int s3c24xx_serial_getsource(struct uart_port *port)
1417 {
1418     const struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
1419     unsigned int ucon;
1420 
1421     if (info->num_clks == 1)
1422         return 0;
1423 
1424     ucon = rd_regl(port, S3C2410_UCON);
1425     ucon &= info->clksel_mask;
1426     return ucon >> info->clksel_shift;
1427 }
1428 
1429 static void s3c24xx_serial_setsource(struct uart_port *port,
1430             unsigned int clk_sel)
1431 {
1432     const struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
1433     unsigned int ucon;
1434 
1435     if (info->num_clks == 1)
1436         return;
1437 
1438     ucon = rd_regl(port, S3C2410_UCON);
1439     if ((ucon & info->clksel_mask) >> info->clksel_shift == clk_sel)
1440         return;
1441 
1442     ucon &= ~info->clksel_mask;
1443     ucon |= clk_sel << info->clksel_shift;
1444     wr_regl(port, S3C2410_UCON, ucon);
1445 }
1446 
1447 static unsigned int s3c24xx_serial_getclk(struct s3c24xx_uart_port *ourport,
1448             unsigned int req_baud, struct clk **best_clk,
1449             unsigned int *clk_num)
1450 {
1451     const struct s3c24xx_uart_info *info = ourport->info;
1452     struct clk *clk;
1453     unsigned long rate;
1454     unsigned int cnt, baud, quot, best_quot = 0;
1455     char clkname[MAX_CLK_NAME_LENGTH];
1456     int calc_deviation, deviation = (1 << 30) - 1;
1457 
1458     for (cnt = 0; cnt < info->num_clks; cnt++) {
1459         /* Keep selected clock if provided */
1460         if (ourport->cfg->clk_sel &&
1461             !(ourport->cfg->clk_sel & (1 << cnt)))
1462             continue;
1463 
1464         sprintf(clkname, "clk_uart_baud%d", cnt);
1465         clk = clk_get(ourport->port.dev, clkname);
1466         if (IS_ERR(clk))
1467             continue;
1468 
1469         rate = clk_get_rate(clk);
1470         if (!rate)
1471             continue;
1472 
1473         if (ourport->info->has_divslot) {
1474             unsigned long div = rate / req_baud;
1475 
1476             /* The UDIVSLOT register on the newer UARTs allows us to
1477              * get a divisor adjustment of 1/16th on the baud clock.
1478              *
1479              * We don't keep the UDIVSLOT value (the 16ths we
1480              * calculated by not multiplying the baud by 16) as it
1481              * is easy enough to recalculate.
1482              */
1483 
1484             quot = div / 16;
1485             baud = rate / div;
1486         } else {
1487             quot = (rate + (8 * req_baud)) / (16 * req_baud);
1488             baud = rate / (quot * 16);
1489         }
1490         quot--;
1491 
1492         calc_deviation = req_baud - baud;
1493         if (calc_deviation < 0)
1494             calc_deviation = -calc_deviation;
1495 
1496         if (calc_deviation < deviation) {
1497             *best_clk = clk;
1498             best_quot = quot;
1499             *clk_num = cnt;
1500             deviation = calc_deviation;
1501         }
1502     }
1503 
1504     return best_quot;
1505 }
1506 
1507 /* udivslot_table[]
1508  *
1509  * This table takes the fractional value of the baud divisor and gives
1510  * the recommended setting for the UDIVSLOT register.
1511  */
1512 static const u16 udivslot_table[16] = {
1513     [0] = 0x0000,
1514     [1] = 0x0080,
1515     [2] = 0x0808,
1516     [3] = 0x0888,
1517     [4] = 0x2222,
1518     [5] = 0x4924,
1519     [6] = 0x4A52,
1520     [7] = 0x54AA,
1521     [8] = 0x5555,
1522     [9] = 0xD555,
1523     [10] = 0xD5D5,
1524     [11] = 0xDDD5,
1525     [12] = 0xDDDD,
1526     [13] = 0xDFDD,
1527     [14] = 0xDFDF,
1528     [15] = 0xFFDF,
1529 };
1530 
1531 static void s3c24xx_serial_set_termios(struct uart_port *port,
1532                        struct ktermios *termios,
1533                        struct ktermios *old)
1534 {
1535     const struct s3c2410_uartcfg *cfg = s3c24xx_port_to_cfg(port);
1536     struct s3c24xx_uart_port *ourport = to_ourport(port);
1537     struct clk *clk = ERR_PTR(-EINVAL);
1538     unsigned long flags;
1539     unsigned int baud, quot, clk_sel = 0;
1540     unsigned int ulcon;
1541     unsigned int umcon;
1542     unsigned int udivslot = 0;
1543 
1544     /*
1545      * We don't support modem control lines.
1546      */
1547     termios->c_cflag &= ~(HUPCL | CMSPAR);
1548     termios->c_cflag |= CLOCAL;
1549 
1550     /*
1551      * Ask the core to calculate the divisor for us.
1552      */
1553 
1554     baud = uart_get_baud_rate(port, termios, old, 0, 3000000);
1555     quot = s3c24xx_serial_getclk(ourport, baud, &clk, &clk_sel);
1556     if (baud == 38400 && (port->flags & UPF_SPD_MASK) == UPF_SPD_CUST)
1557         quot = port->custom_divisor;
1558     if (IS_ERR(clk))
1559         return;
1560 
1561     /* check to see if we need  to change clock source */
1562 
1563     if (ourport->baudclk != clk) {
1564         clk_prepare_enable(clk);
1565 
1566         s3c24xx_serial_setsource(port, clk_sel);
1567 
1568         if (!IS_ERR(ourport->baudclk)) {
1569             clk_disable_unprepare(ourport->baudclk);
1570             ourport->baudclk = ERR_PTR(-EINVAL);
1571         }
1572 
1573         ourport->baudclk = clk;
1574         ourport->baudclk_rate = clk ? clk_get_rate(clk) : 0;
1575     }
1576 
1577     if (ourport->info->has_divslot) {
1578         unsigned int div = ourport->baudclk_rate / baud;
1579 
1580         if (cfg->has_fracval) {
1581             udivslot = (div & 15);
1582             dev_dbg(port->dev, "fracval = %04x\n", udivslot);
1583         } else {
1584             udivslot = udivslot_table[div & 15];
1585             dev_dbg(port->dev, "udivslot = %04x (div %d)\n",
1586                 udivslot, div & 15);
1587         }
1588     }
1589 
1590     switch (termios->c_cflag & CSIZE) {
1591     case CS5:
1592         dev_dbg(port->dev, "config: 5bits/char\n");
1593         ulcon = S3C2410_LCON_CS5;
1594         break;
1595     case CS6:
1596         dev_dbg(port->dev, "config: 6bits/char\n");
1597         ulcon = S3C2410_LCON_CS6;
1598         break;
1599     case CS7:
1600         dev_dbg(port->dev, "config: 7bits/char\n");
1601         ulcon = S3C2410_LCON_CS7;
1602         break;
1603     case CS8:
1604     default:
1605         dev_dbg(port->dev, "config: 8bits/char\n");
1606         ulcon = S3C2410_LCON_CS8;
1607         break;
1608     }
1609 
1610     /* preserve original lcon IR settings */
1611     ulcon |= (cfg->ulcon & S3C2410_LCON_IRM);
1612 
1613     if (termios->c_cflag & CSTOPB)
1614         ulcon |= S3C2410_LCON_STOPB;
1615 
1616     if (termios->c_cflag & PARENB) {
1617         if (termios->c_cflag & PARODD)
1618             ulcon |= S3C2410_LCON_PODD;
1619         else
1620             ulcon |= S3C2410_LCON_PEVEN;
1621     } else {
1622         ulcon |= S3C2410_LCON_PNONE;
1623     }
1624 
1625     spin_lock_irqsave(&port->lock, flags);
1626 
1627     dev_dbg(port->dev,
1628         "setting ulcon to %08x, brddiv to %d, udivslot %08x\n",
1629         ulcon, quot, udivslot);
1630 
1631     wr_regl(port, S3C2410_ULCON, ulcon);
1632     wr_regl(port, S3C2410_UBRDIV, quot);
1633 
1634     port->status &= ~UPSTAT_AUTOCTS;
1635 
1636     umcon = rd_regl(port, S3C2410_UMCON);
1637     if (termios->c_cflag & CRTSCTS) {
1638         umcon |= S3C2410_UMCOM_AFC;
1639         /* Disable RTS when RX FIFO contains 63 bytes */
1640         umcon &= ~S3C2412_UMCON_AFC_8;
1641         port->status = UPSTAT_AUTOCTS;
1642     } else {
1643         umcon &= ~S3C2410_UMCOM_AFC;
1644     }
1645     wr_regl(port, S3C2410_UMCON, umcon);
1646 
1647     if (ourport->info->has_divslot)
1648         wr_regl(port, S3C2443_DIVSLOT, udivslot);
1649 
1650     dev_dbg(port->dev,
1651         "uart: ulcon = 0x%08x, ucon = 0x%08x, ufcon = 0x%08x\n",
1652         rd_regl(port, S3C2410_ULCON),
1653         rd_regl(port, S3C2410_UCON),
1654         rd_regl(port, S3C2410_UFCON));
1655 
1656     /*
1657      * Update the per-port timeout.
1658      */
1659     uart_update_timeout(port, termios->c_cflag, baud);
1660 
1661     /*
1662      * Which character status flags are we interested in?
1663      */
1664     port->read_status_mask = S3C2410_UERSTAT_OVERRUN;
1665     if (termios->c_iflag & INPCK)
1666         port->read_status_mask |= S3C2410_UERSTAT_FRAME |
1667             S3C2410_UERSTAT_PARITY;
1668     /*
1669      * Which character status flags should we ignore?
1670      */
1671     port->ignore_status_mask = 0;
1672     if (termios->c_iflag & IGNPAR)
1673         port->ignore_status_mask |= S3C2410_UERSTAT_OVERRUN;
1674     if (termios->c_iflag & IGNBRK && termios->c_iflag & IGNPAR)
1675         port->ignore_status_mask |= S3C2410_UERSTAT_FRAME;
1676 
1677     /*
1678      * Ignore all characters if CREAD is not set.
1679      */
1680     if ((termios->c_cflag & CREAD) == 0)
1681         port->ignore_status_mask |= RXSTAT_DUMMY_READ;
1682 
1683     spin_unlock_irqrestore(&port->lock, flags);
1684 }
1685 
1686 static const char *s3c24xx_serial_type(struct uart_port *port)
1687 {
1688     const struct s3c24xx_uart_port *ourport = to_ourport(port);
1689 
1690     switch (ourport->info->type) {
1691     case TYPE_S3C24XX:
1692         return "S3C24XX";
1693     case TYPE_S3C6400:
1694         return "S3C6400/10";
1695     case TYPE_APPLE_S5L:
1696         return "APPLE S5L";
1697     default:
1698         return NULL;
1699     }
1700 }
1701 
1702 static void s3c24xx_serial_config_port(struct uart_port *port, int flags)
1703 {
1704     const struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
1705 
1706     if (flags & UART_CONFIG_TYPE)
1707         port->type = info->port_type;
1708 }
1709 
1710 /*
1711  * verify the new serial_struct (for TIOCSSERIAL).
1712  */
1713 static int
1714 s3c24xx_serial_verify_port(struct uart_port *port, struct serial_struct *ser)
1715 {
1716     const struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
1717 
1718     if (ser->type != PORT_UNKNOWN && ser->type != info->port_type)
1719         return -EINVAL;
1720 
1721     return 0;
1722 }
1723 
1724 #ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE
1725 
1726 static struct console s3c24xx_serial_console;
1727 
1728 static void __init s3c24xx_serial_register_console(void)
1729 {
1730     register_console(&s3c24xx_serial_console);
1731 }
1732 
1733 static void s3c24xx_serial_unregister_console(void)
1734 {
1735     if (s3c24xx_serial_console.flags & CON_ENABLED)
1736         unregister_console(&s3c24xx_serial_console);
1737 }
1738 
1739 #define S3C24XX_SERIAL_CONSOLE &s3c24xx_serial_console
1740 #else
1741 static inline void s3c24xx_serial_register_console(void) { }
1742 static inline void s3c24xx_serial_unregister_console(void) { }
1743 #define S3C24XX_SERIAL_CONSOLE NULL
1744 #endif
1745 
1746 #if defined(CONFIG_SERIAL_SAMSUNG_CONSOLE) && defined(CONFIG_CONSOLE_POLL)
1747 static int s3c24xx_serial_get_poll_char(struct uart_port *port);
1748 static void s3c24xx_serial_put_poll_char(struct uart_port *port,
1749              unsigned char c);
1750 #endif
1751 
1752 static const struct uart_ops s3c24xx_serial_ops = {
1753     .pm     = s3c24xx_serial_pm,
1754     .tx_empty   = s3c24xx_serial_tx_empty,
1755     .get_mctrl  = s3c24xx_serial_get_mctrl,
1756     .set_mctrl  = s3c24xx_serial_set_mctrl,
1757     .stop_tx    = s3c24xx_serial_stop_tx,
1758     .start_tx   = s3c24xx_serial_start_tx,
1759     .stop_rx    = s3c24xx_serial_stop_rx,
1760     .break_ctl  = s3c24xx_serial_break_ctl,
1761     .startup    = s3c24xx_serial_startup,
1762     .shutdown   = s3c24xx_serial_shutdown,
1763     .set_termios    = s3c24xx_serial_set_termios,
1764     .type       = s3c24xx_serial_type,
1765     .config_port    = s3c24xx_serial_config_port,
1766     .verify_port    = s3c24xx_serial_verify_port,
1767 #if defined(CONFIG_SERIAL_SAMSUNG_CONSOLE) && defined(CONFIG_CONSOLE_POLL)
1768     .poll_get_char = s3c24xx_serial_get_poll_char,
1769     .poll_put_char = s3c24xx_serial_put_poll_char,
1770 #endif
1771 };
1772 
1773 static const struct uart_ops s3c64xx_serial_ops = {
1774     .pm     = s3c24xx_serial_pm,
1775     .tx_empty   = s3c24xx_serial_tx_empty,
1776     .get_mctrl  = s3c24xx_serial_get_mctrl,
1777     .set_mctrl  = s3c24xx_serial_set_mctrl,
1778     .stop_tx    = s3c24xx_serial_stop_tx,
1779     .start_tx   = s3c24xx_serial_start_tx,
1780     .stop_rx    = s3c24xx_serial_stop_rx,
1781     .break_ctl  = s3c24xx_serial_break_ctl,
1782     .startup    = s3c64xx_serial_startup,
1783     .shutdown   = s3c64xx_serial_shutdown,
1784     .set_termios    = s3c24xx_serial_set_termios,
1785     .type       = s3c24xx_serial_type,
1786     .config_port    = s3c24xx_serial_config_port,
1787     .verify_port    = s3c24xx_serial_verify_port,
1788 #if defined(CONFIG_SERIAL_SAMSUNG_CONSOLE) && defined(CONFIG_CONSOLE_POLL)
1789     .poll_get_char = s3c24xx_serial_get_poll_char,
1790     .poll_put_char = s3c24xx_serial_put_poll_char,
1791 #endif
1792 };
1793 
1794 static const struct uart_ops apple_s5l_serial_ops = {
1795     .pm     = s3c24xx_serial_pm,
1796     .tx_empty   = s3c24xx_serial_tx_empty,
1797     .get_mctrl  = s3c24xx_serial_get_mctrl,
1798     .set_mctrl  = s3c24xx_serial_set_mctrl,
1799     .stop_tx    = s3c24xx_serial_stop_tx,
1800     .start_tx   = s3c24xx_serial_start_tx,
1801     .stop_rx    = s3c24xx_serial_stop_rx,
1802     .break_ctl  = s3c24xx_serial_break_ctl,
1803     .startup    = apple_s5l_serial_startup,
1804     .shutdown   = apple_s5l_serial_shutdown,
1805     .set_termios    = s3c24xx_serial_set_termios,
1806     .type       = s3c24xx_serial_type,
1807     .config_port    = s3c24xx_serial_config_port,
1808     .verify_port    = s3c24xx_serial_verify_port,
1809 #if defined(CONFIG_SERIAL_SAMSUNG_CONSOLE) && defined(CONFIG_CONSOLE_POLL)
1810     .poll_get_char = s3c24xx_serial_get_poll_char,
1811     .poll_put_char = s3c24xx_serial_put_poll_char,
1812 #endif
1813 };
1814 
1815 static struct uart_driver s3c24xx_uart_drv = {
1816     .owner      = THIS_MODULE,
1817     .driver_name    = "s3c2410_serial",
1818     .nr     = UART_NR,
1819     .cons       = S3C24XX_SERIAL_CONSOLE,
1820     .dev_name   = S3C24XX_SERIAL_NAME,
1821     .major      = S3C24XX_SERIAL_MAJOR,
1822     .minor      = S3C24XX_SERIAL_MINOR,
1823 };
1824 
1825 static struct s3c24xx_uart_port s3c24xx_serial_ports[UART_NR];
1826 
1827 static void s3c24xx_serial_init_port_default(int index) {
1828     struct uart_port *port = &s3c24xx_serial_ports[index].port;
1829 
1830     spin_lock_init(&port->lock);
1831 
1832     port->iotype = UPIO_MEM;
1833     port->uartclk = 0;
1834     port->fifosize = 16;
1835     port->ops = &s3c24xx_serial_ops;
1836     port->flags = UPF_BOOT_AUTOCONF;
1837     port->line = index;
1838 }
1839 
1840 /* s3c24xx_serial_resetport
1841  *
1842  * reset the fifos and other the settings.
1843  */
1844 
1845 static void s3c24xx_serial_resetport(struct uart_port *port,
1846                      const struct s3c2410_uartcfg *cfg)
1847 {
1848     const struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
1849     unsigned long ucon = rd_regl(port, S3C2410_UCON);
1850 
1851     ucon &= (info->clksel_mask | info->ucon_mask);
1852     wr_regl(port, S3C2410_UCON, ucon | cfg->ucon);
1853 
1854     /* reset both fifos */
1855     wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH);
1856     wr_regl(port, S3C2410_UFCON, cfg->ufcon);
1857 
1858     /* some delay is required after fifo reset */
1859     udelay(1);
1860 }
1861 
1862 #ifdef CONFIG_ARM_S3C24XX_CPUFREQ
1863 
1864 static int s3c24xx_serial_cpufreq_transition(struct notifier_block *nb,
1865                          unsigned long val, void *data)
1866 {
1867     struct s3c24xx_uart_port *port;
1868     struct uart_port *uport;
1869 
1870     port = container_of(nb, struct s3c24xx_uart_port, freq_transition);
1871     uport = &port->port;
1872 
1873     /* check to see if port is enabled */
1874 
1875     if (port->pm_level != 0)
1876         return 0;
1877 
1878     /* try and work out if the baudrate is changing, we can detect
1879      * a change in rate, but we do not have support for detecting
1880      * a disturbance in the clock-rate over the change.
1881      */
1882 
1883     if (IS_ERR(port->baudclk))
1884         goto exit;
1885 
1886     if (port->baudclk_rate == clk_get_rate(port->baudclk))
1887         goto exit;
1888 
1889     if (val == CPUFREQ_PRECHANGE) {
1890         /* we should really shut the port down whilst the
1891          * frequency change is in progress.
1892          */
1893 
1894     } else if (val == CPUFREQ_POSTCHANGE) {
1895         struct ktermios *termios;
1896         struct tty_struct *tty;
1897 
1898         if (uport->state == NULL)
1899             goto exit;
1900 
1901         tty = uport->state->port.tty;
1902 
1903         if (tty == NULL)
1904             goto exit;
1905 
1906         termios = &tty->termios;
1907 
1908         if (termios == NULL) {
1909             dev_warn(uport->dev, "%s: no termios?\n", __func__);
1910             goto exit;
1911         }
1912 
1913         s3c24xx_serial_set_termios(uport, termios, NULL);
1914     }
1915 
1916 exit:
1917     return 0;
1918 }
1919 
1920 static inline int
1921 s3c24xx_serial_cpufreq_register(struct s3c24xx_uart_port *port)
1922 {
1923     port->freq_transition.notifier_call = s3c24xx_serial_cpufreq_transition;
1924 
1925     return cpufreq_register_notifier(&port->freq_transition,
1926                      CPUFREQ_TRANSITION_NOTIFIER);
1927 }
1928 
1929 static inline void
1930 s3c24xx_serial_cpufreq_deregister(struct s3c24xx_uart_port *port)
1931 {
1932     cpufreq_unregister_notifier(&port->freq_transition,
1933                     CPUFREQ_TRANSITION_NOTIFIER);
1934 }
1935 
1936 #else
1937 static inline int
1938 s3c24xx_serial_cpufreq_register(struct s3c24xx_uart_port *port)
1939 {
1940     return 0;
1941 }
1942 
1943 static inline void
1944 s3c24xx_serial_cpufreq_deregister(struct s3c24xx_uart_port *port)
1945 {
1946 }
1947 #endif
1948 
1949 static int s3c24xx_serial_enable_baudclk(struct s3c24xx_uart_port *ourport)
1950 {
1951     struct device *dev = ourport->port.dev;
1952     const struct s3c24xx_uart_info *info = ourport->info;
1953     char clk_name[MAX_CLK_NAME_LENGTH];
1954     unsigned int clk_sel;
1955     struct clk *clk;
1956     int clk_num;
1957     int ret;
1958 
1959     clk_sel = ourport->cfg->clk_sel ? : info->def_clk_sel;
1960     for (clk_num = 0; clk_num < info->num_clks; clk_num++) {
1961         if (!(clk_sel & (1 << clk_num)))
1962             continue;
1963 
1964         sprintf(clk_name, "clk_uart_baud%d", clk_num);
1965         clk = clk_get(dev, clk_name);
1966         if (IS_ERR(clk))
1967             continue;
1968 
1969         ret = clk_prepare_enable(clk);
1970         if (ret) {
1971             clk_put(clk);
1972             continue;
1973         }
1974 
1975         ourport->baudclk = clk;
1976         ourport->baudclk_rate = clk_get_rate(clk);
1977         s3c24xx_serial_setsource(&ourport->port, clk_num);
1978 
1979         return 0;
1980     }
1981 
1982     return -EINVAL;
1983 }
1984 
1985 /* s3c24xx_serial_init_port
1986  *
1987  * initialise a single serial port from the platform device given
1988  */
1989 
1990 static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
1991                     struct platform_device *platdev)
1992 {
1993     struct uart_port *port = &ourport->port;
1994     const struct s3c2410_uartcfg *cfg = ourport->cfg;
1995     struct resource *res;
1996     int ret;
1997 
1998     if (platdev == NULL)
1999         return -ENODEV;
2000 
2001     if (port->mapbase != 0)
2002         return -EINVAL;
2003 
2004     /* setup info for port */
2005     port->dev   = &platdev->dev;
2006 
2007     port->uartclk = 1;
2008 
2009     if (cfg->uart_flags & UPF_CONS_FLOW) {
2010         dev_dbg(port->dev, "enabling flow control\n");
2011         port->flags |= UPF_CONS_FLOW;
2012     }
2013 
2014     /* sort our the physical and virtual addresses for each UART */
2015 
2016     res = platform_get_resource(platdev, IORESOURCE_MEM, 0);
2017     if (res == NULL) {
2018         dev_err(port->dev, "failed to find memory resource for uart\n");
2019         return -EINVAL;
2020     }
2021 
2022     dev_dbg(port->dev, "resource %pR)\n", res);
2023 
2024     port->membase = devm_ioremap_resource(port->dev, res);
2025     if (IS_ERR(port->membase)) {
2026         dev_err(port->dev, "failed to remap controller address\n");
2027         return -EBUSY;
2028     }
2029 
2030     port->mapbase = res->start;
2031     ret = platform_get_irq(platdev, 0);
2032     if (ret < 0) {
2033         port->irq = 0;
2034     } else {
2035         port->irq = ret;
2036         ourport->rx_irq = ret;
2037         ourport->tx_irq = ret + 1;
2038     }
2039 
2040     switch (ourport->info->type) {
2041     case TYPE_S3C24XX:
2042         ret = platform_get_irq(platdev, 1);
2043         if (ret > 0)
2044             ourport->tx_irq = ret;
2045         break;
2046     default:
2047         break;
2048     }
2049 
2050     /*
2051      * DMA is currently supported only on DT platforms, if DMA properties
2052      * are specified.
2053      */
2054     if (platdev->dev.of_node && of_find_property(platdev->dev.of_node,
2055                              "dmas", NULL)) {
2056         ourport->dma = devm_kzalloc(port->dev,
2057                         sizeof(*ourport->dma),
2058                         GFP_KERNEL);
2059         if (!ourport->dma) {
2060             ret = -ENOMEM;
2061             goto err;
2062         }
2063     }
2064 
2065     ourport->clk    = clk_get(&platdev->dev, "uart");
2066     if (IS_ERR(ourport->clk)) {
2067         pr_err("%s: Controller clock not found\n",
2068                 dev_name(&platdev->dev));
2069         ret = PTR_ERR(ourport->clk);
2070         goto err;
2071     }
2072 
2073     ret = clk_prepare_enable(ourport->clk);
2074     if (ret) {
2075         pr_err("uart: clock failed to prepare+enable: %d\n", ret);
2076         clk_put(ourport->clk);
2077         goto err;
2078     }
2079 
2080     ret = s3c24xx_serial_enable_baudclk(ourport);
2081     if (ret)
2082         pr_warn("uart: failed to enable baudclk\n");
2083 
2084     /* Keep all interrupts masked and cleared */
2085     switch (ourport->info->type) {
2086     case TYPE_S3C6400:
2087         wr_regl(port, S3C64XX_UINTM, 0xf);
2088         wr_regl(port, S3C64XX_UINTP, 0xf);
2089         wr_regl(port, S3C64XX_UINTSP, 0xf);
2090         break;
2091     case TYPE_APPLE_S5L: {
2092         unsigned int ucon;
2093 
2094         ucon = rd_regl(port, S3C2410_UCON);
2095         ucon &= ~(APPLE_S5L_UCON_TXTHRESH_ENA_MSK |
2096             APPLE_S5L_UCON_RXTHRESH_ENA_MSK |
2097             APPLE_S5L_UCON_RXTO_ENA_MSK);
2098         wr_regl(port, S3C2410_UCON, ucon);
2099 
2100         wr_regl(port, S3C2410_UTRSTAT, APPLE_S5L_UTRSTAT_ALL_FLAGS);
2101         break;
2102     }
2103     default:
2104         break;
2105     }
2106 
2107     dev_dbg(port->dev, "port: map=%pa, mem=%p, irq=%d (%d,%d), clock=%u\n",
2108         &port->mapbase, port->membase, port->irq,
2109         ourport->rx_irq, ourport->tx_irq, port->uartclk);
2110 
2111     /* reset the fifos (and setup the uart) */
2112     s3c24xx_serial_resetport(port, cfg);
2113 
2114     return 0;
2115 
2116 err:
2117     port->mapbase = 0;
2118     return ret;
2119 }
2120 
2121 /* Device driver serial port probe */
2122 
2123 static int probe_index;
2124 
2125 static inline const struct s3c24xx_serial_drv_data *
2126 s3c24xx_get_driver_data(struct platform_device *pdev)
2127 {
2128     if (dev_of_node(&pdev->dev))
2129         return of_device_get_match_data(&pdev->dev);
2130 
2131     return (struct s3c24xx_serial_drv_data *)
2132             platform_get_device_id(pdev)->driver_data;
2133 }
2134 
2135 static int s3c24xx_serial_probe(struct platform_device *pdev)
2136 {
2137     struct device_node *np = pdev->dev.of_node;
2138     struct s3c24xx_uart_port *ourport;
2139     int index = probe_index;
2140     int ret, prop = 0;
2141 
2142     if (np) {
2143         ret = of_alias_get_id(np, "serial");
2144         if (ret >= 0)
2145             index = ret;
2146     }
2147 
2148     if (index >= ARRAY_SIZE(s3c24xx_serial_ports)) {
2149         dev_err(&pdev->dev, "serial%d out of range\n", index);
2150         return -EINVAL;
2151     }
2152     ourport = &s3c24xx_serial_ports[index];
2153 
2154     s3c24xx_serial_init_port_default(index);
2155 
2156     ourport->drv_data = s3c24xx_get_driver_data(pdev);
2157     if (!ourport->drv_data) {
2158         dev_err(&pdev->dev, "could not find driver data\n");
2159         return -ENODEV;
2160     }
2161 
2162     ourport->baudclk = ERR_PTR(-EINVAL);
2163     ourport->info = &ourport->drv_data->info;
2164     ourport->cfg = (dev_get_platdata(&pdev->dev)) ?
2165             dev_get_platdata(&pdev->dev) :
2166             &ourport->drv_data->def_cfg;
2167 
2168     switch (ourport->info->type) {
2169     case TYPE_S3C24XX:
2170         ourport->port.ops = &s3c24xx_serial_ops;
2171         break;
2172     case TYPE_S3C6400:
2173         ourport->port.ops = &s3c64xx_serial_ops;
2174         break;
2175     case TYPE_APPLE_S5L:
2176         ourport->port.ops = &apple_s5l_serial_ops;
2177         break;
2178     }
2179 
2180     if (np) {
2181         of_property_read_u32(np,
2182             "samsung,uart-fifosize", &ourport->port.fifosize);
2183 
2184         if (of_property_read_u32(np, "reg-io-width", &prop) == 0) {
2185             switch (prop) {
2186             case 1:
2187                 ourport->port.iotype = UPIO_MEM;
2188                 break;
2189             case 4:
2190                 ourport->port.iotype = UPIO_MEM32;
2191                 break;
2192             default:
2193                 dev_warn(&pdev->dev, "unsupported reg-io-width (%d)\n",
2194                         prop);
2195                 return -EINVAL;
2196             }
2197         }
2198     }
2199 
2200     if (ourport->drv_data->fifosize[index])
2201         ourport->port.fifosize = ourport->drv_data->fifosize[index];
2202     else if (ourport->info->fifosize)
2203         ourport->port.fifosize = ourport->info->fifosize;
2204     ourport->port.has_sysrq = IS_ENABLED(CONFIG_SERIAL_SAMSUNG_CONSOLE);
2205 
2206     /*
2207      * DMA transfers must be aligned at least to cache line size,
2208      * so find minimal transfer size suitable for DMA mode
2209      */
2210     ourport->min_dma_size = max_t(int, ourport->port.fifosize,
2211                     dma_get_cache_alignment());
2212 
2213     dev_dbg(&pdev->dev, "%s: initialising port %p...\n", __func__, ourport);
2214 
2215     ret = s3c24xx_serial_init_port(ourport, pdev);
2216     if (ret < 0)
2217         return ret;
2218 
2219     if (!s3c24xx_uart_drv.state) {
2220         ret = uart_register_driver(&s3c24xx_uart_drv);
2221         if (ret < 0) {
2222             pr_err("Failed to register Samsung UART driver\n");
2223             return ret;
2224         }
2225     }
2226 
2227     dev_dbg(&pdev->dev, "%s: adding port\n", __func__);
2228     uart_add_one_port(&s3c24xx_uart_drv, &ourport->port);
2229     platform_set_drvdata(pdev, &ourport->port);
2230 
2231     /*
2232      * Deactivate the clock enabled in s3c24xx_serial_init_port here,
2233      * so that a potential re-enablement through the pm-callback overlaps
2234      * and keeps the clock enabled in this case.
2235      */
2236     clk_disable_unprepare(ourport->clk);
2237     if (!IS_ERR(ourport->baudclk))
2238         clk_disable_unprepare(ourport->baudclk);
2239 
2240     ret = s3c24xx_serial_cpufreq_register(ourport);
2241     if (ret < 0)
2242         dev_err(&pdev->dev, "failed to add cpufreq notifier\n");
2243 
2244     probe_index++;
2245 
2246     return 0;
2247 }
2248 
2249 static int s3c24xx_serial_remove(struct platform_device *dev)
2250 {
2251     struct uart_port *port = s3c24xx_dev_to_port(&dev->dev);
2252 
2253     if (port) {
2254         s3c24xx_serial_cpufreq_deregister(to_ourport(port));
2255         uart_remove_one_port(&s3c24xx_uart_drv, port);
2256     }
2257 
2258     uart_unregister_driver(&s3c24xx_uart_drv);
2259 
2260     return 0;
2261 }
2262 
2263 /* UART power management code */
2264 #ifdef CONFIG_PM_SLEEP
2265 static int s3c24xx_serial_suspend(struct device *dev)
2266 {
2267     struct uart_port *port = s3c24xx_dev_to_port(dev);
2268 
2269     if (port)
2270         uart_suspend_port(&s3c24xx_uart_drv, port);
2271 
2272     return 0;
2273 }
2274 
2275 static int s3c24xx_serial_resume(struct device *dev)
2276 {
2277     struct uart_port *port = s3c24xx_dev_to_port(dev);
2278     struct s3c24xx_uart_port *ourport = to_ourport(port);
2279 
2280     if (port) {
2281         clk_prepare_enable(ourport->clk);
2282         if (!IS_ERR(ourport->baudclk))
2283             clk_prepare_enable(ourport->baudclk);
2284         s3c24xx_serial_resetport(port, s3c24xx_port_to_cfg(port));
2285         if (!IS_ERR(ourport->baudclk))
2286             clk_disable_unprepare(ourport->baudclk);
2287         clk_disable_unprepare(ourport->clk);
2288 
2289         uart_resume_port(&s3c24xx_uart_drv, port);
2290     }
2291 
2292     return 0;
2293 }
2294 
2295 static int s3c24xx_serial_resume_noirq(struct device *dev)
2296 {
2297     struct uart_port *port = s3c24xx_dev_to_port(dev);
2298     struct s3c24xx_uart_port *ourport = to_ourport(port);
2299 
2300     if (port) {
2301         /* restore IRQ mask */
2302         switch (ourport->info->type) {
2303         case TYPE_S3C6400: {
2304             unsigned int uintm = 0xf;
2305 
2306             if (ourport->tx_enabled)
2307                 uintm &= ~S3C64XX_UINTM_TXD_MSK;
2308             if (ourport->rx_enabled)
2309                 uintm &= ~S3C64XX_UINTM_RXD_MSK;
2310             clk_prepare_enable(ourport->clk);
2311             if (!IS_ERR(ourport->baudclk))
2312                 clk_prepare_enable(ourport->baudclk);
2313             wr_regl(port, S3C64XX_UINTM, uintm);
2314             if (!IS_ERR(ourport->baudclk))
2315                 clk_disable_unprepare(ourport->baudclk);
2316             clk_disable_unprepare(ourport->clk);
2317             break;
2318         }
2319         case TYPE_APPLE_S5L: {
2320             unsigned int ucon;
2321             int ret;
2322 
2323             ret = clk_prepare_enable(ourport->clk);
2324             if (ret) {
2325                 dev_err(dev, "clk_enable clk failed: %d\n", ret);
2326                 return ret;
2327             }
2328             if (!IS_ERR(ourport->baudclk)) {
2329                 ret = clk_prepare_enable(ourport->baudclk);
2330                 if (ret) {
2331                     dev_err(dev, "clk_enable baudclk failed: %d\n", ret);
2332                     clk_disable_unprepare(ourport->clk);
2333                     return ret;
2334                 }
2335             }
2336 
2337             ucon = rd_regl(port, S3C2410_UCON);
2338 
2339             ucon &= ~(APPLE_S5L_UCON_TXTHRESH_ENA_MSK |
2340                   APPLE_S5L_UCON_RXTHRESH_ENA_MSK |
2341                   APPLE_S5L_UCON_RXTO_ENA_MSK);
2342 
2343             if (ourport->tx_enabled)
2344                 ucon |= APPLE_S5L_UCON_TXTHRESH_ENA_MSK;
2345             if (ourport->rx_enabled)
2346                 ucon |= APPLE_S5L_UCON_RXTHRESH_ENA_MSK |
2347                     APPLE_S5L_UCON_RXTO_ENA_MSK;
2348 
2349             wr_regl(port, S3C2410_UCON, ucon);
2350 
2351             if (!IS_ERR(ourport->baudclk))
2352                 clk_disable_unprepare(ourport->baudclk);
2353             clk_disable_unprepare(ourport->clk);
2354             break;
2355         }
2356         default:
2357             break;
2358         }
2359     }
2360 
2361     return 0;
2362 }
2363 
2364 static const struct dev_pm_ops s3c24xx_serial_pm_ops = {
2365     .suspend = s3c24xx_serial_suspend,
2366     .resume = s3c24xx_serial_resume,
2367     .resume_noirq = s3c24xx_serial_resume_noirq,
2368 };
2369 #define SERIAL_SAMSUNG_PM_OPS   (&s3c24xx_serial_pm_ops)
2370 
2371 #else /* !CONFIG_PM_SLEEP */
2372 
2373 #define SERIAL_SAMSUNG_PM_OPS   NULL
2374 #endif /* CONFIG_PM_SLEEP */
2375 
2376 /* Console code */
2377 
2378 #ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE
2379 
2380 static struct uart_port *cons_uart;
2381 
2382 static int
2383 s3c24xx_serial_console_txrdy(struct uart_port *port, unsigned int ufcon)
2384 {
2385     const struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
2386     unsigned long ufstat, utrstat;
2387 
2388     if (ufcon & S3C2410_UFCON_FIFOMODE) {
2389         /* fifo mode - check amount of data in fifo registers... */
2390 
2391         ufstat = rd_regl(port, S3C2410_UFSTAT);
2392         return (ufstat & info->tx_fifofull) ? 0 : 1;
2393     }
2394 
2395     /* in non-fifo mode, we go and use the tx buffer empty */
2396 
2397     utrstat = rd_regl(port, S3C2410_UTRSTAT);
2398     return (utrstat & S3C2410_UTRSTAT_TXE) ? 1 : 0;
2399 }
2400 
2401 static bool
2402 s3c24xx_port_configured(unsigned int ucon)
2403 {
2404     /* consider the serial port configured if the tx/rx mode set */
2405     return (ucon & 0xf) != 0;
2406 }
2407 
2408 #ifdef CONFIG_CONSOLE_POLL
2409 /*
2410  * Console polling routines for writing and reading from the uart while
2411  * in an interrupt or debug context.
2412  */
2413 
2414 static int s3c24xx_serial_get_poll_char(struct uart_port *port)
2415 {
2416     const struct s3c24xx_uart_port *ourport = to_ourport(port);
2417     unsigned int ufstat;
2418 
2419     ufstat = rd_regl(port, S3C2410_UFSTAT);
2420     if (s3c24xx_serial_rx_fifocnt(ourport, ufstat) == 0)
2421         return NO_POLL_CHAR;
2422 
2423     return rd_reg(port, S3C2410_URXH);
2424 }
2425 
2426 static void s3c24xx_serial_put_poll_char(struct uart_port *port,
2427         unsigned char c)
2428 {
2429     unsigned int ufcon = rd_regl(port, S3C2410_UFCON);
2430     unsigned int ucon = rd_regl(port, S3C2410_UCON);
2431 
2432     /* not possible to xmit on unconfigured port */
2433     if (!s3c24xx_port_configured(ucon))
2434         return;
2435 
2436     while (!s3c24xx_serial_console_txrdy(port, ufcon))
2437         cpu_relax();
2438     wr_reg(port, S3C2410_UTXH, c);
2439 }
2440 
2441 #endif /* CONFIG_CONSOLE_POLL */
2442 
2443 static void
2444 s3c24xx_serial_console_putchar(struct uart_port *port, unsigned char ch)
2445 {
2446     unsigned int ufcon = rd_regl(port, S3C2410_UFCON);
2447 
2448     while (!s3c24xx_serial_console_txrdy(port, ufcon))
2449         cpu_relax();
2450     wr_reg(port, S3C2410_UTXH, ch);
2451 }
2452 
2453 static void
2454 s3c24xx_serial_console_write(struct console *co, const char *s,
2455                  unsigned int count)
2456 {
2457     unsigned int ucon = rd_regl(cons_uart, S3C2410_UCON);
2458     unsigned long flags;
2459     bool locked = true;
2460 
2461     /* not possible to xmit on unconfigured port */
2462     if (!s3c24xx_port_configured(ucon))
2463         return;
2464 
2465     if (cons_uart->sysrq)
2466         locked = false;
2467     else if (oops_in_progress)
2468         locked = spin_trylock_irqsave(&cons_uart->lock, flags);
2469     else
2470         spin_lock_irqsave(&cons_uart->lock, flags);
2471 
2472     uart_console_write(cons_uart, s, count, s3c24xx_serial_console_putchar);
2473 
2474     if (locked)
2475         spin_unlock_irqrestore(&cons_uart->lock, flags);
2476 }
2477 
2478 /* Shouldn't be __init, as it can be instantiated from other module */
2479 static void
2480 s3c24xx_serial_get_options(struct uart_port *port, int *baud,
2481                int *parity, int *bits)
2482 {
2483     struct clk *clk;
2484     unsigned int ulcon;
2485     unsigned int ucon;
2486     unsigned int ubrdiv;
2487     unsigned long rate;
2488     unsigned int clk_sel;
2489     char clk_name[MAX_CLK_NAME_LENGTH];
2490 
2491     ulcon  = rd_regl(port, S3C2410_ULCON);
2492     ucon   = rd_regl(port, S3C2410_UCON);
2493     ubrdiv = rd_regl(port, S3C2410_UBRDIV);
2494 
2495     if (s3c24xx_port_configured(ucon)) {
2496         switch (ulcon & S3C2410_LCON_CSMASK) {
2497         case S3C2410_LCON_CS5:
2498             *bits = 5;
2499             break;
2500         case S3C2410_LCON_CS6:
2501             *bits = 6;
2502             break;
2503         case S3C2410_LCON_CS7:
2504             *bits = 7;
2505             break;
2506         case S3C2410_LCON_CS8:
2507         default:
2508             *bits = 8;
2509             break;
2510         }
2511 
2512         switch (ulcon & S3C2410_LCON_PMASK) {
2513         case S3C2410_LCON_PEVEN:
2514             *parity = 'e';
2515             break;
2516 
2517         case S3C2410_LCON_PODD:
2518             *parity = 'o';
2519             break;
2520 
2521         case S3C2410_LCON_PNONE:
2522         default:
2523             *parity = 'n';
2524         }
2525 
2526         /* now calculate the baud rate */
2527 
2528         clk_sel = s3c24xx_serial_getsource(port);
2529         sprintf(clk_name, "clk_uart_baud%d", clk_sel);
2530 
2531         clk = clk_get(port->dev, clk_name);
2532         if (!IS_ERR(clk))
2533             rate = clk_get_rate(clk);
2534         else
2535             rate = 1;
2536 
2537         *baud = rate / (16 * (ubrdiv + 1));
2538         dev_dbg(port->dev, "calculated baud %d\n", *baud);
2539     }
2540 }
2541 
2542 /* Shouldn't be __init, as it can be instantiated from other module */
2543 static int
2544 s3c24xx_serial_console_setup(struct console *co, char *options)
2545 {
2546     struct uart_port *port;
2547     int baud = 9600;
2548     int bits = 8;
2549     int parity = 'n';
2550     int flow = 'n';
2551 
2552     /* is this a valid port */
2553 
2554     if (co->index == -1 || co->index >= UART_NR)
2555         co->index = 0;
2556 
2557     port = &s3c24xx_serial_ports[co->index].port;
2558 
2559     /* is the port configured? */
2560 
2561     if (port->mapbase == 0x0)
2562         return -ENODEV;
2563 
2564     cons_uart = port;
2565 
2566     /*
2567      * Check whether an invalid uart number has been specified, and
2568      * if so, search for the first available port that does have
2569      * console support.
2570      */
2571     if (options)
2572         uart_parse_options(options, &baud, &parity, &bits, &flow);
2573     else
2574         s3c24xx_serial_get_options(port, &baud, &parity, &bits);
2575 
2576     dev_dbg(port->dev, "baud %d\n", baud);
2577 
2578     return uart_set_options(port, co, baud, parity, bits, flow);
2579 }
2580 
2581 static struct console s3c24xx_serial_console = {
2582     .name       = S3C24XX_SERIAL_NAME,
2583     .device     = uart_console_device,
2584     .flags      = CON_PRINTBUFFER,
2585     .index      = -1,
2586     .write      = s3c24xx_serial_console_write,
2587     .setup      = s3c24xx_serial_console_setup,
2588     .data       = &s3c24xx_uart_drv,
2589 };
2590 #endif /* CONFIG_SERIAL_SAMSUNG_CONSOLE */
2591 
2592 #ifdef CONFIG_CPU_S3C2410
2593 static const struct s3c24xx_serial_drv_data s3c2410_serial_drv_data = {
2594     .info = {
2595         .name       = "Samsung S3C2410 UART",
2596         .type       = TYPE_S3C24XX,
2597         .port_type  = PORT_S3C2410,
2598         .fifosize   = 16,
2599         .rx_fifomask    = S3C2410_UFSTAT_RXMASK,
2600         .rx_fifoshift   = S3C2410_UFSTAT_RXSHIFT,
2601         .rx_fifofull    = S3C2410_UFSTAT_RXFULL,
2602         .tx_fifofull    = S3C2410_UFSTAT_TXFULL,
2603         .tx_fifomask    = S3C2410_UFSTAT_TXMASK,
2604         .tx_fifoshift   = S3C2410_UFSTAT_TXSHIFT,
2605         .def_clk_sel    = S3C2410_UCON_CLKSEL0,
2606         .num_clks   = 2,
2607         .clksel_mask    = S3C2410_UCON_CLKMASK,
2608         .clksel_shift   = S3C2410_UCON_CLKSHIFT,
2609     },
2610     .def_cfg = {
2611         .ucon       = S3C2410_UCON_DEFAULT,
2612         .ufcon      = S3C2410_UFCON_DEFAULT,
2613     },
2614 };
2615 #define S3C2410_SERIAL_DRV_DATA (&s3c2410_serial_drv_data)
2616 #else
2617 #define S3C2410_SERIAL_DRV_DATA NULL
2618 #endif
2619 
2620 #ifdef CONFIG_CPU_S3C2412
2621 static const struct s3c24xx_serial_drv_data s3c2412_serial_drv_data = {
2622     .info = {
2623         .name       = "Samsung S3C2412 UART",
2624         .type       = TYPE_S3C24XX,
2625         .port_type  = PORT_S3C2412,
2626         .fifosize   = 64,
2627         .has_divslot    = 1,
2628         .rx_fifomask    = S3C2440_UFSTAT_RXMASK,
2629         .rx_fifoshift   = S3C2440_UFSTAT_RXSHIFT,
2630         .rx_fifofull    = S3C2440_UFSTAT_RXFULL,
2631         .tx_fifofull    = S3C2440_UFSTAT_TXFULL,
2632         .tx_fifomask    = S3C2440_UFSTAT_TXMASK,
2633         .tx_fifoshift   = S3C2440_UFSTAT_TXSHIFT,
2634         .def_clk_sel    = S3C2410_UCON_CLKSEL2,
2635         .num_clks   = 4,
2636         .clksel_mask    = S3C2412_UCON_CLKMASK,
2637         .clksel_shift   = S3C2412_UCON_CLKSHIFT,
2638     },
2639     .def_cfg = {
2640         .ucon       = S3C2410_UCON_DEFAULT,
2641         .ufcon      = S3C2410_UFCON_DEFAULT,
2642     },
2643 };
2644 #define S3C2412_SERIAL_DRV_DATA (&s3c2412_serial_drv_data)
2645 #else
2646 #define S3C2412_SERIAL_DRV_DATA NULL
2647 #endif
2648 
2649 #if defined(CONFIG_CPU_S3C2440) || defined(CONFIG_CPU_S3C2416) || \
2650     defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2442)
2651 static const struct s3c24xx_serial_drv_data s3c2440_serial_drv_data = {
2652     .info = {
2653         .name       = "Samsung S3C2440 UART",
2654         .type       = TYPE_S3C24XX,
2655         .port_type  = PORT_S3C2440,
2656         .fifosize   = 64,
2657         .has_divslot    = 1,
2658         .rx_fifomask    = S3C2440_UFSTAT_RXMASK,
2659         .rx_fifoshift   = S3C2440_UFSTAT_RXSHIFT,
2660         .rx_fifofull    = S3C2440_UFSTAT_RXFULL,
2661         .tx_fifofull    = S3C2440_UFSTAT_TXFULL,
2662         .tx_fifomask    = S3C2440_UFSTAT_TXMASK,
2663         .tx_fifoshift   = S3C2440_UFSTAT_TXSHIFT,
2664         .def_clk_sel    = S3C2410_UCON_CLKSEL2,
2665         .num_clks   = 4,
2666         .clksel_mask    = S3C2412_UCON_CLKMASK,
2667         .clksel_shift   = S3C2412_UCON_CLKSHIFT,
2668         .ucon_mask  = S3C2440_UCON0_DIVMASK,
2669     },
2670     .def_cfg = {
2671         .ucon       = S3C2410_UCON_DEFAULT,
2672         .ufcon      = S3C2410_UFCON_DEFAULT,
2673     },
2674 };
2675 #define S3C2440_SERIAL_DRV_DATA (&s3c2440_serial_drv_data)
2676 #else
2677 #define S3C2440_SERIAL_DRV_DATA NULL
2678 #endif
2679 
2680 #if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
2681 static const struct s3c24xx_serial_drv_data s3c6400_serial_drv_data = {
2682     .info = {
2683         .name       = "Samsung S3C6400 UART",
2684         .type       = TYPE_S3C6400,
2685         .port_type  = PORT_S3C6400,
2686         .fifosize   = 64,
2687         .has_divslot    = 1,
2688         .rx_fifomask    = S3C2440_UFSTAT_RXMASK,
2689         .rx_fifoshift   = S3C2440_UFSTAT_RXSHIFT,
2690         .rx_fifofull    = S3C2440_UFSTAT_RXFULL,
2691         .tx_fifofull    = S3C2440_UFSTAT_TXFULL,
2692         .tx_fifomask    = S3C2440_UFSTAT_TXMASK,
2693         .tx_fifoshift   = S3C2440_UFSTAT_TXSHIFT,
2694         .def_clk_sel    = S3C2410_UCON_CLKSEL2,
2695         .num_clks   = 4,
2696         .clksel_mask    = S3C6400_UCON_CLKMASK,
2697         .clksel_shift   = S3C6400_UCON_CLKSHIFT,
2698     },
2699     .def_cfg = {
2700         .ucon       = S3C2410_UCON_DEFAULT,
2701         .ufcon      = S3C2410_UFCON_DEFAULT,
2702     },
2703 };
2704 #define S3C6400_SERIAL_DRV_DATA (&s3c6400_serial_drv_data)
2705 #else
2706 #define S3C6400_SERIAL_DRV_DATA NULL
2707 #endif
2708 
2709 #ifdef CONFIG_CPU_S5PV210
2710 static const struct s3c24xx_serial_drv_data s5pv210_serial_drv_data = {
2711     .info = {
2712         .name       = "Samsung S5PV210 UART",
2713         .type       = TYPE_S3C6400,
2714         .port_type  = PORT_S3C6400,
2715         .has_divslot    = 1,
2716         .rx_fifomask    = S5PV210_UFSTAT_RXMASK,
2717         .rx_fifoshift   = S5PV210_UFSTAT_RXSHIFT,
2718         .rx_fifofull    = S5PV210_UFSTAT_RXFULL,
2719         .tx_fifofull    = S5PV210_UFSTAT_TXFULL,
2720         .tx_fifomask    = S5PV210_UFSTAT_TXMASK,
2721         .tx_fifoshift   = S5PV210_UFSTAT_TXSHIFT,
2722         .def_clk_sel    = S3C2410_UCON_CLKSEL0,
2723         .num_clks   = 2,
2724         .clksel_mask    = S5PV210_UCON_CLKMASK,
2725         .clksel_shift   = S5PV210_UCON_CLKSHIFT,
2726     },
2727     .def_cfg = {
2728         .ucon       = S5PV210_UCON_DEFAULT,
2729         .ufcon      = S5PV210_UFCON_DEFAULT,
2730     },
2731     .fifosize = { 256, 64, 16, 16 },
2732 };
2733 #define S5PV210_SERIAL_DRV_DATA (&s5pv210_serial_drv_data)
2734 #else
2735 #define S5PV210_SERIAL_DRV_DATA NULL
2736 #endif
2737 
2738 #if defined(CONFIG_ARCH_EXYNOS)
2739 #define EXYNOS_COMMON_SERIAL_DRV_DATA()             \
2740     .info = {                       \
2741         .name       = "Samsung Exynos UART",    \
2742         .type       = TYPE_S3C6400,         \
2743         .port_type  = PORT_S3C6400,         \
2744         .has_divslot    = 1,                \
2745         .rx_fifomask    = S5PV210_UFSTAT_RXMASK,    \
2746         .rx_fifoshift   = S5PV210_UFSTAT_RXSHIFT,   \
2747         .rx_fifofull    = S5PV210_UFSTAT_RXFULL,    \
2748         .tx_fifofull    = S5PV210_UFSTAT_TXFULL,    \
2749         .tx_fifomask    = S5PV210_UFSTAT_TXMASK,    \
2750         .tx_fifoshift   = S5PV210_UFSTAT_TXSHIFT,   \
2751         .def_clk_sel    = S3C2410_UCON_CLKSEL0,     \
2752         .num_clks   = 1,                \
2753         .clksel_mask    = 0,                \
2754         .clksel_shift   = 0,                \
2755     },                          \
2756     .def_cfg = {                        \
2757         .ucon       = S5PV210_UCON_DEFAULT,     \
2758         .ufcon      = S5PV210_UFCON_DEFAULT,    \
2759         .has_fracval    = 1,                \
2760     }                           \
2761 
2762 static const struct s3c24xx_serial_drv_data exynos4210_serial_drv_data = {
2763     EXYNOS_COMMON_SERIAL_DRV_DATA(),
2764     .fifosize = { 256, 64, 16, 16 },
2765 };
2766 
2767 static const struct s3c24xx_serial_drv_data exynos5433_serial_drv_data = {
2768     EXYNOS_COMMON_SERIAL_DRV_DATA(),
2769     .fifosize = { 64, 256, 16, 256 },
2770 };
2771 
2772 static const struct s3c24xx_serial_drv_data exynos850_serial_drv_data = {
2773     EXYNOS_COMMON_SERIAL_DRV_DATA(),
2774     .fifosize = { 256, 64, 64, 64 },
2775 };
2776 
2777 #define EXYNOS4210_SERIAL_DRV_DATA (&exynos4210_serial_drv_data)
2778 #define EXYNOS5433_SERIAL_DRV_DATA (&exynos5433_serial_drv_data)
2779 #define EXYNOS850_SERIAL_DRV_DATA (&exynos850_serial_drv_data)
2780 
2781 #else
2782 #define EXYNOS4210_SERIAL_DRV_DATA NULL
2783 #define EXYNOS5433_SERIAL_DRV_DATA NULL
2784 #define EXYNOS850_SERIAL_DRV_DATA NULL
2785 #endif
2786 
2787 #ifdef CONFIG_ARCH_APPLE
2788 static const struct s3c24xx_serial_drv_data s5l_serial_drv_data = {
2789     .info = {
2790         .name       = "Apple S5L UART",
2791         .type       = TYPE_APPLE_S5L,
2792         .port_type  = PORT_8250,
2793         .fifosize   = 16,
2794         .rx_fifomask    = S3C2410_UFSTAT_RXMASK,
2795         .rx_fifoshift   = S3C2410_UFSTAT_RXSHIFT,
2796         .rx_fifofull    = S3C2410_UFSTAT_RXFULL,
2797         .tx_fifofull    = S3C2410_UFSTAT_TXFULL,
2798         .tx_fifomask    = S3C2410_UFSTAT_TXMASK,
2799         .tx_fifoshift   = S3C2410_UFSTAT_TXSHIFT,
2800         .def_clk_sel    = S3C2410_UCON_CLKSEL0,
2801         .num_clks   = 1,
2802         .clksel_mask    = 0,
2803         .clksel_shift   = 0,
2804         .ucon_mask  = APPLE_S5L_UCON_MASK,
2805     },
2806     .def_cfg = {
2807         .ucon       = APPLE_S5L_UCON_DEFAULT,
2808         .ufcon      = S3C2410_UFCON_DEFAULT,
2809     },
2810 };
2811 #define S5L_SERIAL_DRV_DATA (&s5l_serial_drv_data)
2812 #else
2813 #define S5L_SERIAL_DRV_DATA NULL
2814 #endif
2815 
2816 #if defined(CONFIG_ARCH_ARTPEC)
2817 static const struct s3c24xx_serial_drv_data artpec8_serial_drv_data = {
2818     .info = {
2819         .name       = "Axis ARTPEC-8 UART",
2820         .type       = TYPE_S3C6400,
2821         .port_type  = PORT_S3C6400,
2822         .fifosize   = 64,
2823         .has_divslot    = 1,
2824         .rx_fifomask    = S5PV210_UFSTAT_RXMASK,
2825         .rx_fifoshift   = S5PV210_UFSTAT_RXSHIFT,
2826         .rx_fifofull    = S5PV210_UFSTAT_RXFULL,
2827         .tx_fifofull    = S5PV210_UFSTAT_TXFULL,
2828         .tx_fifomask    = S5PV210_UFSTAT_TXMASK,
2829         .tx_fifoshift   = S5PV210_UFSTAT_TXSHIFT,
2830         .def_clk_sel    = S3C2410_UCON_CLKSEL0,
2831         .num_clks   = 1,
2832         .clksel_mask    = 0,
2833         .clksel_shift   = 0,
2834     },
2835     .def_cfg = {
2836         .ucon       = S5PV210_UCON_DEFAULT,
2837         .ufcon      = S5PV210_UFCON_DEFAULT,
2838         .has_fracval    = 1,
2839     }
2840 };
2841 #define ARTPEC8_SERIAL_DRV_DATA (&artpec8_serial_drv_data)
2842 #else
2843 #define ARTPEC8_SERIAL_DRV_DATA (NULL)
2844 #endif
2845 
2846 static const struct platform_device_id s3c24xx_serial_driver_ids[] = {
2847     {
2848         .name       = "s3c2410-uart",
2849         .driver_data    = (kernel_ulong_t)S3C2410_SERIAL_DRV_DATA,
2850     }, {
2851         .name       = "s3c2412-uart",
2852         .driver_data    = (kernel_ulong_t)S3C2412_SERIAL_DRV_DATA,
2853     }, {
2854         .name       = "s3c2440-uart",
2855         .driver_data    = (kernel_ulong_t)S3C2440_SERIAL_DRV_DATA,
2856     }, {
2857         .name       = "s3c6400-uart",
2858         .driver_data    = (kernel_ulong_t)S3C6400_SERIAL_DRV_DATA,
2859     }, {
2860         .name       = "s5pv210-uart",
2861         .driver_data    = (kernel_ulong_t)S5PV210_SERIAL_DRV_DATA,
2862     }, {
2863         .name       = "exynos4210-uart",
2864         .driver_data    = (kernel_ulong_t)EXYNOS4210_SERIAL_DRV_DATA,
2865     }, {
2866         .name       = "exynos5433-uart",
2867         .driver_data    = (kernel_ulong_t)EXYNOS5433_SERIAL_DRV_DATA,
2868     }, {
2869         .name       = "s5l-uart",
2870         .driver_data    = (kernel_ulong_t)S5L_SERIAL_DRV_DATA,
2871     }, {
2872         .name       = "exynos850-uart",
2873         .driver_data    = (kernel_ulong_t)EXYNOS850_SERIAL_DRV_DATA,
2874     }, {
2875         .name       = "artpec8-uart",
2876         .driver_data    = (kernel_ulong_t)ARTPEC8_SERIAL_DRV_DATA,
2877     },
2878     { },
2879 };
2880 MODULE_DEVICE_TABLE(platform, s3c24xx_serial_driver_ids);
2881 
2882 #ifdef CONFIG_OF
2883 static const struct of_device_id s3c24xx_uart_dt_match[] = {
2884     { .compatible = "samsung,s3c2410-uart",
2885         .data = S3C2410_SERIAL_DRV_DATA },
2886     { .compatible = "samsung,s3c2412-uart",
2887         .data = S3C2412_SERIAL_DRV_DATA },
2888     { .compatible = "samsung,s3c2440-uart",
2889         .data = S3C2440_SERIAL_DRV_DATA },
2890     { .compatible = "samsung,s3c6400-uart",
2891         .data = S3C6400_SERIAL_DRV_DATA },
2892     { .compatible = "samsung,s5pv210-uart",
2893         .data = S5PV210_SERIAL_DRV_DATA },
2894     { .compatible = "samsung,exynos4210-uart",
2895         .data = EXYNOS4210_SERIAL_DRV_DATA },
2896     { .compatible = "samsung,exynos5433-uart",
2897         .data = EXYNOS5433_SERIAL_DRV_DATA },
2898     { .compatible = "apple,s5l-uart",
2899         .data = S5L_SERIAL_DRV_DATA },
2900     { .compatible = "samsung,exynos850-uart",
2901         .data = EXYNOS850_SERIAL_DRV_DATA },
2902     { .compatible = "axis,artpec8-uart",
2903         .data = ARTPEC8_SERIAL_DRV_DATA },
2904     {},
2905 };
2906 MODULE_DEVICE_TABLE(of, s3c24xx_uart_dt_match);
2907 #endif
2908 
2909 static struct platform_driver samsung_serial_driver = {
2910     .probe      = s3c24xx_serial_probe,
2911     .remove     = s3c24xx_serial_remove,
2912     .id_table   = s3c24xx_serial_driver_ids,
2913     .driver     = {
2914         .name   = "samsung-uart",
2915         .pm = SERIAL_SAMSUNG_PM_OPS,
2916         .of_match_table = of_match_ptr(s3c24xx_uart_dt_match),
2917     },
2918 };
2919 
2920 static int __init samsung_serial_init(void)
2921 {
2922     int ret;
2923 
2924     s3c24xx_serial_register_console();
2925 
2926     ret = platform_driver_register(&samsung_serial_driver);
2927     if (ret) {
2928         s3c24xx_serial_unregister_console();
2929         return ret;
2930     }
2931 
2932     return 0;
2933 }
2934 
2935 static void __exit samsung_serial_exit(void)
2936 {
2937     platform_driver_unregister(&samsung_serial_driver);
2938     s3c24xx_serial_unregister_console();
2939 }
2940 
2941 module_init(samsung_serial_init);
2942 module_exit(samsung_serial_exit);
2943 
2944 #ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE
2945 /*
2946  * Early console.
2947  */
2948 
2949 static void wr_reg_barrier(const struct uart_port *port, u32 reg, u32 val)
2950 {
2951     switch (port->iotype) {
2952     case UPIO_MEM:
2953         writeb(val, portaddr(port, reg));
2954         break;
2955     case UPIO_MEM32:
2956         writel(val, portaddr(port, reg));
2957         break;
2958     }
2959 }
2960 
2961 struct samsung_early_console_data {
2962     u32 txfull_mask;
2963     u32 rxfifo_mask;
2964 };
2965 
2966 static void samsung_early_busyuart(const struct uart_port *port)
2967 {
2968     while (!(readl(port->membase + S3C2410_UTRSTAT) & S3C2410_UTRSTAT_TXFE))
2969         ;
2970 }
2971 
2972 static void samsung_early_busyuart_fifo(const struct uart_port *port)
2973 {
2974     const struct samsung_early_console_data *data = port->private_data;
2975 
2976     while (readl(port->membase + S3C2410_UFSTAT) & data->txfull_mask)
2977         ;
2978 }
2979 
2980 static void samsung_early_putc(struct uart_port *port, unsigned char c)
2981 {
2982     if (readl(port->membase + S3C2410_UFCON) & S3C2410_UFCON_FIFOMODE)
2983         samsung_early_busyuart_fifo(port);
2984     else
2985         samsung_early_busyuart(port);
2986 
2987     wr_reg_barrier(port, S3C2410_UTXH, c);
2988 }
2989 
2990 static void samsung_early_write(struct console *con, const char *s,
2991                 unsigned int n)
2992 {
2993     struct earlycon_device *dev = con->data;
2994 
2995     uart_console_write(&dev->port, s, n, samsung_early_putc);
2996 }
2997 
2998 static int samsung_early_read(struct console *con, char *s, unsigned int n)
2999 {
3000     struct earlycon_device *dev = con->data;
3001     const struct samsung_early_console_data *data = dev->port.private_data;
3002     int ch, ufstat, num_read = 0;
3003 
3004     while (num_read < n) {
3005         ufstat = rd_regl(&dev->port, S3C2410_UFSTAT);
3006         if (!(ufstat & data->rxfifo_mask))
3007             break;
3008         ch = rd_reg(&dev->port, S3C2410_URXH);
3009         if (ch == NO_POLL_CHAR)
3010             break;
3011 
3012         s[num_read++] = ch;
3013     }
3014 
3015     return num_read;
3016 }
3017 
3018 static int __init samsung_early_console_setup(struct earlycon_device *device,
3019                           const char *opt)
3020 {
3021     if (!device->port.membase)
3022         return -ENODEV;
3023 
3024     device->con->write = samsung_early_write;
3025     device->con->read = samsung_early_read;
3026     return 0;
3027 }
3028 
3029 /* S3C2410 */
3030 static struct samsung_early_console_data s3c2410_early_console_data = {
3031     .txfull_mask = S3C2410_UFSTAT_TXFULL,
3032     .rxfifo_mask = S3C2410_UFSTAT_RXFULL | S3C2410_UFSTAT_RXMASK,
3033 };
3034 
3035 static int __init s3c2410_early_console_setup(struct earlycon_device *device,
3036                           const char *opt)
3037 {
3038     device->port.private_data = &s3c2410_early_console_data;
3039     return samsung_early_console_setup(device, opt);
3040 }
3041 
3042 OF_EARLYCON_DECLARE(s3c2410, "samsung,s3c2410-uart",
3043             s3c2410_early_console_setup);
3044 
3045 /* S3C2412, S3C2440, S3C64xx */
3046 static struct samsung_early_console_data s3c2440_early_console_data = {
3047     .txfull_mask = S3C2440_UFSTAT_TXFULL,
3048     .rxfifo_mask = S3C2440_UFSTAT_RXFULL | S3C2440_UFSTAT_RXMASK,
3049 };
3050 
3051 static int __init s3c2440_early_console_setup(struct earlycon_device *device,
3052                           const char *opt)
3053 {
3054     device->port.private_data = &s3c2440_early_console_data;
3055     return samsung_early_console_setup(device, opt);
3056 }
3057 
3058 OF_EARLYCON_DECLARE(s3c2412, "samsung,s3c2412-uart",
3059             s3c2440_early_console_setup);
3060 OF_EARLYCON_DECLARE(s3c2440, "samsung,s3c2440-uart",
3061             s3c2440_early_console_setup);
3062 OF_EARLYCON_DECLARE(s3c6400, "samsung,s3c6400-uart",
3063             s3c2440_early_console_setup);
3064 
3065 /* S5PV210, Exynos */
3066 static struct samsung_early_console_data s5pv210_early_console_data = {
3067     .txfull_mask = S5PV210_UFSTAT_TXFULL,
3068     .rxfifo_mask = S5PV210_UFSTAT_RXFULL | S5PV210_UFSTAT_RXMASK,
3069 };
3070 
3071 static int __init s5pv210_early_console_setup(struct earlycon_device *device,
3072                           const char *opt)
3073 {
3074     device->port.private_data = &s5pv210_early_console_data;
3075     return samsung_early_console_setup(device, opt);
3076 }
3077 
3078 OF_EARLYCON_DECLARE(s5pv210, "samsung,s5pv210-uart",
3079             s5pv210_early_console_setup);
3080 OF_EARLYCON_DECLARE(exynos4210, "samsung,exynos4210-uart",
3081             s5pv210_early_console_setup);
3082 OF_EARLYCON_DECLARE(artpec8, "axis,artpec8-uart",
3083             s5pv210_early_console_setup);
3084 
3085 /* Apple S5L */
3086 static int __init apple_s5l_early_console_setup(struct earlycon_device *device,
3087                         const char *opt)
3088 {
3089     /* Close enough to S3C2410 for earlycon... */
3090     device->port.private_data = &s3c2410_early_console_data;
3091 
3092 #ifdef CONFIG_ARM64
3093     /* ... but we need to override the existing fixmap entry as nGnRnE */
3094     __set_fixmap(FIX_EARLYCON_MEM_BASE, device->port.mapbase,
3095              __pgprot(PROT_DEVICE_nGnRnE));
3096 #endif
3097     return samsung_early_console_setup(device, opt);
3098 }
3099 
3100 OF_EARLYCON_DECLARE(s5l, "apple,s5l-uart", apple_s5l_early_console_setup);
3101 #endif
3102 
3103 MODULE_ALIAS("platform:samsung-uart");
3104 MODULE_DESCRIPTION("Samsung SoC Serial port driver");
3105 MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
3106 MODULE_LICENSE("GPL v2");