Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v4.5-rc6 2499 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 int max_count = port->fifosize; 605 606 while (max_count-- > 0) { 607 ufcon = rd_regl(port, S3C2410_UFCON); 608 ufstat = rd_regl(port, S3C2410_UFSTAT); 609 610 if (s3c24xx_serial_rx_fifocnt(ourport, ufstat) == 0) 611 break; 612 613 uerstat = rd_regl(port, S3C2410_UERSTAT); 614 ch = rd_regb(port, S3C2410_URXH); 615 616 if (port->flags & UPF_CONS_FLOW) { 617 int txe = s3c24xx_serial_txempty_nofifo(port); 618 619 if (rx_enabled(port)) { 620 if (!txe) { 621 rx_enabled(port) = 0; 622 continue; 623 } 624 } else { 625 if (txe) { 626 ufcon |= S3C2410_UFCON_RESETRX; 627 wr_regl(port, S3C2410_UFCON, ufcon); 628 rx_enabled(port) = 1; 629 return; 630 } 631 continue; 632 } 633 } 634 635 /* insert the character into the buffer */ 636 637 flag = TTY_NORMAL; 638 port->icount.rx++; 639 640 if (unlikely(uerstat & S3C2410_UERSTAT_ANY)) { 641 dbg("rxerr: port ch=0x%02x, rxs=0x%08x\n", 642 ch, uerstat); 643 644 /* check for break */ 645 if (uerstat & S3C2410_UERSTAT_BREAK) { 646 dbg("break!\n"); 647 port->icount.brk++; 648 if (uart_handle_break(port)) 649 continue; /* Ignore character */ 650 } 651 652 if (uerstat & S3C2410_UERSTAT_FRAME) 653 port->icount.frame++; 654 if (uerstat & S3C2410_UERSTAT_OVERRUN) 655 port->icount.overrun++; 656 657 uerstat &= port->read_status_mask; 658 659 if (uerstat & S3C2410_UERSTAT_BREAK) 660 flag = TTY_BREAK; 661 else if (uerstat & S3C2410_UERSTAT_PARITY) 662 flag = TTY_PARITY; 663 else if (uerstat & (S3C2410_UERSTAT_FRAME | 664 S3C2410_UERSTAT_OVERRUN)) 665 flag = TTY_FRAME; 666 } 667 668 if (uart_handle_sysrq_char(port, ch)) 669 continue; /* Ignore character */ 670 671 uart_insert_char(port, uerstat, S3C2410_UERSTAT_OVERRUN, 672 ch, flag); 673 } 674 675 tty_flip_buffer_push(&port->state->port); 676} 677 678static irqreturn_t s3c24xx_serial_rx_chars_pio(void *dev_id) 679{ 680 struct s3c24xx_uart_port *ourport = dev_id; 681 struct uart_port *port = &ourport->port; 682 unsigned long flags; 683 684 spin_lock_irqsave(&port->lock, flags); 685 s3c24xx_serial_rx_drain_fifo(ourport); 686 spin_unlock_irqrestore(&port->lock, flags); 687 688 return IRQ_HANDLED; 689} 690 691 692static irqreturn_t s3c24xx_serial_rx_chars(int irq, void *dev_id) 693{ 694 struct s3c24xx_uart_port *ourport = dev_id; 695 696 if (ourport->dma && ourport->dma->rx_chan) 697 return s3c24xx_serial_rx_chars_dma(dev_id); 698 return s3c24xx_serial_rx_chars_pio(dev_id); 699} 700 701static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id) 702{ 703 struct s3c24xx_uart_port *ourport = id; 704 struct uart_port *port = &ourport->port; 705 struct circ_buf *xmit = &port->state->xmit; 706 unsigned long flags; 707 int count, dma_count = 0; 708 709 spin_lock_irqsave(&port->lock, flags); 710 711 count = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE); 712 713 if (ourport->dma && ourport->dma->tx_chan && 714 count >= ourport->min_dma_size) { 715 int align = dma_get_cache_alignment() - 716 (xmit->tail & (dma_get_cache_alignment() - 1)); 717 if (count-align >= ourport->min_dma_size) { 718 dma_count = count-align; 719 count = align; 720 } 721 } 722 723 if (port->x_char) { 724 wr_regb(port, S3C2410_UTXH, port->x_char); 725 port->icount.tx++; 726 port->x_char = 0; 727 goto out; 728 } 729 730 /* if there isn't anything more to transmit, or the uart is now 731 * stopped, disable the uart and exit 732 */ 733 734 if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { 735 s3c24xx_serial_stop_tx(port); 736 goto out; 737 } 738 739 /* try and drain the buffer... */ 740 741 if (count > port->fifosize) { 742 count = port->fifosize; 743 dma_count = 0; 744 } 745 746 while (!uart_circ_empty(xmit) && count > 0) { 747 if (rd_regl(port, S3C2410_UFSTAT) & ourport->info->tx_fifofull) 748 break; 749 750 wr_regb(port, S3C2410_UTXH, xmit->buf[xmit->tail]); 751 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); 752 port->icount.tx++; 753 count--; 754 } 755 756 if (!count && dma_count) { 757 s3c24xx_serial_start_tx_dma(ourport, dma_count); 758 goto out; 759 } 760 761 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) { 762 spin_unlock(&port->lock); 763 uart_write_wakeup(port); 764 spin_lock(&port->lock); 765 } 766 767 if (uart_circ_empty(xmit)) 768 s3c24xx_serial_stop_tx(port); 769 770out: 771 spin_unlock_irqrestore(&port->lock, flags); 772 return IRQ_HANDLED; 773} 774 775/* interrupt handler for s3c64xx and later SoC's.*/ 776static irqreturn_t s3c64xx_serial_handle_irq(int irq, void *id) 777{ 778 struct s3c24xx_uart_port *ourport = id; 779 struct uart_port *port = &ourport->port; 780 unsigned int pend = rd_regl(port, S3C64XX_UINTP); 781 irqreturn_t ret = IRQ_HANDLED; 782 783 if (pend & S3C64XX_UINTM_RXD_MSK) { 784 ret = s3c24xx_serial_rx_chars(irq, id); 785 wr_regl(port, S3C64XX_UINTP, S3C64XX_UINTM_RXD_MSK); 786 } 787 if (pend & S3C64XX_UINTM_TXD_MSK) { 788 ret = s3c24xx_serial_tx_chars(irq, id); 789 wr_regl(port, S3C64XX_UINTP, S3C64XX_UINTM_TXD_MSK); 790 } 791 return ret; 792} 793 794static unsigned int s3c24xx_serial_tx_empty(struct uart_port *port) 795{ 796 struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port); 797 unsigned long ufstat = rd_regl(port, S3C2410_UFSTAT); 798 unsigned long ufcon = rd_regl(port, S3C2410_UFCON); 799 800 if (ufcon & S3C2410_UFCON_FIFOMODE) { 801 if ((ufstat & info->tx_fifomask) != 0 || 802 (ufstat & info->tx_fifofull)) 803 return 0; 804 805 return 1; 806 } 807 808 return s3c24xx_serial_txempty_nofifo(port); 809} 810 811/* no modem control lines */ 812static unsigned int s3c24xx_serial_get_mctrl(struct uart_port *port) 813{ 814 unsigned int umstat = rd_regb(port, S3C2410_UMSTAT); 815 816 if (umstat & S3C2410_UMSTAT_CTS) 817 return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS; 818 else 819 return TIOCM_CAR | TIOCM_DSR; 820} 821 822static void s3c24xx_serial_set_mctrl(struct uart_port *port, unsigned int mctrl) 823{ 824 unsigned int umcon = rd_regl(port, S3C2410_UMCON); 825 826 if (mctrl & TIOCM_RTS) 827 umcon |= S3C2410_UMCOM_RTS_LOW; 828 else 829 umcon &= ~S3C2410_UMCOM_RTS_LOW; 830 831 wr_regl(port, S3C2410_UMCON, umcon); 832} 833 834static void s3c24xx_serial_break_ctl(struct uart_port *port, int break_state) 835{ 836 unsigned long flags; 837 unsigned int ucon; 838 839 spin_lock_irqsave(&port->lock, flags); 840 841 ucon = rd_regl(port, S3C2410_UCON); 842 843 if (break_state) 844 ucon |= S3C2410_UCON_SBREAK; 845 else 846 ucon &= ~S3C2410_UCON_SBREAK; 847 848 wr_regl(port, S3C2410_UCON, ucon); 849 850 spin_unlock_irqrestore(&port->lock, flags); 851} 852 853static int s3c24xx_serial_request_dma(struct s3c24xx_uart_port *p) 854{ 855 struct s3c24xx_uart_dma *dma = p->dma; 856 dma_cap_mask_t mask; 857 unsigned long flags; 858 859 /* Default slave configuration parameters */ 860 dma->rx_conf.direction = DMA_DEV_TO_MEM; 861 dma->rx_conf.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; 862 dma->rx_conf.src_addr = p->port.mapbase + S3C2410_URXH; 863 dma->rx_conf.src_maxburst = 16; 864 865 dma->tx_conf.direction = DMA_MEM_TO_DEV; 866 dma->tx_conf.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; 867 dma->tx_conf.dst_addr = p->port.mapbase + S3C2410_UTXH; 868 if (dma_get_cache_alignment() >= 16) 869 dma->tx_conf.dst_maxburst = 16; 870 else 871 dma->tx_conf.dst_maxburst = 1; 872 873 dma_cap_zero(mask); 874 dma_cap_set(DMA_SLAVE, mask); 875 876 dma->rx_chan = dma_request_slave_channel_compat(mask, dma->fn, 877 dma->rx_param, p->port.dev, "rx"); 878 if (!dma->rx_chan) 879 return -ENODEV; 880 881 dmaengine_slave_config(dma->rx_chan, &dma->rx_conf); 882 883 dma->tx_chan = dma_request_slave_channel_compat(mask, dma->fn, 884 dma->tx_param, p->port.dev, "tx"); 885 if (!dma->tx_chan) { 886 dma_release_channel(dma->rx_chan); 887 return -ENODEV; 888 } 889 890 dmaengine_slave_config(dma->tx_chan, &dma->tx_conf); 891 892 /* RX buffer */ 893 dma->rx_size = PAGE_SIZE; 894 895 dma->rx_buf = kmalloc(dma->rx_size, GFP_KERNEL); 896 897 if (!dma->rx_buf) { 898 dma_release_channel(dma->rx_chan); 899 dma_release_channel(dma->tx_chan); 900 return -ENOMEM; 901 } 902 903 dma->rx_addr = dma_map_single(dma->rx_chan->device->dev, dma->rx_buf, 904 dma->rx_size, DMA_FROM_DEVICE); 905 906 spin_lock_irqsave(&p->port.lock, flags); 907 908 /* TX buffer */ 909 dma->tx_addr = dma_map_single(dma->tx_chan->device->dev, 910 p->port.state->xmit.buf, 911 UART_XMIT_SIZE, DMA_TO_DEVICE); 912 913 spin_unlock_irqrestore(&p->port.lock, flags); 914 915 return 0; 916} 917 918static void s3c24xx_serial_release_dma(struct s3c24xx_uart_port *p) 919{ 920 struct s3c24xx_uart_dma *dma = p->dma; 921 922 if (dma->rx_chan) { 923 dmaengine_terminate_all(dma->rx_chan); 924 dma_unmap_single(dma->rx_chan->device->dev, dma->rx_addr, 925 dma->rx_size, DMA_FROM_DEVICE); 926 kfree(dma->rx_buf); 927 dma_release_channel(dma->rx_chan); 928 dma->rx_chan = NULL; 929 } 930 931 if (dma->tx_chan) { 932 dmaengine_terminate_all(dma->tx_chan); 933 dma_unmap_single(dma->tx_chan->device->dev, dma->tx_addr, 934 UART_XMIT_SIZE, DMA_TO_DEVICE); 935 dma_release_channel(dma->tx_chan); 936 dma->tx_chan = NULL; 937 } 938} 939 940static void s3c24xx_serial_shutdown(struct uart_port *port) 941{ 942 struct s3c24xx_uart_port *ourport = to_ourport(port); 943 944 if (ourport->tx_claimed) { 945 if (!s3c24xx_serial_has_interrupt_mask(port)) 946 free_irq(ourport->tx_irq, ourport); 947 tx_enabled(port) = 0; 948 ourport->tx_claimed = 0; 949 ourport->tx_mode = 0; 950 } 951 952 if (ourport->rx_claimed) { 953 if (!s3c24xx_serial_has_interrupt_mask(port)) 954 free_irq(ourport->rx_irq, ourport); 955 ourport->rx_claimed = 0; 956 rx_enabled(port) = 0; 957 } 958 959 /* Clear pending interrupts and mask all interrupts */ 960 if (s3c24xx_serial_has_interrupt_mask(port)) { 961 free_irq(port->irq, ourport); 962 963 wr_regl(port, S3C64XX_UINTP, 0xf); 964 wr_regl(port, S3C64XX_UINTM, 0xf); 965 } 966 967 if (ourport->dma) 968 s3c24xx_serial_release_dma(ourport); 969 970 ourport->tx_in_progress = 0; 971} 972 973static int s3c24xx_serial_startup(struct uart_port *port) 974{ 975 struct s3c24xx_uart_port *ourport = to_ourport(port); 976 int ret; 977 978 dbg("s3c24xx_serial_startup: port=%p (%08llx,%p)\n", 979 port, (unsigned long long)port->mapbase, port->membase); 980 981 rx_enabled(port) = 1; 982 983 ret = request_irq(ourport->rx_irq, s3c24xx_serial_rx_chars, 0, 984 s3c24xx_serial_portname(port), ourport); 985 986 if (ret != 0) { 987 dev_err(port->dev, "cannot get irq %d\n", ourport->rx_irq); 988 return ret; 989 } 990 991 ourport->rx_claimed = 1; 992 993 dbg("requesting tx irq...\n"); 994 995 tx_enabled(port) = 1; 996 997 ret = request_irq(ourport->tx_irq, s3c24xx_serial_tx_chars, 0, 998 s3c24xx_serial_portname(port), ourport); 999 1000 if (ret) { 1001 dev_err(port->dev, "cannot get irq %d\n", ourport->tx_irq); 1002 goto err; 1003 } 1004 1005 ourport->tx_claimed = 1; 1006 1007 dbg("s3c24xx_serial_startup ok\n"); 1008 1009 /* the port reset code should have done the correct 1010 * register setup for the port controls */ 1011 1012 return ret; 1013 1014err: 1015 s3c24xx_serial_shutdown(port); 1016 return ret; 1017} 1018 1019static int s3c64xx_serial_startup(struct uart_port *port) 1020{ 1021 struct s3c24xx_uart_port *ourport = to_ourport(port); 1022 unsigned long flags; 1023 unsigned int ufcon; 1024 int ret; 1025 1026 dbg("s3c64xx_serial_startup: port=%p (%08llx,%p)\n", 1027 port, (unsigned long long)port->mapbase, port->membase); 1028 1029 wr_regl(port, S3C64XX_UINTM, 0xf); 1030 if (ourport->dma) { 1031 ret = s3c24xx_serial_request_dma(ourport); 1032 if (ret < 0) { 1033 dev_warn(port->dev, "DMA request failed\n"); 1034 return ret; 1035 } 1036 } 1037 1038 ret = request_irq(port->irq, s3c64xx_serial_handle_irq, IRQF_SHARED, 1039 s3c24xx_serial_portname(port), ourport); 1040 if (ret) { 1041 dev_err(port->dev, "cannot get irq %d\n", port->irq); 1042 return ret; 1043 } 1044 1045 /* For compatibility with s3c24xx Soc's */ 1046 rx_enabled(port) = 1; 1047 ourport->rx_claimed = 1; 1048 tx_enabled(port) = 0; 1049 ourport->tx_claimed = 1; 1050 1051 spin_lock_irqsave(&port->lock, flags); 1052 1053 ufcon = rd_regl(port, S3C2410_UFCON); 1054 ufcon |= S3C2410_UFCON_RESETRX | S5PV210_UFCON_RXTRIG8; 1055 if (!uart_console(port)) 1056 ufcon |= S3C2410_UFCON_RESETTX; 1057 wr_regl(port, S3C2410_UFCON, ufcon); 1058 1059 enable_rx_pio(ourport); 1060 1061 spin_unlock_irqrestore(&port->lock, flags); 1062 1063 /* Enable Rx Interrupt */ 1064 __clear_bit(S3C64XX_UINTM_RXD, portaddrl(port, S3C64XX_UINTM)); 1065 1066 dbg("s3c64xx_serial_startup ok\n"); 1067 return ret; 1068} 1069 1070/* power power management control */ 1071 1072static void s3c24xx_serial_pm(struct uart_port *port, unsigned int level, 1073 unsigned int old) 1074{ 1075 struct s3c24xx_uart_port *ourport = to_ourport(port); 1076 int timeout = 10000; 1077 1078 ourport->pm_level = level; 1079 1080 switch (level) { 1081 case 3: 1082 while (--timeout && !s3c24xx_serial_txempty_nofifo(port)) 1083 udelay(100); 1084 1085 if (!IS_ERR(ourport->baudclk)) 1086 clk_disable_unprepare(ourport->baudclk); 1087 1088 clk_disable_unprepare(ourport->clk); 1089 break; 1090 1091 case 0: 1092 clk_prepare_enable(ourport->clk); 1093 1094 if (!IS_ERR(ourport->baudclk)) 1095 clk_prepare_enable(ourport->baudclk); 1096 1097 break; 1098 default: 1099 dev_err(port->dev, "s3c24xx_serial: unknown pm %d\n", level); 1100 } 1101} 1102 1103/* baud rate calculation 1104 * 1105 * The UARTs on the S3C2410/S3C2440 can take their clocks from a number 1106 * of different sources, including the peripheral clock ("pclk") and an 1107 * external clock ("uclk"). The S3C2440 also adds the core clock ("fclk") 1108 * with a programmable extra divisor. 1109 * 1110 * The following code goes through the clock sources, and calculates the 1111 * baud clocks (and the resultant actual baud rates) and then tries to 1112 * pick the closest one and select that. 1113 * 1114*/ 1115 1116#define MAX_CLK_NAME_LENGTH 15 1117 1118static inline int s3c24xx_serial_getsource(struct uart_port *port) 1119{ 1120 struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port); 1121 unsigned int ucon; 1122 1123 if (info->num_clks == 1) 1124 return 0; 1125 1126 ucon = rd_regl(port, S3C2410_UCON); 1127 ucon &= info->clksel_mask; 1128 return ucon >> info->clksel_shift; 1129} 1130 1131static void s3c24xx_serial_setsource(struct uart_port *port, 1132 unsigned int clk_sel) 1133{ 1134 struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port); 1135 unsigned int ucon; 1136 1137 if (info->num_clks == 1) 1138 return; 1139 1140 ucon = rd_regl(port, S3C2410_UCON); 1141 if ((ucon & info->clksel_mask) >> info->clksel_shift == clk_sel) 1142 return; 1143 1144 ucon &= ~info->clksel_mask; 1145 ucon |= clk_sel << info->clksel_shift; 1146 wr_regl(port, S3C2410_UCON, ucon); 1147} 1148 1149static unsigned int s3c24xx_serial_getclk(struct s3c24xx_uart_port *ourport, 1150 unsigned int req_baud, struct clk **best_clk, 1151 unsigned int *clk_num) 1152{ 1153 struct s3c24xx_uart_info *info = ourport->info; 1154 struct clk *clk; 1155 unsigned long rate; 1156 unsigned int cnt, baud, quot, clk_sel, best_quot = 0; 1157 char clkname[MAX_CLK_NAME_LENGTH]; 1158 int calc_deviation, deviation = (1 << 30) - 1; 1159 1160 clk_sel = (ourport->cfg->clk_sel) ? ourport->cfg->clk_sel : 1161 ourport->info->def_clk_sel; 1162 for (cnt = 0; cnt < info->num_clks; cnt++) { 1163 if (!(clk_sel & (1 << cnt))) 1164 continue; 1165 1166 sprintf(clkname, "clk_uart_baud%d", cnt); 1167 clk = clk_get(ourport->port.dev, clkname); 1168 if (IS_ERR(clk)) 1169 continue; 1170 1171 rate = clk_get_rate(clk); 1172 if (!rate) 1173 continue; 1174 1175 if (ourport->info->has_divslot) { 1176 unsigned long div = rate / req_baud; 1177 1178 /* The UDIVSLOT register on the newer UARTs allows us to 1179 * get a divisor adjustment of 1/16th on the baud clock. 1180 * 1181 * We don't keep the UDIVSLOT value (the 16ths we 1182 * calculated by not multiplying the baud by 16) as it 1183 * is easy enough to recalculate. 1184 */ 1185 1186 quot = div / 16; 1187 baud = rate / div; 1188 } else { 1189 quot = (rate + (8 * req_baud)) / (16 * req_baud); 1190 baud = rate / (quot * 16); 1191 } 1192 quot--; 1193 1194 calc_deviation = req_baud - baud; 1195 if (calc_deviation < 0) 1196 calc_deviation = -calc_deviation; 1197 1198 if (calc_deviation < deviation) { 1199 *best_clk = clk; 1200 best_quot = quot; 1201 *clk_num = cnt; 1202 deviation = calc_deviation; 1203 } 1204 } 1205 1206 return best_quot; 1207} 1208 1209/* udivslot_table[] 1210 * 1211 * This table takes the fractional value of the baud divisor and gives 1212 * the recommended setting for the UDIVSLOT register. 1213 */ 1214static u16 udivslot_table[16] = { 1215 [0] = 0x0000, 1216 [1] = 0x0080, 1217 [2] = 0x0808, 1218 [3] = 0x0888, 1219 [4] = 0x2222, 1220 [5] = 0x4924, 1221 [6] = 0x4A52, 1222 [7] = 0x54AA, 1223 [8] = 0x5555, 1224 [9] = 0xD555, 1225 [10] = 0xD5D5, 1226 [11] = 0xDDD5, 1227 [12] = 0xDDDD, 1228 [13] = 0xDFDD, 1229 [14] = 0xDFDF, 1230 [15] = 0xFFDF, 1231}; 1232 1233static void s3c24xx_serial_set_termios(struct uart_port *port, 1234 struct ktermios *termios, 1235 struct ktermios *old) 1236{ 1237 struct s3c2410_uartcfg *cfg = s3c24xx_port_to_cfg(port); 1238 struct s3c24xx_uart_port *ourport = to_ourport(port); 1239 struct clk *clk = ERR_PTR(-EINVAL); 1240 unsigned long flags; 1241 unsigned int baud, quot, clk_sel = 0; 1242 unsigned int ulcon; 1243 unsigned int umcon; 1244 unsigned int udivslot = 0; 1245 1246 /* 1247 * We don't support modem control lines. 1248 */ 1249 termios->c_cflag &= ~(HUPCL | CMSPAR); 1250 termios->c_cflag |= CLOCAL; 1251 1252 /* 1253 * Ask the core to calculate the divisor for us. 1254 */ 1255 1256 baud = uart_get_baud_rate(port, termios, old, 0, 115200*8); 1257 quot = s3c24xx_serial_getclk(ourport, baud, &clk, &clk_sel); 1258 if (baud == 38400 && (port->flags & UPF_SPD_MASK) == UPF_SPD_CUST) 1259 quot = port->custom_divisor; 1260 if (IS_ERR(clk)) 1261 return; 1262 1263 /* check to see if we need to change clock source */ 1264 1265 if (ourport->baudclk != clk) { 1266 s3c24xx_serial_setsource(port, clk_sel); 1267 1268 if (!IS_ERR(ourport->baudclk)) { 1269 clk_disable_unprepare(ourport->baudclk); 1270 ourport->baudclk = ERR_PTR(-EINVAL); 1271 } 1272 1273 clk_prepare_enable(clk); 1274 1275 ourport->baudclk = clk; 1276 ourport->baudclk_rate = clk ? clk_get_rate(clk) : 0; 1277 } 1278 1279 if (ourport->info->has_divslot) { 1280 unsigned int div = ourport->baudclk_rate / baud; 1281 1282 if (cfg->has_fracval) { 1283 udivslot = (div & 15); 1284 dbg("fracval = %04x\n", udivslot); 1285 } else { 1286 udivslot = udivslot_table[div & 15]; 1287 dbg("udivslot = %04x (div %d)\n", udivslot, div & 15); 1288 } 1289 } 1290 1291 switch (termios->c_cflag & CSIZE) { 1292 case CS5: 1293 dbg("config: 5bits/char\n"); 1294 ulcon = S3C2410_LCON_CS5; 1295 break; 1296 case CS6: 1297 dbg("config: 6bits/char\n"); 1298 ulcon = S3C2410_LCON_CS6; 1299 break; 1300 case CS7: 1301 dbg("config: 7bits/char\n"); 1302 ulcon = S3C2410_LCON_CS7; 1303 break; 1304 case CS8: 1305 default: 1306 dbg("config: 8bits/char\n"); 1307 ulcon = S3C2410_LCON_CS8; 1308 break; 1309 } 1310 1311 /* preserve original lcon IR settings */ 1312 ulcon |= (cfg->ulcon & S3C2410_LCON_IRM); 1313 1314 if (termios->c_cflag & CSTOPB) 1315 ulcon |= S3C2410_LCON_STOPB; 1316 1317 if (termios->c_cflag & PARENB) { 1318 if (termios->c_cflag & PARODD) 1319 ulcon |= S3C2410_LCON_PODD; 1320 else 1321 ulcon |= S3C2410_LCON_PEVEN; 1322 } else { 1323 ulcon |= S3C2410_LCON_PNONE; 1324 } 1325 1326 spin_lock_irqsave(&port->lock, flags); 1327 1328 dbg("setting ulcon to %08x, brddiv to %d, udivslot %08x\n", 1329 ulcon, quot, udivslot); 1330 1331 wr_regl(port, S3C2410_ULCON, ulcon); 1332 wr_regl(port, S3C2410_UBRDIV, quot); 1333 1334 umcon = rd_regl(port, S3C2410_UMCON); 1335 if (termios->c_cflag & CRTSCTS) { 1336 umcon |= S3C2410_UMCOM_AFC; 1337 /* Disable RTS when RX FIFO contains 63 bytes */ 1338 umcon &= ~S3C2412_UMCON_AFC_8; 1339 } else { 1340 umcon &= ~S3C2410_UMCOM_AFC; 1341 } 1342 wr_regl(port, S3C2410_UMCON, umcon); 1343 1344 if (ourport->info->has_divslot) 1345 wr_regl(port, S3C2443_DIVSLOT, udivslot); 1346 1347 dbg("uart: ulcon = 0x%08x, ucon = 0x%08x, ufcon = 0x%08x\n", 1348 rd_regl(port, S3C2410_ULCON), 1349 rd_regl(port, S3C2410_UCON), 1350 rd_regl(port, S3C2410_UFCON)); 1351 1352 /* 1353 * Update the per-port timeout. 1354 */ 1355 uart_update_timeout(port, termios->c_cflag, baud); 1356 1357 /* 1358 * Which character status flags are we interested in? 1359 */ 1360 port->read_status_mask = S3C2410_UERSTAT_OVERRUN; 1361 if (termios->c_iflag & INPCK) 1362 port->read_status_mask |= S3C2410_UERSTAT_FRAME | 1363 S3C2410_UERSTAT_PARITY; 1364 /* 1365 * Which character status flags should we ignore? 1366 */ 1367 port->ignore_status_mask = 0; 1368 if (termios->c_iflag & IGNPAR) 1369 port->ignore_status_mask |= S3C2410_UERSTAT_OVERRUN; 1370 if (termios->c_iflag & IGNBRK && termios->c_iflag & IGNPAR) 1371 port->ignore_status_mask |= S3C2410_UERSTAT_FRAME; 1372 1373 /* 1374 * Ignore all characters if CREAD is not set. 1375 */ 1376 if ((termios->c_cflag & CREAD) == 0) 1377 port->ignore_status_mask |= RXSTAT_DUMMY_READ; 1378 1379 spin_unlock_irqrestore(&port->lock, flags); 1380} 1381 1382static const char *s3c24xx_serial_type(struct uart_port *port) 1383{ 1384 switch (port->type) { 1385 case PORT_S3C2410: 1386 return "S3C2410"; 1387 case PORT_S3C2440: 1388 return "S3C2440"; 1389 case PORT_S3C2412: 1390 return "S3C2412"; 1391 case PORT_S3C6400: 1392 return "S3C6400/10"; 1393 default: 1394 return NULL; 1395 } 1396} 1397 1398#define MAP_SIZE (0x100) 1399 1400static void s3c24xx_serial_release_port(struct uart_port *port) 1401{ 1402 release_mem_region(port->mapbase, MAP_SIZE); 1403} 1404 1405static int s3c24xx_serial_request_port(struct uart_port *port) 1406{ 1407 const char *name = s3c24xx_serial_portname(port); 1408 return request_mem_region(port->mapbase, MAP_SIZE, name) ? 0 : -EBUSY; 1409} 1410 1411static void s3c24xx_serial_config_port(struct uart_port *port, int flags) 1412{ 1413 struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port); 1414 1415 if (flags & UART_CONFIG_TYPE && 1416 s3c24xx_serial_request_port(port) == 0) 1417 port->type = info->type; 1418} 1419 1420/* 1421 * verify the new serial_struct (for TIOCSSERIAL). 1422 */ 1423static int 1424s3c24xx_serial_verify_port(struct uart_port *port, struct serial_struct *ser) 1425{ 1426 struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port); 1427 1428 if (ser->type != PORT_UNKNOWN && ser->type != info->type) 1429 return -EINVAL; 1430 1431 return 0; 1432} 1433 1434 1435#ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE 1436 1437static struct console s3c24xx_serial_console; 1438 1439static int __init s3c24xx_serial_console_init(void) 1440{ 1441 register_console(&s3c24xx_serial_console); 1442 return 0; 1443} 1444console_initcall(s3c24xx_serial_console_init); 1445 1446#define S3C24XX_SERIAL_CONSOLE &s3c24xx_serial_console 1447#else 1448#define S3C24XX_SERIAL_CONSOLE NULL 1449#endif 1450 1451#if defined(CONFIG_SERIAL_SAMSUNG_CONSOLE) && defined(CONFIG_CONSOLE_POLL) 1452static int s3c24xx_serial_get_poll_char(struct uart_port *port); 1453static void s3c24xx_serial_put_poll_char(struct uart_port *port, 1454 unsigned char c); 1455#endif 1456 1457static struct uart_ops s3c24xx_serial_ops = { 1458 .pm = s3c24xx_serial_pm, 1459 .tx_empty = s3c24xx_serial_tx_empty, 1460 .get_mctrl = s3c24xx_serial_get_mctrl, 1461 .set_mctrl = s3c24xx_serial_set_mctrl, 1462 .stop_tx = s3c24xx_serial_stop_tx, 1463 .start_tx = s3c24xx_serial_start_tx, 1464 .stop_rx = s3c24xx_serial_stop_rx, 1465 .break_ctl = s3c24xx_serial_break_ctl, 1466 .startup = s3c24xx_serial_startup, 1467 .shutdown = s3c24xx_serial_shutdown, 1468 .set_termios = s3c24xx_serial_set_termios, 1469 .type = s3c24xx_serial_type, 1470 .release_port = s3c24xx_serial_release_port, 1471 .request_port = s3c24xx_serial_request_port, 1472 .config_port = s3c24xx_serial_config_port, 1473 .verify_port = s3c24xx_serial_verify_port, 1474#if defined(CONFIG_SERIAL_SAMSUNG_CONSOLE) && defined(CONFIG_CONSOLE_POLL) 1475 .poll_get_char = s3c24xx_serial_get_poll_char, 1476 .poll_put_char = s3c24xx_serial_put_poll_char, 1477#endif 1478}; 1479 1480static struct uart_driver s3c24xx_uart_drv = { 1481 .owner = THIS_MODULE, 1482 .driver_name = "s3c2410_serial", 1483 .nr = CONFIG_SERIAL_SAMSUNG_UARTS, 1484 .cons = S3C24XX_SERIAL_CONSOLE, 1485 .dev_name = S3C24XX_SERIAL_NAME, 1486 .major = S3C24XX_SERIAL_MAJOR, 1487 .minor = S3C24XX_SERIAL_MINOR, 1488}; 1489 1490#define __PORT_LOCK_UNLOCKED(i) \ 1491 __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[i].port.lock) 1492static struct s3c24xx_uart_port 1493s3c24xx_serial_ports[CONFIG_SERIAL_SAMSUNG_UARTS] = { 1494 [0] = { 1495 .port = { 1496 .lock = __PORT_LOCK_UNLOCKED(0), 1497 .iotype = UPIO_MEM, 1498 .uartclk = 0, 1499 .fifosize = 16, 1500 .ops = &s3c24xx_serial_ops, 1501 .flags = UPF_BOOT_AUTOCONF, 1502 .line = 0, 1503 } 1504 }, 1505 [1] = { 1506 .port = { 1507 .lock = __PORT_LOCK_UNLOCKED(1), 1508 .iotype = UPIO_MEM, 1509 .uartclk = 0, 1510 .fifosize = 16, 1511 .ops = &s3c24xx_serial_ops, 1512 .flags = UPF_BOOT_AUTOCONF, 1513 .line = 1, 1514 } 1515 }, 1516#if CONFIG_SERIAL_SAMSUNG_UARTS > 2 1517 1518 [2] = { 1519 .port = { 1520 .lock = __PORT_LOCK_UNLOCKED(2), 1521 .iotype = UPIO_MEM, 1522 .uartclk = 0, 1523 .fifosize = 16, 1524 .ops = &s3c24xx_serial_ops, 1525 .flags = UPF_BOOT_AUTOCONF, 1526 .line = 2, 1527 } 1528 }, 1529#endif 1530#if CONFIG_SERIAL_SAMSUNG_UARTS > 3 1531 [3] = { 1532 .port = { 1533 .lock = __PORT_LOCK_UNLOCKED(3), 1534 .iotype = UPIO_MEM, 1535 .uartclk = 0, 1536 .fifosize = 16, 1537 .ops = &s3c24xx_serial_ops, 1538 .flags = UPF_BOOT_AUTOCONF, 1539 .line = 3, 1540 } 1541 } 1542#endif 1543}; 1544#undef __PORT_LOCK_UNLOCKED 1545 1546/* s3c24xx_serial_resetport 1547 * 1548 * reset the fifos and other the settings. 1549*/ 1550 1551static void s3c24xx_serial_resetport(struct uart_port *port, 1552 struct s3c2410_uartcfg *cfg) 1553{ 1554 struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port); 1555 unsigned long ucon = rd_regl(port, S3C2410_UCON); 1556 unsigned int ucon_mask; 1557 1558 ucon_mask = info->clksel_mask; 1559 if (info->type == PORT_S3C2440) 1560 ucon_mask |= S3C2440_UCON0_DIVMASK; 1561 1562 ucon &= ucon_mask; 1563 wr_regl(port, S3C2410_UCON, ucon | cfg->ucon); 1564 1565 /* reset both fifos */ 1566 wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH); 1567 wr_regl(port, S3C2410_UFCON, cfg->ufcon); 1568 1569 /* some delay is required after fifo reset */ 1570 udelay(1); 1571} 1572 1573 1574#ifdef CONFIG_CPU_FREQ 1575 1576static int s3c24xx_serial_cpufreq_transition(struct notifier_block *nb, 1577 unsigned long val, void *data) 1578{ 1579 struct s3c24xx_uart_port *port; 1580 struct uart_port *uport; 1581 1582 port = container_of(nb, struct s3c24xx_uart_port, freq_transition); 1583 uport = &port->port; 1584 1585 /* check to see if port is enabled */ 1586 1587 if (port->pm_level != 0) 1588 return 0; 1589 1590 /* try and work out if the baudrate is changing, we can detect 1591 * a change in rate, but we do not have support for detecting 1592 * a disturbance in the clock-rate over the change. 1593 */ 1594 1595 if (IS_ERR(port->baudclk)) 1596 goto exit; 1597 1598 if (port->baudclk_rate == clk_get_rate(port->baudclk)) 1599 goto exit; 1600 1601 if (val == CPUFREQ_PRECHANGE) { 1602 /* we should really shut the port down whilst the 1603 * frequency change is in progress. */ 1604 1605 } else if (val == CPUFREQ_POSTCHANGE) { 1606 struct ktermios *termios; 1607 struct tty_struct *tty; 1608 1609 if (uport->state == NULL) 1610 goto exit; 1611 1612 tty = uport->state->port.tty; 1613 1614 if (tty == NULL) 1615 goto exit; 1616 1617 termios = &tty->termios; 1618 1619 if (termios == NULL) { 1620 dev_warn(uport->dev, "%s: no termios?\n", __func__); 1621 goto exit; 1622 } 1623 1624 s3c24xx_serial_set_termios(uport, termios, NULL); 1625 } 1626 1627exit: 1628 return 0; 1629} 1630 1631static inline int 1632s3c24xx_serial_cpufreq_register(struct s3c24xx_uart_port *port) 1633{ 1634 port->freq_transition.notifier_call = s3c24xx_serial_cpufreq_transition; 1635 1636 return cpufreq_register_notifier(&port->freq_transition, 1637 CPUFREQ_TRANSITION_NOTIFIER); 1638} 1639 1640static inline void 1641s3c24xx_serial_cpufreq_deregister(struct s3c24xx_uart_port *port) 1642{ 1643 cpufreq_unregister_notifier(&port->freq_transition, 1644 CPUFREQ_TRANSITION_NOTIFIER); 1645} 1646 1647#else 1648static inline int 1649s3c24xx_serial_cpufreq_register(struct s3c24xx_uart_port *port) 1650{ 1651 return 0; 1652} 1653 1654static inline void 1655s3c24xx_serial_cpufreq_deregister(struct s3c24xx_uart_port *port) 1656{ 1657} 1658#endif 1659 1660/* s3c24xx_serial_init_port 1661 * 1662 * initialise a single serial port from the platform device given 1663 */ 1664 1665static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport, 1666 struct platform_device *platdev) 1667{ 1668 struct uart_port *port = &ourport->port; 1669 struct s3c2410_uartcfg *cfg = ourport->cfg; 1670 struct resource *res; 1671 int ret; 1672 1673 dbg("s3c24xx_serial_init_port: port=%p, platdev=%p\n", port, platdev); 1674 1675 if (platdev == NULL) 1676 return -ENODEV; 1677 1678 if (port->mapbase != 0) 1679 return 0; 1680 1681 /* setup info for port */ 1682 port->dev = &platdev->dev; 1683 1684 /* Startup sequence is different for s3c64xx and higher SoC's */ 1685 if (s3c24xx_serial_has_interrupt_mask(port)) 1686 s3c24xx_serial_ops.startup = s3c64xx_serial_startup; 1687 1688 port->uartclk = 1; 1689 1690 if (cfg->uart_flags & UPF_CONS_FLOW) { 1691 dbg("s3c24xx_serial_init_port: enabling flow control\n"); 1692 port->flags |= UPF_CONS_FLOW; 1693 } 1694 1695 /* sort our the physical and virtual addresses for each UART */ 1696 1697 res = platform_get_resource(platdev, IORESOURCE_MEM, 0); 1698 if (res == NULL) { 1699 dev_err(port->dev, "failed to find memory resource for uart\n"); 1700 return -EINVAL; 1701 } 1702 1703 dbg("resource %pR)\n", res); 1704 1705 port->membase = devm_ioremap(port->dev, res->start, resource_size(res)); 1706 if (!port->membase) { 1707 dev_err(port->dev, "failed to remap controller address\n"); 1708 return -EBUSY; 1709 } 1710 1711 port->mapbase = res->start; 1712 ret = platform_get_irq(platdev, 0); 1713 if (ret < 0) 1714 port->irq = 0; 1715 else { 1716 port->irq = ret; 1717 ourport->rx_irq = ret; 1718 ourport->tx_irq = ret + 1; 1719 } 1720 1721 ret = platform_get_irq(platdev, 1); 1722 if (ret > 0) 1723 ourport->tx_irq = ret; 1724 /* 1725 * DMA is currently supported only on DT platforms, if DMA properties 1726 * are specified. 1727 */ 1728 if (platdev->dev.of_node && of_find_property(platdev->dev.of_node, 1729 "dmas", NULL)) { 1730 ourport->dma = devm_kzalloc(port->dev, 1731 sizeof(*ourport->dma), 1732 GFP_KERNEL); 1733 if (!ourport->dma) 1734 return -ENOMEM; 1735 } 1736 1737 ourport->clk = clk_get(&platdev->dev, "uart"); 1738 if (IS_ERR(ourport->clk)) { 1739 pr_err("%s: Controller clock not found\n", 1740 dev_name(&platdev->dev)); 1741 return PTR_ERR(ourport->clk); 1742 } 1743 1744 ret = clk_prepare_enable(ourport->clk); 1745 if (ret) { 1746 pr_err("uart: clock failed to prepare+enable: %d\n", ret); 1747 clk_put(ourport->clk); 1748 return ret; 1749 } 1750 1751 /* Keep all interrupts masked and cleared */ 1752 if (s3c24xx_serial_has_interrupt_mask(port)) { 1753 wr_regl(port, S3C64XX_UINTM, 0xf); 1754 wr_regl(port, S3C64XX_UINTP, 0xf); 1755 wr_regl(port, S3C64XX_UINTSP, 0xf); 1756 } 1757 1758 dbg("port: map=%pa, mem=%p, irq=%d (%d,%d), clock=%u\n", 1759 &port->mapbase, port->membase, port->irq, 1760 ourport->rx_irq, ourport->tx_irq, port->uartclk); 1761 1762 /* reset the fifos (and setup the uart) */ 1763 s3c24xx_serial_resetport(port, cfg); 1764 return 0; 1765} 1766 1767/* Device driver serial port probe */ 1768 1769static const struct of_device_id s3c24xx_uart_dt_match[]; 1770static int probe_index; 1771 1772static inline struct s3c24xx_serial_drv_data *s3c24xx_get_driver_data( 1773 struct platform_device *pdev) 1774{ 1775#ifdef CONFIG_OF 1776 if (pdev->dev.of_node) { 1777 const struct of_device_id *match; 1778 match = of_match_node(s3c24xx_uart_dt_match, pdev->dev.of_node); 1779 return (struct s3c24xx_serial_drv_data *)match->data; 1780 } 1781#endif 1782 return (struct s3c24xx_serial_drv_data *) 1783 platform_get_device_id(pdev)->driver_data; 1784} 1785 1786static int s3c24xx_serial_probe(struct platform_device *pdev) 1787{ 1788 struct device_node *np = pdev->dev.of_node; 1789 struct s3c24xx_uart_port *ourport; 1790 int index = probe_index; 1791 int ret; 1792 1793 if (np) { 1794 ret = of_alias_get_id(np, "serial"); 1795 if (ret >= 0) 1796 index = ret; 1797 } 1798 1799 dbg("s3c24xx_serial_probe(%p) %d\n", pdev, index); 1800 1801 ourport = &s3c24xx_serial_ports[index]; 1802 1803 ourport->drv_data = s3c24xx_get_driver_data(pdev); 1804 if (!ourport->drv_data) { 1805 dev_err(&pdev->dev, "could not find driver data\n"); 1806 return -ENODEV; 1807 } 1808 1809 ourport->baudclk = ERR_PTR(-EINVAL); 1810 ourport->info = ourport->drv_data->info; 1811 ourport->cfg = (dev_get_platdata(&pdev->dev)) ? 1812 dev_get_platdata(&pdev->dev) : 1813 ourport->drv_data->def_cfg; 1814 1815 if (np) 1816 of_property_read_u32(np, 1817 "samsung,uart-fifosize", &ourport->port.fifosize); 1818 1819 if (ourport->drv_data->fifosize[index]) 1820 ourport->port.fifosize = ourport->drv_data->fifosize[index]; 1821 else if (ourport->info->fifosize) 1822 ourport->port.fifosize = ourport->info->fifosize; 1823 1824 /* 1825 * DMA transfers must be aligned at least to cache line size, 1826 * so find minimal transfer size suitable for DMA mode 1827 */ 1828 ourport->min_dma_size = max_t(int, ourport->port.fifosize, 1829 dma_get_cache_alignment()); 1830 1831 probe_index++; 1832 1833 dbg("%s: initialising port %p...\n", __func__, ourport); 1834 1835 ret = s3c24xx_serial_init_port(ourport, pdev); 1836 if (ret < 0) 1837 return ret; 1838 1839 if (!s3c24xx_uart_drv.state) { 1840 ret = uart_register_driver(&s3c24xx_uart_drv); 1841 if (ret < 0) { 1842 pr_err("Failed to register Samsung UART driver\n"); 1843 return ret; 1844 } 1845 } 1846 1847 dbg("%s: adding port\n", __func__); 1848 uart_add_one_port(&s3c24xx_uart_drv, &ourport->port); 1849 platform_set_drvdata(pdev, &ourport->port); 1850 1851 /* 1852 * Deactivate the clock enabled in s3c24xx_serial_init_port here, 1853 * so that a potential re-enablement through the pm-callback overlaps 1854 * and keeps the clock enabled in this case. 1855 */ 1856 clk_disable_unprepare(ourport->clk); 1857 1858 ret = s3c24xx_serial_cpufreq_register(ourport); 1859 if (ret < 0) 1860 dev_err(&pdev->dev, "failed to add cpufreq notifier\n"); 1861 1862 return 0; 1863} 1864 1865static int s3c24xx_serial_remove(struct platform_device *dev) 1866{ 1867 struct uart_port *port = s3c24xx_dev_to_port(&dev->dev); 1868 1869 if (port) { 1870 s3c24xx_serial_cpufreq_deregister(to_ourport(port)); 1871 uart_remove_one_port(&s3c24xx_uart_drv, port); 1872 } 1873 1874 uart_unregister_driver(&s3c24xx_uart_drv); 1875 1876 return 0; 1877} 1878 1879/* UART power management code */ 1880#ifdef CONFIG_PM_SLEEP 1881static int s3c24xx_serial_suspend(struct device *dev) 1882{ 1883 struct uart_port *port = s3c24xx_dev_to_port(dev); 1884 1885 if (port) 1886 uart_suspend_port(&s3c24xx_uart_drv, port); 1887 1888 return 0; 1889} 1890 1891static int s3c24xx_serial_resume(struct device *dev) 1892{ 1893 struct uart_port *port = s3c24xx_dev_to_port(dev); 1894 struct s3c24xx_uart_port *ourport = to_ourport(port); 1895 1896 if (port) { 1897 clk_prepare_enable(ourport->clk); 1898 s3c24xx_serial_resetport(port, s3c24xx_port_to_cfg(port)); 1899 clk_disable_unprepare(ourport->clk); 1900 1901 uart_resume_port(&s3c24xx_uart_drv, port); 1902 } 1903 1904 return 0; 1905} 1906 1907static int s3c24xx_serial_resume_noirq(struct device *dev) 1908{ 1909 struct uart_port *port = s3c24xx_dev_to_port(dev); 1910 1911 if (port) { 1912 /* restore IRQ mask */ 1913 if (s3c24xx_serial_has_interrupt_mask(port)) { 1914 unsigned int uintm = 0xf; 1915 if (tx_enabled(port)) 1916 uintm &= ~S3C64XX_UINTM_TXD_MSK; 1917 if (rx_enabled(port)) 1918 uintm &= ~S3C64XX_UINTM_RXD_MSK; 1919 wr_regl(port, S3C64XX_UINTM, uintm); 1920 } 1921 } 1922 1923 return 0; 1924} 1925 1926static const struct dev_pm_ops s3c24xx_serial_pm_ops = { 1927 .suspend = s3c24xx_serial_suspend, 1928 .resume = s3c24xx_serial_resume, 1929 .resume_noirq = s3c24xx_serial_resume_noirq, 1930}; 1931#define SERIAL_SAMSUNG_PM_OPS (&s3c24xx_serial_pm_ops) 1932 1933#else /* !CONFIG_PM_SLEEP */ 1934 1935#define SERIAL_SAMSUNG_PM_OPS NULL 1936#endif /* CONFIG_PM_SLEEP */ 1937 1938/* Console code */ 1939 1940#ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE 1941 1942static struct uart_port *cons_uart; 1943 1944static int 1945s3c24xx_serial_console_txrdy(struct uart_port *port, unsigned int ufcon) 1946{ 1947 struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port); 1948 unsigned long ufstat, utrstat; 1949 1950 if (ufcon & S3C2410_UFCON_FIFOMODE) { 1951 /* fifo mode - check amount of data in fifo registers... */ 1952 1953 ufstat = rd_regl(port, S3C2410_UFSTAT); 1954 return (ufstat & info->tx_fifofull) ? 0 : 1; 1955 } 1956 1957 /* in non-fifo mode, we go and use the tx buffer empty */ 1958 1959 utrstat = rd_regl(port, S3C2410_UTRSTAT); 1960 return (utrstat & S3C2410_UTRSTAT_TXE) ? 1 : 0; 1961} 1962 1963static bool 1964s3c24xx_port_configured(unsigned int ucon) 1965{ 1966 /* consider the serial port configured if the tx/rx mode set */ 1967 return (ucon & 0xf) != 0; 1968} 1969 1970#ifdef CONFIG_CONSOLE_POLL 1971/* 1972 * Console polling routines for writing and reading from the uart while 1973 * in an interrupt or debug context. 1974 */ 1975 1976static int s3c24xx_serial_get_poll_char(struct uart_port *port) 1977{ 1978 struct s3c24xx_uart_port *ourport = to_ourport(port); 1979 unsigned int ufstat; 1980 1981 ufstat = rd_regl(port, S3C2410_UFSTAT); 1982 if (s3c24xx_serial_rx_fifocnt(ourport, ufstat) == 0) 1983 return NO_POLL_CHAR; 1984 1985 return rd_regb(port, S3C2410_URXH); 1986} 1987 1988static void s3c24xx_serial_put_poll_char(struct uart_port *port, 1989 unsigned char c) 1990{ 1991 unsigned int ufcon = rd_regl(port, S3C2410_UFCON); 1992 unsigned int ucon = rd_regl(port, S3C2410_UCON); 1993 1994 /* not possible to xmit on unconfigured port */ 1995 if (!s3c24xx_port_configured(ucon)) 1996 return; 1997 1998 while (!s3c24xx_serial_console_txrdy(port, ufcon)) 1999 cpu_relax(); 2000 wr_regb(port, S3C2410_UTXH, c); 2001} 2002 2003#endif /* CONFIG_CONSOLE_POLL */ 2004 2005static void 2006s3c24xx_serial_console_putchar(struct uart_port *port, int ch) 2007{ 2008 unsigned int ufcon = rd_regl(port, S3C2410_UFCON); 2009 2010 while (!s3c24xx_serial_console_txrdy(port, ufcon)) 2011 cpu_relax(); 2012 wr_regb(port, S3C2410_UTXH, ch); 2013} 2014 2015static void 2016s3c24xx_serial_console_write(struct console *co, const char *s, 2017 unsigned int count) 2018{ 2019 unsigned int ucon = rd_regl(cons_uart, S3C2410_UCON); 2020 2021 /* not possible to xmit on unconfigured port */ 2022 if (!s3c24xx_port_configured(ucon)) 2023 return; 2024 2025 uart_console_write(cons_uart, s, count, s3c24xx_serial_console_putchar); 2026} 2027 2028static void __init 2029s3c24xx_serial_get_options(struct uart_port *port, int *baud, 2030 int *parity, int *bits) 2031{ 2032 struct clk *clk; 2033 unsigned int ulcon; 2034 unsigned int ucon; 2035 unsigned int ubrdiv; 2036 unsigned long rate; 2037 unsigned int clk_sel; 2038 char clk_name[MAX_CLK_NAME_LENGTH]; 2039 2040 ulcon = rd_regl(port, S3C2410_ULCON); 2041 ucon = rd_regl(port, S3C2410_UCON); 2042 ubrdiv = rd_regl(port, S3C2410_UBRDIV); 2043 2044 dbg("s3c24xx_serial_get_options: port=%p\n" 2045 "registers: ulcon=%08x, ucon=%08x, ubdriv=%08x\n", 2046 port, ulcon, ucon, ubrdiv); 2047 2048 if (s3c24xx_port_configured(ucon)) { 2049 switch (ulcon & S3C2410_LCON_CSMASK) { 2050 case S3C2410_LCON_CS5: 2051 *bits = 5; 2052 break; 2053 case S3C2410_LCON_CS6: 2054 *bits = 6; 2055 break; 2056 case S3C2410_LCON_CS7: 2057 *bits = 7; 2058 break; 2059 case S3C2410_LCON_CS8: 2060 default: 2061 *bits = 8; 2062 break; 2063 } 2064 2065 switch (ulcon & S3C2410_LCON_PMASK) { 2066 case S3C2410_LCON_PEVEN: 2067 *parity = 'e'; 2068 break; 2069 2070 case S3C2410_LCON_PODD: 2071 *parity = 'o'; 2072 break; 2073 2074 case S3C2410_LCON_PNONE: 2075 default: 2076 *parity = 'n'; 2077 } 2078 2079 /* now calculate the baud rate */ 2080 2081 clk_sel = s3c24xx_serial_getsource(port); 2082 sprintf(clk_name, "clk_uart_baud%d", clk_sel); 2083 2084 clk = clk_get(port->dev, clk_name); 2085 if (!IS_ERR(clk)) 2086 rate = clk_get_rate(clk); 2087 else 2088 rate = 1; 2089 2090 *baud = rate / (16 * (ubrdiv + 1)); 2091 dbg("calculated baud %d\n", *baud); 2092 } 2093 2094} 2095 2096static int __init 2097s3c24xx_serial_console_setup(struct console *co, char *options) 2098{ 2099 struct uart_port *port; 2100 int baud = 9600; 2101 int bits = 8; 2102 int parity = 'n'; 2103 int flow = 'n'; 2104 2105 dbg("s3c24xx_serial_console_setup: co=%p (%d), %s\n", 2106 co, co->index, options); 2107 2108 /* is this a valid port */ 2109 2110 if (co->index == -1 || co->index >= CONFIG_SERIAL_SAMSUNG_UARTS) 2111 co->index = 0; 2112 2113 port = &s3c24xx_serial_ports[co->index].port; 2114 2115 /* is the port configured? */ 2116 2117 if (port->mapbase == 0x0) 2118 return -ENODEV; 2119 2120 cons_uart = port; 2121 2122 dbg("s3c24xx_serial_console_setup: port=%p (%d)\n", port, co->index); 2123 2124 /* 2125 * Check whether an invalid uart number has been specified, and 2126 * if so, search for the first available port that does have 2127 * console support. 2128 */ 2129 if (options) 2130 uart_parse_options(options, &baud, &parity, &bits, &flow); 2131 else 2132 s3c24xx_serial_get_options(port, &baud, &parity, &bits); 2133 2134 dbg("s3c24xx_serial_console_setup: baud %d\n", baud); 2135 2136 return uart_set_options(port, co, baud, parity, bits, flow); 2137} 2138 2139static struct console s3c24xx_serial_console = { 2140 .name = S3C24XX_SERIAL_NAME, 2141 .device = uart_console_device, 2142 .flags = CON_PRINTBUFFER, 2143 .index = -1, 2144 .write = s3c24xx_serial_console_write, 2145 .setup = s3c24xx_serial_console_setup, 2146 .data = &s3c24xx_uart_drv, 2147}; 2148#endif /* CONFIG_SERIAL_SAMSUNG_CONSOLE */ 2149 2150#ifdef CONFIG_CPU_S3C2410 2151static struct s3c24xx_serial_drv_data s3c2410_serial_drv_data = { 2152 .info = &(struct s3c24xx_uart_info) { 2153 .name = "Samsung S3C2410 UART", 2154 .type = PORT_S3C2410, 2155 .fifosize = 16, 2156 .rx_fifomask = S3C2410_UFSTAT_RXMASK, 2157 .rx_fifoshift = S3C2410_UFSTAT_RXSHIFT, 2158 .rx_fifofull = S3C2410_UFSTAT_RXFULL, 2159 .tx_fifofull = S3C2410_UFSTAT_TXFULL, 2160 .tx_fifomask = S3C2410_UFSTAT_TXMASK, 2161 .tx_fifoshift = S3C2410_UFSTAT_TXSHIFT, 2162 .def_clk_sel = S3C2410_UCON_CLKSEL0, 2163 .num_clks = 2, 2164 .clksel_mask = S3C2410_UCON_CLKMASK, 2165 .clksel_shift = S3C2410_UCON_CLKSHIFT, 2166 }, 2167 .def_cfg = &(struct s3c2410_uartcfg) { 2168 .ucon = S3C2410_UCON_DEFAULT, 2169 .ufcon = S3C2410_UFCON_DEFAULT, 2170 }, 2171}; 2172#define S3C2410_SERIAL_DRV_DATA ((kernel_ulong_t)&s3c2410_serial_drv_data) 2173#else 2174#define S3C2410_SERIAL_DRV_DATA (kernel_ulong_t)NULL 2175#endif 2176 2177#ifdef CONFIG_CPU_S3C2412 2178static struct s3c24xx_serial_drv_data s3c2412_serial_drv_data = { 2179 .info = &(struct s3c24xx_uart_info) { 2180 .name = "Samsung S3C2412 UART", 2181 .type = PORT_S3C2412, 2182 .fifosize = 64, 2183 .has_divslot = 1, 2184 .rx_fifomask = S3C2440_UFSTAT_RXMASK, 2185 .rx_fifoshift = S3C2440_UFSTAT_RXSHIFT, 2186 .rx_fifofull = S3C2440_UFSTAT_RXFULL, 2187 .tx_fifofull = S3C2440_UFSTAT_TXFULL, 2188 .tx_fifomask = S3C2440_UFSTAT_TXMASK, 2189 .tx_fifoshift = S3C2440_UFSTAT_TXSHIFT, 2190 .def_clk_sel = S3C2410_UCON_CLKSEL2, 2191 .num_clks = 4, 2192 .clksel_mask = S3C2412_UCON_CLKMASK, 2193 .clksel_shift = S3C2412_UCON_CLKSHIFT, 2194 }, 2195 .def_cfg = &(struct s3c2410_uartcfg) { 2196 .ucon = S3C2410_UCON_DEFAULT, 2197 .ufcon = S3C2410_UFCON_DEFAULT, 2198 }, 2199}; 2200#define S3C2412_SERIAL_DRV_DATA ((kernel_ulong_t)&s3c2412_serial_drv_data) 2201#else 2202#define S3C2412_SERIAL_DRV_DATA (kernel_ulong_t)NULL 2203#endif 2204 2205#if defined(CONFIG_CPU_S3C2440) || defined(CONFIG_CPU_S3C2416) || \ 2206 defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2442) 2207static struct s3c24xx_serial_drv_data s3c2440_serial_drv_data = { 2208 .info = &(struct s3c24xx_uart_info) { 2209 .name = "Samsung S3C2440 UART", 2210 .type = PORT_S3C2440, 2211 .fifosize = 64, 2212 .has_divslot = 1, 2213 .rx_fifomask = S3C2440_UFSTAT_RXMASK, 2214 .rx_fifoshift = S3C2440_UFSTAT_RXSHIFT, 2215 .rx_fifofull = S3C2440_UFSTAT_RXFULL, 2216 .tx_fifofull = S3C2440_UFSTAT_TXFULL, 2217 .tx_fifomask = S3C2440_UFSTAT_TXMASK, 2218 .tx_fifoshift = S3C2440_UFSTAT_TXSHIFT, 2219 .def_clk_sel = S3C2410_UCON_CLKSEL2, 2220 .num_clks = 4, 2221 .clksel_mask = S3C2412_UCON_CLKMASK, 2222 .clksel_shift = S3C2412_UCON_CLKSHIFT, 2223 }, 2224 .def_cfg = &(struct s3c2410_uartcfg) { 2225 .ucon = S3C2410_UCON_DEFAULT, 2226 .ufcon = S3C2410_UFCON_DEFAULT, 2227 }, 2228}; 2229#define S3C2440_SERIAL_DRV_DATA ((kernel_ulong_t)&s3c2440_serial_drv_data) 2230#else 2231#define S3C2440_SERIAL_DRV_DATA (kernel_ulong_t)NULL 2232#endif 2233 2234#if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410) 2235static struct s3c24xx_serial_drv_data s3c6400_serial_drv_data = { 2236 .info = &(struct s3c24xx_uart_info) { 2237 .name = "Samsung S3C6400 UART", 2238 .type = PORT_S3C6400, 2239 .fifosize = 64, 2240 .has_divslot = 1, 2241 .rx_fifomask = S3C2440_UFSTAT_RXMASK, 2242 .rx_fifoshift = S3C2440_UFSTAT_RXSHIFT, 2243 .rx_fifofull = S3C2440_UFSTAT_RXFULL, 2244 .tx_fifofull = S3C2440_UFSTAT_TXFULL, 2245 .tx_fifomask = S3C2440_UFSTAT_TXMASK, 2246 .tx_fifoshift = S3C2440_UFSTAT_TXSHIFT, 2247 .def_clk_sel = S3C2410_UCON_CLKSEL2, 2248 .num_clks = 4, 2249 .clksel_mask = S3C6400_UCON_CLKMASK, 2250 .clksel_shift = S3C6400_UCON_CLKSHIFT, 2251 }, 2252 .def_cfg = &(struct s3c2410_uartcfg) { 2253 .ucon = S3C2410_UCON_DEFAULT, 2254 .ufcon = S3C2410_UFCON_DEFAULT, 2255 }, 2256}; 2257#define S3C6400_SERIAL_DRV_DATA ((kernel_ulong_t)&s3c6400_serial_drv_data) 2258#else 2259#define S3C6400_SERIAL_DRV_DATA (kernel_ulong_t)NULL 2260#endif 2261 2262#ifdef CONFIG_CPU_S5PV210 2263static struct s3c24xx_serial_drv_data s5pv210_serial_drv_data = { 2264 .info = &(struct s3c24xx_uart_info) { 2265 .name = "Samsung S5PV210 UART", 2266 .type = PORT_S3C6400, 2267 .has_divslot = 1, 2268 .rx_fifomask = S5PV210_UFSTAT_RXMASK, 2269 .rx_fifoshift = S5PV210_UFSTAT_RXSHIFT, 2270 .rx_fifofull = S5PV210_UFSTAT_RXFULL, 2271 .tx_fifofull = S5PV210_UFSTAT_TXFULL, 2272 .tx_fifomask = S5PV210_UFSTAT_TXMASK, 2273 .tx_fifoshift = S5PV210_UFSTAT_TXSHIFT, 2274 .def_clk_sel = S3C2410_UCON_CLKSEL0, 2275 .num_clks = 2, 2276 .clksel_mask = S5PV210_UCON_CLKMASK, 2277 .clksel_shift = S5PV210_UCON_CLKSHIFT, 2278 }, 2279 .def_cfg = &(struct s3c2410_uartcfg) { 2280 .ucon = S5PV210_UCON_DEFAULT, 2281 .ufcon = S5PV210_UFCON_DEFAULT, 2282 }, 2283 .fifosize = { 256, 64, 16, 16 }, 2284}; 2285#define S5PV210_SERIAL_DRV_DATA ((kernel_ulong_t)&s5pv210_serial_drv_data) 2286#else 2287#define S5PV210_SERIAL_DRV_DATA (kernel_ulong_t)NULL 2288#endif 2289 2290#if defined(CONFIG_ARCH_EXYNOS) 2291#define EXYNOS_COMMON_SERIAL_DRV_DATA \ 2292 .info = &(struct s3c24xx_uart_info) { \ 2293 .name = "Samsung Exynos UART", \ 2294 .type = PORT_S3C6400, \ 2295 .has_divslot = 1, \ 2296 .rx_fifomask = S5PV210_UFSTAT_RXMASK, \ 2297 .rx_fifoshift = S5PV210_UFSTAT_RXSHIFT, \ 2298 .rx_fifofull = S5PV210_UFSTAT_RXFULL, \ 2299 .tx_fifofull = S5PV210_UFSTAT_TXFULL, \ 2300 .tx_fifomask = S5PV210_UFSTAT_TXMASK, \ 2301 .tx_fifoshift = S5PV210_UFSTAT_TXSHIFT, \ 2302 .def_clk_sel = S3C2410_UCON_CLKSEL0, \ 2303 .num_clks = 1, \ 2304 .clksel_mask = 0, \ 2305 .clksel_shift = 0, \ 2306 }, \ 2307 .def_cfg = &(struct s3c2410_uartcfg) { \ 2308 .ucon = S5PV210_UCON_DEFAULT, \ 2309 .ufcon = S5PV210_UFCON_DEFAULT, \ 2310 .has_fracval = 1, \ 2311 } \ 2312 2313static struct s3c24xx_serial_drv_data exynos4210_serial_drv_data = { 2314 EXYNOS_COMMON_SERIAL_DRV_DATA, 2315 .fifosize = { 256, 64, 16, 16 }, 2316}; 2317 2318static struct s3c24xx_serial_drv_data exynos5433_serial_drv_data = { 2319 EXYNOS_COMMON_SERIAL_DRV_DATA, 2320 .fifosize = { 64, 256, 16, 256 }, 2321}; 2322 2323#define EXYNOS4210_SERIAL_DRV_DATA ((kernel_ulong_t)&exynos4210_serial_drv_data) 2324#define EXYNOS5433_SERIAL_DRV_DATA ((kernel_ulong_t)&exynos5433_serial_drv_data) 2325#else 2326#define EXYNOS4210_SERIAL_DRV_DATA (kernel_ulong_t)NULL 2327#define EXYNOS5433_SERIAL_DRV_DATA (kernel_ulong_t)NULL 2328#endif 2329 2330static const struct platform_device_id s3c24xx_serial_driver_ids[] = { 2331 { 2332 .name = "s3c2410-uart", 2333 .driver_data = S3C2410_SERIAL_DRV_DATA, 2334 }, { 2335 .name = "s3c2412-uart", 2336 .driver_data = S3C2412_SERIAL_DRV_DATA, 2337 }, { 2338 .name = "s3c2440-uart", 2339 .driver_data = S3C2440_SERIAL_DRV_DATA, 2340 }, { 2341 .name = "s3c6400-uart", 2342 .driver_data = S3C6400_SERIAL_DRV_DATA, 2343 }, { 2344 .name = "s5pv210-uart", 2345 .driver_data = S5PV210_SERIAL_DRV_DATA, 2346 }, { 2347 .name = "exynos4210-uart", 2348 .driver_data = EXYNOS4210_SERIAL_DRV_DATA, 2349 }, { 2350 .name = "exynos5433-uart", 2351 .driver_data = EXYNOS5433_SERIAL_DRV_DATA, 2352 }, 2353 { }, 2354}; 2355MODULE_DEVICE_TABLE(platform, s3c24xx_serial_driver_ids); 2356 2357#ifdef CONFIG_OF 2358static const struct of_device_id s3c24xx_uart_dt_match[] = { 2359 { .compatible = "samsung,s3c2410-uart", 2360 .data = (void *)S3C2410_SERIAL_DRV_DATA }, 2361 { .compatible = "samsung,s3c2412-uart", 2362 .data = (void *)S3C2412_SERIAL_DRV_DATA }, 2363 { .compatible = "samsung,s3c2440-uart", 2364 .data = (void *)S3C2440_SERIAL_DRV_DATA }, 2365 { .compatible = "samsung,s3c6400-uart", 2366 .data = (void *)S3C6400_SERIAL_DRV_DATA }, 2367 { .compatible = "samsung,s5pv210-uart", 2368 .data = (void *)S5PV210_SERIAL_DRV_DATA }, 2369 { .compatible = "samsung,exynos4210-uart", 2370 .data = (void *)EXYNOS4210_SERIAL_DRV_DATA }, 2371 { .compatible = "samsung,exynos5433-uart", 2372 .data = (void *)EXYNOS5433_SERIAL_DRV_DATA }, 2373 {}, 2374}; 2375MODULE_DEVICE_TABLE(of, s3c24xx_uart_dt_match); 2376#endif 2377 2378static struct platform_driver samsung_serial_driver = { 2379 .probe = s3c24xx_serial_probe, 2380 .remove = s3c24xx_serial_remove, 2381 .id_table = s3c24xx_serial_driver_ids, 2382 .driver = { 2383 .name = "samsung-uart", 2384 .pm = SERIAL_SAMSUNG_PM_OPS, 2385 .of_match_table = of_match_ptr(s3c24xx_uart_dt_match), 2386 }, 2387}; 2388 2389module_platform_driver(samsung_serial_driver); 2390 2391#ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE 2392/* 2393 * Early console. 2394 */ 2395 2396struct samsung_early_console_data { 2397 u32 txfull_mask; 2398}; 2399 2400static void samsung_early_busyuart(struct uart_port *port) 2401{ 2402 while (!(readl(port->membase + S3C2410_UTRSTAT) & S3C2410_UTRSTAT_TXFE)) 2403 ; 2404} 2405 2406static void samsung_early_busyuart_fifo(struct uart_port *port) 2407{ 2408 struct samsung_early_console_data *data = port->private_data; 2409 2410 while (readl(port->membase + S3C2410_UFSTAT) & data->txfull_mask) 2411 ; 2412} 2413 2414static void samsung_early_putc(struct uart_port *port, int c) 2415{ 2416 if (readl(port->membase + S3C2410_UFCON) & S3C2410_UFCON_FIFOMODE) 2417 samsung_early_busyuart_fifo(port); 2418 else 2419 samsung_early_busyuart(port); 2420 2421 writeb(c, port->membase + S3C2410_UTXH); 2422} 2423 2424static void samsung_early_write(struct console *con, const char *s, unsigned n) 2425{ 2426 struct earlycon_device *dev = con->data; 2427 2428 uart_console_write(&dev->port, s, n, samsung_early_putc); 2429} 2430 2431static int __init samsung_early_console_setup(struct earlycon_device *device, 2432 const char *opt) 2433{ 2434 if (!device->port.membase) 2435 return -ENODEV; 2436 2437 device->con->write = samsung_early_write; 2438 return 0; 2439} 2440 2441/* S3C2410 */ 2442static struct samsung_early_console_data s3c2410_early_console_data = { 2443 .txfull_mask = S3C2410_UFSTAT_TXFULL, 2444}; 2445 2446static int __init s3c2410_early_console_setup(struct earlycon_device *device, 2447 const char *opt) 2448{ 2449 device->port.private_data = &s3c2410_early_console_data; 2450 return samsung_early_console_setup(device, opt); 2451} 2452OF_EARLYCON_DECLARE(s3c2410, "samsung,s3c2410-uart", 2453 s3c2410_early_console_setup); 2454EARLYCON_DECLARE(s3c2410, s3c2410_early_console_setup); 2455 2456/* S3C2412, S3C2440, S3C64xx */ 2457static struct samsung_early_console_data s3c2440_early_console_data = { 2458 .txfull_mask = S3C2440_UFSTAT_TXFULL, 2459}; 2460 2461static int __init s3c2440_early_console_setup(struct earlycon_device *device, 2462 const char *opt) 2463{ 2464 device->port.private_data = &s3c2440_early_console_data; 2465 return samsung_early_console_setup(device, opt); 2466} 2467OF_EARLYCON_DECLARE(s3c2412, "samsung,s3c2412-uart", 2468 s3c2440_early_console_setup); 2469OF_EARLYCON_DECLARE(s3c2440, "samsung,s3c2440-uart", 2470 s3c2440_early_console_setup); 2471OF_EARLYCON_DECLARE(s3c6400, "samsung,s3c6400-uart", 2472 s3c2440_early_console_setup); 2473EARLYCON_DECLARE(s3c2412, s3c2440_early_console_setup); 2474EARLYCON_DECLARE(s3c2440, s3c2440_early_console_setup); 2475EARLYCON_DECLARE(s3c6400, s3c2440_early_console_setup); 2476 2477/* S5PV210, EXYNOS */ 2478static struct samsung_early_console_data s5pv210_early_console_data = { 2479 .txfull_mask = S5PV210_UFSTAT_TXFULL, 2480}; 2481 2482static int __init s5pv210_early_console_setup(struct earlycon_device *device, 2483 const char *opt) 2484{ 2485 device->port.private_data = &s5pv210_early_console_data; 2486 return samsung_early_console_setup(device, opt); 2487} 2488OF_EARLYCON_DECLARE(s5pv210, "samsung,s5pv210-uart", 2489 s5pv210_early_console_setup); 2490OF_EARLYCON_DECLARE(exynos4210, "samsung,exynos4210-uart", 2491 s5pv210_early_console_setup); 2492EARLYCON_DECLARE(s5pv210, s5pv210_early_console_setup); 2493EARLYCON_DECLARE(exynos4210, s5pv210_early_console_setup); 2494#endif 2495 2496MODULE_ALIAS("platform:samsung-uart"); 2497MODULE_DESCRIPTION("Samsung SoC Serial port driver"); 2498MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); 2499MODULE_LICENSE("GPL v2");