Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v4.6 2501 lines 64 kB view raw
1/* 2 * Driver core for Samsung SoC onboard UARTs. 3 * 4 * Ben Dooks, Copyright (c) 2003-2008 Simtec Electronics 5 * http://armlinux.simtec.co.uk/ 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 as 9 * published by the Free Software Foundation. 10*/ 11 12/* Hote on 2410 error handling 13 * 14 * The s3c2410 manual has a love/hate affair with the contents of the 15 * UERSTAT register in the UART blocks, and keeps marking some of the 16 * error bits as reserved. Having checked with the s3c2410x01, 17 * it copes with BREAKs properly, so I am happy to ignore the RESERVED 18 * feature from the latter versions of the manual. 19 * 20 * If it becomes aparrent that latter versions of the 2410 remove these 21 * bits, then action will have to be taken to differentiate the versions 22 * and change the policy on BREAK 23 * 24 * BJD, 04-Nov-2004 25*/ 26 27#if defined(CONFIG_SERIAL_SAMSUNG_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) 28#define SUPPORT_SYSRQ 29#endif 30 31#include <linux/dmaengine.h> 32#include <linux/dma-mapping.h> 33#include <linux/slab.h> 34#include <linux/module.h> 35#include <linux/ioport.h> 36#include <linux/io.h> 37#include <linux/platform_device.h> 38#include <linux/init.h> 39#include <linux/sysrq.h> 40#include <linux/console.h> 41#include <linux/tty.h> 42#include <linux/tty_flip.h> 43#include <linux/serial_core.h> 44#include <linux/serial.h> 45#include <linux/serial_s3c.h> 46#include <linux/delay.h> 47#include <linux/clk.h> 48#include <linux/cpufreq.h> 49#include <linux/of.h> 50 51#include <asm/irq.h> 52 53#include "samsung.h" 54 55#if defined(CONFIG_SERIAL_SAMSUNG_DEBUG) && \ 56 !defined(MODULE) 57 58extern void printascii(const char *); 59 60__printf(1, 2) 61static void dbg(const char *fmt, ...) 62{ 63 va_list va; 64 char buff[256]; 65 66 va_start(va, fmt); 67 vscnprintf(buff, sizeof(buff), fmt, va); 68 va_end(va); 69 70 printascii(buff); 71} 72 73#else 74#define dbg(fmt, ...) do { if (0) no_printk(fmt, ##__VA_ARGS__); } while (0) 75#endif 76 77/* UART name and device definitions */ 78 79#define S3C24XX_SERIAL_NAME "ttySAC" 80#define S3C24XX_SERIAL_MAJOR 204 81#define S3C24XX_SERIAL_MINOR 64 82 83#define S3C24XX_TX_PIO 1 84#define S3C24XX_TX_DMA 2 85#define S3C24XX_RX_PIO 1 86#define S3C24XX_RX_DMA 2 87/* macros to change one thing to another */ 88 89#define tx_enabled(port) ((port)->unused[0]) 90#define rx_enabled(port) ((port)->unused[1]) 91 92/* flag to ignore all characters coming in */ 93#define RXSTAT_DUMMY_READ (0x10000000) 94 95static inline struct s3c24xx_uart_port *to_ourport(struct uart_port *port) 96{ 97 return container_of(port, struct s3c24xx_uart_port, port); 98} 99 100/* translate a port to the device name */ 101 102static inline const char *s3c24xx_serial_portname(struct uart_port *port) 103{ 104 return to_platform_device(port->dev)->name; 105} 106 107static int s3c24xx_serial_txempty_nofifo(struct uart_port *port) 108{ 109 return rd_regl(port, S3C2410_UTRSTAT) & S3C2410_UTRSTAT_TXE; 110} 111 112/* 113 * s3c64xx and later SoC's include the interrupt mask and status registers in 114 * the controller itself, unlike the s3c24xx SoC's which have these registers 115 * in the interrupt controller. Check if the port type is s3c64xx or higher. 116 */ 117static int s3c24xx_serial_has_interrupt_mask(struct uart_port *port) 118{ 119 return to_ourport(port)->info->type == PORT_S3C6400; 120} 121 122static void s3c24xx_serial_rx_enable(struct uart_port *port) 123{ 124 unsigned long flags; 125 unsigned int ucon, ufcon; 126 int count = 10000; 127 128 spin_lock_irqsave(&port->lock, flags); 129 130 while (--count && !s3c24xx_serial_txempty_nofifo(port)) 131 udelay(100); 132 133 ufcon = rd_regl(port, S3C2410_UFCON); 134 ufcon |= S3C2410_UFCON_RESETRX; 135 wr_regl(port, S3C2410_UFCON, ufcon); 136 137 ucon = rd_regl(port, S3C2410_UCON); 138 ucon |= S3C2410_UCON_RXIRQMODE; 139 wr_regl(port, S3C2410_UCON, ucon); 140 141 rx_enabled(port) = 1; 142 spin_unlock_irqrestore(&port->lock, flags); 143} 144 145static void s3c24xx_serial_rx_disable(struct uart_port *port) 146{ 147 unsigned long flags; 148 unsigned int ucon; 149 150 spin_lock_irqsave(&port->lock, flags); 151 152 ucon = rd_regl(port, S3C2410_UCON); 153 ucon &= ~S3C2410_UCON_RXIRQMODE; 154 wr_regl(port, S3C2410_UCON, ucon); 155 156 rx_enabled(port) = 0; 157 spin_unlock_irqrestore(&port->lock, flags); 158} 159 160static void s3c24xx_serial_stop_tx(struct uart_port *port) 161{ 162 struct s3c24xx_uart_port *ourport = to_ourport(port); 163 struct s3c24xx_uart_dma *dma = ourport->dma; 164 struct circ_buf *xmit = &port->state->xmit; 165 struct dma_tx_state state; 166 int count; 167 168 if (!tx_enabled(port)) 169 return; 170 171 if (s3c24xx_serial_has_interrupt_mask(port)) 172 __set_bit(S3C64XX_UINTM_TXD, 173 portaddrl(port, S3C64XX_UINTM)); 174 else 175 disable_irq_nosync(ourport->tx_irq); 176 177 if (dma && dma->tx_chan && ourport->tx_in_progress == S3C24XX_TX_DMA) { 178 dmaengine_pause(dma->tx_chan); 179 dmaengine_tx_status(dma->tx_chan, dma->tx_cookie, &state); 180 dmaengine_terminate_all(dma->tx_chan); 181 dma_sync_single_for_cpu(ourport->port.dev, 182 dma->tx_transfer_addr, dma->tx_size, DMA_TO_DEVICE); 183 async_tx_ack(dma->tx_desc); 184 count = dma->tx_bytes_requested - state.residue; 185 xmit->tail = (xmit->tail + count) & (UART_XMIT_SIZE - 1); 186 port->icount.tx += count; 187 } 188 189 tx_enabled(port) = 0; 190 ourport->tx_in_progress = 0; 191 192 if (port->flags & UPF_CONS_FLOW) 193 s3c24xx_serial_rx_enable(port); 194 195 ourport->tx_mode = 0; 196} 197 198static void s3c24xx_serial_start_next_tx(struct s3c24xx_uart_port *ourport); 199 200static void s3c24xx_serial_tx_dma_complete(void *args) 201{ 202 struct s3c24xx_uart_port *ourport = args; 203 struct uart_port *port = &ourport->port; 204 struct circ_buf *xmit = &port->state->xmit; 205 struct s3c24xx_uart_dma *dma = ourport->dma; 206 struct dma_tx_state state; 207 unsigned long flags; 208 int count; 209 210 211 dmaengine_tx_status(dma->tx_chan, dma->tx_cookie, &state); 212 count = dma->tx_bytes_requested - state.residue; 213 async_tx_ack(dma->tx_desc); 214 215 dma_sync_single_for_cpu(ourport->port.dev, dma->tx_transfer_addr, 216 dma->tx_size, DMA_TO_DEVICE); 217 218 spin_lock_irqsave(&port->lock, flags); 219 220 xmit->tail = (xmit->tail + count) & (UART_XMIT_SIZE - 1); 221 port->icount.tx += count; 222 ourport->tx_in_progress = 0; 223 224 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) 225 uart_write_wakeup(port); 226 227 s3c24xx_serial_start_next_tx(ourport); 228 spin_unlock_irqrestore(&port->lock, flags); 229} 230 231static void enable_tx_dma(struct s3c24xx_uart_port *ourport) 232{ 233 struct uart_port *port = &ourport->port; 234 u32 ucon; 235 236 /* Mask Tx interrupt */ 237 if (s3c24xx_serial_has_interrupt_mask(port)) 238 __set_bit(S3C64XX_UINTM_TXD, 239 portaddrl(port, S3C64XX_UINTM)); 240 else 241 disable_irq_nosync(ourport->tx_irq); 242 243 /* Enable tx dma mode */ 244 ucon = rd_regl(port, S3C2410_UCON); 245 ucon &= ~(S3C64XX_UCON_TXBURST_MASK | S3C64XX_UCON_TXMODE_MASK); 246 ucon |= (dma_get_cache_alignment() >= 16) ? 247 S3C64XX_UCON_TXBURST_16 : S3C64XX_UCON_TXBURST_1; 248 ucon |= S3C64XX_UCON_TXMODE_DMA; 249 wr_regl(port, S3C2410_UCON, ucon); 250 251 ourport->tx_mode = S3C24XX_TX_DMA; 252} 253 254static void enable_tx_pio(struct s3c24xx_uart_port *ourport) 255{ 256 struct uart_port *port = &ourport->port; 257 u32 ucon, ufcon; 258 259 /* Set ufcon txtrig */ 260 ourport->tx_in_progress = S3C24XX_TX_PIO; 261 ufcon = rd_regl(port, S3C2410_UFCON); 262 wr_regl(port, S3C2410_UFCON, ufcon); 263 264 /* Enable tx pio mode */ 265 ucon = rd_regl(port, S3C2410_UCON); 266 ucon &= ~(S3C64XX_UCON_TXMODE_MASK); 267 ucon |= S3C64XX_UCON_TXMODE_CPU; 268 wr_regl(port, S3C2410_UCON, ucon); 269 270 /* Unmask Tx interrupt */ 271 if (s3c24xx_serial_has_interrupt_mask(port)) 272 __clear_bit(S3C64XX_UINTM_TXD, 273 portaddrl(port, S3C64XX_UINTM)); 274 else 275 enable_irq(ourport->tx_irq); 276 277 ourport->tx_mode = S3C24XX_TX_PIO; 278} 279 280static void s3c24xx_serial_start_tx_pio(struct s3c24xx_uart_port *ourport) 281{ 282 if (ourport->tx_mode != S3C24XX_TX_PIO) 283 enable_tx_pio(ourport); 284} 285 286static int s3c24xx_serial_start_tx_dma(struct s3c24xx_uart_port *ourport, 287 unsigned int count) 288{ 289 struct uart_port *port = &ourport->port; 290 struct circ_buf *xmit = &port->state->xmit; 291 struct s3c24xx_uart_dma *dma = ourport->dma; 292 293 294 if (ourport->tx_mode != S3C24XX_TX_DMA) 295 enable_tx_dma(ourport); 296 297 dma->tx_size = count & ~(dma_get_cache_alignment() - 1); 298 dma->tx_transfer_addr = dma->tx_addr + xmit->tail; 299 300 dma_sync_single_for_device(ourport->port.dev, dma->tx_transfer_addr, 301 dma->tx_size, DMA_TO_DEVICE); 302 303 dma->tx_desc = dmaengine_prep_slave_single(dma->tx_chan, 304 dma->tx_transfer_addr, dma->tx_size, 305 DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT); 306 if (!dma->tx_desc) { 307 dev_err(ourport->port.dev, "Unable to get desc for Tx\n"); 308 return -EIO; 309 } 310 311 dma->tx_desc->callback = s3c24xx_serial_tx_dma_complete; 312 dma->tx_desc->callback_param = ourport; 313 dma->tx_bytes_requested = dma->tx_size; 314 315 ourport->tx_in_progress = S3C24XX_TX_DMA; 316 dma->tx_cookie = dmaengine_submit(dma->tx_desc); 317 dma_async_issue_pending(dma->tx_chan); 318 return 0; 319} 320 321static void s3c24xx_serial_start_next_tx(struct s3c24xx_uart_port *ourport) 322{ 323 struct uart_port *port = &ourport->port; 324 struct circ_buf *xmit = &port->state->xmit; 325 unsigned long count; 326 327 /* Get data size up to the end of buffer */ 328 count = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE); 329 330 if (!count) { 331 s3c24xx_serial_stop_tx(port); 332 return; 333 } 334 335 if (!ourport->dma || !ourport->dma->tx_chan || 336 count < ourport->min_dma_size || 337 xmit->tail & (dma_get_cache_alignment() - 1)) 338 s3c24xx_serial_start_tx_pio(ourport); 339 else 340 s3c24xx_serial_start_tx_dma(ourport, count); 341} 342 343static void s3c24xx_serial_start_tx(struct uart_port *port) 344{ 345 struct s3c24xx_uart_port *ourport = to_ourport(port); 346 struct circ_buf *xmit = &port->state->xmit; 347 348 if (!tx_enabled(port)) { 349 if (port->flags & UPF_CONS_FLOW) 350 s3c24xx_serial_rx_disable(port); 351 352 tx_enabled(port) = 1; 353 if (!ourport->dma || !ourport->dma->tx_chan) 354 s3c24xx_serial_start_tx_pio(ourport); 355 } 356 357 if (ourport->dma && ourport->dma->tx_chan) { 358 if (!uart_circ_empty(xmit) && !ourport->tx_in_progress) 359 s3c24xx_serial_start_next_tx(ourport); 360 } 361} 362 363static void s3c24xx_uart_copy_rx_to_tty(struct s3c24xx_uart_port *ourport, 364 struct tty_port *tty, int count) 365{ 366 struct s3c24xx_uart_dma *dma = ourport->dma; 367 int copied; 368 369 if (!count) 370 return; 371 372 dma_sync_single_for_cpu(ourport->port.dev, dma->rx_addr, 373 dma->rx_size, DMA_FROM_DEVICE); 374 375 ourport->port.icount.rx += count; 376 if (!tty) { 377 dev_err(ourport->port.dev, "No tty port\n"); 378 return; 379 } 380 copied = tty_insert_flip_string(tty, 381 ((unsigned char *)(ourport->dma->rx_buf)), count); 382 if (copied != count) { 383 WARN_ON(1); 384 dev_err(ourport->port.dev, "RxData copy to tty layer failed\n"); 385 } 386} 387 388static void s3c24xx_serial_stop_rx(struct uart_port *port) 389{ 390 struct s3c24xx_uart_port *ourport = to_ourport(port); 391 struct s3c24xx_uart_dma *dma = ourport->dma; 392 struct tty_port *t = &port->state->port; 393 struct dma_tx_state state; 394 enum dma_status dma_status; 395 unsigned int received; 396 397 if (rx_enabled(port)) { 398 dbg("s3c24xx_serial_stop_rx: port=%p\n", port); 399 if (s3c24xx_serial_has_interrupt_mask(port)) 400 __set_bit(S3C64XX_UINTM_RXD, 401 portaddrl(port, S3C64XX_UINTM)); 402 else 403 disable_irq_nosync(ourport->rx_irq); 404 rx_enabled(port) = 0; 405 } 406 if (dma && dma->rx_chan) { 407 dmaengine_pause(dma->tx_chan); 408 dma_status = dmaengine_tx_status(dma->rx_chan, 409 dma->rx_cookie, &state); 410 if (dma_status == DMA_IN_PROGRESS || 411 dma_status == DMA_PAUSED) { 412 received = dma->rx_bytes_requested - state.residue; 413 dmaengine_terminate_all(dma->rx_chan); 414 s3c24xx_uart_copy_rx_to_tty(ourport, t, received); 415 } 416 } 417} 418 419static inline struct s3c24xx_uart_info 420 *s3c24xx_port_to_info(struct uart_port *port) 421{ 422 return to_ourport(port)->info; 423} 424 425static inline struct s3c2410_uartcfg 426 *s3c24xx_port_to_cfg(struct uart_port *port) 427{ 428 struct s3c24xx_uart_port *ourport; 429 430 if (port->dev == NULL) 431 return NULL; 432 433 ourport = container_of(port, struct s3c24xx_uart_port, port); 434 return ourport->cfg; 435} 436 437static int s3c24xx_serial_rx_fifocnt(struct s3c24xx_uart_port *ourport, 438 unsigned long ufstat) 439{ 440 struct s3c24xx_uart_info *info = ourport->info; 441 442 if (ufstat & info->rx_fifofull) 443 return ourport->port.fifosize; 444 445 return (ufstat & info->rx_fifomask) >> info->rx_fifoshift; 446} 447 448static void s3c64xx_start_rx_dma(struct s3c24xx_uart_port *ourport); 449static void s3c24xx_serial_rx_dma_complete(void *args) 450{ 451 struct s3c24xx_uart_port *ourport = args; 452 struct uart_port *port = &ourport->port; 453 454 struct s3c24xx_uart_dma *dma = ourport->dma; 455 struct tty_port *t = &port->state->port; 456 struct tty_struct *tty = tty_port_tty_get(&ourport->port.state->port); 457 458 struct dma_tx_state state; 459 unsigned long flags; 460 int received; 461 462 dmaengine_tx_status(dma->rx_chan, dma->rx_cookie, &state); 463 received = dma->rx_bytes_requested - state.residue; 464 async_tx_ack(dma->rx_desc); 465 466 spin_lock_irqsave(&port->lock, flags); 467 468 if (received) 469 s3c24xx_uart_copy_rx_to_tty(ourport, t, received); 470 471 if (tty) { 472 tty_flip_buffer_push(t); 473 tty_kref_put(tty); 474 } 475 476 s3c64xx_start_rx_dma(ourport); 477 478 spin_unlock_irqrestore(&port->lock, flags); 479} 480 481static void s3c64xx_start_rx_dma(struct s3c24xx_uart_port *ourport) 482{ 483 struct s3c24xx_uart_dma *dma = ourport->dma; 484 485 dma_sync_single_for_device(ourport->port.dev, dma->rx_addr, 486 dma->rx_size, DMA_FROM_DEVICE); 487 488 dma->rx_desc = dmaengine_prep_slave_single(dma->rx_chan, 489 dma->rx_addr, dma->rx_size, DMA_DEV_TO_MEM, 490 DMA_PREP_INTERRUPT); 491 if (!dma->rx_desc) { 492 dev_err(ourport->port.dev, "Unable to get desc for Rx\n"); 493 return; 494 } 495 496 dma->rx_desc->callback = s3c24xx_serial_rx_dma_complete; 497 dma->rx_desc->callback_param = ourport; 498 dma->rx_bytes_requested = dma->rx_size; 499 500 dma->rx_cookie = dmaengine_submit(dma->rx_desc); 501 dma_async_issue_pending(dma->rx_chan); 502} 503 504/* ? - where has parity gone?? */ 505#define S3C2410_UERSTAT_PARITY (0x1000) 506 507static void enable_rx_dma(struct s3c24xx_uart_port *ourport) 508{ 509 struct uart_port *port = &ourport->port; 510 unsigned int ucon; 511 512 /* set Rx mode to DMA mode */ 513 ucon = rd_regl(port, S3C2410_UCON); 514 ucon &= ~(S3C64XX_UCON_RXBURST_MASK | 515 S3C64XX_UCON_TIMEOUT_MASK | 516 S3C64XX_UCON_EMPTYINT_EN | 517 S3C64XX_UCON_DMASUS_EN | 518 S3C64XX_UCON_TIMEOUT_EN | 519 S3C64XX_UCON_RXMODE_MASK); 520 ucon |= S3C64XX_UCON_RXBURST_16 | 521 0xf << S3C64XX_UCON_TIMEOUT_SHIFT | 522 S3C64XX_UCON_EMPTYINT_EN | 523 S3C64XX_UCON_TIMEOUT_EN | 524 S3C64XX_UCON_RXMODE_DMA; 525 wr_regl(port, S3C2410_UCON, ucon); 526 527 ourport->rx_mode = S3C24XX_RX_DMA; 528} 529 530static void enable_rx_pio(struct s3c24xx_uart_port *ourport) 531{ 532 struct uart_port *port = &ourport->port; 533 unsigned int ucon; 534 535 /* set Rx mode to DMA mode */ 536 ucon = rd_regl(port, S3C2410_UCON); 537 ucon &= ~(S3C64XX_UCON_TIMEOUT_MASK | 538 S3C64XX_UCON_EMPTYINT_EN | 539 S3C64XX_UCON_DMASUS_EN | 540 S3C64XX_UCON_TIMEOUT_EN | 541 S3C64XX_UCON_RXMODE_MASK); 542 ucon |= 0xf << S3C64XX_UCON_TIMEOUT_SHIFT | 543 S3C64XX_UCON_TIMEOUT_EN | 544 S3C64XX_UCON_RXMODE_CPU; 545 wr_regl(port, S3C2410_UCON, ucon); 546 547 ourport->rx_mode = S3C24XX_RX_PIO; 548} 549 550static void s3c24xx_serial_rx_drain_fifo(struct s3c24xx_uart_port *ourport); 551 552static irqreturn_t s3c24xx_serial_rx_chars_dma(void *dev_id) 553{ 554 unsigned int utrstat, ufstat, received; 555 struct s3c24xx_uart_port *ourport = dev_id; 556 struct uart_port *port = &ourport->port; 557 struct s3c24xx_uart_dma *dma = ourport->dma; 558 struct tty_struct *tty = tty_port_tty_get(&ourport->port.state->port); 559 struct tty_port *t = &port->state->port; 560 unsigned long flags; 561 struct dma_tx_state state; 562 563 utrstat = rd_regl(port, S3C2410_UTRSTAT); 564 ufstat = rd_regl(port, S3C2410_UFSTAT); 565 566 spin_lock_irqsave(&port->lock, flags); 567 568 if (!(utrstat & S3C2410_UTRSTAT_TIMEOUT)) { 569 s3c64xx_start_rx_dma(ourport); 570 if (ourport->rx_mode == S3C24XX_RX_PIO) 571 enable_rx_dma(ourport); 572 goto finish; 573 } 574 575 if (ourport->rx_mode == S3C24XX_RX_DMA) { 576 dmaengine_pause(dma->rx_chan); 577 dmaengine_tx_status(dma->rx_chan, dma->rx_cookie, &state); 578 dmaengine_terminate_all(dma->rx_chan); 579 received = dma->rx_bytes_requested - state.residue; 580 s3c24xx_uart_copy_rx_to_tty(ourport, t, received); 581 582 enable_rx_pio(ourport); 583 } 584 585 s3c24xx_serial_rx_drain_fifo(ourport); 586 587 if (tty) { 588 tty_flip_buffer_push(t); 589 tty_kref_put(tty); 590 } 591 592 wr_regl(port, S3C2410_UTRSTAT, S3C2410_UTRSTAT_TIMEOUT); 593 594finish: 595 spin_unlock_irqrestore(&port->lock, flags); 596 597 return IRQ_HANDLED; 598} 599 600static void s3c24xx_serial_rx_drain_fifo(struct s3c24xx_uart_port *ourport) 601{ 602 struct uart_port *port = &ourport->port; 603 unsigned int ufcon, ch, flag, ufstat, uerstat; 604 unsigned int fifocnt = 0; 605 int max_count = port->fifosize; 606 607 while (max_count-- > 0) { 608 /* 609 * Receive all characters known to be in FIFO 610 * before reading FIFO level again 611 */ 612 if (fifocnt == 0) { 613 ufstat = rd_regl(port, S3C2410_UFSTAT); 614 fifocnt = s3c24xx_serial_rx_fifocnt(ourport, ufstat); 615 if (fifocnt == 0) 616 break; 617 } 618 fifocnt--; 619 620 uerstat = rd_regl(port, S3C2410_UERSTAT); 621 ch = rd_regb(port, S3C2410_URXH); 622 623 if (port->flags & UPF_CONS_FLOW) { 624 int txe = s3c24xx_serial_txempty_nofifo(port); 625 626 if (rx_enabled(port)) { 627 if (!txe) { 628 rx_enabled(port) = 0; 629 continue; 630 } 631 } else { 632 if (txe) { 633 ufcon = rd_regl(port, S3C2410_UFCON); 634 ufcon |= S3C2410_UFCON_RESETRX; 635 wr_regl(port, S3C2410_UFCON, ufcon); 636 rx_enabled(port) = 1; 637 return; 638 } 639 continue; 640 } 641 } 642 643 /* insert the character into the buffer */ 644 645 flag = TTY_NORMAL; 646 port->icount.rx++; 647 648 if (unlikely(uerstat & S3C2410_UERSTAT_ANY)) { 649 dbg("rxerr: port ch=0x%02x, rxs=0x%08x\n", 650 ch, uerstat); 651 652 /* check for break */ 653 if (uerstat & S3C2410_UERSTAT_BREAK) { 654 dbg("break!\n"); 655 port->icount.brk++; 656 if (uart_handle_break(port)) 657 continue; /* Ignore character */ 658 } 659 660 if (uerstat & S3C2410_UERSTAT_FRAME) 661 port->icount.frame++; 662 if (uerstat & S3C2410_UERSTAT_OVERRUN) 663 port->icount.overrun++; 664 665 uerstat &= port->read_status_mask; 666 667 if (uerstat & S3C2410_UERSTAT_BREAK) 668 flag = TTY_BREAK; 669 else if (uerstat & S3C2410_UERSTAT_PARITY) 670 flag = TTY_PARITY; 671 else if (uerstat & (S3C2410_UERSTAT_FRAME | 672 S3C2410_UERSTAT_OVERRUN)) 673 flag = TTY_FRAME; 674 } 675 676 if (uart_handle_sysrq_char(port, ch)) 677 continue; /* Ignore character */ 678 679 uart_insert_char(port, uerstat, S3C2410_UERSTAT_OVERRUN, 680 ch, flag); 681 } 682 683 tty_flip_buffer_push(&port->state->port); 684} 685 686static irqreturn_t s3c24xx_serial_rx_chars_pio(void *dev_id) 687{ 688 struct s3c24xx_uart_port *ourport = dev_id; 689 struct uart_port *port = &ourport->port; 690 unsigned long flags; 691 692 spin_lock_irqsave(&port->lock, flags); 693 s3c24xx_serial_rx_drain_fifo(ourport); 694 spin_unlock_irqrestore(&port->lock, flags); 695 696 return IRQ_HANDLED; 697} 698 699 700static irqreturn_t s3c24xx_serial_rx_chars(int irq, void *dev_id) 701{ 702 struct s3c24xx_uart_port *ourport = dev_id; 703 704 if (ourport->dma && ourport->dma->rx_chan) 705 return s3c24xx_serial_rx_chars_dma(dev_id); 706 return s3c24xx_serial_rx_chars_pio(dev_id); 707} 708 709static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id) 710{ 711 struct s3c24xx_uart_port *ourport = id; 712 struct uart_port *port = &ourport->port; 713 struct circ_buf *xmit = &port->state->xmit; 714 unsigned long flags; 715 int count, dma_count = 0; 716 717 spin_lock_irqsave(&port->lock, flags); 718 719 count = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE); 720 721 if (ourport->dma && ourport->dma->tx_chan && 722 count >= ourport->min_dma_size) { 723 int align = dma_get_cache_alignment() - 724 (xmit->tail & (dma_get_cache_alignment() - 1)); 725 if (count-align >= ourport->min_dma_size) { 726 dma_count = count-align; 727 count = align; 728 } 729 } 730 731 if (port->x_char) { 732 wr_regb(port, S3C2410_UTXH, port->x_char); 733 port->icount.tx++; 734 port->x_char = 0; 735 goto out; 736 } 737 738 /* if there isn't anything more to transmit, or the uart is now 739 * stopped, disable the uart and exit 740 */ 741 742 if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { 743 s3c24xx_serial_stop_tx(port); 744 goto out; 745 } 746 747 /* try and drain the buffer... */ 748 749 if (count > port->fifosize) { 750 count = port->fifosize; 751 dma_count = 0; 752 } 753 754 while (!uart_circ_empty(xmit) && count > 0) { 755 if (rd_regl(port, S3C2410_UFSTAT) & ourport->info->tx_fifofull) 756 break; 757 758 wr_regb(port, S3C2410_UTXH, xmit->buf[xmit->tail]); 759 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); 760 port->icount.tx++; 761 count--; 762 } 763 764 if (!count && dma_count) { 765 s3c24xx_serial_start_tx_dma(ourport, dma_count); 766 goto out; 767 } 768 769 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) { 770 spin_unlock(&port->lock); 771 uart_write_wakeup(port); 772 spin_lock(&port->lock); 773 } 774 775 if (uart_circ_empty(xmit)) 776 s3c24xx_serial_stop_tx(port); 777 778out: 779 spin_unlock_irqrestore(&port->lock, flags); 780 return IRQ_HANDLED; 781} 782 783/* interrupt handler for s3c64xx and later SoC's.*/ 784static irqreturn_t s3c64xx_serial_handle_irq(int irq, void *id) 785{ 786 struct s3c24xx_uart_port *ourport = id; 787 struct uart_port *port = &ourport->port; 788 unsigned int pend = rd_regl(port, S3C64XX_UINTP); 789 irqreturn_t ret = IRQ_HANDLED; 790 791 if (pend & S3C64XX_UINTM_RXD_MSK) { 792 ret = s3c24xx_serial_rx_chars(irq, id); 793 wr_regl(port, S3C64XX_UINTP, S3C64XX_UINTM_RXD_MSK); 794 } 795 if (pend & S3C64XX_UINTM_TXD_MSK) { 796 ret = s3c24xx_serial_tx_chars(irq, id); 797 wr_regl(port, S3C64XX_UINTP, S3C64XX_UINTM_TXD_MSK); 798 } 799 return ret; 800} 801 802static unsigned int s3c24xx_serial_tx_empty(struct uart_port *port) 803{ 804 struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port); 805 unsigned long ufstat = rd_regl(port, S3C2410_UFSTAT); 806 unsigned long ufcon = rd_regl(port, S3C2410_UFCON); 807 808 if (ufcon & S3C2410_UFCON_FIFOMODE) { 809 if ((ufstat & info->tx_fifomask) != 0 || 810 (ufstat & info->tx_fifofull)) 811 return 0; 812 813 return 1; 814 } 815 816 return s3c24xx_serial_txempty_nofifo(port); 817} 818 819/* no modem control lines */ 820static unsigned int s3c24xx_serial_get_mctrl(struct uart_port *port) 821{ 822 unsigned int umstat = rd_regb(port, S3C2410_UMSTAT); 823 824 if (umstat & S3C2410_UMSTAT_CTS) 825 return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS; 826 else 827 return TIOCM_CAR | TIOCM_DSR; 828} 829 830static void s3c24xx_serial_set_mctrl(struct uart_port *port, unsigned int mctrl) 831{ 832 unsigned int umcon = rd_regl(port, S3C2410_UMCON); 833 834 if (mctrl & TIOCM_RTS) 835 umcon |= S3C2410_UMCOM_RTS_LOW; 836 else 837 umcon &= ~S3C2410_UMCOM_RTS_LOW; 838 839 wr_regl(port, S3C2410_UMCON, umcon); 840} 841 842static void s3c24xx_serial_break_ctl(struct uart_port *port, int break_state) 843{ 844 unsigned long flags; 845 unsigned int ucon; 846 847 spin_lock_irqsave(&port->lock, flags); 848 849 ucon = rd_regl(port, S3C2410_UCON); 850 851 if (break_state) 852 ucon |= S3C2410_UCON_SBREAK; 853 else 854 ucon &= ~S3C2410_UCON_SBREAK; 855 856 wr_regl(port, S3C2410_UCON, ucon); 857 858 spin_unlock_irqrestore(&port->lock, flags); 859} 860 861static int s3c24xx_serial_request_dma(struct s3c24xx_uart_port *p) 862{ 863 struct s3c24xx_uart_dma *dma = p->dma; 864 dma_cap_mask_t mask; 865 unsigned long flags; 866 867 /* Default slave configuration parameters */ 868 dma->rx_conf.direction = DMA_DEV_TO_MEM; 869 dma->rx_conf.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; 870 dma->rx_conf.src_addr = p->port.mapbase + S3C2410_URXH; 871 dma->rx_conf.src_maxburst = 16; 872 873 dma->tx_conf.direction = DMA_MEM_TO_DEV; 874 dma->tx_conf.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; 875 dma->tx_conf.dst_addr = p->port.mapbase + S3C2410_UTXH; 876 if (dma_get_cache_alignment() >= 16) 877 dma->tx_conf.dst_maxburst = 16; 878 else 879 dma->tx_conf.dst_maxburst = 1; 880 881 dma_cap_zero(mask); 882 dma_cap_set(DMA_SLAVE, mask); 883 884 dma->rx_chan = dma_request_slave_channel_compat(mask, dma->fn, 885 dma->rx_param, p->port.dev, "rx"); 886 if (!dma->rx_chan) 887 return -ENODEV; 888 889 dmaengine_slave_config(dma->rx_chan, &dma->rx_conf); 890 891 dma->tx_chan = dma_request_slave_channel_compat(mask, dma->fn, 892 dma->tx_param, p->port.dev, "tx"); 893 if (!dma->tx_chan) { 894 dma_release_channel(dma->rx_chan); 895 return -ENODEV; 896 } 897 898 dmaengine_slave_config(dma->tx_chan, &dma->tx_conf); 899 900 /* RX buffer */ 901 dma->rx_size = PAGE_SIZE; 902 903 dma->rx_buf = kmalloc(dma->rx_size, GFP_KERNEL); 904 905 if (!dma->rx_buf) { 906 dma_release_channel(dma->rx_chan); 907 dma_release_channel(dma->tx_chan); 908 return -ENOMEM; 909 } 910 911 dma->rx_addr = dma_map_single(dma->rx_chan->device->dev, dma->rx_buf, 912 dma->rx_size, DMA_FROM_DEVICE); 913 914 spin_lock_irqsave(&p->port.lock, flags); 915 916 /* TX buffer */ 917 dma->tx_addr = dma_map_single(dma->tx_chan->device->dev, 918 p->port.state->xmit.buf, 919 UART_XMIT_SIZE, DMA_TO_DEVICE); 920 921 spin_unlock_irqrestore(&p->port.lock, flags); 922 923 return 0; 924} 925 926static void s3c24xx_serial_release_dma(struct s3c24xx_uart_port *p) 927{ 928 struct s3c24xx_uart_dma *dma = p->dma; 929 930 if (dma->rx_chan) { 931 dmaengine_terminate_all(dma->rx_chan); 932 dma_unmap_single(dma->rx_chan->device->dev, dma->rx_addr, 933 dma->rx_size, DMA_FROM_DEVICE); 934 kfree(dma->rx_buf); 935 dma_release_channel(dma->rx_chan); 936 dma->rx_chan = NULL; 937 } 938 939 if (dma->tx_chan) { 940 dmaengine_terminate_all(dma->tx_chan); 941 dma_unmap_single(dma->tx_chan->device->dev, dma->tx_addr, 942 UART_XMIT_SIZE, DMA_TO_DEVICE); 943 dma_release_channel(dma->tx_chan); 944 dma->tx_chan = NULL; 945 } 946} 947 948static void s3c24xx_serial_shutdown(struct uart_port *port) 949{ 950 struct s3c24xx_uart_port *ourport = to_ourport(port); 951 952 if (ourport->tx_claimed) { 953 if (!s3c24xx_serial_has_interrupt_mask(port)) 954 free_irq(ourport->tx_irq, ourport); 955 tx_enabled(port) = 0; 956 ourport->tx_claimed = 0; 957 ourport->tx_mode = 0; 958 } 959 960 if (ourport->rx_claimed) { 961 if (!s3c24xx_serial_has_interrupt_mask(port)) 962 free_irq(ourport->rx_irq, ourport); 963 ourport->rx_claimed = 0; 964 rx_enabled(port) = 0; 965 } 966 967 /* Clear pending interrupts and mask all interrupts */ 968 if (s3c24xx_serial_has_interrupt_mask(port)) { 969 free_irq(port->irq, ourport); 970 971 wr_regl(port, S3C64XX_UINTP, 0xf); 972 wr_regl(port, S3C64XX_UINTM, 0xf); 973 } 974 975 if (ourport->dma) 976 s3c24xx_serial_release_dma(ourport); 977 978 ourport->tx_in_progress = 0; 979} 980 981static int s3c24xx_serial_startup(struct uart_port *port) 982{ 983 struct s3c24xx_uart_port *ourport = to_ourport(port); 984 int ret; 985 986 dbg("s3c24xx_serial_startup: port=%p (%08llx,%p)\n", 987 port, (unsigned long long)port->mapbase, port->membase); 988 989 rx_enabled(port) = 1; 990 991 ret = request_irq(ourport->rx_irq, s3c24xx_serial_rx_chars, 0, 992 s3c24xx_serial_portname(port), ourport); 993 994 if (ret != 0) { 995 dev_err(port->dev, "cannot get irq %d\n", ourport->rx_irq); 996 return ret; 997 } 998 999 ourport->rx_claimed = 1; 1000 1001 dbg("requesting tx irq...\n"); 1002 1003 tx_enabled(port) = 1; 1004 1005 ret = request_irq(ourport->tx_irq, s3c24xx_serial_tx_chars, 0, 1006 s3c24xx_serial_portname(port), ourport); 1007 1008 if (ret) { 1009 dev_err(port->dev, "cannot get irq %d\n", ourport->tx_irq); 1010 goto err; 1011 } 1012 1013 ourport->tx_claimed = 1; 1014 1015 dbg("s3c24xx_serial_startup ok\n"); 1016 1017 /* the port reset code should have done the correct 1018 * register setup for the port controls */ 1019 1020 return ret; 1021 1022err: 1023 s3c24xx_serial_shutdown(port); 1024 return ret; 1025} 1026 1027static int s3c64xx_serial_startup(struct uart_port *port) 1028{ 1029 struct s3c24xx_uart_port *ourport = to_ourport(port); 1030 unsigned long flags; 1031 unsigned int ufcon; 1032 int ret; 1033 1034 dbg("s3c64xx_serial_startup: port=%p (%08llx,%p)\n", 1035 port, (unsigned long long)port->mapbase, port->membase); 1036 1037 wr_regl(port, S3C64XX_UINTM, 0xf); 1038 if (ourport->dma) { 1039 ret = s3c24xx_serial_request_dma(ourport); 1040 if (ret < 0) { 1041 dev_warn(port->dev, "DMA request failed\n"); 1042 return ret; 1043 } 1044 } 1045 1046 ret = request_irq(port->irq, s3c64xx_serial_handle_irq, IRQF_SHARED, 1047 s3c24xx_serial_portname(port), ourport); 1048 if (ret) { 1049 dev_err(port->dev, "cannot get irq %d\n", port->irq); 1050 return ret; 1051 } 1052 1053 /* For compatibility with s3c24xx Soc's */ 1054 rx_enabled(port) = 1; 1055 ourport->rx_claimed = 1; 1056 tx_enabled(port) = 0; 1057 ourport->tx_claimed = 1; 1058 1059 spin_lock_irqsave(&port->lock, flags); 1060 1061 ufcon = rd_regl(port, S3C2410_UFCON); 1062 ufcon |= S3C2410_UFCON_RESETRX | S5PV210_UFCON_RXTRIG8; 1063 if (!uart_console(port)) 1064 ufcon |= S3C2410_UFCON_RESETTX; 1065 wr_regl(port, S3C2410_UFCON, ufcon); 1066 1067 enable_rx_pio(ourport); 1068 1069 spin_unlock_irqrestore(&port->lock, flags); 1070 1071 /* Enable Rx Interrupt */ 1072 __clear_bit(S3C64XX_UINTM_RXD, portaddrl(port, S3C64XX_UINTM)); 1073 1074 dbg("s3c64xx_serial_startup ok\n"); 1075 return ret; 1076} 1077 1078/* power power management control */ 1079 1080static void s3c24xx_serial_pm(struct uart_port *port, unsigned int level, 1081 unsigned int old) 1082{ 1083 struct s3c24xx_uart_port *ourport = to_ourport(port); 1084 int timeout = 10000; 1085 1086 ourport->pm_level = level; 1087 1088 switch (level) { 1089 case 3: 1090 while (--timeout && !s3c24xx_serial_txempty_nofifo(port)) 1091 udelay(100); 1092 1093 if (!IS_ERR(ourport->baudclk)) 1094 clk_disable_unprepare(ourport->baudclk); 1095 1096 clk_disable_unprepare(ourport->clk); 1097 break; 1098 1099 case 0: 1100 clk_prepare_enable(ourport->clk); 1101 1102 if (!IS_ERR(ourport->baudclk)) 1103 clk_prepare_enable(ourport->baudclk); 1104 1105 break; 1106 default: 1107 dev_err(port->dev, "s3c24xx_serial: unknown pm %d\n", level); 1108 } 1109} 1110 1111/* baud rate calculation 1112 * 1113 * The UARTs on the S3C2410/S3C2440 can take their clocks from a number 1114 * of different sources, including the peripheral clock ("pclk") and an 1115 * external clock ("uclk"). The S3C2440 also adds the core clock ("fclk") 1116 * with a programmable extra divisor. 1117 * 1118 * The following code goes through the clock sources, and calculates the 1119 * baud clocks (and the resultant actual baud rates) and then tries to 1120 * pick the closest one and select that. 1121 * 1122*/ 1123 1124#define MAX_CLK_NAME_LENGTH 15 1125 1126static inline int s3c24xx_serial_getsource(struct uart_port *port) 1127{ 1128 struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port); 1129 unsigned int ucon; 1130 1131 if (info->num_clks == 1) 1132 return 0; 1133 1134 ucon = rd_regl(port, S3C2410_UCON); 1135 ucon &= info->clksel_mask; 1136 return ucon >> info->clksel_shift; 1137} 1138 1139static void s3c24xx_serial_setsource(struct uart_port *port, 1140 unsigned int clk_sel) 1141{ 1142 struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port); 1143 unsigned int ucon; 1144 1145 if (info->num_clks == 1) 1146 return; 1147 1148 ucon = rd_regl(port, S3C2410_UCON); 1149 if ((ucon & info->clksel_mask) >> info->clksel_shift == clk_sel) 1150 return; 1151 1152 ucon &= ~info->clksel_mask; 1153 ucon |= clk_sel << info->clksel_shift; 1154 wr_regl(port, S3C2410_UCON, ucon); 1155} 1156 1157static unsigned int s3c24xx_serial_getclk(struct s3c24xx_uart_port *ourport, 1158 unsigned int req_baud, struct clk **best_clk, 1159 unsigned int *clk_num) 1160{ 1161 struct s3c24xx_uart_info *info = ourport->info; 1162 struct clk *clk; 1163 unsigned long rate; 1164 unsigned int cnt, baud, quot, clk_sel, best_quot = 0; 1165 char clkname[MAX_CLK_NAME_LENGTH]; 1166 int calc_deviation, deviation = (1 << 30) - 1; 1167 1168 clk_sel = (ourport->cfg->clk_sel) ? ourport->cfg->clk_sel : 1169 ourport->info->def_clk_sel; 1170 for (cnt = 0; cnt < info->num_clks; cnt++) { 1171 if (!(clk_sel & (1 << cnt))) 1172 continue; 1173 1174 sprintf(clkname, "clk_uart_baud%d", cnt); 1175 clk = clk_get(ourport->port.dev, clkname); 1176 if (IS_ERR(clk)) 1177 continue; 1178 1179 rate = clk_get_rate(clk); 1180 if (!rate) 1181 continue; 1182 1183 if (ourport->info->has_divslot) { 1184 unsigned long div = rate / req_baud; 1185 1186 /* The UDIVSLOT register on the newer UARTs allows us to 1187 * get a divisor adjustment of 1/16th on the baud clock. 1188 * 1189 * We don't keep the UDIVSLOT value (the 16ths we 1190 * calculated by not multiplying the baud by 16) as it 1191 * is easy enough to recalculate. 1192 */ 1193 1194 quot = div / 16; 1195 baud = rate / div; 1196 } else { 1197 quot = (rate + (8 * req_baud)) / (16 * req_baud); 1198 baud = rate / (quot * 16); 1199 } 1200 quot--; 1201 1202 calc_deviation = req_baud - baud; 1203 if (calc_deviation < 0) 1204 calc_deviation = -calc_deviation; 1205 1206 if (calc_deviation < deviation) { 1207 *best_clk = clk; 1208 best_quot = quot; 1209 *clk_num = cnt; 1210 deviation = calc_deviation; 1211 } 1212 } 1213 1214 return best_quot; 1215} 1216 1217/* udivslot_table[] 1218 * 1219 * This table takes the fractional value of the baud divisor and gives 1220 * the recommended setting for the UDIVSLOT register. 1221 */ 1222static u16 udivslot_table[16] = { 1223 [0] = 0x0000, 1224 [1] = 0x0080, 1225 [2] = 0x0808, 1226 [3] = 0x0888, 1227 [4] = 0x2222, 1228 [5] = 0x4924, 1229 [6] = 0x4A52, 1230 [7] = 0x54AA, 1231 [8] = 0x5555, 1232 [9] = 0xD555, 1233 [10] = 0xD5D5, 1234 [11] = 0xDDD5, 1235 [12] = 0xDDDD, 1236 [13] = 0xDFDD, 1237 [14] = 0xDFDF, 1238 [15] = 0xFFDF, 1239}; 1240 1241static void s3c24xx_serial_set_termios(struct uart_port *port, 1242 struct ktermios *termios, 1243 struct ktermios *old) 1244{ 1245 struct s3c2410_uartcfg *cfg = s3c24xx_port_to_cfg(port); 1246 struct s3c24xx_uart_port *ourport = to_ourport(port); 1247 struct clk *clk = ERR_PTR(-EINVAL); 1248 unsigned long flags; 1249 unsigned int baud, quot, clk_sel = 0; 1250 unsigned int ulcon; 1251 unsigned int umcon; 1252 unsigned int udivslot = 0; 1253 1254 /* 1255 * We don't support modem control lines. 1256 */ 1257 termios->c_cflag &= ~(HUPCL | CMSPAR); 1258 termios->c_cflag |= CLOCAL; 1259 1260 /* 1261 * Ask the core to calculate the divisor for us. 1262 */ 1263 1264 baud = uart_get_baud_rate(port, termios, old, 0, 115200*8); 1265 quot = s3c24xx_serial_getclk(ourport, baud, &clk, &clk_sel); 1266 if (baud == 38400 && (port->flags & UPF_SPD_MASK) == UPF_SPD_CUST) 1267 quot = port->custom_divisor; 1268 if (IS_ERR(clk)) 1269 return; 1270 1271 /* check to see if we need to change clock source */ 1272 1273 if (ourport->baudclk != clk) { 1274 s3c24xx_serial_setsource(port, clk_sel); 1275 1276 if (!IS_ERR(ourport->baudclk)) { 1277 clk_disable_unprepare(ourport->baudclk); 1278 ourport->baudclk = ERR_PTR(-EINVAL); 1279 } 1280 1281 clk_prepare_enable(clk); 1282 1283 ourport->baudclk = clk; 1284 ourport->baudclk_rate = clk ? clk_get_rate(clk) : 0; 1285 } 1286 1287 if (ourport->info->has_divslot) { 1288 unsigned int div = ourport->baudclk_rate / baud; 1289 1290 if (cfg->has_fracval) { 1291 udivslot = (div & 15); 1292 dbg("fracval = %04x\n", udivslot); 1293 } else { 1294 udivslot = udivslot_table[div & 15]; 1295 dbg("udivslot = %04x (div %d)\n", udivslot, div & 15); 1296 } 1297 } 1298 1299 switch (termios->c_cflag & CSIZE) { 1300 case CS5: 1301 dbg("config: 5bits/char\n"); 1302 ulcon = S3C2410_LCON_CS5; 1303 break; 1304 case CS6: 1305 dbg("config: 6bits/char\n"); 1306 ulcon = S3C2410_LCON_CS6; 1307 break; 1308 case CS7: 1309 dbg("config: 7bits/char\n"); 1310 ulcon = S3C2410_LCON_CS7; 1311 break; 1312 case CS8: 1313 default: 1314 dbg("config: 8bits/char\n"); 1315 ulcon = S3C2410_LCON_CS8; 1316 break; 1317 } 1318 1319 /* preserve original lcon IR settings */ 1320 ulcon |= (cfg->ulcon & S3C2410_LCON_IRM); 1321 1322 if (termios->c_cflag & CSTOPB) 1323 ulcon |= S3C2410_LCON_STOPB; 1324 1325 if (termios->c_cflag & PARENB) { 1326 if (termios->c_cflag & PARODD) 1327 ulcon |= S3C2410_LCON_PODD; 1328 else 1329 ulcon |= S3C2410_LCON_PEVEN; 1330 } else { 1331 ulcon |= S3C2410_LCON_PNONE; 1332 } 1333 1334 spin_lock_irqsave(&port->lock, flags); 1335 1336 dbg("setting ulcon to %08x, brddiv to %d, udivslot %08x\n", 1337 ulcon, quot, udivslot); 1338 1339 wr_regl(port, S3C2410_ULCON, ulcon); 1340 wr_regl(port, S3C2410_UBRDIV, quot); 1341 1342 umcon = rd_regl(port, S3C2410_UMCON); 1343 if (termios->c_cflag & CRTSCTS) { 1344 umcon |= S3C2410_UMCOM_AFC; 1345 /* Disable RTS when RX FIFO contains 63 bytes */ 1346 umcon &= ~S3C2412_UMCON_AFC_8; 1347 } else { 1348 umcon &= ~S3C2410_UMCOM_AFC; 1349 } 1350 wr_regl(port, S3C2410_UMCON, umcon); 1351 1352 if (ourport->info->has_divslot) 1353 wr_regl(port, S3C2443_DIVSLOT, udivslot); 1354 1355 dbg("uart: ulcon = 0x%08x, ucon = 0x%08x, ufcon = 0x%08x\n", 1356 rd_regl(port, S3C2410_ULCON), 1357 rd_regl(port, S3C2410_UCON), 1358 rd_regl(port, S3C2410_UFCON)); 1359 1360 /* 1361 * Update the per-port timeout. 1362 */ 1363 uart_update_timeout(port, termios->c_cflag, baud); 1364 1365 /* 1366 * Which character status flags are we interested in? 1367 */ 1368 port->read_status_mask = S3C2410_UERSTAT_OVERRUN; 1369 if (termios->c_iflag & INPCK) 1370 port->read_status_mask |= S3C2410_UERSTAT_FRAME | 1371 S3C2410_UERSTAT_PARITY; 1372 /* 1373 * Which character status flags should we ignore? 1374 */ 1375 port->ignore_status_mask = 0; 1376 if (termios->c_iflag & IGNPAR) 1377 port->ignore_status_mask |= S3C2410_UERSTAT_OVERRUN; 1378 if (termios->c_iflag & IGNBRK && termios->c_iflag & IGNPAR) 1379 port->ignore_status_mask |= S3C2410_UERSTAT_FRAME; 1380 1381 /* 1382 * Ignore all characters if CREAD is not set. 1383 */ 1384 if ((termios->c_cflag & CREAD) == 0) 1385 port->ignore_status_mask |= RXSTAT_DUMMY_READ; 1386 1387 spin_unlock_irqrestore(&port->lock, flags); 1388} 1389 1390static const char *s3c24xx_serial_type(struct uart_port *port) 1391{ 1392 switch (port->type) { 1393 case PORT_S3C2410: 1394 return "S3C2410"; 1395 case PORT_S3C2440: 1396 return "S3C2440"; 1397 case PORT_S3C2412: 1398 return "S3C2412"; 1399 case PORT_S3C6400: 1400 return "S3C6400/10"; 1401 default: 1402 return NULL; 1403 } 1404} 1405 1406#define MAP_SIZE (0x100) 1407 1408static void s3c24xx_serial_release_port(struct uart_port *port) 1409{ 1410 release_mem_region(port->mapbase, MAP_SIZE); 1411} 1412 1413static int s3c24xx_serial_request_port(struct uart_port *port) 1414{ 1415 const char *name = s3c24xx_serial_portname(port); 1416 return request_mem_region(port->mapbase, MAP_SIZE, name) ? 0 : -EBUSY; 1417} 1418 1419static void s3c24xx_serial_config_port(struct uart_port *port, int flags) 1420{ 1421 struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port); 1422 1423 if (flags & UART_CONFIG_TYPE && 1424 s3c24xx_serial_request_port(port) == 0) 1425 port->type = info->type; 1426} 1427 1428/* 1429 * verify the new serial_struct (for TIOCSSERIAL). 1430 */ 1431static int 1432s3c24xx_serial_verify_port(struct uart_port *port, struct serial_struct *ser) 1433{ 1434 struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port); 1435 1436 if (ser->type != PORT_UNKNOWN && ser->type != info->type) 1437 return -EINVAL; 1438 1439 return 0; 1440} 1441 1442 1443#ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE 1444 1445static struct console s3c24xx_serial_console; 1446 1447static int __init s3c24xx_serial_console_init(void) 1448{ 1449 register_console(&s3c24xx_serial_console); 1450 return 0; 1451} 1452console_initcall(s3c24xx_serial_console_init); 1453 1454#define S3C24XX_SERIAL_CONSOLE &s3c24xx_serial_console 1455#else 1456#define S3C24XX_SERIAL_CONSOLE NULL 1457#endif 1458 1459#if defined(CONFIG_SERIAL_SAMSUNG_CONSOLE) && defined(CONFIG_CONSOLE_POLL) 1460static int s3c24xx_serial_get_poll_char(struct uart_port *port); 1461static void s3c24xx_serial_put_poll_char(struct uart_port *port, 1462 unsigned char c); 1463#endif 1464 1465static struct uart_ops s3c24xx_serial_ops = { 1466 .pm = s3c24xx_serial_pm, 1467 .tx_empty = s3c24xx_serial_tx_empty, 1468 .get_mctrl = s3c24xx_serial_get_mctrl, 1469 .set_mctrl = s3c24xx_serial_set_mctrl, 1470 .stop_tx = s3c24xx_serial_stop_tx, 1471 .start_tx = s3c24xx_serial_start_tx, 1472 .stop_rx = s3c24xx_serial_stop_rx, 1473 .break_ctl = s3c24xx_serial_break_ctl, 1474 .startup = s3c24xx_serial_startup, 1475 .shutdown = s3c24xx_serial_shutdown, 1476 .set_termios = s3c24xx_serial_set_termios, 1477 .type = s3c24xx_serial_type, 1478 .release_port = s3c24xx_serial_release_port, 1479 .request_port = s3c24xx_serial_request_port, 1480 .config_port = s3c24xx_serial_config_port, 1481 .verify_port = s3c24xx_serial_verify_port, 1482#if defined(CONFIG_SERIAL_SAMSUNG_CONSOLE) && defined(CONFIG_CONSOLE_POLL) 1483 .poll_get_char = s3c24xx_serial_get_poll_char, 1484 .poll_put_char = s3c24xx_serial_put_poll_char, 1485#endif 1486}; 1487 1488static struct uart_driver s3c24xx_uart_drv = { 1489 .owner = THIS_MODULE, 1490 .driver_name = "s3c2410_serial", 1491 .nr = CONFIG_SERIAL_SAMSUNG_UARTS, 1492 .cons = S3C24XX_SERIAL_CONSOLE, 1493 .dev_name = S3C24XX_SERIAL_NAME, 1494 .major = S3C24XX_SERIAL_MAJOR, 1495 .minor = S3C24XX_SERIAL_MINOR, 1496}; 1497 1498#define __PORT_LOCK_UNLOCKED(i) \ 1499 __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[i].port.lock) 1500static struct s3c24xx_uart_port 1501s3c24xx_serial_ports[CONFIG_SERIAL_SAMSUNG_UARTS] = { 1502 [0] = { 1503 .port = { 1504 .lock = __PORT_LOCK_UNLOCKED(0), 1505 .iotype = UPIO_MEM, 1506 .uartclk = 0, 1507 .fifosize = 16, 1508 .ops = &s3c24xx_serial_ops, 1509 .flags = UPF_BOOT_AUTOCONF, 1510 .line = 0, 1511 } 1512 }, 1513 [1] = { 1514 .port = { 1515 .lock = __PORT_LOCK_UNLOCKED(1), 1516 .iotype = UPIO_MEM, 1517 .uartclk = 0, 1518 .fifosize = 16, 1519 .ops = &s3c24xx_serial_ops, 1520 .flags = UPF_BOOT_AUTOCONF, 1521 .line = 1, 1522 } 1523 }, 1524#if CONFIG_SERIAL_SAMSUNG_UARTS > 2 1525 1526 [2] = { 1527 .port = { 1528 .lock = __PORT_LOCK_UNLOCKED(2), 1529 .iotype = UPIO_MEM, 1530 .uartclk = 0, 1531 .fifosize = 16, 1532 .ops = &s3c24xx_serial_ops, 1533 .flags = UPF_BOOT_AUTOCONF, 1534 .line = 2, 1535 } 1536 }, 1537#endif 1538#if CONFIG_SERIAL_SAMSUNG_UARTS > 3 1539 [3] = { 1540 .port = { 1541 .lock = __PORT_LOCK_UNLOCKED(3), 1542 .iotype = UPIO_MEM, 1543 .uartclk = 0, 1544 .fifosize = 16, 1545 .ops = &s3c24xx_serial_ops, 1546 .flags = UPF_BOOT_AUTOCONF, 1547 .line = 3, 1548 } 1549 } 1550#endif 1551}; 1552#undef __PORT_LOCK_UNLOCKED 1553 1554/* s3c24xx_serial_resetport 1555 * 1556 * reset the fifos and other the settings. 1557*/ 1558 1559static void s3c24xx_serial_resetport(struct uart_port *port, 1560 struct s3c2410_uartcfg *cfg) 1561{ 1562 struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port); 1563 unsigned long ucon = rd_regl(port, S3C2410_UCON); 1564 unsigned int ucon_mask; 1565 1566 ucon_mask = info->clksel_mask; 1567 if (info->type == PORT_S3C2440) 1568 ucon_mask |= S3C2440_UCON0_DIVMASK; 1569 1570 ucon &= ucon_mask; 1571 wr_regl(port, S3C2410_UCON, ucon | cfg->ucon); 1572 1573 /* reset both fifos */ 1574 wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH); 1575 wr_regl(port, S3C2410_UFCON, cfg->ufcon); 1576 1577 /* some delay is required after fifo reset */ 1578 udelay(1); 1579} 1580 1581 1582#ifdef CONFIG_CPU_FREQ 1583 1584static int s3c24xx_serial_cpufreq_transition(struct notifier_block *nb, 1585 unsigned long val, void *data) 1586{ 1587 struct s3c24xx_uart_port *port; 1588 struct uart_port *uport; 1589 1590 port = container_of(nb, struct s3c24xx_uart_port, freq_transition); 1591 uport = &port->port; 1592 1593 /* check to see if port is enabled */ 1594 1595 if (port->pm_level != 0) 1596 return 0; 1597 1598 /* try and work out if the baudrate is changing, we can detect 1599 * a change in rate, but we do not have support for detecting 1600 * a disturbance in the clock-rate over the change. 1601 */ 1602 1603 if (IS_ERR(port->baudclk)) 1604 goto exit; 1605 1606 if (port->baudclk_rate == clk_get_rate(port->baudclk)) 1607 goto exit; 1608 1609 if (val == CPUFREQ_PRECHANGE) { 1610 /* we should really shut the port down whilst the 1611 * frequency change is in progress. */ 1612 1613 } else if (val == CPUFREQ_POSTCHANGE) { 1614 struct ktermios *termios; 1615 struct tty_struct *tty; 1616 1617 if (uport->state == NULL) 1618 goto exit; 1619 1620 tty = uport->state->port.tty; 1621 1622 if (tty == NULL) 1623 goto exit; 1624 1625 termios = &tty->termios; 1626 1627 if (termios == NULL) { 1628 dev_warn(uport->dev, "%s: no termios?\n", __func__); 1629 goto exit; 1630 } 1631 1632 s3c24xx_serial_set_termios(uport, termios, NULL); 1633 } 1634 1635exit: 1636 return 0; 1637} 1638 1639static inline int 1640s3c24xx_serial_cpufreq_register(struct s3c24xx_uart_port *port) 1641{ 1642 port->freq_transition.notifier_call = s3c24xx_serial_cpufreq_transition; 1643 1644 return cpufreq_register_notifier(&port->freq_transition, 1645 CPUFREQ_TRANSITION_NOTIFIER); 1646} 1647 1648static inline void 1649s3c24xx_serial_cpufreq_deregister(struct s3c24xx_uart_port *port) 1650{ 1651 cpufreq_unregister_notifier(&port->freq_transition, 1652 CPUFREQ_TRANSITION_NOTIFIER); 1653} 1654 1655#else 1656static inline int 1657s3c24xx_serial_cpufreq_register(struct s3c24xx_uart_port *port) 1658{ 1659 return 0; 1660} 1661 1662static inline void 1663s3c24xx_serial_cpufreq_deregister(struct s3c24xx_uart_port *port) 1664{ 1665} 1666#endif 1667 1668/* s3c24xx_serial_init_port 1669 * 1670 * initialise a single serial port from the platform device given 1671 */ 1672 1673static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport, 1674 struct platform_device *platdev) 1675{ 1676 struct uart_port *port = &ourport->port; 1677 struct s3c2410_uartcfg *cfg = ourport->cfg; 1678 struct resource *res; 1679 int ret; 1680 1681 dbg("s3c24xx_serial_init_port: port=%p, platdev=%p\n", port, platdev); 1682 1683 if (platdev == NULL) 1684 return -ENODEV; 1685 1686 if (port->mapbase != 0) 1687 return 0; 1688 1689 /* setup info for port */ 1690 port->dev = &platdev->dev; 1691 1692 /* Startup sequence is different for s3c64xx and higher SoC's */ 1693 if (s3c24xx_serial_has_interrupt_mask(port)) 1694 s3c24xx_serial_ops.startup = s3c64xx_serial_startup; 1695 1696 port->uartclk = 1; 1697 1698 if (cfg->uart_flags & UPF_CONS_FLOW) { 1699 dbg("s3c24xx_serial_init_port: enabling flow control\n"); 1700 port->flags |= UPF_CONS_FLOW; 1701 } 1702 1703 /* sort our the physical and virtual addresses for each UART */ 1704 1705 res = platform_get_resource(platdev, IORESOURCE_MEM, 0); 1706 if (res == NULL) { 1707 dev_err(port->dev, "failed to find memory resource for uart\n"); 1708 return -EINVAL; 1709 } 1710 1711 dbg("resource %pR)\n", res); 1712 1713 port->membase = devm_ioremap(port->dev, res->start, resource_size(res)); 1714 if (!port->membase) { 1715 dev_err(port->dev, "failed to remap controller address\n"); 1716 return -EBUSY; 1717 } 1718 1719 port->mapbase = res->start; 1720 ret = platform_get_irq(platdev, 0); 1721 if (ret < 0) 1722 port->irq = 0; 1723 else { 1724 port->irq = ret; 1725 ourport->rx_irq = ret; 1726 ourport->tx_irq = ret + 1; 1727 } 1728 1729 ret = platform_get_irq(platdev, 1); 1730 if (ret > 0) 1731 ourport->tx_irq = ret; 1732 /* 1733 * DMA is currently supported only on DT platforms, if DMA properties 1734 * are specified. 1735 */ 1736 if (platdev->dev.of_node && of_find_property(platdev->dev.of_node, 1737 "dmas", NULL)) { 1738 ourport->dma = devm_kzalloc(port->dev, 1739 sizeof(*ourport->dma), 1740 GFP_KERNEL); 1741 if (!ourport->dma) 1742 return -ENOMEM; 1743 } 1744 1745 ourport->clk = clk_get(&platdev->dev, "uart"); 1746 if (IS_ERR(ourport->clk)) { 1747 pr_err("%s: Controller clock not found\n", 1748 dev_name(&platdev->dev)); 1749 return PTR_ERR(ourport->clk); 1750 } 1751 1752 ret = clk_prepare_enable(ourport->clk); 1753 if (ret) { 1754 pr_err("uart: clock failed to prepare+enable: %d\n", ret); 1755 clk_put(ourport->clk); 1756 return ret; 1757 } 1758 1759 /* Keep all interrupts masked and cleared */ 1760 if (s3c24xx_serial_has_interrupt_mask(port)) { 1761 wr_regl(port, S3C64XX_UINTM, 0xf); 1762 wr_regl(port, S3C64XX_UINTP, 0xf); 1763 wr_regl(port, S3C64XX_UINTSP, 0xf); 1764 } 1765 1766 dbg("port: map=%pa, mem=%p, irq=%d (%d,%d), clock=%u\n", 1767 &port->mapbase, port->membase, port->irq, 1768 ourport->rx_irq, ourport->tx_irq, port->uartclk); 1769 1770 /* reset the fifos (and setup the uart) */ 1771 s3c24xx_serial_resetport(port, cfg); 1772 return 0; 1773} 1774 1775/* Device driver serial port probe */ 1776 1777static const struct of_device_id s3c24xx_uart_dt_match[]; 1778static int probe_index; 1779 1780static inline struct s3c24xx_serial_drv_data *s3c24xx_get_driver_data( 1781 struct platform_device *pdev) 1782{ 1783#ifdef CONFIG_OF 1784 if (pdev->dev.of_node) { 1785 const struct of_device_id *match; 1786 match = of_match_node(s3c24xx_uart_dt_match, pdev->dev.of_node); 1787 return (struct s3c24xx_serial_drv_data *)match->data; 1788 } 1789#endif 1790 return (struct s3c24xx_serial_drv_data *) 1791 platform_get_device_id(pdev)->driver_data; 1792} 1793 1794static int s3c24xx_serial_probe(struct platform_device *pdev) 1795{ 1796 struct device_node *np = pdev->dev.of_node; 1797 struct s3c24xx_uart_port *ourport; 1798 int index = probe_index; 1799 int ret; 1800 1801 if (np) { 1802 ret = of_alias_get_id(np, "serial"); 1803 if (ret >= 0) 1804 index = ret; 1805 } 1806 1807 dbg("s3c24xx_serial_probe(%p) %d\n", pdev, index); 1808 1809 ourport = &s3c24xx_serial_ports[index]; 1810 1811 ourport->drv_data = s3c24xx_get_driver_data(pdev); 1812 if (!ourport->drv_data) { 1813 dev_err(&pdev->dev, "could not find driver data\n"); 1814 return -ENODEV; 1815 } 1816 1817 ourport->baudclk = ERR_PTR(-EINVAL); 1818 ourport->info = ourport->drv_data->info; 1819 ourport->cfg = (dev_get_platdata(&pdev->dev)) ? 1820 dev_get_platdata(&pdev->dev) : 1821 ourport->drv_data->def_cfg; 1822 1823 if (np) 1824 of_property_read_u32(np, 1825 "samsung,uart-fifosize", &ourport->port.fifosize); 1826 1827 if (ourport->drv_data->fifosize[index]) 1828 ourport->port.fifosize = ourport->drv_data->fifosize[index]; 1829 else if (ourport->info->fifosize) 1830 ourport->port.fifosize = ourport->info->fifosize; 1831 1832 /* 1833 * DMA transfers must be aligned at least to cache line size, 1834 * so find minimal transfer size suitable for DMA mode 1835 */ 1836 ourport->min_dma_size = max_t(int, ourport->port.fifosize, 1837 dma_get_cache_alignment()); 1838 1839 probe_index++; 1840 1841 dbg("%s: initialising port %p...\n", __func__, ourport); 1842 1843 ret = s3c24xx_serial_init_port(ourport, pdev); 1844 if (ret < 0) 1845 return ret; 1846 1847 if (!s3c24xx_uart_drv.state) { 1848 ret = uart_register_driver(&s3c24xx_uart_drv); 1849 if (ret < 0) { 1850 pr_err("Failed to register Samsung UART driver\n"); 1851 return ret; 1852 } 1853 } 1854 1855 dbg("%s: adding port\n", __func__); 1856 uart_add_one_port(&s3c24xx_uart_drv, &ourport->port); 1857 platform_set_drvdata(pdev, &ourport->port); 1858 1859 /* 1860 * Deactivate the clock enabled in s3c24xx_serial_init_port here, 1861 * so that a potential re-enablement through the pm-callback overlaps 1862 * and keeps the clock enabled in this case. 1863 */ 1864 clk_disable_unprepare(ourport->clk); 1865 1866 ret = s3c24xx_serial_cpufreq_register(ourport); 1867 if (ret < 0) 1868 dev_err(&pdev->dev, "failed to add cpufreq notifier\n"); 1869 1870 return 0; 1871} 1872 1873static int s3c24xx_serial_remove(struct platform_device *dev) 1874{ 1875 struct uart_port *port = s3c24xx_dev_to_port(&dev->dev); 1876 1877 if (port) { 1878 s3c24xx_serial_cpufreq_deregister(to_ourport(port)); 1879 uart_remove_one_port(&s3c24xx_uart_drv, port); 1880 } 1881 1882 uart_unregister_driver(&s3c24xx_uart_drv); 1883 1884 return 0; 1885} 1886 1887/* UART power management code */ 1888#ifdef CONFIG_PM_SLEEP 1889static int s3c24xx_serial_suspend(struct device *dev) 1890{ 1891 struct uart_port *port = s3c24xx_dev_to_port(dev); 1892 1893 if (port) 1894 uart_suspend_port(&s3c24xx_uart_drv, port); 1895 1896 return 0; 1897} 1898 1899static int s3c24xx_serial_resume(struct device *dev) 1900{ 1901 struct uart_port *port = s3c24xx_dev_to_port(dev); 1902 struct s3c24xx_uart_port *ourport = to_ourport(port); 1903 1904 if (port) { 1905 clk_prepare_enable(ourport->clk); 1906 s3c24xx_serial_resetport(port, s3c24xx_port_to_cfg(port)); 1907 clk_disable_unprepare(ourport->clk); 1908 1909 uart_resume_port(&s3c24xx_uart_drv, port); 1910 } 1911 1912 return 0; 1913} 1914 1915static int s3c24xx_serial_resume_noirq(struct device *dev) 1916{ 1917 struct uart_port *port = s3c24xx_dev_to_port(dev); 1918 1919 if (port) { 1920 /* restore IRQ mask */ 1921 if (s3c24xx_serial_has_interrupt_mask(port)) { 1922 unsigned int uintm = 0xf; 1923 if (tx_enabled(port)) 1924 uintm &= ~S3C64XX_UINTM_TXD_MSK; 1925 if (rx_enabled(port)) 1926 uintm &= ~S3C64XX_UINTM_RXD_MSK; 1927 wr_regl(port, S3C64XX_UINTM, uintm); 1928 } 1929 } 1930 1931 return 0; 1932} 1933 1934static const struct dev_pm_ops s3c24xx_serial_pm_ops = { 1935 .suspend = s3c24xx_serial_suspend, 1936 .resume = s3c24xx_serial_resume, 1937 .resume_noirq = s3c24xx_serial_resume_noirq, 1938}; 1939#define SERIAL_SAMSUNG_PM_OPS (&s3c24xx_serial_pm_ops) 1940 1941#else /* !CONFIG_PM_SLEEP */ 1942 1943#define SERIAL_SAMSUNG_PM_OPS NULL 1944#endif /* CONFIG_PM_SLEEP */ 1945 1946/* Console code */ 1947 1948#ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE 1949 1950static struct uart_port *cons_uart; 1951 1952static int 1953s3c24xx_serial_console_txrdy(struct uart_port *port, unsigned int ufcon) 1954{ 1955 struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port); 1956 unsigned long ufstat, utrstat; 1957 1958 if (ufcon & S3C2410_UFCON_FIFOMODE) { 1959 /* fifo mode - check amount of data in fifo registers... */ 1960 1961 ufstat = rd_regl(port, S3C2410_UFSTAT); 1962 return (ufstat & info->tx_fifofull) ? 0 : 1; 1963 } 1964 1965 /* in non-fifo mode, we go and use the tx buffer empty */ 1966 1967 utrstat = rd_regl(port, S3C2410_UTRSTAT); 1968 return (utrstat & S3C2410_UTRSTAT_TXE) ? 1 : 0; 1969} 1970 1971static bool 1972s3c24xx_port_configured(unsigned int ucon) 1973{ 1974 /* consider the serial port configured if the tx/rx mode set */ 1975 return (ucon & 0xf) != 0; 1976} 1977 1978#ifdef CONFIG_CONSOLE_POLL 1979/* 1980 * Console polling routines for writing and reading from the uart while 1981 * in an interrupt or debug context. 1982 */ 1983 1984static int s3c24xx_serial_get_poll_char(struct uart_port *port) 1985{ 1986 struct s3c24xx_uart_port *ourport = to_ourport(port); 1987 unsigned int ufstat; 1988 1989 ufstat = rd_regl(port, S3C2410_UFSTAT); 1990 if (s3c24xx_serial_rx_fifocnt(ourport, ufstat) == 0) 1991 return NO_POLL_CHAR; 1992 1993 return rd_regb(port, S3C2410_URXH); 1994} 1995 1996static void s3c24xx_serial_put_poll_char(struct uart_port *port, 1997 unsigned char c) 1998{ 1999 unsigned int ufcon = rd_regl(port, S3C2410_UFCON); 2000 unsigned int ucon = rd_regl(port, S3C2410_UCON); 2001 2002 /* not possible to xmit on unconfigured port */ 2003 if (!s3c24xx_port_configured(ucon)) 2004 return; 2005 2006 while (!s3c24xx_serial_console_txrdy(port, ufcon)) 2007 cpu_relax(); 2008 wr_regb(port, S3C2410_UTXH, c); 2009} 2010 2011#endif /* CONFIG_CONSOLE_POLL */ 2012 2013static void 2014s3c24xx_serial_console_putchar(struct uart_port *port, int ch) 2015{ 2016 unsigned int ufcon = rd_regl(port, S3C2410_UFCON); 2017 2018 while (!s3c24xx_serial_console_txrdy(port, ufcon)) 2019 cpu_relax(); 2020 wr_regb(port, S3C2410_UTXH, ch); 2021} 2022 2023static void 2024s3c24xx_serial_console_write(struct console *co, const char *s, 2025 unsigned int count) 2026{ 2027 unsigned int ucon = rd_regl(cons_uart, S3C2410_UCON); 2028 2029 /* not possible to xmit on unconfigured port */ 2030 if (!s3c24xx_port_configured(ucon)) 2031 return; 2032 2033 uart_console_write(cons_uart, s, count, s3c24xx_serial_console_putchar); 2034} 2035 2036static void __init 2037s3c24xx_serial_get_options(struct uart_port *port, int *baud, 2038 int *parity, int *bits) 2039{ 2040 struct clk *clk; 2041 unsigned int ulcon; 2042 unsigned int ucon; 2043 unsigned int ubrdiv; 2044 unsigned long rate; 2045 unsigned int clk_sel; 2046 char clk_name[MAX_CLK_NAME_LENGTH]; 2047 2048 ulcon = rd_regl(port, S3C2410_ULCON); 2049 ucon = rd_regl(port, S3C2410_UCON); 2050 ubrdiv = rd_regl(port, S3C2410_UBRDIV); 2051 2052 dbg("s3c24xx_serial_get_options: port=%p\n" 2053 "registers: ulcon=%08x, ucon=%08x, ubdriv=%08x\n", 2054 port, ulcon, ucon, ubrdiv); 2055 2056 if (s3c24xx_port_configured(ucon)) { 2057 switch (ulcon & S3C2410_LCON_CSMASK) { 2058 case S3C2410_LCON_CS5: 2059 *bits = 5; 2060 break; 2061 case S3C2410_LCON_CS6: 2062 *bits = 6; 2063 break; 2064 case S3C2410_LCON_CS7: 2065 *bits = 7; 2066 break; 2067 case S3C2410_LCON_CS8: 2068 default: 2069 *bits = 8; 2070 break; 2071 } 2072 2073 switch (ulcon & S3C2410_LCON_PMASK) { 2074 case S3C2410_LCON_PEVEN: 2075 *parity = 'e'; 2076 break; 2077 2078 case S3C2410_LCON_PODD: 2079 *parity = 'o'; 2080 break; 2081 2082 case S3C2410_LCON_PNONE: 2083 default: 2084 *parity = 'n'; 2085 } 2086 2087 /* now calculate the baud rate */ 2088 2089 clk_sel = s3c24xx_serial_getsource(port); 2090 sprintf(clk_name, "clk_uart_baud%d", clk_sel); 2091 2092 clk = clk_get(port->dev, clk_name); 2093 if (!IS_ERR(clk)) 2094 rate = clk_get_rate(clk); 2095 else 2096 rate = 1; 2097 2098 *baud = rate / (16 * (ubrdiv + 1)); 2099 dbg("calculated baud %d\n", *baud); 2100 } 2101 2102} 2103 2104static int __init 2105s3c24xx_serial_console_setup(struct console *co, char *options) 2106{ 2107 struct uart_port *port; 2108 int baud = 9600; 2109 int bits = 8; 2110 int parity = 'n'; 2111 int flow = 'n'; 2112 2113 dbg("s3c24xx_serial_console_setup: co=%p (%d), %s\n", 2114 co, co->index, options); 2115 2116 /* is this a valid port */ 2117 2118 if (co->index == -1 || co->index >= CONFIG_SERIAL_SAMSUNG_UARTS) 2119 co->index = 0; 2120 2121 port = &s3c24xx_serial_ports[co->index].port; 2122 2123 /* is the port configured? */ 2124 2125 if (port->mapbase == 0x0) 2126 return -ENODEV; 2127 2128 cons_uart = port; 2129 2130 dbg("s3c24xx_serial_console_setup: port=%p (%d)\n", port, co->index); 2131 2132 /* 2133 * Check whether an invalid uart number has been specified, and 2134 * if so, search for the first available port that does have 2135 * console support. 2136 */ 2137 if (options) 2138 uart_parse_options(options, &baud, &parity, &bits, &flow); 2139 else 2140 s3c24xx_serial_get_options(port, &baud, &parity, &bits); 2141 2142 dbg("s3c24xx_serial_console_setup: baud %d\n", baud); 2143 2144 return uart_set_options(port, co, baud, parity, bits, flow); 2145} 2146 2147static struct console s3c24xx_serial_console = { 2148 .name = S3C24XX_SERIAL_NAME, 2149 .device = uart_console_device, 2150 .flags = CON_PRINTBUFFER, 2151 .index = -1, 2152 .write = s3c24xx_serial_console_write, 2153 .setup = s3c24xx_serial_console_setup, 2154 .data = &s3c24xx_uart_drv, 2155}; 2156#endif /* CONFIG_SERIAL_SAMSUNG_CONSOLE */ 2157 2158#ifdef CONFIG_CPU_S3C2410 2159static struct s3c24xx_serial_drv_data s3c2410_serial_drv_data = { 2160 .info = &(struct s3c24xx_uart_info) { 2161 .name = "Samsung S3C2410 UART", 2162 .type = PORT_S3C2410, 2163 .fifosize = 16, 2164 .rx_fifomask = S3C2410_UFSTAT_RXMASK, 2165 .rx_fifoshift = S3C2410_UFSTAT_RXSHIFT, 2166 .rx_fifofull = S3C2410_UFSTAT_RXFULL, 2167 .tx_fifofull = S3C2410_UFSTAT_TXFULL, 2168 .tx_fifomask = S3C2410_UFSTAT_TXMASK, 2169 .tx_fifoshift = S3C2410_UFSTAT_TXSHIFT, 2170 .def_clk_sel = S3C2410_UCON_CLKSEL0, 2171 .num_clks = 2, 2172 .clksel_mask = S3C2410_UCON_CLKMASK, 2173 .clksel_shift = S3C2410_UCON_CLKSHIFT, 2174 }, 2175 .def_cfg = &(struct s3c2410_uartcfg) { 2176 .ucon = S3C2410_UCON_DEFAULT, 2177 .ufcon = S3C2410_UFCON_DEFAULT, 2178 }, 2179}; 2180#define S3C2410_SERIAL_DRV_DATA ((kernel_ulong_t)&s3c2410_serial_drv_data) 2181#else 2182#define S3C2410_SERIAL_DRV_DATA (kernel_ulong_t)NULL 2183#endif 2184 2185#ifdef CONFIG_CPU_S3C2412 2186static struct s3c24xx_serial_drv_data s3c2412_serial_drv_data = { 2187 .info = &(struct s3c24xx_uart_info) { 2188 .name = "Samsung S3C2412 UART", 2189 .type = PORT_S3C2412, 2190 .fifosize = 64, 2191 .has_divslot = 1, 2192 .rx_fifomask = S3C2440_UFSTAT_RXMASK, 2193 .rx_fifoshift = S3C2440_UFSTAT_RXSHIFT, 2194 .rx_fifofull = S3C2440_UFSTAT_RXFULL, 2195 .tx_fifofull = S3C2440_UFSTAT_TXFULL, 2196 .tx_fifomask = S3C2440_UFSTAT_TXMASK, 2197 .tx_fifoshift = S3C2440_UFSTAT_TXSHIFT, 2198 .def_clk_sel = S3C2410_UCON_CLKSEL2, 2199 .num_clks = 4, 2200 .clksel_mask = S3C2412_UCON_CLKMASK, 2201 .clksel_shift = S3C2412_UCON_CLKSHIFT, 2202 }, 2203 .def_cfg = &(struct s3c2410_uartcfg) { 2204 .ucon = S3C2410_UCON_DEFAULT, 2205 .ufcon = S3C2410_UFCON_DEFAULT, 2206 }, 2207}; 2208#define S3C2412_SERIAL_DRV_DATA ((kernel_ulong_t)&s3c2412_serial_drv_data) 2209#else 2210#define S3C2412_SERIAL_DRV_DATA (kernel_ulong_t)NULL 2211#endif 2212 2213#if defined(CONFIG_CPU_S3C2440) || defined(CONFIG_CPU_S3C2416) || \ 2214 defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2442) 2215static struct s3c24xx_serial_drv_data s3c2440_serial_drv_data = { 2216 .info = &(struct s3c24xx_uart_info) { 2217 .name = "Samsung S3C2440 UART", 2218 .type = PORT_S3C2440, 2219 .fifosize = 64, 2220 .has_divslot = 1, 2221 .rx_fifomask = S3C2440_UFSTAT_RXMASK, 2222 .rx_fifoshift = S3C2440_UFSTAT_RXSHIFT, 2223 .rx_fifofull = S3C2440_UFSTAT_RXFULL, 2224 .tx_fifofull = S3C2440_UFSTAT_TXFULL, 2225 .tx_fifomask = S3C2440_UFSTAT_TXMASK, 2226 .tx_fifoshift = S3C2440_UFSTAT_TXSHIFT, 2227 .def_clk_sel = S3C2410_UCON_CLKSEL2, 2228 .num_clks = 4, 2229 .clksel_mask = S3C2412_UCON_CLKMASK, 2230 .clksel_shift = S3C2412_UCON_CLKSHIFT, 2231 }, 2232 .def_cfg = &(struct s3c2410_uartcfg) { 2233 .ucon = S3C2410_UCON_DEFAULT, 2234 .ufcon = S3C2410_UFCON_DEFAULT, 2235 }, 2236}; 2237#define S3C2440_SERIAL_DRV_DATA ((kernel_ulong_t)&s3c2440_serial_drv_data) 2238#else 2239#define S3C2440_SERIAL_DRV_DATA (kernel_ulong_t)NULL 2240#endif 2241 2242#if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410) 2243static struct s3c24xx_serial_drv_data s3c6400_serial_drv_data = { 2244 .info = &(struct s3c24xx_uart_info) { 2245 .name = "Samsung S3C6400 UART", 2246 .type = PORT_S3C6400, 2247 .fifosize = 64, 2248 .has_divslot = 1, 2249 .rx_fifomask = S3C2440_UFSTAT_RXMASK, 2250 .rx_fifoshift = S3C2440_UFSTAT_RXSHIFT, 2251 .rx_fifofull = S3C2440_UFSTAT_RXFULL, 2252 .tx_fifofull = S3C2440_UFSTAT_TXFULL, 2253 .tx_fifomask = S3C2440_UFSTAT_TXMASK, 2254 .tx_fifoshift = S3C2440_UFSTAT_TXSHIFT, 2255 .def_clk_sel = S3C2410_UCON_CLKSEL2, 2256 .num_clks = 4, 2257 .clksel_mask = S3C6400_UCON_CLKMASK, 2258 .clksel_shift = S3C6400_UCON_CLKSHIFT, 2259 }, 2260 .def_cfg = &(struct s3c2410_uartcfg) { 2261 .ucon = S3C2410_UCON_DEFAULT, 2262 .ufcon = S3C2410_UFCON_DEFAULT, 2263 }, 2264}; 2265#define S3C6400_SERIAL_DRV_DATA ((kernel_ulong_t)&s3c6400_serial_drv_data) 2266#else 2267#define S3C6400_SERIAL_DRV_DATA (kernel_ulong_t)NULL 2268#endif 2269 2270#ifdef CONFIG_CPU_S5PV210 2271static struct s3c24xx_serial_drv_data s5pv210_serial_drv_data = { 2272 .info = &(struct s3c24xx_uart_info) { 2273 .name = "Samsung S5PV210 UART", 2274 .type = PORT_S3C6400, 2275 .has_divslot = 1, 2276 .rx_fifomask = S5PV210_UFSTAT_RXMASK, 2277 .rx_fifoshift = S5PV210_UFSTAT_RXSHIFT, 2278 .rx_fifofull = S5PV210_UFSTAT_RXFULL, 2279 .tx_fifofull = S5PV210_UFSTAT_TXFULL, 2280 .tx_fifomask = S5PV210_UFSTAT_TXMASK, 2281 .tx_fifoshift = S5PV210_UFSTAT_TXSHIFT, 2282 .def_clk_sel = S3C2410_UCON_CLKSEL0, 2283 .num_clks = 2, 2284 .clksel_mask = S5PV210_UCON_CLKMASK, 2285 .clksel_shift = S5PV210_UCON_CLKSHIFT, 2286 }, 2287 .def_cfg = &(struct s3c2410_uartcfg) { 2288 .ucon = S5PV210_UCON_DEFAULT, 2289 .ufcon = S5PV210_UFCON_DEFAULT, 2290 }, 2291 .fifosize = { 256, 64, 16, 16 }, 2292}; 2293#define S5PV210_SERIAL_DRV_DATA ((kernel_ulong_t)&s5pv210_serial_drv_data) 2294#else 2295#define S5PV210_SERIAL_DRV_DATA (kernel_ulong_t)NULL 2296#endif 2297 2298#if defined(CONFIG_ARCH_EXYNOS) 2299#define EXYNOS_COMMON_SERIAL_DRV_DATA \ 2300 .info = &(struct s3c24xx_uart_info) { \ 2301 .name = "Samsung Exynos UART", \ 2302 .type = PORT_S3C6400, \ 2303 .has_divslot = 1, \ 2304 .rx_fifomask = S5PV210_UFSTAT_RXMASK, \ 2305 .rx_fifoshift = S5PV210_UFSTAT_RXSHIFT, \ 2306 .rx_fifofull = S5PV210_UFSTAT_RXFULL, \ 2307 .tx_fifofull = S5PV210_UFSTAT_TXFULL, \ 2308 .tx_fifomask = S5PV210_UFSTAT_TXMASK, \ 2309 .tx_fifoshift = S5PV210_UFSTAT_TXSHIFT, \ 2310 .def_clk_sel = S3C2410_UCON_CLKSEL0, \ 2311 .num_clks = 1, \ 2312 .clksel_mask = 0, \ 2313 .clksel_shift = 0, \ 2314 }, \ 2315 .def_cfg = &(struct s3c2410_uartcfg) { \ 2316 .ucon = S5PV210_UCON_DEFAULT, \ 2317 .ufcon = S5PV210_UFCON_DEFAULT, \ 2318 .has_fracval = 1, \ 2319 } \ 2320 2321static struct s3c24xx_serial_drv_data exynos4210_serial_drv_data = { 2322 EXYNOS_COMMON_SERIAL_DRV_DATA, 2323 .fifosize = { 256, 64, 16, 16 }, 2324}; 2325 2326static struct s3c24xx_serial_drv_data exynos5433_serial_drv_data = { 2327 EXYNOS_COMMON_SERIAL_DRV_DATA, 2328 .fifosize = { 64, 256, 16, 256 }, 2329}; 2330 2331#define EXYNOS4210_SERIAL_DRV_DATA ((kernel_ulong_t)&exynos4210_serial_drv_data) 2332#define EXYNOS5433_SERIAL_DRV_DATA ((kernel_ulong_t)&exynos5433_serial_drv_data) 2333#else 2334#define EXYNOS4210_SERIAL_DRV_DATA (kernel_ulong_t)NULL 2335#define EXYNOS5433_SERIAL_DRV_DATA (kernel_ulong_t)NULL 2336#endif 2337 2338static const struct platform_device_id s3c24xx_serial_driver_ids[] = { 2339 { 2340 .name = "s3c2410-uart", 2341 .driver_data = S3C2410_SERIAL_DRV_DATA, 2342 }, { 2343 .name = "s3c2412-uart", 2344 .driver_data = S3C2412_SERIAL_DRV_DATA, 2345 }, { 2346 .name = "s3c2440-uart", 2347 .driver_data = S3C2440_SERIAL_DRV_DATA, 2348 }, { 2349 .name = "s3c6400-uart", 2350 .driver_data = S3C6400_SERIAL_DRV_DATA, 2351 }, { 2352 .name = "s5pv210-uart", 2353 .driver_data = S5PV210_SERIAL_DRV_DATA, 2354 }, { 2355 .name = "exynos4210-uart", 2356 .driver_data = EXYNOS4210_SERIAL_DRV_DATA, 2357 }, { 2358 .name = "exynos5433-uart", 2359 .driver_data = EXYNOS5433_SERIAL_DRV_DATA, 2360 }, 2361 { }, 2362}; 2363MODULE_DEVICE_TABLE(platform, s3c24xx_serial_driver_ids); 2364 2365#ifdef CONFIG_OF 2366static const struct of_device_id s3c24xx_uart_dt_match[] = { 2367 { .compatible = "samsung,s3c2410-uart", 2368 .data = (void *)S3C2410_SERIAL_DRV_DATA }, 2369 { .compatible = "samsung,s3c2412-uart", 2370 .data = (void *)S3C2412_SERIAL_DRV_DATA }, 2371 { .compatible = "samsung,s3c2440-uart", 2372 .data = (void *)S3C2440_SERIAL_DRV_DATA }, 2373 { .compatible = "samsung,s3c6400-uart", 2374 .data = (void *)S3C6400_SERIAL_DRV_DATA }, 2375 { .compatible = "samsung,s5pv210-uart", 2376 .data = (void *)S5PV210_SERIAL_DRV_DATA }, 2377 { .compatible = "samsung,exynos4210-uart", 2378 .data = (void *)EXYNOS4210_SERIAL_DRV_DATA }, 2379 { .compatible = "samsung,exynos5433-uart", 2380 .data = (void *)EXYNOS5433_SERIAL_DRV_DATA }, 2381 {}, 2382}; 2383MODULE_DEVICE_TABLE(of, s3c24xx_uart_dt_match); 2384#endif 2385 2386static struct platform_driver samsung_serial_driver = { 2387 .probe = s3c24xx_serial_probe, 2388 .remove = s3c24xx_serial_remove, 2389 .id_table = s3c24xx_serial_driver_ids, 2390 .driver = { 2391 .name = "samsung-uart", 2392 .pm = SERIAL_SAMSUNG_PM_OPS, 2393 .of_match_table = of_match_ptr(s3c24xx_uart_dt_match), 2394 }, 2395}; 2396 2397module_platform_driver(samsung_serial_driver); 2398 2399#ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE 2400/* 2401 * Early console. 2402 */ 2403 2404struct samsung_early_console_data { 2405 u32 txfull_mask; 2406}; 2407 2408static void samsung_early_busyuart(struct uart_port *port) 2409{ 2410 while (!(readl(port->membase + S3C2410_UTRSTAT) & S3C2410_UTRSTAT_TXFE)) 2411 ; 2412} 2413 2414static void samsung_early_busyuart_fifo(struct uart_port *port) 2415{ 2416 struct samsung_early_console_data *data = port->private_data; 2417 2418 while (readl(port->membase + S3C2410_UFSTAT) & data->txfull_mask) 2419 ; 2420} 2421 2422static void samsung_early_putc(struct uart_port *port, int c) 2423{ 2424 if (readl(port->membase + S3C2410_UFCON) & S3C2410_UFCON_FIFOMODE) 2425 samsung_early_busyuart_fifo(port); 2426 else 2427 samsung_early_busyuart(port); 2428 2429 writeb(c, port->membase + S3C2410_UTXH); 2430} 2431 2432static void samsung_early_write(struct console *con, const char *s, unsigned n) 2433{ 2434 struct earlycon_device *dev = con->data; 2435 2436 uart_console_write(&dev->port, s, n, samsung_early_putc); 2437} 2438 2439static int __init samsung_early_console_setup(struct earlycon_device *device, 2440 const char *opt) 2441{ 2442 if (!device->port.membase) 2443 return -ENODEV; 2444 2445 device->con->write = samsung_early_write; 2446 return 0; 2447} 2448 2449/* S3C2410 */ 2450static struct samsung_early_console_data s3c2410_early_console_data = { 2451 .txfull_mask = S3C2410_UFSTAT_TXFULL, 2452}; 2453 2454static int __init s3c2410_early_console_setup(struct earlycon_device *device, 2455 const char *opt) 2456{ 2457 device->port.private_data = &s3c2410_early_console_data; 2458 return samsung_early_console_setup(device, opt); 2459} 2460OF_EARLYCON_DECLARE(s3c2410, "samsung,s3c2410-uart", 2461 s3c2410_early_console_setup); 2462 2463/* S3C2412, S3C2440, S3C64xx */ 2464static struct samsung_early_console_data s3c2440_early_console_data = { 2465 .txfull_mask = S3C2440_UFSTAT_TXFULL, 2466}; 2467 2468static int __init s3c2440_early_console_setup(struct earlycon_device *device, 2469 const char *opt) 2470{ 2471 device->port.private_data = &s3c2440_early_console_data; 2472 return samsung_early_console_setup(device, opt); 2473} 2474OF_EARLYCON_DECLARE(s3c2412, "samsung,s3c2412-uart", 2475 s3c2440_early_console_setup); 2476OF_EARLYCON_DECLARE(s3c2440, "samsung,s3c2440-uart", 2477 s3c2440_early_console_setup); 2478OF_EARLYCON_DECLARE(s3c6400, "samsung,s3c6400-uart", 2479 s3c2440_early_console_setup); 2480 2481/* S5PV210, EXYNOS */ 2482static struct samsung_early_console_data s5pv210_early_console_data = { 2483 .txfull_mask = S5PV210_UFSTAT_TXFULL, 2484}; 2485 2486static int __init s5pv210_early_console_setup(struct earlycon_device *device, 2487 const char *opt) 2488{ 2489 device->port.private_data = &s5pv210_early_console_data; 2490 return samsung_early_console_setup(device, opt); 2491} 2492OF_EARLYCON_DECLARE(s5pv210, "samsung,s5pv210-uart", 2493 s5pv210_early_console_setup); 2494OF_EARLYCON_DECLARE(exynos4210, "samsung,exynos4210-uart", 2495 s5pv210_early_console_setup); 2496#endif 2497 2498MODULE_ALIAS("platform:samsung-uart"); 2499MODULE_DESCRIPTION("Samsung SoC Serial port driver"); 2500MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); 2501MODULE_LICENSE("GPL v2");