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 v2.6.12-rc3 1177 lines 28 kB view raw
1/* 2 * linux/drivers/serial/cpm_uart.c 3 * 4 * Driver for CPM (SCC/SMC) serial ports; core driver 5 * 6 * Based on arch/ppc/cpm2_io/uart.c by Dan Malek 7 * Based on ppc8xx.c by Thomas Gleixner 8 * Based on drivers/serial/amba.c by Russell King 9 * 10 * Maintainer: Kumar Gala (kumar.gala@freescale.com) (CPM2) 11 * Pantelis Antoniou (panto@intracom.gr) (CPM1) 12 * 13 * Copyright (C) 2004 Freescale Semiconductor, Inc. 14 * (C) 2004 Intracom, S.A. 15 * 16 * This program is free software; you can redistribute it and/or modify 17 * it under the terms of the GNU General Public License as published by 18 * the Free Software Foundation; either version 2 of the License, or 19 * (at your option) any later version. 20 * 21 * This program is distributed in the hope that it will be useful, 22 * but WITHOUT ANY WARRANTY; without even the implied warranty of 23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 24 * GNU General Public License for more details. 25 * 26 * You should have received a copy of the GNU General Public License 27 * along with this program; if not, write to the Free Software 28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 29 * 30 */ 31 32#include <linux/config.h> 33#include <linux/module.h> 34#include <linux/tty.h> 35#include <linux/ioport.h> 36#include <linux/init.h> 37#include <linux/serial.h> 38#include <linux/console.h> 39#include <linux/sysrq.h> 40#include <linux/device.h> 41#include <linux/bootmem.h> 42#include <linux/dma-mapping.h> 43 44#include <asm/io.h> 45#include <asm/irq.h> 46#include <asm/delay.h> 47 48#if defined(CONFIG_SERIAL_CPM_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) 49#define SUPPORT_SYSRQ 50#endif 51 52#include <linux/serial_core.h> 53#include <linux/kernel.h> 54 55#include "cpm_uart.h" 56 57/***********************************************************************/ 58 59/* Track which ports are configured as uarts */ 60int cpm_uart_port_map[UART_NR]; 61/* How many ports did we config as uarts */ 62int cpm_uart_nr; 63 64/**************************************************************/ 65 66static int cpm_uart_tx_pump(struct uart_port *port); 67static void cpm_uart_init_smc(struct uart_cpm_port *pinfo); 68static void cpm_uart_init_scc(struct uart_cpm_port *pinfo); 69static void cpm_uart_initbd(struct uart_cpm_port *pinfo); 70 71/**************************************************************/ 72 73/* 74 * Check, if transmit buffers are processed 75*/ 76static unsigned int cpm_uart_tx_empty(struct uart_port *port) 77{ 78 struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; 79 volatile cbd_t *bdp = pinfo->tx_bd_base; 80 int ret = 0; 81 82 while (1) { 83 if (bdp->cbd_sc & BD_SC_READY) 84 break; 85 86 if (bdp->cbd_sc & BD_SC_WRAP) { 87 ret = TIOCSER_TEMT; 88 break; 89 } 90 bdp++; 91 } 92 93 pr_debug("CPM uart[%d]:tx_empty: %d\n", port->line, ret); 94 95 return ret; 96} 97 98static void cpm_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) 99{ 100 /* Whee. Do nothing. */ 101} 102 103static unsigned int cpm_uart_get_mctrl(struct uart_port *port) 104{ 105 /* Whee. Do nothing. */ 106 return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS; 107} 108 109/* 110 * Stop transmitter 111 */ 112static void cpm_uart_stop_tx(struct uart_port *port, unsigned int tty_stop) 113{ 114 struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; 115 volatile smc_t *smcp = pinfo->smcp; 116 volatile scc_t *sccp = pinfo->sccp; 117 118 pr_debug("CPM uart[%d]:stop tx\n", port->line); 119 120 if (IS_SMC(pinfo)) 121 smcp->smc_smcm &= ~SMCM_TX; 122 else 123 sccp->scc_sccm &= ~UART_SCCM_TX; 124} 125 126/* 127 * Start transmitter 128 */ 129static void cpm_uart_start_tx(struct uart_port *port, unsigned int tty_start) 130{ 131 struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; 132 volatile smc_t *smcp = pinfo->smcp; 133 volatile scc_t *sccp = pinfo->sccp; 134 135 pr_debug("CPM uart[%d]:start tx\n", port->line); 136 137 if (IS_SMC(pinfo)) { 138 if (smcp->smc_smcm & SMCM_TX) 139 return; 140 } else { 141 if (sccp->scc_sccm & UART_SCCM_TX) 142 return; 143 } 144 145 if (cpm_uart_tx_pump(port) != 0) { 146 if (IS_SMC(pinfo)) 147 smcp->smc_smcm |= SMCM_TX; 148 else 149 sccp->scc_sccm |= UART_SCCM_TX; 150 } 151} 152 153/* 154 * Stop receiver 155 */ 156static void cpm_uart_stop_rx(struct uart_port *port) 157{ 158 struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; 159 volatile smc_t *smcp = pinfo->smcp; 160 volatile scc_t *sccp = pinfo->sccp; 161 162 pr_debug("CPM uart[%d]:stop rx\n", port->line); 163 164 if (IS_SMC(pinfo)) 165 smcp->smc_smcm &= ~SMCM_RX; 166 else 167 sccp->scc_sccm &= ~UART_SCCM_RX; 168} 169 170/* 171 * Enable Modem status interrupts 172 */ 173static void cpm_uart_enable_ms(struct uart_port *port) 174{ 175 pr_debug("CPM uart[%d]:enable ms\n", port->line); 176} 177 178/* 179 * Generate a break. 180 */ 181static void cpm_uart_break_ctl(struct uart_port *port, int break_state) 182{ 183 struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; 184 int line = pinfo - cpm_uart_ports; 185 186 pr_debug("CPM uart[%d]:break ctrl, break_state: %d\n", port->line, 187 break_state); 188 189 if (break_state) 190 cpm_line_cr_cmd(line, CPM_CR_STOP_TX); 191 else 192 cpm_line_cr_cmd(line, CPM_CR_RESTART_TX); 193} 194 195/* 196 * Transmit characters, refill buffer descriptor, if possible 197 */ 198static void cpm_uart_int_tx(struct uart_port *port, struct pt_regs *regs) 199{ 200 pr_debug("CPM uart[%d]:TX INT\n", port->line); 201 202 cpm_uart_tx_pump(port); 203} 204 205/* 206 * Receive characters 207 */ 208static void cpm_uart_int_rx(struct uart_port *port, struct pt_regs *regs) 209{ 210 int i; 211 unsigned char ch, *cp; 212 struct tty_struct *tty = port->info->tty; 213 struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; 214 volatile cbd_t *bdp; 215 u16 status; 216 unsigned int flg; 217 218 pr_debug("CPM uart[%d]:RX INT\n", port->line); 219 220 /* Just loop through the closed BDs and copy the characters into 221 * the buffer. 222 */ 223 bdp = pinfo->rx_cur; 224 for (;;) { 225 /* get status */ 226 status = bdp->cbd_sc; 227 /* If this one is empty, return happy */ 228 if (status & BD_SC_EMPTY) 229 break; 230 231 /* get number of characters, and check spce in flip-buffer */ 232 i = bdp->cbd_datlen; 233 234 /* If we have not enough room in tty flip buffer, then we try 235 * later, which will be the next rx-interrupt or a timeout 236 */ 237 if ((tty->flip.count + i) >= TTY_FLIPBUF_SIZE) { 238 tty->flip.work.func((void *)tty); 239 if ((tty->flip.count + i) >= TTY_FLIPBUF_SIZE) { 240 printk(KERN_WARNING "TTY_DONT_FLIP set\n"); 241 return; 242 } 243 } 244 245 /* get pointer */ 246 cp = (unsigned char *)bus_to_virt(bdp->cbd_bufaddr); 247 248 /* loop through the buffer */ 249 while (i-- > 0) { 250 ch = *cp++; 251 port->icount.rx++; 252 flg = TTY_NORMAL; 253 254 if (status & 255 (BD_SC_BR | BD_SC_FR | BD_SC_PR | BD_SC_OV)) 256 goto handle_error; 257 if (uart_handle_sysrq_char(port, ch, regs)) 258 continue; 259 260 error_return: 261 *tty->flip.char_buf_ptr++ = ch; 262 *tty->flip.flag_buf_ptr++ = flg; 263 tty->flip.count++; 264 265 } /* End while (i--) */ 266 267 /* This BD is ready to be used again. Clear status. get next */ 268 bdp->cbd_sc &= ~(BD_SC_BR | BD_SC_FR | BD_SC_PR | BD_SC_OV); 269 bdp->cbd_sc |= BD_SC_EMPTY; 270 271 if (bdp->cbd_sc & BD_SC_WRAP) 272 bdp = pinfo->rx_bd_base; 273 else 274 bdp++; 275 } /* End for (;;) */ 276 277 /* Write back buffer pointer */ 278 pinfo->rx_cur = (volatile cbd_t *) bdp; 279 280 /* activate BH processing */ 281 tty_flip_buffer_push(tty); 282 283 return; 284 285 /* Error processing */ 286 287 handle_error: 288 /* Statistics */ 289 if (status & BD_SC_BR) 290 port->icount.brk++; 291 if (status & BD_SC_PR) 292 port->icount.parity++; 293 if (status & BD_SC_FR) 294 port->icount.frame++; 295 if (status & BD_SC_OV) 296 port->icount.overrun++; 297 298 /* Mask out ignored conditions */ 299 status &= port->read_status_mask; 300 301 /* Handle the remaining ones */ 302 if (status & BD_SC_BR) 303 flg = TTY_BREAK; 304 else if (status & BD_SC_PR) 305 flg = TTY_PARITY; 306 else if (status & BD_SC_FR) 307 flg = TTY_FRAME; 308 309 /* overrun does not affect the current character ! */ 310 if (status & BD_SC_OV) { 311 ch = 0; 312 flg = TTY_OVERRUN; 313 /* We skip this buffer */ 314 /* CHECK: Is really nothing senseful there */ 315 /* ASSUMPTION: it contains nothing valid */ 316 i = 0; 317 } 318#ifdef SUPPORT_SYSRQ 319 port->sysrq = 0; 320#endif 321 goto error_return; 322} 323 324/* 325 * Asynchron mode interrupt handler 326 */ 327static irqreturn_t cpm_uart_int(int irq, void *data, struct pt_regs *regs) 328{ 329 u8 events; 330 struct uart_port *port = (struct uart_port *)data; 331 struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; 332 volatile smc_t *smcp = pinfo->smcp; 333 volatile scc_t *sccp = pinfo->sccp; 334 335 pr_debug("CPM uart[%d]:IRQ\n", port->line); 336 337 if (IS_SMC(pinfo)) { 338 events = smcp->smc_smce; 339 if (events & SMCM_BRKE) 340 uart_handle_break(port); 341 if (events & SMCM_RX) 342 cpm_uart_int_rx(port, regs); 343 if (events & SMCM_TX) 344 cpm_uart_int_tx(port, regs); 345 smcp->smc_smce = events; 346 } else { 347 events = sccp->scc_scce; 348 if (events & UART_SCCM_BRKE) 349 uart_handle_break(port); 350 if (events & UART_SCCM_RX) 351 cpm_uart_int_rx(port, regs); 352 if (events & UART_SCCM_TX) 353 cpm_uart_int_tx(port, regs); 354 sccp->scc_scce = events; 355 } 356 return (events) ? IRQ_HANDLED : IRQ_NONE; 357} 358 359static int cpm_uart_startup(struct uart_port *port) 360{ 361 int retval; 362 struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; 363 364 pr_debug("CPM uart[%d]:startup\n", port->line); 365 366 /* Install interrupt handler. */ 367 retval = request_irq(port->irq, cpm_uart_int, 0, "cpm_uart", port); 368 if (retval) 369 return retval; 370 371 /* Startup rx-int */ 372 if (IS_SMC(pinfo)) { 373 pinfo->smcp->smc_smcm |= SMCM_RX; 374 pinfo->smcp->smc_smcmr |= SMCMR_REN; 375 } else { 376 pinfo->sccp->scc_sccm |= UART_SCCM_RX; 377 } 378 379 return 0; 380} 381 382/* 383 * Shutdown the uart 384 */ 385static void cpm_uart_shutdown(struct uart_port *port) 386{ 387 struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; 388 int line = pinfo - cpm_uart_ports; 389 390 pr_debug("CPM uart[%d]:shutdown\n", port->line); 391 392 /* free interrupt handler */ 393 free_irq(port->irq, port); 394 395 /* If the port is not the console, disable Rx and Tx. */ 396 if (!(pinfo->flags & FLAG_CONSOLE)) { 397 /* Stop uarts */ 398 if (IS_SMC(pinfo)) { 399 volatile smc_t *smcp = pinfo->smcp; 400 smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); 401 smcp->smc_smcm &= ~(SMCM_RX | SMCM_TX); 402 } else { 403 volatile scc_t *sccp = pinfo->sccp; 404 sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); 405 sccp->scc_sccm &= ~(UART_SCCM_TX | UART_SCCM_RX); 406 } 407 408 /* Shut them really down and reinit buffer descriptors */ 409 cpm_line_cr_cmd(line, CPM_CR_STOP_TX); 410 cpm_uart_initbd(pinfo); 411 } 412} 413 414static void cpm_uart_set_termios(struct uart_port *port, 415 struct termios *termios, struct termios *old) 416{ 417 int baud; 418 unsigned long flags; 419 u16 cval, scval, prev_mode; 420 int bits, sbits; 421 struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; 422 volatile smc_t *smcp = pinfo->smcp; 423 volatile scc_t *sccp = pinfo->sccp; 424 425 pr_debug("CPM uart[%d]:set_termios\n", port->line); 426 427 baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16); 428 429 /* Character length programmed into the mode register is the 430 * sum of: 1 start bit, number of data bits, 0 or 1 parity bit, 431 * 1 or 2 stop bits, minus 1. 432 * The value 'bits' counts this for us. 433 */ 434 cval = 0; 435 scval = 0; 436 437 /* byte size */ 438 switch (termios->c_cflag & CSIZE) { 439 case CS5: 440 bits = 5; 441 break; 442 case CS6: 443 bits = 6; 444 break; 445 case CS7: 446 bits = 7; 447 break; 448 case CS8: 449 bits = 8; 450 break; 451 /* Never happens, but GCC is too dumb to figure it out */ 452 default: 453 bits = 8; 454 break; 455 } 456 sbits = bits - 5; 457 458 if (termios->c_cflag & CSTOPB) { 459 cval |= SMCMR_SL; /* Two stops */ 460 scval |= SCU_PSMR_SL; 461 bits++; 462 } 463 464 if (termios->c_cflag & PARENB) { 465 cval |= SMCMR_PEN; 466 scval |= SCU_PSMR_PEN; 467 bits++; 468 if (!(termios->c_cflag & PARODD)) { 469 cval |= SMCMR_PM_EVEN; 470 scval |= (SCU_PSMR_REVP | SCU_PSMR_TEVP); 471 } 472 } 473 474 /* 475 * Set up parity check flag 476 */ 477#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) 478 479 port->read_status_mask = (BD_SC_EMPTY | BD_SC_OV); 480 if (termios->c_iflag & INPCK) 481 port->read_status_mask |= BD_SC_FR | BD_SC_PR; 482 if ((termios->c_iflag & BRKINT) || (termios->c_iflag & PARMRK)) 483 port->read_status_mask |= BD_SC_BR; 484 485 /* 486 * Characters to ignore 487 */ 488 port->ignore_status_mask = 0; 489 if (termios->c_iflag & IGNPAR) 490 port->ignore_status_mask |= BD_SC_PR | BD_SC_FR; 491 if (termios->c_iflag & IGNBRK) { 492 port->ignore_status_mask |= BD_SC_BR; 493 /* 494 * If we're ignore parity and break indicators, ignore 495 * overruns too. (For real raw support). 496 */ 497 if (termios->c_iflag & IGNPAR) 498 port->ignore_status_mask |= BD_SC_OV; 499 } 500 /* 501 * !!! ignore all characters if CREAD is not set 502 */ 503 if ((termios->c_cflag & CREAD) == 0) 504 port->read_status_mask &= ~BD_SC_EMPTY; 505 506 spin_lock_irqsave(&port->lock, flags); 507 508 /* Start bit has not been added (so don't, because we would just 509 * subtract it later), and we need to add one for the number of 510 * stops bits (there is always at least one). 511 */ 512 bits++; 513 if (IS_SMC(pinfo)) { 514 /* Set the mode register. We want to keep a copy of the 515 * enables, because we want to put them back if they were 516 * present. 517 */ 518 prev_mode = smcp->smc_smcmr; 519 smcp->smc_smcmr = smcr_mk_clen(bits) | cval | SMCMR_SM_UART; 520 smcp->smc_smcmr |= (prev_mode & (SMCMR_REN | SMCMR_TEN)); 521 } else { 522 sccp->scc_psmr = (sbits << 12) | scval; 523 } 524 525 cpm_set_brg(pinfo->brg - 1, baud); 526 spin_unlock_irqrestore(&port->lock, flags); 527 528} 529 530static const char *cpm_uart_type(struct uart_port *port) 531{ 532 pr_debug("CPM uart[%d]:uart_type\n", port->line); 533 534 return port->type == PORT_CPM ? "CPM UART" : NULL; 535} 536 537/* 538 * verify the new serial_struct (for TIOCSSERIAL). 539 */ 540static int cpm_uart_verify_port(struct uart_port *port, 541 struct serial_struct *ser) 542{ 543 int ret = 0; 544 545 pr_debug("CPM uart[%d]:verify_port\n", port->line); 546 547 if (ser->type != PORT_UNKNOWN && ser->type != PORT_CPM) 548 ret = -EINVAL; 549 if (ser->irq < 0 || ser->irq >= NR_IRQS) 550 ret = -EINVAL; 551 if (ser->baud_base < 9600) 552 ret = -EINVAL; 553 return ret; 554} 555 556/* 557 * Transmit characters, refill buffer descriptor, if possible 558 */ 559static int cpm_uart_tx_pump(struct uart_port *port) 560{ 561 volatile cbd_t *bdp; 562 unsigned char *p; 563 int count; 564 struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; 565 struct circ_buf *xmit = &port->info->xmit; 566 567 /* Handle xon/xoff */ 568 if (port->x_char) { 569 /* Pick next descriptor and fill from buffer */ 570 bdp = pinfo->tx_cur; 571 572 p = bus_to_virt(bdp->cbd_bufaddr); 573 *p++ = xmit->buf[xmit->tail]; 574 bdp->cbd_datlen = 1; 575 bdp->cbd_sc |= BD_SC_READY; 576 /* Get next BD. */ 577 if (bdp->cbd_sc & BD_SC_WRAP) 578 bdp = pinfo->tx_bd_base; 579 else 580 bdp++; 581 pinfo->tx_cur = bdp; 582 583 port->icount.tx++; 584 port->x_char = 0; 585 return 1; 586 } 587 588 if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { 589 cpm_uart_stop_tx(port, 0); 590 return 0; 591 } 592 593 /* Pick next descriptor and fill from buffer */ 594 bdp = pinfo->tx_cur; 595 596 while (!(bdp->cbd_sc & BD_SC_READY) && (xmit->tail != xmit->head)) { 597 count = 0; 598 p = bus_to_virt(bdp->cbd_bufaddr); 599 while (count < pinfo->tx_fifosize) { 600 *p++ = xmit->buf[xmit->tail]; 601 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); 602 port->icount.tx++; 603 count++; 604 if (xmit->head == xmit->tail) 605 break; 606 } 607 bdp->cbd_datlen = count; 608 bdp->cbd_sc |= BD_SC_READY; 609 /* Get next BD. */ 610 if (bdp->cbd_sc & BD_SC_WRAP) 611 bdp = pinfo->tx_bd_base; 612 else 613 bdp++; 614 } 615 pinfo->tx_cur = bdp; 616 617 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) 618 uart_write_wakeup(port); 619 620 if (uart_circ_empty(xmit)) { 621 cpm_uart_stop_tx(port, 0); 622 return 0; 623 } 624 625 return 1; 626} 627 628/* 629 * init buffer descriptors 630 */ 631static void cpm_uart_initbd(struct uart_cpm_port *pinfo) 632{ 633 int i; 634 u8 *mem_addr; 635 volatile cbd_t *bdp; 636 637 pr_debug("CPM uart[%d]:initbd\n", pinfo->port.line); 638 639 /* Set the physical address of the host memory 640 * buffers in the buffer descriptors, and the 641 * virtual address for us to work with. 642 */ 643 mem_addr = pinfo->mem_addr; 644 bdp = pinfo->rx_cur = pinfo->rx_bd_base; 645 for (i = 0; i < (pinfo->rx_nrfifos - 1); i++, bdp++) { 646 bdp->cbd_bufaddr = virt_to_bus(mem_addr); 647 bdp->cbd_sc = BD_SC_EMPTY | BD_SC_INTRPT; 648 mem_addr += pinfo->rx_fifosize; 649 } 650 651 bdp->cbd_bufaddr = virt_to_bus(mem_addr); 652 bdp->cbd_sc = BD_SC_WRAP | BD_SC_EMPTY | BD_SC_INTRPT; 653 654 /* Set the physical address of the host memory 655 * buffers in the buffer descriptors, and the 656 * virtual address for us to work with. 657 */ 658 mem_addr = pinfo->mem_addr + L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize); 659 bdp = pinfo->tx_cur = pinfo->tx_bd_base; 660 for (i = 0; i < (pinfo->tx_nrfifos - 1); i++, bdp++) { 661 bdp->cbd_bufaddr = virt_to_bus(mem_addr); 662 bdp->cbd_sc = BD_SC_INTRPT; 663 mem_addr += pinfo->tx_fifosize; 664 } 665 666 bdp->cbd_bufaddr = virt_to_bus(mem_addr); 667 bdp->cbd_sc = BD_SC_WRAP | BD_SC_INTRPT; 668} 669 670static void cpm_uart_init_scc(struct uart_cpm_port *pinfo) 671{ 672 int line = pinfo - cpm_uart_ports; 673 volatile scc_t *scp; 674 volatile scc_uart_t *sup; 675 676 pr_debug("CPM uart[%d]:init_scc\n", pinfo->port.line); 677 678 scp = pinfo->sccp; 679 sup = pinfo->sccup; 680 681 /* Store address */ 682 pinfo->sccup->scc_genscc.scc_rbase = (unsigned char *)pinfo->rx_bd_base - DPRAM_BASE; 683 pinfo->sccup->scc_genscc.scc_tbase = (unsigned char *)pinfo->tx_bd_base - DPRAM_BASE; 684 685 /* Set up the uart parameters in the 686 * parameter ram. 687 */ 688 689 cpm_set_scc_fcr(sup); 690 691 sup->scc_genscc.scc_mrblr = pinfo->rx_fifosize; 692 sup->scc_maxidl = pinfo->rx_fifosize; 693 sup->scc_brkcr = 1; 694 sup->scc_parec = 0; 695 sup->scc_frmec = 0; 696 sup->scc_nosec = 0; 697 sup->scc_brkec = 0; 698 sup->scc_uaddr1 = 0; 699 sup->scc_uaddr2 = 0; 700 sup->scc_toseq = 0; 701 sup->scc_char1 = 0x8000; 702 sup->scc_char2 = 0x8000; 703 sup->scc_char3 = 0x8000; 704 sup->scc_char4 = 0x8000; 705 sup->scc_char5 = 0x8000; 706 sup->scc_char6 = 0x8000; 707 sup->scc_char7 = 0x8000; 708 sup->scc_char8 = 0x8000; 709 sup->scc_rccm = 0xc0ff; 710 711 /* Send the CPM an initialize command. 712 */ 713 cpm_line_cr_cmd(line, CPM_CR_INIT_TRX); 714 715 /* Set UART mode, 8 bit, no parity, one stop. 716 * Enable receive and transmit. 717 */ 718 scp->scc_gsmrh = 0; 719 scp->scc_gsmrl = 720 (SCC_GSMRL_MODE_UART | SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16); 721 722 /* Enable rx interrupts and clear all pending events. */ 723 scp->scc_sccm = 0; 724 scp->scc_scce = 0xffff; 725 scp->scc_dsr = 0x7e7e; 726 scp->scc_psmr = 0x3000; 727 728 scp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT); 729} 730 731static void cpm_uart_init_smc(struct uart_cpm_port *pinfo) 732{ 733 int line = pinfo - cpm_uart_ports; 734 volatile smc_t *sp; 735 volatile smc_uart_t *up; 736 737 pr_debug("CPM uart[%d]:init_smc\n", pinfo->port.line); 738 739 sp = pinfo->smcp; 740 up = pinfo->smcup; 741 742 /* Store address */ 743 pinfo->smcup->smc_rbase = (u_char *)pinfo->rx_bd_base - DPRAM_BASE; 744 pinfo->smcup->smc_tbase = (u_char *)pinfo->tx_bd_base - DPRAM_BASE; 745 746/* 747 * In case SMC1 is being relocated... 748 */ 749#if defined (CONFIG_I2C_SPI_SMC1_UCODE_PATCH) 750 up->smc_rbptr = pinfo->smcup->smc_rbase; 751 up->smc_tbptr = pinfo->smcup->smc_tbase; 752 up->smc_rstate = 0; 753 up->smc_tstate = 0; 754 up->smc_brkcr = 1; /* number of break chars */ 755 up->smc_brkec = 0; 756#endif 757 758 /* Set up the uart parameters in the 759 * parameter ram. 760 */ 761 cpm_set_smc_fcr(up); 762 763 /* Using idle charater time requires some additional tuning. */ 764 up->smc_mrblr = pinfo->rx_fifosize; 765 up->smc_maxidl = pinfo->rx_fifosize; 766 up->smc_brkcr = 1; 767 768 cpm_line_cr_cmd(line, CPM_CR_INIT_TRX); 769 770 /* Set UART mode, 8 bit, no parity, one stop. 771 * Enable receive and transmit. 772 */ 773 sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART; 774 775 /* Enable only rx interrupts clear all pending events. */ 776 sp->smc_smcm = 0; 777 sp->smc_smce = 0xff; 778 779 sp->smc_smcmr |= (SMCMR_REN | SMCMR_TEN); 780} 781 782/* 783 * Initialize port. This is called from early_console stuff 784 * so we have to be careful here ! 785 */ 786static int cpm_uart_request_port(struct uart_port *port) 787{ 788 struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; 789 int ret; 790 791 pr_debug("CPM uart[%d]:request port\n", port->line); 792 793 if (pinfo->flags & FLAG_CONSOLE) 794 return 0; 795 796 /* 797 * Setup any port IO, connect any baud rate generators, 798 * etc. This is expected to be handled by board 799 * dependant code 800 */ 801 if (pinfo->set_lineif) 802 pinfo->set_lineif(pinfo); 803 804 if (IS_SMC(pinfo)) { 805 pinfo->smcp->smc_smcm &= ~(SMCM_RX | SMCM_TX); 806 pinfo->smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); 807 } else { 808 pinfo->sccp->scc_sccm &= ~(UART_SCCM_TX | UART_SCCM_RX); 809 pinfo->sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); 810 } 811 812 ret = cpm_uart_allocbuf(pinfo, 0); 813 814 if (ret) 815 return ret; 816 817 cpm_uart_initbd(pinfo); 818 819 return 0; 820} 821 822static void cpm_uart_release_port(struct uart_port *port) 823{ 824 struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; 825 826 if (!(pinfo->flags & FLAG_CONSOLE)) 827 cpm_uart_freebuf(pinfo); 828} 829 830/* 831 * Configure/autoconfigure the port. 832 */ 833static void cpm_uart_config_port(struct uart_port *port, int flags) 834{ 835 pr_debug("CPM uart[%d]:config_port\n", port->line); 836 837 if (flags & UART_CONFIG_TYPE) { 838 port->type = PORT_CPM; 839 cpm_uart_request_port(port); 840 } 841} 842static struct uart_ops cpm_uart_pops = { 843 .tx_empty = cpm_uart_tx_empty, 844 .set_mctrl = cpm_uart_set_mctrl, 845 .get_mctrl = cpm_uart_get_mctrl, 846 .stop_tx = cpm_uart_stop_tx, 847 .start_tx = cpm_uart_start_tx, 848 .stop_rx = cpm_uart_stop_rx, 849 .enable_ms = cpm_uart_enable_ms, 850 .break_ctl = cpm_uart_break_ctl, 851 .startup = cpm_uart_startup, 852 .shutdown = cpm_uart_shutdown, 853 .set_termios = cpm_uart_set_termios, 854 .type = cpm_uart_type, 855 .release_port = cpm_uart_release_port, 856 .request_port = cpm_uart_request_port, 857 .config_port = cpm_uart_config_port, 858 .verify_port = cpm_uart_verify_port, 859}; 860 861struct uart_cpm_port cpm_uart_ports[UART_NR] = { 862 [UART_SMC1] = { 863 .port = { 864 .irq = SMC1_IRQ, 865 .ops = &cpm_uart_pops, 866 .iotype = SERIAL_IO_MEM, 867 .lock = SPIN_LOCK_UNLOCKED, 868 }, 869 .flags = FLAG_SMC, 870 .tx_nrfifos = TX_NUM_FIFO, 871 .tx_fifosize = TX_BUF_SIZE, 872 .rx_nrfifos = RX_NUM_FIFO, 873 .rx_fifosize = RX_BUF_SIZE, 874 .set_lineif = smc1_lineif, 875 }, 876 [UART_SMC2] = { 877 .port = { 878 .irq = SMC2_IRQ, 879 .ops = &cpm_uart_pops, 880 .iotype = SERIAL_IO_MEM, 881 .lock = SPIN_LOCK_UNLOCKED, 882 }, 883 .flags = FLAG_SMC, 884 .tx_nrfifos = TX_NUM_FIFO, 885 .tx_fifosize = TX_BUF_SIZE, 886 .rx_nrfifos = RX_NUM_FIFO, 887 .rx_fifosize = RX_BUF_SIZE, 888 .set_lineif = smc2_lineif, 889#ifdef CONFIG_SERIAL_CPM_ALT_SMC2 890 .is_portb = 1, 891#endif 892 }, 893 [UART_SCC1] = { 894 .port = { 895 .irq = SCC1_IRQ, 896 .ops = &cpm_uart_pops, 897 .iotype = SERIAL_IO_MEM, 898 .lock = SPIN_LOCK_UNLOCKED, 899 }, 900 .tx_nrfifos = TX_NUM_FIFO, 901 .tx_fifosize = TX_BUF_SIZE, 902 .rx_nrfifos = RX_NUM_FIFO, 903 .rx_fifosize = RX_BUF_SIZE, 904 .set_lineif = scc1_lineif, 905 }, 906 [UART_SCC2] = { 907 .port = { 908 .irq = SCC2_IRQ, 909 .ops = &cpm_uart_pops, 910 .iotype = SERIAL_IO_MEM, 911 .lock = SPIN_LOCK_UNLOCKED, 912 }, 913 .tx_nrfifos = TX_NUM_FIFO, 914 .tx_fifosize = TX_BUF_SIZE, 915 .rx_nrfifos = RX_NUM_FIFO, 916 .rx_fifosize = RX_BUF_SIZE, 917 .set_lineif = scc2_lineif, 918 }, 919 [UART_SCC3] = { 920 .port = { 921 .irq = SCC3_IRQ, 922 .ops = &cpm_uart_pops, 923 .iotype = SERIAL_IO_MEM, 924 .lock = SPIN_LOCK_UNLOCKED, 925 }, 926 .tx_nrfifos = TX_NUM_FIFO, 927 .tx_fifosize = TX_BUF_SIZE, 928 .rx_nrfifos = RX_NUM_FIFO, 929 .rx_fifosize = RX_BUF_SIZE, 930 .set_lineif = scc3_lineif, 931 }, 932 [UART_SCC4] = { 933 .port = { 934 .irq = SCC4_IRQ, 935 .ops = &cpm_uart_pops, 936 .iotype = SERIAL_IO_MEM, 937 .lock = SPIN_LOCK_UNLOCKED, 938 }, 939 .tx_nrfifos = TX_NUM_FIFO, 940 .tx_fifosize = TX_BUF_SIZE, 941 .rx_nrfifos = RX_NUM_FIFO, 942 .rx_fifosize = RX_BUF_SIZE, 943 .set_lineif = scc4_lineif, 944 }, 945}; 946 947#ifdef CONFIG_SERIAL_CPM_CONSOLE 948/* 949 * Print a string to the serial port trying not to disturb 950 * any possible real use of the port... 951 * 952 * Note that this is called with interrupts already disabled 953 */ 954static void cpm_uart_console_write(struct console *co, const char *s, 955 u_int count) 956{ 957 struct uart_cpm_port *pinfo = 958 &cpm_uart_ports[cpm_uart_port_map[co->index]]; 959 unsigned int i; 960 volatile cbd_t *bdp, *bdbase; 961 volatile unsigned char *cp; 962 963 /* Get the address of the host memory buffer. 964 */ 965 bdp = pinfo->tx_cur; 966 bdbase = pinfo->tx_bd_base; 967 968 /* 969 * Now, do each character. This is not as bad as it looks 970 * since this is a holding FIFO and not a transmitting FIFO. 971 * We could add the complexity of filling the entire transmit 972 * buffer, but we would just wait longer between accesses...... 973 */ 974 for (i = 0; i < count; i++, s++) { 975 /* Wait for transmitter fifo to empty. 976 * Ready indicates output is ready, and xmt is doing 977 * that, not that it is ready for us to send. 978 */ 979 while ((bdp->cbd_sc & BD_SC_READY) != 0) 980 ; 981 982 /* Send the character out. 983 * If the buffer address is in the CPM DPRAM, don't 984 * convert it. 985 */ 986 if ((uint) (bdp->cbd_bufaddr) > (uint) CPM_ADDR) 987 cp = (unsigned char *) (bdp->cbd_bufaddr); 988 else 989 cp = bus_to_virt(bdp->cbd_bufaddr); 990 991 *cp = *s; 992 993 bdp->cbd_datlen = 1; 994 bdp->cbd_sc |= BD_SC_READY; 995 996 if (bdp->cbd_sc & BD_SC_WRAP) 997 bdp = bdbase; 998 else 999 bdp++; 1000 1001 /* if a LF, also do CR... */ 1002 if (*s == 10) { 1003 while ((bdp->cbd_sc & BD_SC_READY) != 0) 1004 ; 1005 1006 if ((uint) (bdp->cbd_bufaddr) > (uint) CPM_ADDR) 1007 cp = (unsigned char *) (bdp->cbd_bufaddr); 1008 else 1009 cp = bus_to_virt(bdp->cbd_bufaddr); 1010 1011 *cp = 13; 1012 bdp->cbd_datlen = 1; 1013 bdp->cbd_sc |= BD_SC_READY; 1014 1015 if (bdp->cbd_sc & BD_SC_WRAP) 1016 bdp = bdbase; 1017 else 1018 bdp++; 1019 } 1020 } 1021 1022 /* 1023 * Finally, Wait for transmitter & holding register to empty 1024 * and restore the IER 1025 */ 1026 while ((bdp->cbd_sc & BD_SC_READY) != 0) 1027 ; 1028 1029 pinfo->tx_cur = (volatile cbd_t *) bdp; 1030} 1031 1032/* 1033 * Setup console. Be careful is called early ! 1034 */ 1035static int __init cpm_uart_console_setup(struct console *co, char *options) 1036{ 1037 struct uart_port *port; 1038 struct uart_cpm_port *pinfo; 1039 int baud = 38400; 1040 int bits = 8; 1041 int parity = 'n'; 1042 int flow = 'n'; 1043 int ret; 1044 1045 port = 1046 (struct uart_port *)&cpm_uart_ports[cpm_uart_port_map[co->index]]; 1047 pinfo = (struct uart_cpm_port *)port; 1048 1049 pinfo->flags |= FLAG_CONSOLE; 1050 1051 if (options) { 1052 uart_parse_options(options, &baud, &parity, &bits, &flow); 1053 } else { 1054 bd_t *bd = (bd_t *) __res; 1055 1056 if (bd->bi_baudrate) 1057 baud = bd->bi_baudrate; 1058 else 1059 baud = 9600; 1060 } 1061 1062 /* 1063 * Setup any port IO, connect any baud rate generators, 1064 * etc. This is expected to be handled by board 1065 * dependant code 1066 */ 1067 if (pinfo->set_lineif) 1068 pinfo->set_lineif(pinfo); 1069 1070 if (IS_SMC(pinfo)) { 1071 pinfo->smcp->smc_smcm &= ~(SMCM_RX | SMCM_TX); 1072 pinfo->smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); 1073 } else { 1074 pinfo->sccp->scc_sccm &= ~(UART_SCCM_TX | UART_SCCM_RX); 1075 pinfo->sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); 1076 } 1077 1078 ret = cpm_uart_allocbuf(pinfo, 1); 1079 1080 if (ret) 1081 return ret; 1082 1083 cpm_uart_initbd(pinfo); 1084 1085 if (IS_SMC(pinfo)) 1086 cpm_uart_init_smc(pinfo); 1087 else 1088 cpm_uart_init_scc(pinfo); 1089 1090 uart_set_options(port, co, baud, parity, bits, flow); 1091 1092 return 0; 1093} 1094 1095extern struct uart_driver cpm_reg; 1096static struct console cpm_scc_uart_console = { 1097 .name "ttyCPM", 1098 .write cpm_uart_console_write, 1099 .device uart_console_device, 1100 .setup cpm_uart_console_setup, 1101 .flags CON_PRINTBUFFER, 1102 .index -1, 1103 .data = &cpm_reg, 1104}; 1105 1106int __init cpm_uart_console_init(void) 1107{ 1108 int ret = cpm_uart_init_portdesc(); 1109 1110 if (!ret) 1111 register_console(&cpm_scc_uart_console); 1112 return ret; 1113} 1114 1115console_initcall(cpm_uart_console_init); 1116 1117#define CPM_UART_CONSOLE &cpm_scc_uart_console 1118#else 1119#define CPM_UART_CONSOLE NULL 1120#endif 1121 1122static struct uart_driver cpm_reg = { 1123 .owner = THIS_MODULE, 1124 .driver_name = "ttyCPM", 1125 .dev_name = "ttyCPM", 1126 .major = SERIAL_CPM_MAJOR, 1127 .minor = SERIAL_CPM_MINOR, 1128 .cons = CPM_UART_CONSOLE, 1129}; 1130 1131static int __init cpm_uart_init(void) 1132{ 1133 int ret, i; 1134 1135 printk(KERN_INFO "Serial: CPM driver $Revision: 0.01 $\n"); 1136 1137#ifndef CONFIG_SERIAL_CPM_CONSOLE 1138 ret = cpm_uart_init_portdesc(); 1139 if (ret) 1140 return ret; 1141#endif 1142 1143 cpm_reg.nr = cpm_uart_nr; 1144 ret = uart_register_driver(&cpm_reg); 1145 1146 if (ret) 1147 return ret; 1148 1149 for (i = 0; i < cpm_uart_nr; i++) { 1150 int con = cpm_uart_port_map[i]; 1151 cpm_uart_ports[con].port.line = i; 1152 cpm_uart_ports[con].port.flags = UPF_BOOT_AUTOCONF; 1153 uart_add_one_port(&cpm_reg, &cpm_uart_ports[con].port); 1154 } 1155 1156 return ret; 1157} 1158 1159static void __exit cpm_uart_exit(void) 1160{ 1161 int i; 1162 1163 for (i = 0; i < cpm_uart_nr; i++) { 1164 int con = cpm_uart_port_map[i]; 1165 uart_remove_one_port(&cpm_reg, &cpm_uart_ports[con].port); 1166 } 1167 1168 uart_unregister_driver(&cpm_reg); 1169} 1170 1171module_init(cpm_uart_init); 1172module_exit(cpm_uart_exit); 1173 1174MODULE_AUTHOR("Kumar Gala/Antoniou Pantelis"); 1175MODULE_DESCRIPTION("CPM SCC/SMC port driver $Revision: 0.01 $"); 1176MODULE_LICENSE("GPL"); 1177MODULE_ALIAS_CHARDEV(SERIAL_CPM_MAJOR, SERIAL_CPM_MINOR);