1// SPDX-License-Identifier: GPL-2.0 2/* 3 * UART driver for PNX8XXX SoCs 4 * 5 * Author: Per Hallsmark per.hallsmark@mvista.com 6 * Ported to 2.6 kernel by EmbeddedAlley 7 * Reworked by Vitaly Wool <vitalywool@gmail.com> 8 * 9 * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o. 10 * Copyright (C) 2000 Deep Blue Solutions Ltd. 11 */ 12 13#include <linux/module.h> 14#include <linux/ioport.h> 15#include <linux/init.h> 16#include <linux/console.h> 17#include <linux/sysrq.h> 18#include <linux/device.h> 19#include <linux/platform_device.h> 20#include <linux/tty.h> 21#include <linux/tty_flip.h> 22#include <linux/serial_core.h> 23#include <linux/serial.h> 24#include <linux/serial_pnx8xxx.h> 25 26#include <asm/io.h> 27#include <asm/irq.h> 28 29/* We'll be using StrongARM sa1100 serial port major/minor */ 30#define SERIAL_PNX8XXX_MAJOR 204 31#define MINOR_START 5 32 33#define NR_PORTS 2 34 35#define PNX8XXX_ISR_PASS_LIMIT 256 36 37/* 38 * Convert from ignore_status_mask or read_status_mask to FIFO 39 * and interrupt status bits 40 */ 41#define SM_TO_FIFO(x) ((x) >> 10) 42#define SM_TO_ISTAT(x) ((x) & 0x000001ff) 43#define FIFO_TO_SM(x) ((x) << 10) 44#define ISTAT_TO_SM(x) ((x) & 0x000001ff) 45 46/* 47 * This is the size of our serial port register set. 48 */ 49#define UART_PORT_SIZE 0x1000 50 51/* 52 * This determines how often we check the modem status signals 53 * for any change. They generally aren't connected to an IRQ 54 * so we have to poll them. We also check immediately before 55 * filling the TX fifo incase CTS has been dropped. 56 */ 57#define MCTRL_TIMEOUT (250*HZ/1000) 58 59extern struct pnx8xxx_port pnx8xxx_ports[]; 60 61static inline int serial_in(struct pnx8xxx_port *sport, int offset) 62{ 63 return (__raw_readl(sport->port.membase + offset)); 64} 65 66static inline void serial_out(struct pnx8xxx_port *sport, int offset, int value) 67{ 68 __raw_writel(value, sport->port.membase + offset); 69} 70 71/* 72 * Handle any change of modem status signal since we were last called. 73 */ 74static void pnx8xxx_mctrl_check(struct pnx8xxx_port *sport) 75{ 76 unsigned int status, changed; 77 78 status = sport->port.ops->get_mctrl(&sport->port); 79 changed = status ^ sport->old_status; 80 81 if (changed == 0) 82 return; 83 84 sport->old_status = status; 85 86 if (changed & TIOCM_RI) 87 sport->port.icount.rng++; 88 if (changed & TIOCM_DSR) 89 sport->port.icount.dsr++; 90 if (changed & TIOCM_CAR) 91 uart_handle_dcd_change(&sport->port, status & TIOCM_CAR); 92 if (changed & TIOCM_CTS) 93 uart_handle_cts_change(&sport->port, status & TIOCM_CTS); 94 95 wake_up_interruptible(&sport->port.state->port.delta_msr_wait); 96} 97 98/* 99 * This is our per-port timeout handler, for checking the 100 * modem status signals. 101 */ 102static void pnx8xxx_timeout(struct timer_list *t) 103{ 104 struct pnx8xxx_port *sport = from_timer(sport, t, timer); 105 unsigned long flags; 106 107 if (sport->port.state) { 108 spin_lock_irqsave(&sport->port.lock, flags); 109 pnx8xxx_mctrl_check(sport); 110 spin_unlock_irqrestore(&sport->port.lock, flags); 111 112 mod_timer(&sport->timer, jiffies + MCTRL_TIMEOUT); 113 } 114} 115 116/* 117 * interrupts disabled on entry 118 */ 119static void pnx8xxx_stop_tx(struct uart_port *port) 120{ 121 struct pnx8xxx_port *sport = 122 container_of(port, struct pnx8xxx_port, port); 123 u32 ien; 124 125 /* Disable TX intr */ 126 ien = serial_in(sport, PNX8XXX_IEN); 127 serial_out(sport, PNX8XXX_IEN, ien & ~PNX8XXX_UART_INT_ALLTX); 128 129 /* Clear all pending TX intr */ 130 serial_out(sport, PNX8XXX_ICLR, PNX8XXX_UART_INT_ALLTX); 131} 132 133/* 134 * interrupts may not be disabled on entry 135 */ 136static void pnx8xxx_start_tx(struct uart_port *port) 137{ 138 struct pnx8xxx_port *sport = 139 container_of(port, struct pnx8xxx_port, port); 140 u32 ien; 141 142 /* Clear all pending TX intr */ 143 serial_out(sport, PNX8XXX_ICLR, PNX8XXX_UART_INT_ALLTX); 144 145 /* Enable TX intr */ 146 ien = serial_in(sport, PNX8XXX_IEN); 147 serial_out(sport, PNX8XXX_IEN, ien | PNX8XXX_UART_INT_ALLTX); 148} 149 150/* 151 * Interrupts enabled 152 */ 153static void pnx8xxx_stop_rx(struct uart_port *port) 154{ 155 struct pnx8xxx_port *sport = 156 container_of(port, struct pnx8xxx_port, port); 157 u32 ien; 158 159 /* Disable RX intr */ 160 ien = serial_in(sport, PNX8XXX_IEN); 161 serial_out(sport, PNX8XXX_IEN, ien & ~PNX8XXX_UART_INT_ALLRX); 162 163 /* Clear all pending RX intr */ 164 serial_out(sport, PNX8XXX_ICLR, PNX8XXX_UART_INT_ALLRX); 165} 166 167/* 168 * Set the modem control timer to fire immediately. 169 */ 170static void pnx8xxx_enable_ms(struct uart_port *port) 171{ 172 struct pnx8xxx_port *sport = 173 container_of(port, struct pnx8xxx_port, port); 174 175 mod_timer(&sport->timer, jiffies); 176} 177 178static void pnx8xxx_rx_chars(struct pnx8xxx_port *sport) 179{ 180 unsigned int status, ch, flg; 181 182 status = FIFO_TO_SM(serial_in(sport, PNX8XXX_FIFO)) | 183 ISTAT_TO_SM(serial_in(sport, PNX8XXX_ISTAT)); 184 while (status & FIFO_TO_SM(PNX8XXX_UART_FIFO_RXFIFO)) { 185 ch = serial_in(sport, PNX8XXX_FIFO) & 0xff; 186 187 sport->port.icount.rx++; 188 189 flg = TTY_NORMAL; 190 191 /* 192 * note that the error handling code is 193 * out of the main execution path 194 */ 195 if (status & (FIFO_TO_SM(PNX8XXX_UART_FIFO_RXFE | 196 PNX8XXX_UART_FIFO_RXPAR | 197 PNX8XXX_UART_FIFO_RXBRK) | 198 ISTAT_TO_SM(PNX8XXX_UART_INT_RXOVRN))) { 199 if (status & FIFO_TO_SM(PNX8XXX_UART_FIFO_RXBRK)) { 200 status &= ~(FIFO_TO_SM(PNX8XXX_UART_FIFO_RXFE) | 201 FIFO_TO_SM(PNX8XXX_UART_FIFO_RXPAR)); 202 sport->port.icount.brk++; 203 if (uart_handle_break(&sport->port)) 204 goto ignore_char; 205 } else if (status & FIFO_TO_SM(PNX8XXX_UART_FIFO_RXPAR)) 206 sport->port.icount.parity++; 207 else if (status & FIFO_TO_SM(PNX8XXX_UART_FIFO_RXFE)) 208 sport->port.icount.frame++; 209 if (status & ISTAT_TO_SM(PNX8XXX_UART_INT_RXOVRN)) 210 sport->port.icount.overrun++; 211 212 status &= sport->port.read_status_mask; 213 214 if (status & FIFO_TO_SM(PNX8XXX_UART_FIFO_RXPAR)) 215 flg = TTY_PARITY; 216 else if (status & FIFO_TO_SM(PNX8XXX_UART_FIFO_RXFE)) 217 flg = TTY_FRAME; 218 219 sport->port.sysrq = 0; 220 } 221 222 if (uart_handle_sysrq_char(&sport->port, ch)) 223 goto ignore_char; 224 225 uart_insert_char(&sport->port, status, 226 ISTAT_TO_SM(PNX8XXX_UART_INT_RXOVRN), ch, flg); 227 228 ignore_char: 229 serial_out(sport, PNX8XXX_LCR, serial_in(sport, PNX8XXX_LCR) | 230 PNX8XXX_UART_LCR_RX_NEXT); 231 status = FIFO_TO_SM(serial_in(sport, PNX8XXX_FIFO)) | 232 ISTAT_TO_SM(serial_in(sport, PNX8XXX_ISTAT)); 233 } 234 235 spin_unlock(&sport->port.lock); 236 tty_flip_buffer_push(&sport->port.state->port); 237 spin_lock(&sport->port.lock); 238} 239 240static void pnx8xxx_tx_chars(struct pnx8xxx_port *sport) 241{ 242 struct circ_buf *xmit = &sport->port.state->xmit; 243 244 if (sport->port.x_char) { 245 serial_out(sport, PNX8XXX_FIFO, sport->port.x_char); 246 sport->port.icount.tx++; 247 sport->port.x_char = 0; 248 return; 249 } 250 251 /* 252 * Check the modem control lines before 253 * transmitting anything. 254 */ 255 pnx8xxx_mctrl_check(sport); 256 257 if (uart_circ_empty(xmit) || uart_tx_stopped(&sport->port)) { 258 pnx8xxx_stop_tx(&sport->port); 259 return; 260 } 261 262 /* 263 * TX while bytes available 264 */ 265 while (((serial_in(sport, PNX8XXX_FIFO) & 266 PNX8XXX_UART_FIFO_TXFIFO) >> 16) < 16) { 267 serial_out(sport, PNX8XXX_FIFO, xmit->buf[xmit->tail]); 268 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); 269 sport->port.icount.tx++; 270 if (uart_circ_empty(xmit)) 271 break; 272 } 273 274 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) 275 uart_write_wakeup(&sport->port); 276 277 if (uart_circ_empty(xmit)) 278 pnx8xxx_stop_tx(&sport->port); 279} 280 281static irqreturn_t pnx8xxx_int(int irq, void *dev_id) 282{ 283 struct pnx8xxx_port *sport = dev_id; 284 unsigned int status; 285 286 spin_lock(&sport->port.lock); 287 /* Get the interrupts */ 288 status = serial_in(sport, PNX8XXX_ISTAT) & serial_in(sport, PNX8XXX_IEN); 289 290 /* Byte or break signal received */ 291 if (status & (PNX8XXX_UART_INT_RX | PNX8XXX_UART_INT_BREAK)) 292 pnx8xxx_rx_chars(sport); 293 294 /* TX holding register empty - transmit a byte */ 295 if (status & PNX8XXX_UART_INT_TX) 296 pnx8xxx_tx_chars(sport); 297 298 /* Clear the ISTAT register */ 299 serial_out(sport, PNX8XXX_ICLR, status); 300 301 spin_unlock(&sport->port.lock); 302 return IRQ_HANDLED; 303} 304 305/* 306 * Return TIOCSER_TEMT when transmitter is not busy. 307 */ 308static unsigned int pnx8xxx_tx_empty(struct uart_port *port) 309{ 310 struct pnx8xxx_port *sport = 311 container_of(port, struct pnx8xxx_port, port); 312 313 return serial_in(sport, PNX8XXX_FIFO) & PNX8XXX_UART_FIFO_TXFIFO_STA ? 0 : TIOCSER_TEMT; 314} 315 316static unsigned int pnx8xxx_get_mctrl(struct uart_port *port) 317{ 318 struct pnx8xxx_port *sport = 319 container_of(port, struct pnx8xxx_port, port); 320 unsigned int mctrl = TIOCM_DSR; 321 unsigned int msr; 322 323 /* REVISIT */ 324 325 msr = serial_in(sport, PNX8XXX_MCR); 326 327 mctrl |= msr & PNX8XXX_UART_MCR_CTS ? TIOCM_CTS : 0; 328 mctrl |= msr & PNX8XXX_UART_MCR_DCD ? TIOCM_CAR : 0; 329 330 return mctrl; 331} 332 333static void pnx8xxx_set_mctrl(struct uart_port *port, unsigned int mctrl) 334{ 335#if 0 /* FIXME */ 336 struct pnx8xxx_port *sport = (struct pnx8xxx_port *)port; 337 unsigned int msr; 338#endif 339} 340 341/* 342 * Interrupts always disabled. 343 */ 344static void pnx8xxx_break_ctl(struct uart_port *port, int break_state) 345{ 346 struct pnx8xxx_port *sport = 347 container_of(port, struct pnx8xxx_port, port); 348 unsigned long flags; 349 unsigned int lcr; 350 351 spin_lock_irqsave(&sport->port.lock, flags); 352 lcr = serial_in(sport, PNX8XXX_LCR); 353 if (break_state == -1) 354 lcr |= PNX8XXX_UART_LCR_TXBREAK; 355 else 356 lcr &= ~PNX8XXX_UART_LCR_TXBREAK; 357 serial_out(sport, PNX8XXX_LCR, lcr); 358 spin_unlock_irqrestore(&sport->port.lock, flags); 359} 360 361static int pnx8xxx_startup(struct uart_port *port) 362{ 363 struct pnx8xxx_port *sport = 364 container_of(port, struct pnx8xxx_port, port); 365 int retval; 366 367 /* 368 * Allocate the IRQ 369 */ 370 retval = request_irq(sport->port.irq, pnx8xxx_int, 0, 371 "pnx8xxx-uart", sport); 372 if (retval) 373 return retval; 374 375 /* 376 * Finally, clear and enable interrupts 377 */ 378 379 serial_out(sport, PNX8XXX_ICLR, PNX8XXX_UART_INT_ALLRX | 380 PNX8XXX_UART_INT_ALLTX); 381 382 serial_out(sport, PNX8XXX_IEN, serial_in(sport, PNX8XXX_IEN) | 383 PNX8XXX_UART_INT_ALLRX | 384 PNX8XXX_UART_INT_ALLTX); 385 386 /* 387 * Enable modem status interrupts 388 */ 389 spin_lock_irq(&sport->port.lock); 390 pnx8xxx_enable_ms(&sport->port); 391 spin_unlock_irq(&sport->port.lock); 392 393 return 0; 394} 395 396static void pnx8xxx_shutdown(struct uart_port *port) 397{ 398 struct pnx8xxx_port *sport = 399 container_of(port, struct pnx8xxx_port, port); 400 int lcr; 401 402 /* 403 * Stop our timer. 404 */ 405 del_timer_sync(&sport->timer); 406 407 /* 408 * Disable all interrupts 409 */ 410 serial_out(sport, PNX8XXX_IEN, 0); 411 412 /* 413 * Reset the Tx and Rx FIFOS, disable the break condition 414 */ 415 lcr = serial_in(sport, PNX8XXX_LCR); 416 lcr &= ~PNX8XXX_UART_LCR_TXBREAK; 417 lcr |= PNX8XXX_UART_LCR_TX_RST | PNX8XXX_UART_LCR_RX_RST; 418 serial_out(sport, PNX8XXX_LCR, lcr); 419 420 /* 421 * Clear all interrupts 422 */ 423 serial_out(sport, PNX8XXX_ICLR, PNX8XXX_UART_INT_ALLRX | 424 PNX8XXX_UART_INT_ALLTX); 425 426 /* 427 * Free the interrupt 428 */ 429 free_irq(sport->port.irq, sport); 430} 431 432static void 433pnx8xxx_set_termios(struct uart_port *port, struct ktermios *termios, 434 struct ktermios *old) 435{ 436 struct pnx8xxx_port *sport = 437 container_of(port, struct pnx8xxx_port, port); 438 unsigned long flags; 439 unsigned int lcr_fcr, old_ien, baud, quot; 440 unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8; 441 442 /* 443 * We only support CS7 and CS8. 444 */ 445 while ((termios->c_cflag & CSIZE) != CS7 && 446 (termios->c_cflag & CSIZE) != CS8) { 447 termios->c_cflag &= ~CSIZE; 448 termios->c_cflag |= old_csize; 449 old_csize = CS8; 450 } 451 452 if ((termios->c_cflag & CSIZE) == CS8) 453 lcr_fcr = PNX8XXX_UART_LCR_8BIT; 454 else 455 lcr_fcr = 0; 456 457 if (termios->c_cflag & CSTOPB) 458 lcr_fcr |= PNX8XXX_UART_LCR_2STOPB; 459 if (termios->c_cflag & PARENB) { 460 lcr_fcr |= PNX8XXX_UART_LCR_PAREN; 461 if (!(termios->c_cflag & PARODD)) 462 lcr_fcr |= PNX8XXX_UART_LCR_PAREVN; 463 } 464 465 /* 466 * Ask the core to calculate the divisor for us. 467 */ 468 baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); 469 quot = uart_get_divisor(port, baud); 470 471 spin_lock_irqsave(&sport->port.lock, flags); 472 473 sport->port.read_status_mask = ISTAT_TO_SM(PNX8XXX_UART_INT_RXOVRN) | 474 ISTAT_TO_SM(PNX8XXX_UART_INT_EMPTY) | 475 ISTAT_TO_SM(PNX8XXX_UART_INT_RX); 476 if (termios->c_iflag & INPCK) 477 sport->port.read_status_mask |= 478 FIFO_TO_SM(PNX8XXX_UART_FIFO_RXFE) | 479 FIFO_TO_SM(PNX8XXX_UART_FIFO_RXPAR); 480 if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK)) 481 sport->port.read_status_mask |= 482 ISTAT_TO_SM(PNX8XXX_UART_INT_BREAK); 483 484 /* 485 * Characters to ignore 486 */ 487 sport->port.ignore_status_mask = 0; 488 if (termios->c_iflag & IGNPAR) 489 sport->port.ignore_status_mask |= 490 FIFO_TO_SM(PNX8XXX_UART_FIFO_RXFE) | 491 FIFO_TO_SM(PNX8XXX_UART_FIFO_RXPAR); 492 if (termios->c_iflag & IGNBRK) { 493 sport->port.ignore_status_mask |= 494 ISTAT_TO_SM(PNX8XXX_UART_INT_BREAK); 495 /* 496 * If we're ignoring parity and break indicators, 497 * ignore overruns too (for real raw support). 498 */ 499 if (termios->c_iflag & IGNPAR) 500 sport->port.ignore_status_mask |= 501 ISTAT_TO_SM(PNX8XXX_UART_INT_RXOVRN); 502 } 503 504 /* 505 * ignore all characters if CREAD is not set 506 */ 507 if ((termios->c_cflag & CREAD) == 0) 508 sport->port.ignore_status_mask |= 509 ISTAT_TO_SM(PNX8XXX_UART_INT_RX); 510 511 del_timer_sync(&sport->timer); 512 513 /* 514 * Update the per-port timeout. 515 */ 516 uart_update_timeout(port, termios->c_cflag, baud); 517 518 /* 519 * disable interrupts and drain transmitter 520 */ 521 old_ien = serial_in(sport, PNX8XXX_IEN); 522 serial_out(sport, PNX8XXX_IEN, old_ien & ~(PNX8XXX_UART_INT_ALLTX | 523 PNX8XXX_UART_INT_ALLRX)); 524 525 while (serial_in(sport, PNX8XXX_FIFO) & PNX8XXX_UART_FIFO_TXFIFO_STA) 526 barrier(); 527 528 /* then, disable everything */ 529 serial_out(sport, PNX8XXX_IEN, 0); 530 531 /* Reset the Rx and Tx FIFOs too */ 532 lcr_fcr |= PNX8XXX_UART_LCR_TX_RST; 533 lcr_fcr |= PNX8XXX_UART_LCR_RX_RST; 534 535 /* set the parity, stop bits and data size */ 536 serial_out(sport, PNX8XXX_LCR, lcr_fcr); 537 538 /* set the baud rate */ 539 quot -= 1; 540 serial_out(sport, PNX8XXX_BAUD, quot); 541 542 serial_out(sport, PNX8XXX_ICLR, -1); 543 544 serial_out(sport, PNX8XXX_IEN, old_ien); 545 546 if (UART_ENABLE_MS(&sport->port, termios->c_cflag)) 547 pnx8xxx_enable_ms(&sport->port); 548 549 spin_unlock_irqrestore(&sport->port.lock, flags); 550} 551 552static const char *pnx8xxx_type(struct uart_port *port) 553{ 554 struct pnx8xxx_port *sport = 555 container_of(port, struct pnx8xxx_port, port); 556 557 return sport->port.type == PORT_PNX8XXX ? "PNX8XXX" : NULL; 558} 559 560/* 561 * Release the memory region(s) being used by 'port'. 562 */ 563static void pnx8xxx_release_port(struct uart_port *port) 564{ 565 struct pnx8xxx_port *sport = 566 container_of(port, struct pnx8xxx_port, port); 567 568 release_mem_region(sport->port.mapbase, UART_PORT_SIZE); 569} 570 571/* 572 * Request the memory region(s) being used by 'port'. 573 */ 574static int pnx8xxx_request_port(struct uart_port *port) 575{ 576 struct pnx8xxx_port *sport = 577 container_of(port, struct pnx8xxx_port, port); 578 return request_mem_region(sport->port.mapbase, UART_PORT_SIZE, 579 "pnx8xxx-uart") != NULL ? 0 : -EBUSY; 580} 581 582/* 583 * Configure/autoconfigure the port. 584 */ 585static void pnx8xxx_config_port(struct uart_port *port, int flags) 586{ 587 struct pnx8xxx_port *sport = 588 container_of(port, struct pnx8xxx_port, port); 589 590 if (flags & UART_CONFIG_TYPE && 591 pnx8xxx_request_port(&sport->port) == 0) 592 sport->port.type = PORT_PNX8XXX; 593} 594 595/* 596 * Verify the new serial_struct (for TIOCSSERIAL). 597 * The only change we allow are to the flags and type, and 598 * even then only between PORT_PNX8XXX and PORT_UNKNOWN 599 */ 600static int 601pnx8xxx_verify_port(struct uart_port *port, struct serial_struct *ser) 602{ 603 struct pnx8xxx_port *sport = 604 container_of(port, struct pnx8xxx_port, port); 605 int ret = 0; 606 607 if (ser->type != PORT_UNKNOWN && ser->type != PORT_PNX8XXX) 608 ret = -EINVAL; 609 if (sport->port.irq != ser->irq) 610 ret = -EINVAL; 611 if (ser->io_type != SERIAL_IO_MEM) 612 ret = -EINVAL; 613 if (sport->port.uartclk / 16 != ser->baud_base) 614 ret = -EINVAL; 615 if ((void *)sport->port.mapbase != ser->iomem_base) 616 ret = -EINVAL; 617 if (sport->port.iobase != ser->port) 618 ret = -EINVAL; 619 if (ser->hub6 != 0) 620 ret = -EINVAL; 621 return ret; 622} 623 624static const struct uart_ops pnx8xxx_pops = { 625 .tx_empty = pnx8xxx_tx_empty, 626 .set_mctrl = pnx8xxx_set_mctrl, 627 .get_mctrl = pnx8xxx_get_mctrl, 628 .stop_tx = pnx8xxx_stop_tx, 629 .start_tx = pnx8xxx_start_tx, 630 .stop_rx = pnx8xxx_stop_rx, 631 .enable_ms = pnx8xxx_enable_ms, 632 .break_ctl = pnx8xxx_break_ctl, 633 .startup = pnx8xxx_startup, 634 .shutdown = pnx8xxx_shutdown, 635 .set_termios = pnx8xxx_set_termios, 636 .type = pnx8xxx_type, 637 .release_port = pnx8xxx_release_port, 638 .request_port = pnx8xxx_request_port, 639 .config_port = pnx8xxx_config_port, 640 .verify_port = pnx8xxx_verify_port, 641}; 642 643 644/* 645 * Setup the PNX8XXX serial ports. 646 * 647 * Note also that we support "console=ttySx" where "x" is either 0 or 1. 648 */ 649static void __init pnx8xxx_init_ports(void) 650{ 651 static int first = 1; 652 int i; 653 654 if (!first) 655 return; 656 first = 0; 657 658 for (i = 0; i < NR_PORTS; i++) { 659 timer_setup(&pnx8xxx_ports[i].timer, pnx8xxx_timeout, 0); 660 pnx8xxx_ports[i].port.ops = &pnx8xxx_pops; 661 } 662} 663 664#ifdef CONFIG_SERIAL_PNX8XXX_CONSOLE 665 666static void pnx8xxx_console_putchar(struct uart_port *port, int ch) 667{ 668 struct pnx8xxx_port *sport = 669 container_of(port, struct pnx8xxx_port, port); 670 int status; 671 672 do { 673 /* Wait for UART_TX register to empty */ 674 status = serial_in(sport, PNX8XXX_FIFO); 675 } while (status & PNX8XXX_UART_FIFO_TXFIFO); 676 serial_out(sport, PNX8XXX_FIFO, ch); 677} 678 679/* 680 * Interrupts are disabled on entering 681 */static void 682pnx8xxx_console_write(struct console *co, const char *s, unsigned int count) 683{ 684 struct pnx8xxx_port *sport = &pnx8xxx_ports[co->index]; 685 unsigned int old_ien, status; 686 687 /* 688 * First, save IEN and then disable interrupts 689 */ 690 old_ien = serial_in(sport, PNX8XXX_IEN); 691 serial_out(sport, PNX8XXX_IEN, old_ien & ~(PNX8XXX_UART_INT_ALLTX | 692 PNX8XXX_UART_INT_ALLRX)); 693 694 uart_console_write(&sport->port, s, count, pnx8xxx_console_putchar); 695 696 /* 697 * Finally, wait for transmitter to become empty 698 * and restore IEN 699 */ 700 do { 701 /* Wait for UART_TX register to empty */ 702 status = serial_in(sport, PNX8XXX_FIFO); 703 } while (status & PNX8XXX_UART_FIFO_TXFIFO); 704 705 /* Clear TX and EMPTY interrupt */ 706 serial_out(sport, PNX8XXX_ICLR, PNX8XXX_UART_INT_TX | 707 PNX8XXX_UART_INT_EMPTY); 708 709 serial_out(sport, PNX8XXX_IEN, old_ien); 710} 711 712static int __init 713pnx8xxx_console_setup(struct console *co, char *options) 714{ 715 struct pnx8xxx_port *sport; 716 int baud = 38400; 717 int bits = 8; 718 int parity = 'n'; 719 int flow = 'n'; 720 721 /* 722 * Check whether an invalid uart number has been specified, and 723 * if so, search for the first available port that does have 724 * console support. 725 */ 726 if (co->index == -1 || co->index >= NR_PORTS) 727 co->index = 0; 728 sport = &pnx8xxx_ports[co->index]; 729 730 if (options) 731 uart_parse_options(options, &baud, &parity, &bits, &flow); 732 733 return uart_set_options(&sport->port, co, baud, parity, bits, flow); 734} 735 736static struct uart_driver pnx8xxx_reg; 737static struct console pnx8xxx_console = { 738 .name = "ttyS", 739 .write = pnx8xxx_console_write, 740 .device = uart_console_device, 741 .setup = pnx8xxx_console_setup, 742 .flags = CON_PRINTBUFFER, 743 .index = -1, 744 .data = &pnx8xxx_reg, 745}; 746 747static int __init pnx8xxx_rs_console_init(void) 748{ 749 pnx8xxx_init_ports(); 750 register_console(&pnx8xxx_console); 751 return 0; 752} 753console_initcall(pnx8xxx_rs_console_init); 754 755#define PNX8XXX_CONSOLE &pnx8xxx_console 756#else 757#define PNX8XXX_CONSOLE NULL 758#endif 759 760static struct uart_driver pnx8xxx_reg = { 761 .owner = THIS_MODULE, 762 .driver_name = "ttyS", 763 .dev_name = "ttyS", 764 .major = SERIAL_PNX8XXX_MAJOR, 765 .minor = MINOR_START, 766 .nr = NR_PORTS, 767 .cons = PNX8XXX_CONSOLE, 768}; 769 770static int pnx8xxx_serial_suspend(struct platform_device *pdev, pm_message_t state) 771{ 772 struct pnx8xxx_port *sport = platform_get_drvdata(pdev); 773 774 return uart_suspend_port(&pnx8xxx_reg, &sport->port); 775} 776 777static int pnx8xxx_serial_resume(struct platform_device *pdev) 778{ 779 struct pnx8xxx_port *sport = platform_get_drvdata(pdev); 780 781 return uart_resume_port(&pnx8xxx_reg, &sport->port); 782} 783 784static int pnx8xxx_serial_probe(struct platform_device *pdev) 785{ 786 struct resource *res = pdev->resource; 787 int i; 788 789 for (i = 0; i < pdev->num_resources; i++, res++) { 790 if (!(res->flags & IORESOURCE_MEM)) 791 continue; 792 793 for (i = 0; i < NR_PORTS; i++) { 794 if (pnx8xxx_ports[i].port.mapbase != res->start) 795 continue; 796 797 pnx8xxx_ports[i].port.has_sysrq = IS_ENABLED(CONFIG_SERIAL_PNX8XXX_CONSOLE); 798 pnx8xxx_ports[i].port.dev = &pdev->dev; 799 uart_add_one_port(&pnx8xxx_reg, &pnx8xxx_ports[i].port); 800 platform_set_drvdata(pdev, &pnx8xxx_ports[i]); 801 break; 802 } 803 } 804 805 return 0; 806} 807 808static int pnx8xxx_serial_remove(struct platform_device *pdev) 809{ 810 struct pnx8xxx_port *sport = platform_get_drvdata(pdev); 811 812 if (sport) 813 uart_remove_one_port(&pnx8xxx_reg, &sport->port); 814 815 return 0; 816} 817 818static struct platform_driver pnx8xxx_serial_driver = { 819 .driver = { 820 .name = "pnx8xxx-uart", 821 }, 822 .probe = pnx8xxx_serial_probe, 823 .remove = pnx8xxx_serial_remove, 824 .suspend = pnx8xxx_serial_suspend, 825 .resume = pnx8xxx_serial_resume, 826}; 827 828static int __init pnx8xxx_serial_init(void) 829{ 830 int ret; 831 832 printk(KERN_INFO "Serial: PNX8XXX driver\n"); 833 834 pnx8xxx_init_ports(); 835 836 ret = uart_register_driver(&pnx8xxx_reg); 837 if (ret == 0) { 838 ret = platform_driver_register(&pnx8xxx_serial_driver); 839 if (ret) 840 uart_unregister_driver(&pnx8xxx_reg); 841 } 842 return ret; 843} 844 845static void __exit pnx8xxx_serial_exit(void) 846{ 847 platform_driver_unregister(&pnx8xxx_serial_driver); 848 uart_unregister_driver(&pnx8xxx_reg); 849} 850 851module_init(pnx8xxx_serial_init); 852module_exit(pnx8xxx_serial_exit); 853 854MODULE_AUTHOR("Embedded Alley Solutions, Inc."); 855MODULE_DESCRIPTION("PNX8XXX SoCs serial port driver"); 856MODULE_LICENSE("GPL"); 857MODULE_ALIAS_CHARDEV_MAJOR(SERIAL_PNX8XXX_MAJOR); 858MODULE_ALIAS("platform:pnx8xxx-uart"); 859