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.15 950 lines 20 kB view raw
1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Driver for NEC VR4100 series Serial Interface Unit. 4 * 5 * Copyright (C) 2004-2008 Yoichi Yuasa <yuasa@linux-mips.org> 6 * 7 * Based on drivers/serial/8250.c, by Russell King. 8 */ 9 10#if defined(CONFIG_SERIAL_VR41XX_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) 11#define SUPPORT_SYSRQ 12#endif 13 14#include <linux/console.h> 15#include <linux/errno.h> 16#include <linux/init.h> 17#include <linux/interrupt.h> 18#include <linux/ioport.h> 19#include <linux/module.h> 20#include <linux/platform_device.h> 21#include <linux/serial.h> 22#include <linux/serial_core.h> 23#include <linux/serial_reg.h> 24#include <linux/tty.h> 25#include <linux/tty_flip.h> 26 27#include <asm/io.h> 28#include <asm/vr41xx/siu.h> 29#include <asm/vr41xx/vr41xx.h> 30 31#define SIU_BAUD_BASE 1152000 32#define SIU_MAJOR 204 33#define SIU_MINOR_BASE 82 34 35#define RX_MAX_COUNT 256 36#define TX_MAX_COUNT 15 37 38#define SIUIRSEL 0x08 39 #define TMICMODE 0x20 40 #define TMICTX 0x10 41 #define IRMSEL 0x0c 42 #define IRMSEL_HP 0x08 43 #define IRMSEL_TEMIC 0x04 44 #define IRMSEL_SHARP 0x00 45 #define IRUSESEL 0x02 46 #define SIRSEL 0x01 47 48static struct uart_port siu_uart_ports[SIU_PORTS_MAX] = { 49 [0 ... SIU_PORTS_MAX-1] = { 50 .lock = __SPIN_LOCK_UNLOCKED(siu_uart_ports->lock), 51 .irq = 0, 52 }, 53}; 54 55#ifdef CONFIG_SERIAL_VR41XX_CONSOLE 56static uint8_t lsr_break_flag[SIU_PORTS_MAX]; 57#endif 58 59#define siu_read(port, offset) readb((port)->membase + (offset)) 60#define siu_write(port, offset, value) writeb((value), (port)->membase + (offset)) 61 62void vr41xx_select_siu_interface(siu_interface_t interface) 63{ 64 struct uart_port *port; 65 unsigned long flags; 66 uint8_t irsel; 67 68 port = &siu_uart_ports[0]; 69 70 spin_lock_irqsave(&port->lock, flags); 71 72 irsel = siu_read(port, SIUIRSEL); 73 if (interface == SIU_INTERFACE_IRDA) 74 irsel |= SIRSEL; 75 else 76 irsel &= ~SIRSEL; 77 siu_write(port, SIUIRSEL, irsel); 78 79 spin_unlock_irqrestore(&port->lock, flags); 80} 81EXPORT_SYMBOL_GPL(vr41xx_select_siu_interface); 82 83void vr41xx_use_irda(irda_use_t use) 84{ 85 struct uart_port *port; 86 unsigned long flags; 87 uint8_t irsel; 88 89 port = &siu_uart_ports[0]; 90 91 spin_lock_irqsave(&port->lock, flags); 92 93 irsel = siu_read(port, SIUIRSEL); 94 if (use == FIR_USE_IRDA) 95 irsel |= IRUSESEL; 96 else 97 irsel &= ~IRUSESEL; 98 siu_write(port, SIUIRSEL, irsel); 99 100 spin_unlock_irqrestore(&port->lock, flags); 101} 102EXPORT_SYMBOL_GPL(vr41xx_use_irda); 103 104void vr41xx_select_irda_module(irda_module_t module, irda_speed_t speed) 105{ 106 struct uart_port *port; 107 unsigned long flags; 108 uint8_t irsel; 109 110 port = &siu_uart_ports[0]; 111 112 spin_lock_irqsave(&port->lock, flags); 113 114 irsel = siu_read(port, SIUIRSEL); 115 irsel &= ~(IRMSEL | TMICTX | TMICMODE); 116 switch (module) { 117 case SHARP_IRDA: 118 irsel |= IRMSEL_SHARP; 119 break; 120 case TEMIC_IRDA: 121 irsel |= IRMSEL_TEMIC | TMICMODE; 122 if (speed == IRDA_TX_4MBPS) 123 irsel |= TMICTX; 124 break; 125 case HP_IRDA: 126 irsel |= IRMSEL_HP; 127 break; 128 default: 129 break; 130 } 131 siu_write(port, SIUIRSEL, irsel); 132 133 spin_unlock_irqrestore(&port->lock, flags); 134} 135EXPORT_SYMBOL_GPL(vr41xx_select_irda_module); 136 137static inline void siu_clear_fifo(struct uart_port *port) 138{ 139 siu_write(port, UART_FCR, UART_FCR_ENABLE_FIFO); 140 siu_write(port, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR | 141 UART_FCR_CLEAR_XMIT); 142 siu_write(port, UART_FCR, 0); 143} 144 145static inline unsigned long siu_port_size(struct uart_port *port) 146{ 147 switch (port->type) { 148 case PORT_VR41XX_SIU: 149 return 11UL; 150 case PORT_VR41XX_DSIU: 151 return 8UL; 152 } 153 154 return 0; 155} 156 157static inline unsigned int siu_check_type(struct uart_port *port) 158{ 159 if (port->line == 0) 160 return PORT_VR41XX_SIU; 161 if (port->line == 1 && port->irq) 162 return PORT_VR41XX_DSIU; 163 164 return PORT_UNKNOWN; 165} 166 167static inline const char *siu_type_name(struct uart_port *port) 168{ 169 switch (port->type) { 170 case PORT_VR41XX_SIU: 171 return "SIU"; 172 case PORT_VR41XX_DSIU: 173 return "DSIU"; 174 } 175 176 return NULL; 177} 178 179static unsigned int siu_tx_empty(struct uart_port *port) 180{ 181 uint8_t lsr; 182 183 lsr = siu_read(port, UART_LSR); 184 if (lsr & UART_LSR_TEMT) 185 return TIOCSER_TEMT; 186 187 return 0; 188} 189 190static void siu_set_mctrl(struct uart_port *port, unsigned int mctrl) 191{ 192 uint8_t mcr = 0; 193 194 if (mctrl & TIOCM_DTR) 195 mcr |= UART_MCR_DTR; 196 if (mctrl & TIOCM_RTS) 197 mcr |= UART_MCR_RTS; 198 if (mctrl & TIOCM_OUT1) 199 mcr |= UART_MCR_OUT1; 200 if (mctrl & TIOCM_OUT2) 201 mcr |= UART_MCR_OUT2; 202 if (mctrl & TIOCM_LOOP) 203 mcr |= UART_MCR_LOOP; 204 205 siu_write(port, UART_MCR, mcr); 206} 207 208static unsigned int siu_get_mctrl(struct uart_port *port) 209{ 210 uint8_t msr; 211 unsigned int mctrl = 0; 212 213 msr = siu_read(port, UART_MSR); 214 if (msr & UART_MSR_DCD) 215 mctrl |= TIOCM_CAR; 216 if (msr & UART_MSR_RI) 217 mctrl |= TIOCM_RNG; 218 if (msr & UART_MSR_DSR) 219 mctrl |= TIOCM_DSR; 220 if (msr & UART_MSR_CTS) 221 mctrl |= TIOCM_CTS; 222 223 return mctrl; 224} 225 226static void siu_stop_tx(struct uart_port *port) 227{ 228 unsigned long flags; 229 uint8_t ier; 230 231 spin_lock_irqsave(&port->lock, flags); 232 233 ier = siu_read(port, UART_IER); 234 ier &= ~UART_IER_THRI; 235 siu_write(port, UART_IER, ier); 236 237 spin_unlock_irqrestore(&port->lock, flags); 238} 239 240static void siu_start_tx(struct uart_port *port) 241{ 242 unsigned long flags; 243 uint8_t ier; 244 245 spin_lock_irqsave(&port->lock, flags); 246 247 ier = siu_read(port, UART_IER); 248 ier |= UART_IER_THRI; 249 siu_write(port, UART_IER, ier); 250 251 spin_unlock_irqrestore(&port->lock, flags); 252} 253 254static void siu_stop_rx(struct uart_port *port) 255{ 256 unsigned long flags; 257 uint8_t ier; 258 259 spin_lock_irqsave(&port->lock, flags); 260 261 ier = siu_read(port, UART_IER); 262 ier &= ~UART_IER_RLSI; 263 siu_write(port, UART_IER, ier); 264 265 port->read_status_mask &= ~UART_LSR_DR; 266 267 spin_unlock_irqrestore(&port->lock, flags); 268} 269 270static void siu_enable_ms(struct uart_port *port) 271{ 272 unsigned long flags; 273 uint8_t ier; 274 275 spin_lock_irqsave(&port->lock, flags); 276 277 ier = siu_read(port, UART_IER); 278 ier |= UART_IER_MSI; 279 siu_write(port, UART_IER, ier); 280 281 spin_unlock_irqrestore(&port->lock, flags); 282} 283 284static void siu_break_ctl(struct uart_port *port, int ctl) 285{ 286 unsigned long flags; 287 uint8_t lcr; 288 289 spin_lock_irqsave(&port->lock, flags); 290 291 lcr = siu_read(port, UART_LCR); 292 if (ctl == -1) 293 lcr |= UART_LCR_SBC; 294 else 295 lcr &= ~UART_LCR_SBC; 296 siu_write(port, UART_LCR, lcr); 297 298 spin_unlock_irqrestore(&port->lock, flags); 299} 300 301static inline void receive_chars(struct uart_port *port, uint8_t *status) 302{ 303 uint8_t lsr, ch; 304 char flag; 305 int max_count = RX_MAX_COUNT; 306 307 lsr = *status; 308 309 do { 310 ch = siu_read(port, UART_RX); 311 port->icount.rx++; 312 flag = TTY_NORMAL; 313 314#ifdef CONFIG_SERIAL_VR41XX_CONSOLE 315 lsr |= lsr_break_flag[port->line]; 316 lsr_break_flag[port->line] = 0; 317#endif 318 if (unlikely(lsr & (UART_LSR_BI | UART_LSR_FE | 319 UART_LSR_PE | UART_LSR_OE))) { 320 if (lsr & UART_LSR_BI) { 321 lsr &= ~(UART_LSR_FE | UART_LSR_PE); 322 port->icount.brk++; 323 324 if (uart_handle_break(port)) 325 goto ignore_char; 326 } 327 328 if (lsr & UART_LSR_FE) 329 port->icount.frame++; 330 if (lsr & UART_LSR_PE) 331 port->icount.parity++; 332 if (lsr & UART_LSR_OE) 333 port->icount.overrun++; 334 335 lsr &= port->read_status_mask; 336 if (lsr & UART_LSR_BI) 337 flag = TTY_BREAK; 338 if (lsr & UART_LSR_FE) 339 flag = TTY_FRAME; 340 if (lsr & UART_LSR_PE) 341 flag = TTY_PARITY; 342 } 343 344 if (uart_handle_sysrq_char(port, ch)) 345 goto ignore_char; 346 347 uart_insert_char(port, lsr, UART_LSR_OE, ch, flag); 348 349 ignore_char: 350 lsr = siu_read(port, UART_LSR); 351 } while ((lsr & UART_LSR_DR) && (max_count-- > 0)); 352 353 tty_flip_buffer_push(&port->state->port); 354 355 *status = lsr; 356} 357 358static inline void check_modem_status(struct uart_port *port) 359{ 360 uint8_t msr; 361 362 msr = siu_read(port, UART_MSR); 363 if ((msr & UART_MSR_ANY_DELTA) == 0) 364 return; 365 if (msr & UART_MSR_DDCD) 366 uart_handle_dcd_change(port, msr & UART_MSR_DCD); 367 if (msr & UART_MSR_TERI) 368 port->icount.rng++; 369 if (msr & UART_MSR_DDSR) 370 port->icount.dsr++; 371 if (msr & UART_MSR_DCTS) 372 uart_handle_cts_change(port, msr & UART_MSR_CTS); 373 374 wake_up_interruptible(&port->state->port.delta_msr_wait); 375} 376 377static inline void transmit_chars(struct uart_port *port) 378{ 379 struct circ_buf *xmit; 380 int max_count = TX_MAX_COUNT; 381 382 xmit = &port->state->xmit; 383 384 if (port->x_char) { 385 siu_write(port, UART_TX, port->x_char); 386 port->icount.tx++; 387 port->x_char = 0; 388 return; 389 } 390 391 if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { 392 siu_stop_tx(port); 393 return; 394 } 395 396 do { 397 siu_write(port, UART_TX, xmit->buf[xmit->tail]); 398 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); 399 port->icount.tx++; 400 if (uart_circ_empty(xmit)) 401 break; 402 } while (max_count-- > 0); 403 404 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) 405 uart_write_wakeup(port); 406 407 if (uart_circ_empty(xmit)) 408 siu_stop_tx(port); 409} 410 411static irqreturn_t siu_interrupt(int irq, void *dev_id) 412{ 413 struct uart_port *port; 414 uint8_t iir, lsr; 415 416 port = (struct uart_port *)dev_id; 417 418 iir = siu_read(port, UART_IIR); 419 if (iir & UART_IIR_NO_INT) 420 return IRQ_NONE; 421 422 lsr = siu_read(port, UART_LSR); 423 if (lsr & UART_LSR_DR) 424 receive_chars(port, &lsr); 425 426 check_modem_status(port); 427 428 if (lsr & UART_LSR_THRE) 429 transmit_chars(port); 430 431 return IRQ_HANDLED; 432} 433 434static int siu_startup(struct uart_port *port) 435{ 436 int retval; 437 438 if (port->membase == NULL) 439 return -ENODEV; 440 441 siu_clear_fifo(port); 442 443 (void)siu_read(port, UART_LSR); 444 (void)siu_read(port, UART_RX); 445 (void)siu_read(port, UART_IIR); 446 (void)siu_read(port, UART_MSR); 447 448 if (siu_read(port, UART_LSR) == 0xff) 449 return -ENODEV; 450 451 retval = request_irq(port->irq, siu_interrupt, 0, siu_type_name(port), port); 452 if (retval) 453 return retval; 454 455 if (port->type == PORT_VR41XX_DSIU) 456 vr41xx_enable_dsiuint(DSIUINT_ALL); 457 458 siu_write(port, UART_LCR, UART_LCR_WLEN8); 459 460 spin_lock_irq(&port->lock); 461 siu_set_mctrl(port, port->mctrl); 462 spin_unlock_irq(&port->lock); 463 464 siu_write(port, UART_IER, UART_IER_RLSI | UART_IER_RDI); 465 466 (void)siu_read(port, UART_LSR); 467 (void)siu_read(port, UART_RX); 468 (void)siu_read(port, UART_IIR); 469 (void)siu_read(port, UART_MSR); 470 471 return 0; 472} 473 474static void siu_shutdown(struct uart_port *port) 475{ 476 unsigned long flags; 477 uint8_t lcr; 478 479 siu_write(port, UART_IER, 0); 480 481 spin_lock_irqsave(&port->lock, flags); 482 483 port->mctrl &= ~TIOCM_OUT2; 484 siu_set_mctrl(port, port->mctrl); 485 486 spin_unlock_irqrestore(&port->lock, flags); 487 488 lcr = siu_read(port, UART_LCR); 489 lcr &= ~UART_LCR_SBC; 490 siu_write(port, UART_LCR, lcr); 491 492 siu_clear_fifo(port); 493 494 (void)siu_read(port, UART_RX); 495 496 if (port->type == PORT_VR41XX_DSIU) 497 vr41xx_disable_dsiuint(DSIUINT_ALL); 498 499 free_irq(port->irq, port); 500} 501 502static void siu_set_termios(struct uart_port *port, struct ktermios *new, 503 struct ktermios *old) 504{ 505 tcflag_t c_cflag, c_iflag; 506 uint8_t lcr, fcr, ier; 507 unsigned int baud, quot; 508 unsigned long flags; 509 510 c_cflag = new->c_cflag; 511 switch (c_cflag & CSIZE) { 512 case CS5: 513 lcr = UART_LCR_WLEN5; 514 break; 515 case CS6: 516 lcr = UART_LCR_WLEN6; 517 break; 518 case CS7: 519 lcr = UART_LCR_WLEN7; 520 break; 521 default: 522 lcr = UART_LCR_WLEN8; 523 break; 524 } 525 526 if (c_cflag & CSTOPB) 527 lcr |= UART_LCR_STOP; 528 if (c_cflag & PARENB) 529 lcr |= UART_LCR_PARITY; 530 if ((c_cflag & PARODD) != PARODD) 531 lcr |= UART_LCR_EPAR; 532 if (c_cflag & CMSPAR) 533 lcr |= UART_LCR_SPAR; 534 535 baud = uart_get_baud_rate(port, new, old, 0, port->uartclk/16); 536 quot = uart_get_divisor(port, baud); 537 538 fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10; 539 540 spin_lock_irqsave(&port->lock, flags); 541 542 uart_update_timeout(port, c_cflag, baud); 543 544 c_iflag = new->c_iflag; 545 546 port->read_status_mask = UART_LSR_THRE | UART_LSR_OE | UART_LSR_DR; 547 if (c_iflag & INPCK) 548 port->read_status_mask |= UART_LSR_FE | UART_LSR_PE; 549 if (c_iflag & (IGNBRK | BRKINT | PARMRK)) 550 port->read_status_mask |= UART_LSR_BI; 551 552 port->ignore_status_mask = 0; 553 if (c_iflag & IGNPAR) 554 port->ignore_status_mask |= UART_LSR_FE | UART_LSR_PE; 555 if (c_iflag & IGNBRK) { 556 port->ignore_status_mask |= UART_LSR_BI; 557 if (c_iflag & IGNPAR) 558 port->ignore_status_mask |= UART_LSR_OE; 559 } 560 561 if ((c_cflag & CREAD) == 0) 562 port->ignore_status_mask |= UART_LSR_DR; 563 564 ier = siu_read(port, UART_IER); 565 ier &= ~UART_IER_MSI; 566 if (UART_ENABLE_MS(port, c_cflag)) 567 ier |= UART_IER_MSI; 568 siu_write(port, UART_IER, ier); 569 570 siu_write(port, UART_LCR, lcr | UART_LCR_DLAB); 571 572 siu_write(port, UART_DLL, (uint8_t)quot); 573 siu_write(port, UART_DLM, (uint8_t)(quot >> 8)); 574 575 siu_write(port, UART_LCR, lcr); 576 577 siu_write(port, UART_FCR, fcr); 578 579 siu_set_mctrl(port, port->mctrl); 580 581 spin_unlock_irqrestore(&port->lock, flags); 582} 583 584static void siu_pm(struct uart_port *port, unsigned int state, unsigned int oldstate) 585{ 586 switch (state) { 587 case 0: 588 switch (port->type) { 589 case PORT_VR41XX_SIU: 590 vr41xx_supply_clock(SIU_CLOCK); 591 break; 592 case PORT_VR41XX_DSIU: 593 vr41xx_supply_clock(DSIU_CLOCK); 594 break; 595 } 596 break; 597 case 3: 598 switch (port->type) { 599 case PORT_VR41XX_SIU: 600 vr41xx_mask_clock(SIU_CLOCK); 601 break; 602 case PORT_VR41XX_DSIU: 603 vr41xx_mask_clock(DSIU_CLOCK); 604 break; 605 } 606 break; 607 } 608} 609 610static const char *siu_type(struct uart_port *port) 611{ 612 return siu_type_name(port); 613} 614 615static void siu_release_port(struct uart_port *port) 616{ 617 unsigned long size; 618 619 if (port->flags & UPF_IOREMAP) { 620 iounmap(port->membase); 621 port->membase = NULL; 622 } 623 624 size = siu_port_size(port); 625 release_mem_region(port->mapbase, size); 626} 627 628static int siu_request_port(struct uart_port *port) 629{ 630 unsigned long size; 631 struct resource *res; 632 633 size = siu_port_size(port); 634 res = request_mem_region(port->mapbase, size, siu_type_name(port)); 635 if (res == NULL) 636 return -EBUSY; 637 638 if (port->flags & UPF_IOREMAP) { 639 port->membase = ioremap(port->mapbase, size); 640 if (port->membase == NULL) { 641 release_resource(res); 642 return -ENOMEM; 643 } 644 } 645 646 return 0; 647} 648 649static void siu_config_port(struct uart_port *port, int flags) 650{ 651 if (flags & UART_CONFIG_TYPE) { 652 port->type = siu_check_type(port); 653 (void)siu_request_port(port); 654 } 655} 656 657static int siu_verify_port(struct uart_port *port, struct serial_struct *serial) 658{ 659 if (port->type != PORT_VR41XX_SIU && port->type != PORT_VR41XX_DSIU) 660 return -EINVAL; 661 if (port->irq != serial->irq) 662 return -EINVAL; 663 if (port->iotype != serial->io_type) 664 return -EINVAL; 665 if (port->mapbase != (unsigned long)serial->iomem_base) 666 return -EINVAL; 667 668 return 0; 669} 670 671static const struct uart_ops siu_uart_ops = { 672 .tx_empty = siu_tx_empty, 673 .set_mctrl = siu_set_mctrl, 674 .get_mctrl = siu_get_mctrl, 675 .stop_tx = siu_stop_tx, 676 .start_tx = siu_start_tx, 677 .stop_rx = siu_stop_rx, 678 .enable_ms = siu_enable_ms, 679 .break_ctl = siu_break_ctl, 680 .startup = siu_startup, 681 .shutdown = siu_shutdown, 682 .set_termios = siu_set_termios, 683 .pm = siu_pm, 684 .type = siu_type, 685 .release_port = siu_release_port, 686 .request_port = siu_request_port, 687 .config_port = siu_config_port, 688 .verify_port = siu_verify_port, 689}; 690 691static int siu_init_ports(struct platform_device *pdev) 692{ 693 struct uart_port *port; 694 struct resource *res; 695 int *type = dev_get_platdata(&pdev->dev); 696 int i; 697 698 if (!type) 699 return 0; 700 701 port = siu_uart_ports; 702 for (i = 0; i < SIU_PORTS_MAX; i++) { 703 port->type = type[i]; 704 if (port->type == PORT_UNKNOWN) 705 continue; 706 port->irq = platform_get_irq(pdev, i); 707 port->uartclk = SIU_BAUD_BASE * 16; 708 port->fifosize = 16; 709 port->regshift = 0; 710 port->iotype = UPIO_MEM; 711 port->flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF; 712 port->line = i; 713 res = platform_get_resource(pdev, IORESOURCE_MEM, i); 714 port->mapbase = res->start; 715 port++; 716 } 717 718 return i; 719} 720 721#ifdef CONFIG_SERIAL_VR41XX_CONSOLE 722 723#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) 724 725static void wait_for_xmitr(struct uart_port *port) 726{ 727 int timeout = 10000; 728 uint8_t lsr, msr; 729 730 do { 731 lsr = siu_read(port, UART_LSR); 732 if (lsr & UART_LSR_BI) 733 lsr_break_flag[port->line] = UART_LSR_BI; 734 735 if ((lsr & BOTH_EMPTY) == BOTH_EMPTY) 736 break; 737 } while (timeout-- > 0); 738 739 if (port->flags & UPF_CONS_FLOW) { 740 timeout = 1000000; 741 742 do { 743 msr = siu_read(port, UART_MSR); 744 if ((msr & UART_MSR_CTS) != 0) 745 break; 746 } while (timeout-- > 0); 747 } 748} 749 750static void siu_console_putchar(struct uart_port *port, int ch) 751{ 752 wait_for_xmitr(port); 753 siu_write(port, UART_TX, ch); 754} 755 756static void siu_console_write(struct console *con, const char *s, unsigned count) 757{ 758 struct uart_port *port; 759 uint8_t ier; 760 761 port = &siu_uart_ports[con->index]; 762 763 ier = siu_read(port, UART_IER); 764 siu_write(port, UART_IER, 0); 765 766 uart_console_write(port, s, count, siu_console_putchar); 767 768 wait_for_xmitr(port); 769 siu_write(port, UART_IER, ier); 770} 771 772static int __init siu_console_setup(struct console *con, char *options) 773{ 774 struct uart_port *port; 775 int baud = 9600; 776 int parity = 'n'; 777 int bits = 8; 778 int flow = 'n'; 779 780 if (con->index >= SIU_PORTS_MAX) 781 con->index = 0; 782 783 port = &siu_uart_ports[con->index]; 784 if (port->membase == NULL) { 785 if (port->mapbase == 0) 786 return -ENODEV; 787 port->membase = ioremap(port->mapbase, siu_port_size(port)); 788 } 789 790 if (port->type == PORT_VR41XX_SIU) 791 vr41xx_select_siu_interface(SIU_INTERFACE_RS232C); 792 793 if (options != NULL) 794 uart_parse_options(options, &baud, &parity, &bits, &flow); 795 796 return uart_set_options(port, con, baud, parity, bits, flow); 797} 798 799static struct uart_driver siu_uart_driver; 800 801static struct console siu_console = { 802 .name = "ttyVR", 803 .write = siu_console_write, 804 .device = uart_console_device, 805 .setup = siu_console_setup, 806 .flags = CON_PRINTBUFFER, 807 .index = -1, 808 .data = &siu_uart_driver, 809}; 810 811static int siu_console_init(void) 812{ 813 struct uart_port *port; 814 int i; 815 816 for (i = 0; i < SIU_PORTS_MAX; i++) { 817 port = &siu_uart_ports[i]; 818 port->ops = &siu_uart_ops; 819 } 820 821 register_console(&siu_console); 822 823 return 0; 824} 825 826console_initcall(siu_console_init); 827 828void __init vr41xx_siu_early_setup(struct uart_port *port) 829{ 830 if (port->type == PORT_UNKNOWN) 831 return; 832 833 siu_uart_ports[port->line].line = port->line; 834 siu_uart_ports[port->line].type = port->type; 835 siu_uart_ports[port->line].uartclk = SIU_BAUD_BASE * 16; 836 siu_uart_ports[port->line].mapbase = port->mapbase; 837 siu_uart_ports[port->line].ops = &siu_uart_ops; 838} 839 840#define SERIAL_VR41XX_CONSOLE &siu_console 841#else 842#define SERIAL_VR41XX_CONSOLE NULL 843#endif 844 845static struct uart_driver siu_uart_driver = { 846 .owner = THIS_MODULE, 847 .driver_name = "SIU", 848 .dev_name = "ttyVR", 849 .major = SIU_MAJOR, 850 .minor = SIU_MINOR_BASE, 851 .cons = SERIAL_VR41XX_CONSOLE, 852}; 853 854static int siu_probe(struct platform_device *dev) 855{ 856 struct uart_port *port; 857 int num, i, retval; 858 859 num = siu_init_ports(dev); 860 if (num <= 0) 861 return -ENODEV; 862 863 siu_uart_driver.nr = num; 864 retval = uart_register_driver(&siu_uart_driver); 865 if (retval) 866 return retval; 867 868 for (i = 0; i < num; i++) { 869 port = &siu_uart_ports[i]; 870 port->ops = &siu_uart_ops; 871 port->dev = &dev->dev; 872 873 retval = uart_add_one_port(&siu_uart_driver, port); 874 if (retval < 0) { 875 port->dev = NULL; 876 break; 877 } 878 } 879 880 if (i == 0 && retval < 0) { 881 uart_unregister_driver(&siu_uart_driver); 882 return retval; 883 } 884 885 return 0; 886} 887 888static int siu_remove(struct platform_device *dev) 889{ 890 struct uart_port *port; 891 int i; 892 893 for (i = 0; i < siu_uart_driver.nr; i++) { 894 port = &siu_uart_ports[i]; 895 if (port->dev == &dev->dev) { 896 uart_remove_one_port(&siu_uart_driver, port); 897 port->dev = NULL; 898 } 899 } 900 901 uart_unregister_driver(&siu_uart_driver); 902 903 return 0; 904} 905 906static int siu_suspend(struct platform_device *dev, pm_message_t state) 907{ 908 struct uart_port *port; 909 int i; 910 911 for (i = 0; i < siu_uart_driver.nr; i++) { 912 port = &siu_uart_ports[i]; 913 if ((port->type == PORT_VR41XX_SIU || 914 port->type == PORT_VR41XX_DSIU) && port->dev == &dev->dev) 915 uart_suspend_port(&siu_uart_driver, port); 916 917 } 918 919 return 0; 920} 921 922static int siu_resume(struct platform_device *dev) 923{ 924 struct uart_port *port; 925 int i; 926 927 for (i = 0; i < siu_uart_driver.nr; i++) { 928 port = &siu_uart_ports[i]; 929 if ((port->type == PORT_VR41XX_SIU || 930 port->type == PORT_VR41XX_DSIU) && port->dev == &dev->dev) 931 uart_resume_port(&siu_uart_driver, port); 932 } 933 934 return 0; 935} 936 937static struct platform_driver siu_device_driver = { 938 .probe = siu_probe, 939 .remove = siu_remove, 940 .suspend = siu_suspend, 941 .resume = siu_resume, 942 .driver = { 943 .name = "SIU", 944 }, 945}; 946 947module_platform_driver(siu_device_driver); 948 949MODULE_LICENSE("GPL"); 950MODULE_ALIAS("platform:SIU");