0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
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
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
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
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
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
0164
0165 #define s3c24xx_dev_to_port(__dev) dev_get_drvdata(__dev)
0166
0167
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
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
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
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);
0377 break;
0378 default:
0379 disable_irq_nosync(ourport->tx_irq);
0380 break;
0381 }
0382
0383
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
0399 ourport->tx_in_progress = S3C24XX_TX_PIO;
0400 ufcon = rd_regl(port, S3C2410_UFCON);
0401 wr_regl(port, S3C2410_UFCON, ufcon);
0402
0403
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
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
0428
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
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
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
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
0698 ucon = rd_regl(port, S3C2410_UCON);
0699 ucon &= ~S3C64XX_UCON_RXMODE_MASK;
0700 ucon |= S3C64XX_UCON_RXMODE_CPU;
0701
0702
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
0775
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
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
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;
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;
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
0899
0900
0901
0902 if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
0903 s3c24xx_serial_stop_tx(port);
0904 return;
0905 }
0906
0907
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
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
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
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
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
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
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
1275
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
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
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
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
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
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
1402
1403
1404
1405
1406
1407
1408
1409
1410
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
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
1477
1478
1479
1480
1481
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
1508
1509
1510
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
1546
1547 termios->c_cflag &= ~(HUPCL | CMSPAR);
1548 termios->c_cflag |= CLOCAL;
1549
1550
1551
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
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
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
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
1658
1659 uart_update_timeout(port, termios->c_cflag, baud);
1660
1661
1662
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
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
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
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
1841
1842
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
1855 wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH);
1856 wr_regl(port, S3C2410_UFCON, cfg->ufcon);
1857
1858
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
1874
1875 if (port->pm_level != 0)
1876 return 0;
1877
1878
1879
1880
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
1891
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
1986
1987
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
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
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
2052
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
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
2112 s3c24xx_serial_resetport(port, cfg);
2113
2114 return 0;
2115
2116 err:
2117 port->mapbase = 0;
2118 return ret;
2119 }
2120
2121
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
2208
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
2233
2234
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
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
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
2372
2373 #define SERIAL_SAMSUNG_PM_OPS NULL
2374 #endif
2375
2376
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
2390
2391 ufstat = rd_regl(port, S3C2410_UFSTAT);
2392 return (ufstat & info->tx_fifofull) ? 0 : 1;
2393 }
2394
2395
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
2405 return (ucon & 0xf) != 0;
2406 }
2407
2408 #ifdef CONFIG_CONSOLE_POLL
2409
2410
2411
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
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
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
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
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
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
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
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
2560
2561 if (port->mapbase == 0x0)
2562 return -ENODEV;
2563
2564 cons_uart = port;
2565
2566
2567
2568
2569
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
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
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
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
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
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
3086 static int __init apple_s5l_early_console_setup(struct earlycon_device *device,
3087 const char *opt)
3088 {
3089
3090 device->port.private_data = &s3c2410_early_console_data;
3091
3092 #ifdef CONFIG_ARM64
3093
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");