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