root/drivers/tty/serial/sunzilog.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. read_zsreg
  2. write_zsreg
  3. sunzilog_clear_fifo
  4. __load_zsregs
  5. sunzilog_maybe_update_regs
  6. sunzilog_change_mouse_baud
  7. sunzilog_kbdms_receive_chars
  8. sunzilog_receive_chars
  9. sunzilog_status_handle
  10. sunzilog_transmit_chars
  11. sunzilog_interrupt
  12. sunzilog_read_channel_status
  13. sunzilog_tx_empty
  14. sunzilog_get_mctrl
  15. sunzilog_set_mctrl
  16. sunzilog_stop_tx
  17. sunzilog_start_tx
  18. sunzilog_stop_rx
  19. sunzilog_enable_ms
  20. sunzilog_break_ctl
  21. __sunzilog_startup
  22. sunzilog_startup
  23. sunzilog_shutdown
  24. sunzilog_convert_to_zs
  25. sunzilog_set_termios
  26. sunzilog_type
  27. sunzilog_release_port
  28. sunzilog_request_port
  29. sunzilog_config_port
  30. sunzilog_verify_port
  31. sunzilog_get_poll_char
  32. sunzilog_put_poll_char
  33. sunzilog_alloc_tables
  34. sunzilog_free_tables
  35. sunzilog_putchar
  36. sunzilog_serio_write
  37. sunzilog_serio_open
  38. sunzilog_serio_close
  39. sunzilog_console_write
  40. sunzilog_console_setup
  41. SUNZILOG_CONSOLE
  42. sunzilog_init_kbdms
  43. sunzilog_register_serio
  44. sunzilog_init_hw
  45. zs_probe
  46. zs_remove_one
  47. zs_remove
  48. sunzilog_init
  49. sunzilog_exit

   1 // SPDX-License-Identifier: GPL-2.0
   2 /* sunzilog.c: Zilog serial driver for Sparc systems.
   3  *
   4  * Driver for Zilog serial chips found on Sun workstations and
   5  * servers.  This driver could actually be made more generic.
   6  *
   7  * This is based on the old drivers/sbus/char/zs.c code.  A lot
   8  * of code has been simply moved over directly from there but
   9  * much has been rewritten.  Credits therefore go out to Eddie
  10  * C. Dost, Pete Zaitcev, Ted Ts'o and Alex Buell for their
  11  * work there.
  12  *
  13  * Copyright (C) 2002, 2006, 2007 David S. Miller (davem@davemloft.net)
  14  */
  15 
  16 #include <linux/module.h>
  17 #include <linux/kernel.h>
  18 #include <linux/errno.h>
  19 #include <linux/delay.h>
  20 #include <linux/tty.h>
  21 #include <linux/tty_flip.h>
  22 #include <linux/major.h>
  23 #include <linux/string.h>
  24 #include <linux/ptrace.h>
  25 #include <linux/ioport.h>
  26 #include <linux/slab.h>
  27 #include <linux/circ_buf.h>
  28 #include <linux/serial.h>
  29 #include <linux/sysrq.h>
  30 #include <linux/console.h>
  31 #include <linux/spinlock.h>
  32 #ifdef CONFIG_SERIO
  33 #include <linux/serio.h>
  34 #endif
  35 #include <linux/init.h>
  36 #include <linux/of_device.h>
  37 
  38 #include <asm/io.h>
  39 #include <asm/irq.h>
  40 #include <asm/prom.h>
  41 #include <asm/setup.h>
  42 
  43 #if defined(CONFIG_SERIAL_SUNZILOG_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
  44 #define SUPPORT_SYSRQ
  45 #endif
  46 
  47 #include <linux/serial_core.h>
  48 #include <linux/sunserialcore.h>
  49 
  50 #include "sunzilog.h"
  51 
  52 /* On 32-bit sparcs we need to delay after register accesses
  53  * to accommodate sun4 systems, but we do not need to flush writes.
  54  * On 64-bit sparc we only need to flush single writes to ensure
  55  * completion.
  56  */
  57 #ifndef CONFIG_SPARC64
  58 #define ZSDELAY()               udelay(5)
  59 #define ZSDELAY_LONG()          udelay(20)
  60 #define ZS_WSYNC(channel)       do { } while (0)
  61 #else
  62 #define ZSDELAY()
  63 #define ZSDELAY_LONG()
  64 #define ZS_WSYNC(__channel) \
  65         readb(&((__channel)->control))
  66 #endif
  67 
  68 #define ZS_CLOCK                4915200 /* Zilog input clock rate. */
  69 #define ZS_CLOCK_DIVISOR        16      /* Divisor this driver uses. */
  70 
  71 /*
  72  * We wrap our port structure around the generic uart_port.
  73  */
  74 struct uart_sunzilog_port {
  75         struct uart_port                port;
  76 
  77         /* IRQ servicing chain.  */
  78         struct uart_sunzilog_port       *next;
  79 
  80         /* Current values of Zilog write registers.  */
  81         unsigned char                   curregs[NUM_ZSREGS];
  82 
  83         unsigned int                    flags;
  84 #define SUNZILOG_FLAG_CONS_KEYB         0x00000001
  85 #define SUNZILOG_FLAG_CONS_MOUSE        0x00000002
  86 #define SUNZILOG_FLAG_IS_CONS           0x00000004
  87 #define SUNZILOG_FLAG_IS_KGDB           0x00000008
  88 #define SUNZILOG_FLAG_MODEM_STATUS      0x00000010
  89 #define SUNZILOG_FLAG_IS_CHANNEL_A      0x00000020
  90 #define SUNZILOG_FLAG_REGS_HELD         0x00000040
  91 #define SUNZILOG_FLAG_TX_STOPPED        0x00000080
  92 #define SUNZILOG_FLAG_TX_ACTIVE         0x00000100
  93 #define SUNZILOG_FLAG_ESCC              0x00000200
  94 #define SUNZILOG_FLAG_ISR_HANDLER       0x00000400
  95 
  96         unsigned int cflag;
  97 
  98         unsigned char                   parity_mask;
  99         unsigned char                   prev_status;
 100 
 101 #ifdef CONFIG_SERIO
 102         struct serio                    serio;
 103         int                             serio_open;
 104 #endif
 105 };
 106 
 107 static void sunzilog_putchar(struct uart_port *port, int ch);
 108 
 109 #define ZILOG_CHANNEL_FROM_PORT(PORT)   ((struct zilog_channel __iomem *)((PORT)->membase))
 110 #define UART_ZILOG(PORT)                ((struct uart_sunzilog_port *)(PORT))
 111 
 112 #define ZS_IS_KEYB(UP)  ((UP)->flags & SUNZILOG_FLAG_CONS_KEYB)
 113 #define ZS_IS_MOUSE(UP) ((UP)->flags & SUNZILOG_FLAG_CONS_MOUSE)
 114 #define ZS_IS_CONS(UP)  ((UP)->flags & SUNZILOG_FLAG_IS_CONS)
 115 #define ZS_IS_KGDB(UP)  ((UP)->flags & SUNZILOG_FLAG_IS_KGDB)
 116 #define ZS_WANTS_MODEM_STATUS(UP)       ((UP)->flags & SUNZILOG_FLAG_MODEM_STATUS)
 117 #define ZS_IS_CHANNEL_A(UP)     ((UP)->flags & SUNZILOG_FLAG_IS_CHANNEL_A)
 118 #define ZS_REGS_HELD(UP)        ((UP)->flags & SUNZILOG_FLAG_REGS_HELD)
 119 #define ZS_TX_STOPPED(UP)       ((UP)->flags & SUNZILOG_FLAG_TX_STOPPED)
 120 #define ZS_TX_ACTIVE(UP)        ((UP)->flags & SUNZILOG_FLAG_TX_ACTIVE)
 121 
 122 /* Reading and writing Zilog8530 registers.  The delays are to make this
 123  * driver work on the Sun4 which needs a settling delay after each chip
 124  * register access, other machines handle this in hardware via auxiliary
 125  * flip-flops which implement the settle time we do in software.
 126  *
 127  * The port lock must be held and local IRQs must be disabled
 128  * when {read,write}_zsreg is invoked.
 129  */
 130 static unsigned char read_zsreg(struct zilog_channel __iomem *channel,
 131                                 unsigned char reg)
 132 {
 133         unsigned char retval;
 134 
 135         writeb(reg, &channel->control);
 136         ZSDELAY();
 137         retval = readb(&channel->control);
 138         ZSDELAY();
 139 
 140         return retval;
 141 }
 142 
 143 static void write_zsreg(struct zilog_channel __iomem *channel,
 144                         unsigned char reg, unsigned char value)
 145 {
 146         writeb(reg, &channel->control);
 147         ZSDELAY();
 148         writeb(value, &channel->control);
 149         ZSDELAY();
 150 }
 151 
 152 static void sunzilog_clear_fifo(struct zilog_channel __iomem *channel)
 153 {
 154         int i;
 155 
 156         for (i = 0; i < 32; i++) {
 157                 unsigned char regval;
 158 
 159                 regval = readb(&channel->control);
 160                 ZSDELAY();
 161                 if (regval & Rx_CH_AV)
 162                         break;
 163 
 164                 regval = read_zsreg(channel, R1);
 165                 readb(&channel->data);
 166                 ZSDELAY();
 167 
 168                 if (regval & (PAR_ERR | Rx_OVR | CRC_ERR)) {
 169                         writeb(ERR_RES, &channel->control);
 170                         ZSDELAY();
 171                         ZS_WSYNC(channel);
 172                 }
 173         }
 174 }
 175 
 176 /* This function must only be called when the TX is not busy.  The UART
 177  * port lock must be held and local interrupts disabled.
 178  */
 179 static int __load_zsregs(struct zilog_channel __iomem *channel, unsigned char *regs)
 180 {
 181         int i;
 182         int escc;
 183         unsigned char r15;
 184 
 185         /* Let pending transmits finish.  */
 186         for (i = 0; i < 1000; i++) {
 187                 unsigned char stat = read_zsreg(channel, R1);
 188                 if (stat & ALL_SNT)
 189                         break;
 190                 udelay(100);
 191         }
 192 
 193         writeb(ERR_RES, &channel->control);
 194         ZSDELAY();
 195         ZS_WSYNC(channel);
 196 
 197         sunzilog_clear_fifo(channel);
 198 
 199         /* Disable all interrupts.  */
 200         write_zsreg(channel, R1,
 201                     regs[R1] & ~(RxINT_MASK | TxINT_ENAB | EXT_INT_ENAB));
 202 
 203         /* Set parity, sync config, stop bits, and clock divisor.  */
 204         write_zsreg(channel, R4, regs[R4]);
 205 
 206         /* Set misc. TX/RX control bits.  */
 207         write_zsreg(channel, R10, regs[R10]);
 208 
 209         /* Set TX/RX controls sans the enable bits.  */
 210         write_zsreg(channel, R3, regs[R3] & ~RxENAB);
 211         write_zsreg(channel, R5, regs[R5] & ~TxENAB);
 212 
 213         /* Synchronous mode config.  */
 214         write_zsreg(channel, R6, regs[R6]);
 215         write_zsreg(channel, R7, regs[R7]);
 216 
 217         /* Don't mess with the interrupt vector (R2, unused by us) and
 218          * master interrupt control (R9).  We make sure this is setup
 219          * properly at probe time then never touch it again.
 220          */
 221 
 222         /* Disable baud generator.  */
 223         write_zsreg(channel, R14, regs[R14] & ~BRENAB);
 224 
 225         /* Clock mode control.  */
 226         write_zsreg(channel, R11, regs[R11]);
 227 
 228         /* Lower and upper byte of baud rate generator divisor.  */
 229         write_zsreg(channel, R12, regs[R12]);
 230         write_zsreg(channel, R13, regs[R13]);
 231         
 232         /* Now rewrite R14, with BRENAB (if set).  */
 233         write_zsreg(channel, R14, regs[R14]);
 234 
 235         /* External status interrupt control.  */
 236         write_zsreg(channel, R15, (regs[R15] | WR7pEN) & ~FIFOEN);
 237 
 238         /* ESCC Extension Register */
 239         r15 = read_zsreg(channel, R15);
 240         if (r15 & 0x01) {
 241                 write_zsreg(channel, R7,  regs[R7p]);
 242 
 243                 /* External status interrupt and FIFO control.  */
 244                 write_zsreg(channel, R15, regs[R15] & ~WR7pEN);
 245                 escc = 1;
 246         } else {
 247                  /* Clear FIFO bit case it is an issue */
 248                 regs[R15] &= ~FIFOEN;
 249                 escc = 0;
 250         }
 251 
 252         /* Reset external status interrupts.  */
 253         write_zsreg(channel, R0, RES_EXT_INT); /* First Latch  */
 254         write_zsreg(channel, R0, RES_EXT_INT); /* Second Latch */
 255 
 256         /* Rewrite R3/R5, this time without enables masked.  */
 257         write_zsreg(channel, R3, regs[R3]);
 258         write_zsreg(channel, R5, regs[R5]);
 259 
 260         /* Rewrite R1, this time without IRQ enabled masked.  */
 261         write_zsreg(channel, R1, regs[R1]);
 262 
 263         return escc;
 264 }
 265 
 266 /* Reprogram the Zilog channel HW registers with the copies found in the
 267  * software state struct.  If the transmitter is busy, we defer this update
 268  * until the next TX complete interrupt.  Else, we do it right now.
 269  *
 270  * The UART port lock must be held and local interrupts disabled.
 271  */
 272 static void sunzilog_maybe_update_regs(struct uart_sunzilog_port *up,
 273                                        struct zilog_channel __iomem *channel)
 274 {
 275         if (!ZS_REGS_HELD(up)) {
 276                 if (ZS_TX_ACTIVE(up)) {
 277                         up->flags |= SUNZILOG_FLAG_REGS_HELD;
 278                 } else {
 279                         __load_zsregs(channel, up->curregs);
 280                 }
 281         }
 282 }
 283 
 284 static void sunzilog_change_mouse_baud(struct uart_sunzilog_port *up)
 285 {
 286         unsigned int cur_cflag = up->cflag;
 287         int brg, new_baud;
 288 
 289         up->cflag &= ~CBAUD;
 290         up->cflag |= suncore_mouse_baud_cflag_next(cur_cflag, &new_baud);
 291 
 292         brg = BPS_TO_BRG(new_baud, ZS_CLOCK / ZS_CLOCK_DIVISOR);
 293         up->curregs[R12] = (brg & 0xff);
 294         up->curregs[R13] = (brg >> 8) & 0xff;
 295         sunzilog_maybe_update_regs(up, ZILOG_CHANNEL_FROM_PORT(&up->port));
 296 }
 297 
 298 static void sunzilog_kbdms_receive_chars(struct uart_sunzilog_port *up,
 299                                          unsigned char ch, int is_break)
 300 {
 301         if (ZS_IS_KEYB(up)) {
 302                 /* Stop-A is handled by drivers/char/keyboard.c now. */
 303 #ifdef CONFIG_SERIO
 304                 if (up->serio_open)
 305                         serio_interrupt(&up->serio, ch, 0);
 306 #endif
 307         } else if (ZS_IS_MOUSE(up)) {
 308                 int ret = suncore_mouse_baud_detection(ch, is_break);
 309 
 310                 switch (ret) {
 311                 case 2:
 312                         sunzilog_change_mouse_baud(up);
 313                         /* fallthru */
 314                 case 1:
 315                         break;
 316 
 317                 case 0:
 318 #ifdef CONFIG_SERIO
 319                         if (up->serio_open)
 320                                 serio_interrupt(&up->serio, ch, 0);
 321 #endif
 322                         break;
 323                 }
 324         }
 325 }
 326 
 327 static struct tty_port *
 328 sunzilog_receive_chars(struct uart_sunzilog_port *up,
 329                        struct zilog_channel __iomem *channel)
 330 {
 331         struct tty_port *port = NULL;
 332         unsigned char ch, r1, flag;
 333 
 334         if (up->port.state != NULL)             /* Unopened serial console */
 335                 port = &up->port.state->port;
 336 
 337         for (;;) {
 338 
 339                 r1 = read_zsreg(channel, R1);
 340                 if (r1 & (PAR_ERR | Rx_OVR | CRC_ERR)) {
 341                         writeb(ERR_RES, &channel->control);
 342                         ZSDELAY();
 343                         ZS_WSYNC(channel);
 344                 }
 345 
 346                 ch = readb(&channel->control);
 347                 ZSDELAY();
 348 
 349                 /* This funny hack depends upon BRK_ABRT not interfering
 350                  * with the other bits we care about in R1.
 351                  */
 352                 if (ch & BRK_ABRT)
 353                         r1 |= BRK_ABRT;
 354 
 355                 if (!(ch & Rx_CH_AV))
 356                         break;
 357 
 358                 ch = readb(&channel->data);
 359                 ZSDELAY();
 360 
 361                 ch &= up->parity_mask;
 362 
 363                 if (unlikely(ZS_IS_KEYB(up)) || unlikely(ZS_IS_MOUSE(up))) {
 364                         sunzilog_kbdms_receive_chars(up, ch, 0);
 365                         continue;
 366                 }
 367 
 368                 /* A real serial line, record the character and status.  */
 369                 flag = TTY_NORMAL;
 370                 up->port.icount.rx++;
 371                 if (r1 & (BRK_ABRT | PAR_ERR | Rx_OVR | CRC_ERR)) {
 372                         if (r1 & BRK_ABRT) {
 373                                 r1 &= ~(PAR_ERR | CRC_ERR);
 374                                 up->port.icount.brk++;
 375                                 if (uart_handle_break(&up->port))
 376                                         continue;
 377                         }
 378                         else if (r1 & PAR_ERR)
 379                                 up->port.icount.parity++;
 380                         else if (r1 & CRC_ERR)
 381                                 up->port.icount.frame++;
 382                         if (r1 & Rx_OVR)
 383                                 up->port.icount.overrun++;
 384                         r1 &= up->port.read_status_mask;
 385                         if (r1 & BRK_ABRT)
 386                                 flag = TTY_BREAK;
 387                         else if (r1 & PAR_ERR)
 388                                 flag = TTY_PARITY;
 389                         else if (r1 & CRC_ERR)
 390                                 flag = TTY_FRAME;
 391                 }
 392                 if (uart_handle_sysrq_char(&up->port, ch) || !port)
 393                         continue;
 394 
 395                 if (up->port.ignore_status_mask == 0xff ||
 396                     (r1 & up->port.ignore_status_mask) == 0) {
 397                         tty_insert_flip_char(port, ch, flag);
 398                 }
 399                 if (r1 & Rx_OVR)
 400                         tty_insert_flip_char(port, 0, TTY_OVERRUN);
 401         }
 402 
 403         return port;
 404 }
 405 
 406 static void sunzilog_status_handle(struct uart_sunzilog_port *up,
 407                                    struct zilog_channel __iomem *channel)
 408 {
 409         unsigned char status;
 410 
 411         status = readb(&channel->control);
 412         ZSDELAY();
 413 
 414         writeb(RES_EXT_INT, &channel->control);
 415         ZSDELAY();
 416         ZS_WSYNC(channel);
 417 
 418         if (status & BRK_ABRT) {
 419                 if (ZS_IS_MOUSE(up))
 420                         sunzilog_kbdms_receive_chars(up, 0, 1);
 421                 if (ZS_IS_CONS(up)) {
 422                         /* Wait for BREAK to deassert to avoid potentially
 423                          * confusing the PROM.
 424                          */
 425                         while (1) {
 426                                 status = readb(&channel->control);
 427                                 ZSDELAY();
 428                                 if (!(status & BRK_ABRT))
 429                                         break;
 430                         }
 431                         sun_do_break();
 432                         return;
 433                 }
 434         }
 435 
 436         if (ZS_WANTS_MODEM_STATUS(up)) {
 437                 if (status & SYNC)
 438                         up->port.icount.dsr++;
 439 
 440                 /* The Zilog just gives us an interrupt when DCD/CTS/etc. change.
 441                  * But it does not tell us which bit has changed, we have to keep
 442                  * track of this ourselves.
 443                  */
 444                 if ((status ^ up->prev_status) ^ DCD)
 445                         uart_handle_dcd_change(&up->port,
 446                                                (status & DCD));
 447                 if ((status ^ up->prev_status) ^ CTS)
 448                         uart_handle_cts_change(&up->port,
 449                                                (status & CTS));
 450 
 451                 wake_up_interruptible(&up->port.state->port.delta_msr_wait);
 452         }
 453 
 454         up->prev_status = status;
 455 }
 456 
 457 static void sunzilog_transmit_chars(struct uart_sunzilog_port *up,
 458                                     struct zilog_channel __iomem *channel)
 459 {
 460         struct circ_buf *xmit;
 461 
 462         if (ZS_IS_CONS(up)) {
 463                 unsigned char status = readb(&channel->control);
 464                 ZSDELAY();
 465 
 466                 /* TX still busy?  Just wait for the next TX done interrupt.
 467                  *
 468                  * It can occur because of how we do serial console writes.  It would
 469                  * be nice to transmit console writes just like we normally would for
 470                  * a TTY line. (ie. buffered and TX interrupt driven).  That is not
 471                  * easy because console writes cannot sleep.  One solution might be
 472                  * to poll on enough port->xmit space becoming free.  -DaveM
 473                  */
 474                 if (!(status & Tx_BUF_EMP))
 475                         return;
 476         }
 477 
 478         up->flags &= ~SUNZILOG_FLAG_TX_ACTIVE;
 479 
 480         if (ZS_REGS_HELD(up)) {
 481                 __load_zsregs(channel, up->curregs);
 482                 up->flags &= ~SUNZILOG_FLAG_REGS_HELD;
 483         }
 484 
 485         if (ZS_TX_STOPPED(up)) {
 486                 up->flags &= ~SUNZILOG_FLAG_TX_STOPPED;
 487                 goto ack_tx_int;
 488         }
 489 
 490         if (up->port.x_char) {
 491                 up->flags |= SUNZILOG_FLAG_TX_ACTIVE;
 492                 writeb(up->port.x_char, &channel->data);
 493                 ZSDELAY();
 494                 ZS_WSYNC(channel);
 495 
 496                 up->port.icount.tx++;
 497                 up->port.x_char = 0;
 498                 return;
 499         }
 500 
 501         if (up->port.state == NULL)
 502                 goto ack_tx_int;
 503         xmit = &up->port.state->xmit;
 504         if (uart_circ_empty(xmit))
 505                 goto ack_tx_int;
 506 
 507         if (uart_tx_stopped(&up->port))
 508                 goto ack_tx_int;
 509 
 510         up->flags |= SUNZILOG_FLAG_TX_ACTIVE;
 511         writeb(xmit->buf[xmit->tail], &channel->data);
 512         ZSDELAY();
 513         ZS_WSYNC(channel);
 514 
 515         xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
 516         up->port.icount.tx++;
 517 
 518         if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
 519                 uart_write_wakeup(&up->port);
 520 
 521         return;
 522 
 523 ack_tx_int:
 524         writeb(RES_Tx_P, &channel->control);
 525         ZSDELAY();
 526         ZS_WSYNC(channel);
 527 }
 528 
 529 static irqreturn_t sunzilog_interrupt(int irq, void *dev_id)
 530 {
 531         struct uart_sunzilog_port *up = dev_id;
 532 
 533         while (up) {
 534                 struct zilog_channel __iomem *channel
 535                         = ZILOG_CHANNEL_FROM_PORT(&up->port);
 536                 struct tty_port *port;
 537                 unsigned char r3;
 538 
 539                 spin_lock(&up->port.lock);
 540                 r3 = read_zsreg(channel, R3);
 541 
 542                 /* Channel A */
 543                 port = NULL;
 544                 if (r3 & (CHAEXT | CHATxIP | CHARxIP)) {
 545                         writeb(RES_H_IUS, &channel->control);
 546                         ZSDELAY();
 547                         ZS_WSYNC(channel);
 548 
 549                         if (r3 & CHARxIP)
 550                                 port = sunzilog_receive_chars(up, channel);
 551                         if (r3 & CHAEXT)
 552                                 sunzilog_status_handle(up, channel);
 553                         if (r3 & CHATxIP)
 554                                 sunzilog_transmit_chars(up, channel);
 555                 }
 556                 spin_unlock(&up->port.lock);
 557 
 558                 if (port)
 559                         tty_flip_buffer_push(port);
 560 
 561                 /* Channel B */
 562                 up = up->next;
 563                 channel = ZILOG_CHANNEL_FROM_PORT(&up->port);
 564 
 565                 spin_lock(&up->port.lock);
 566                 port = NULL;
 567                 if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) {
 568                         writeb(RES_H_IUS, &channel->control);
 569                         ZSDELAY();
 570                         ZS_WSYNC(channel);
 571 
 572                         if (r3 & CHBRxIP)
 573                                 port = sunzilog_receive_chars(up, channel);
 574                         if (r3 & CHBEXT)
 575                                 sunzilog_status_handle(up, channel);
 576                         if (r3 & CHBTxIP)
 577                                 sunzilog_transmit_chars(up, channel);
 578                 }
 579                 spin_unlock(&up->port.lock);
 580 
 581                 if (port)
 582                         tty_flip_buffer_push(port);
 583 
 584                 up = up->next;
 585         }
 586 
 587         return IRQ_HANDLED;
 588 }
 589 
 590 /* A convenient way to quickly get R0 status.  The caller must _not_ hold the
 591  * port lock, it is acquired here.
 592  */
 593 static __inline__ unsigned char sunzilog_read_channel_status(struct uart_port *port)
 594 {
 595         struct zilog_channel __iomem *channel;
 596         unsigned char status;
 597 
 598         channel = ZILOG_CHANNEL_FROM_PORT(port);
 599         status = readb(&channel->control);
 600         ZSDELAY();
 601 
 602         return status;
 603 }
 604 
 605 /* The port lock is not held.  */
 606 static unsigned int sunzilog_tx_empty(struct uart_port *port)
 607 {
 608         unsigned long flags;
 609         unsigned char status;
 610         unsigned int ret;
 611 
 612         spin_lock_irqsave(&port->lock, flags);
 613 
 614         status = sunzilog_read_channel_status(port);
 615 
 616         spin_unlock_irqrestore(&port->lock, flags);
 617 
 618         if (status & Tx_BUF_EMP)
 619                 ret = TIOCSER_TEMT;
 620         else
 621                 ret = 0;
 622 
 623         return ret;
 624 }
 625 
 626 /* The port lock is held and interrupts are disabled.  */
 627 static unsigned int sunzilog_get_mctrl(struct uart_port *port)
 628 {
 629         unsigned char status;
 630         unsigned int ret;
 631 
 632         status = sunzilog_read_channel_status(port);
 633 
 634         ret = 0;
 635         if (status & DCD)
 636                 ret |= TIOCM_CAR;
 637         if (status & SYNC)
 638                 ret |= TIOCM_DSR;
 639         if (status & CTS)
 640                 ret |= TIOCM_CTS;
 641 
 642         return ret;
 643 }
 644 
 645 /* The port lock is held and interrupts are disabled.  */
 646 static void sunzilog_set_mctrl(struct uart_port *port, unsigned int mctrl)
 647 {
 648         struct uart_sunzilog_port *up =
 649                 container_of(port, struct uart_sunzilog_port, port);
 650         struct zilog_channel __iomem *channel = ZILOG_CHANNEL_FROM_PORT(port);
 651         unsigned char set_bits, clear_bits;
 652 
 653         set_bits = clear_bits = 0;
 654 
 655         if (mctrl & TIOCM_RTS)
 656                 set_bits |= RTS;
 657         else
 658                 clear_bits |= RTS;
 659         if (mctrl & TIOCM_DTR)
 660                 set_bits |= DTR;
 661         else
 662                 clear_bits |= DTR;
 663 
 664         /* NOTE: Not subject to 'transmitter active' rule.  */ 
 665         up->curregs[R5] |= set_bits;
 666         up->curregs[R5] &= ~clear_bits;
 667         write_zsreg(channel, R5, up->curregs[R5]);
 668 }
 669 
 670 /* The port lock is held and interrupts are disabled.  */
 671 static void sunzilog_stop_tx(struct uart_port *port)
 672 {
 673         struct uart_sunzilog_port *up =
 674                 container_of(port, struct uart_sunzilog_port, port);
 675 
 676         up->flags |= SUNZILOG_FLAG_TX_STOPPED;
 677 }
 678 
 679 /* The port lock is held and interrupts are disabled.  */
 680 static void sunzilog_start_tx(struct uart_port *port)
 681 {
 682         struct uart_sunzilog_port *up =
 683                 container_of(port, struct uart_sunzilog_port, port);
 684         struct zilog_channel __iomem *channel = ZILOG_CHANNEL_FROM_PORT(port);
 685         unsigned char status;
 686 
 687         up->flags |= SUNZILOG_FLAG_TX_ACTIVE;
 688         up->flags &= ~SUNZILOG_FLAG_TX_STOPPED;
 689 
 690         status = readb(&channel->control);
 691         ZSDELAY();
 692 
 693         /* TX busy?  Just wait for the TX done interrupt.  */
 694         if (!(status & Tx_BUF_EMP))
 695                 return;
 696 
 697         /* Send the first character to jump-start the TX done
 698          * IRQ sending engine.
 699          */
 700         if (port->x_char) {
 701                 writeb(port->x_char, &channel->data);
 702                 ZSDELAY();
 703                 ZS_WSYNC(channel);
 704 
 705                 port->icount.tx++;
 706                 port->x_char = 0;
 707         } else {
 708                 struct circ_buf *xmit = &port->state->xmit;
 709 
 710                 if (uart_circ_empty(xmit))
 711                         return;
 712                 writeb(xmit->buf[xmit->tail], &channel->data);
 713                 ZSDELAY();
 714                 ZS_WSYNC(channel);
 715 
 716                 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
 717                 port->icount.tx++;
 718 
 719                 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
 720                         uart_write_wakeup(&up->port);
 721         }
 722 }
 723 
 724 /* The port lock is held.  */
 725 static void sunzilog_stop_rx(struct uart_port *port)
 726 {
 727         struct uart_sunzilog_port *up = UART_ZILOG(port);
 728         struct zilog_channel __iomem *channel;
 729 
 730         if (ZS_IS_CONS(up))
 731                 return;
 732 
 733         channel = ZILOG_CHANNEL_FROM_PORT(port);
 734 
 735         /* Disable all RX interrupts.  */
 736         up->curregs[R1] &= ~RxINT_MASK;
 737         sunzilog_maybe_update_regs(up, channel);
 738 }
 739 
 740 /* The port lock is held.  */
 741 static void sunzilog_enable_ms(struct uart_port *port)
 742 {
 743         struct uart_sunzilog_port *up =
 744                 container_of(port, struct uart_sunzilog_port, port);
 745         struct zilog_channel __iomem *channel = ZILOG_CHANNEL_FROM_PORT(port);
 746         unsigned char new_reg;
 747 
 748         new_reg = up->curregs[R15] | (DCDIE | SYNCIE | CTSIE);
 749         if (new_reg != up->curregs[R15]) {
 750                 up->curregs[R15] = new_reg;
 751 
 752                 /* NOTE: Not subject to 'transmitter active' rule.  */ 
 753                 write_zsreg(channel, R15, up->curregs[R15] & ~WR7pEN);
 754         }
 755 }
 756 
 757 /* The port lock is not held.  */
 758 static void sunzilog_break_ctl(struct uart_port *port, int break_state)
 759 {
 760         struct uart_sunzilog_port *up =
 761                 container_of(port, struct uart_sunzilog_port, port);
 762         struct zilog_channel __iomem *channel = ZILOG_CHANNEL_FROM_PORT(port);
 763         unsigned char set_bits, clear_bits, new_reg;
 764         unsigned long flags;
 765 
 766         set_bits = clear_bits = 0;
 767 
 768         if (break_state)
 769                 set_bits |= SND_BRK;
 770         else
 771                 clear_bits |= SND_BRK;
 772 
 773         spin_lock_irqsave(&port->lock, flags);
 774 
 775         new_reg = (up->curregs[R5] | set_bits) & ~clear_bits;
 776         if (new_reg != up->curregs[R5]) {
 777                 up->curregs[R5] = new_reg;
 778 
 779                 /* NOTE: Not subject to 'transmitter active' rule.  */ 
 780                 write_zsreg(channel, R5, up->curregs[R5]);
 781         }
 782 
 783         spin_unlock_irqrestore(&port->lock, flags);
 784 }
 785 
 786 static void __sunzilog_startup(struct uart_sunzilog_port *up)
 787 {
 788         struct zilog_channel __iomem *channel;
 789 
 790         channel = ZILOG_CHANNEL_FROM_PORT(&up->port);
 791         up->prev_status = readb(&channel->control);
 792 
 793         /* Enable receiver and transmitter.  */
 794         up->curregs[R3] |= RxENAB;
 795         up->curregs[R5] |= TxENAB;
 796 
 797         up->curregs[R1] |= EXT_INT_ENAB | INT_ALL_Rx | TxINT_ENAB;
 798         sunzilog_maybe_update_regs(up, channel);
 799 }
 800 
 801 static int sunzilog_startup(struct uart_port *port)
 802 {
 803         struct uart_sunzilog_port *up = UART_ZILOG(port);
 804         unsigned long flags;
 805 
 806         if (ZS_IS_CONS(up))
 807                 return 0;
 808 
 809         spin_lock_irqsave(&port->lock, flags);
 810         __sunzilog_startup(up);
 811         spin_unlock_irqrestore(&port->lock, flags);
 812         return 0;
 813 }
 814 
 815 /*
 816  * The test for ZS_IS_CONS is explained by the following e-mail:
 817  *****
 818  * From: Russell King <rmk@arm.linux.org.uk>
 819  * Date: Sun, 8 Dec 2002 10:18:38 +0000
 820  *
 821  * On Sun, Dec 08, 2002 at 02:43:36AM -0500, Pete Zaitcev wrote:
 822  * > I boot my 2.5 boxes using "console=ttyS0,9600" argument,
 823  * > and I noticed that something is not right with reference
 824  * > counting in this case. It seems that when the console
 825  * > is open by kernel initially, this is not accounted
 826  * > as an open, and uart_startup is not called.
 827  *
 828  * That is correct.  We are unable to call uart_startup when the serial
 829  * console is initialised because it may need to allocate memory (as
 830  * request_irq does) and the memory allocators may not have been
 831  * initialised.
 832  *
 833  * 1. initialise the port into a state where it can send characters in the
 834  *    console write method.
 835  *
 836  * 2. don't do the actual hardware shutdown in your shutdown() method (but
 837  *    do the normal software shutdown - ie, free irqs etc)
 838  *****
 839  */
 840 static void sunzilog_shutdown(struct uart_port *port)
 841 {
 842         struct uart_sunzilog_port *up = UART_ZILOG(port);
 843         struct zilog_channel __iomem *channel;
 844         unsigned long flags;
 845 
 846         if (ZS_IS_CONS(up))
 847                 return;
 848 
 849         spin_lock_irqsave(&port->lock, flags);
 850 
 851         channel = ZILOG_CHANNEL_FROM_PORT(port);
 852 
 853         /* Disable receiver and transmitter.  */
 854         up->curregs[R3] &= ~RxENAB;
 855         up->curregs[R5] &= ~TxENAB;
 856 
 857         /* Disable all interrupts and BRK assertion.  */
 858         up->curregs[R1] &= ~(EXT_INT_ENAB | TxINT_ENAB | RxINT_MASK);
 859         up->curregs[R5] &= ~SND_BRK;
 860         sunzilog_maybe_update_regs(up, channel);
 861 
 862         spin_unlock_irqrestore(&port->lock, flags);
 863 }
 864 
 865 /* Shared by TTY driver and serial console setup.  The port lock is held
 866  * and local interrupts are disabled.
 867  */
 868 static void
 869 sunzilog_convert_to_zs(struct uart_sunzilog_port *up, unsigned int cflag,
 870                        unsigned int iflag, int brg)
 871 {
 872 
 873         up->curregs[R10] = NRZ;
 874         up->curregs[R11] = TCBR | RCBR;
 875 
 876         /* Program BAUD and clock source. */
 877         up->curregs[R4] &= ~XCLK_MASK;
 878         up->curregs[R4] |= X16CLK;
 879         up->curregs[R12] = brg & 0xff;
 880         up->curregs[R13] = (brg >> 8) & 0xff;
 881         up->curregs[R14] = BRSRC | BRENAB;
 882 
 883         /* Character size, stop bits, and parity. */
 884         up->curregs[R3] &= ~RxN_MASK;
 885         up->curregs[R5] &= ~TxN_MASK;
 886         switch (cflag & CSIZE) {
 887         case CS5:
 888                 up->curregs[R3] |= Rx5;
 889                 up->curregs[R5] |= Tx5;
 890                 up->parity_mask = 0x1f;
 891                 break;
 892         case CS6:
 893                 up->curregs[R3] |= Rx6;
 894                 up->curregs[R5] |= Tx6;
 895                 up->parity_mask = 0x3f;
 896                 break;
 897         case CS7:
 898                 up->curregs[R3] |= Rx7;
 899                 up->curregs[R5] |= Tx7;
 900                 up->parity_mask = 0x7f;
 901                 break;
 902         case CS8:
 903         default:
 904                 up->curregs[R3] |= Rx8;
 905                 up->curregs[R5] |= Tx8;
 906                 up->parity_mask = 0xff;
 907                 break;
 908         }
 909         up->curregs[R4] &= ~0x0c;
 910         if (cflag & CSTOPB)
 911                 up->curregs[R4] |= SB2;
 912         else
 913                 up->curregs[R4] |= SB1;
 914         if (cflag & PARENB)
 915                 up->curregs[R4] |= PAR_ENAB;
 916         else
 917                 up->curregs[R4] &= ~PAR_ENAB;
 918         if (!(cflag & PARODD))
 919                 up->curregs[R4] |= PAR_EVEN;
 920         else
 921                 up->curregs[R4] &= ~PAR_EVEN;
 922 
 923         up->port.read_status_mask = Rx_OVR;
 924         if (iflag & INPCK)
 925                 up->port.read_status_mask |= CRC_ERR | PAR_ERR;
 926         if (iflag & (IGNBRK | BRKINT | PARMRK))
 927                 up->port.read_status_mask |= BRK_ABRT;
 928 
 929         up->port.ignore_status_mask = 0;
 930         if (iflag & IGNPAR)
 931                 up->port.ignore_status_mask |= CRC_ERR | PAR_ERR;
 932         if (iflag & IGNBRK) {
 933                 up->port.ignore_status_mask |= BRK_ABRT;
 934                 if (iflag & IGNPAR)
 935                         up->port.ignore_status_mask |= Rx_OVR;
 936         }
 937 
 938         if ((cflag & CREAD) == 0)
 939                 up->port.ignore_status_mask = 0xff;
 940 }
 941 
 942 /* The port lock is not held.  */
 943 static void
 944 sunzilog_set_termios(struct uart_port *port, struct ktermios *termios,
 945                      struct ktermios *old)
 946 {
 947         struct uart_sunzilog_port *up =
 948                 container_of(port, struct uart_sunzilog_port, port);
 949         unsigned long flags;
 950         int baud, brg;
 951 
 952         baud = uart_get_baud_rate(port, termios, old, 1200, 76800);
 953 
 954         spin_lock_irqsave(&up->port.lock, flags);
 955 
 956         brg = BPS_TO_BRG(baud, ZS_CLOCK / ZS_CLOCK_DIVISOR);
 957 
 958         sunzilog_convert_to_zs(up, termios->c_cflag, termios->c_iflag, brg);
 959 
 960         if (UART_ENABLE_MS(&up->port, termios->c_cflag))
 961                 up->flags |= SUNZILOG_FLAG_MODEM_STATUS;
 962         else
 963                 up->flags &= ~SUNZILOG_FLAG_MODEM_STATUS;
 964 
 965         up->cflag = termios->c_cflag;
 966 
 967         sunzilog_maybe_update_regs(up, ZILOG_CHANNEL_FROM_PORT(port));
 968 
 969         uart_update_timeout(port, termios->c_cflag, baud);
 970 
 971         spin_unlock_irqrestore(&up->port.lock, flags);
 972 }
 973 
 974 static const char *sunzilog_type(struct uart_port *port)
 975 {
 976         struct uart_sunzilog_port *up = UART_ZILOG(port);
 977 
 978         return (up->flags & SUNZILOG_FLAG_ESCC) ? "zs (ESCC)" : "zs";
 979 }
 980 
 981 /* We do not request/release mappings of the registers here, this
 982  * happens at early serial probe time.
 983  */
 984 static void sunzilog_release_port(struct uart_port *port)
 985 {
 986 }
 987 
 988 static int sunzilog_request_port(struct uart_port *port)
 989 {
 990         return 0;
 991 }
 992 
 993 /* These do not need to do anything interesting either.  */
 994 static void sunzilog_config_port(struct uart_port *port, int flags)
 995 {
 996 }
 997 
 998 /* We do not support letting the user mess with the divisor, IRQ, etc. */
 999 static int sunzilog_verify_port(struct uart_port *port, struct serial_struct *ser)
1000 {
1001         return -EINVAL;
1002 }
1003 
1004 #ifdef CONFIG_CONSOLE_POLL
1005 static int sunzilog_get_poll_char(struct uart_port *port)
1006 {
1007         unsigned char ch, r1;
1008         struct uart_sunzilog_port *up =
1009                 container_of(port, struct uart_sunzilog_port, port);
1010         struct zilog_channel __iomem *channel
1011                 = ZILOG_CHANNEL_FROM_PORT(&up->port);
1012 
1013 
1014         r1 = read_zsreg(channel, R1);
1015         if (r1 & (PAR_ERR | Rx_OVR | CRC_ERR)) {
1016                 writeb(ERR_RES, &channel->control);
1017                 ZSDELAY();
1018                 ZS_WSYNC(channel);
1019         }
1020 
1021         ch = readb(&channel->control);
1022         ZSDELAY();
1023 
1024         /* This funny hack depends upon BRK_ABRT not interfering
1025          * with the other bits we care about in R1.
1026          */
1027         if (ch & BRK_ABRT)
1028                 r1 |= BRK_ABRT;
1029 
1030         if (!(ch & Rx_CH_AV))
1031                 return NO_POLL_CHAR;
1032 
1033         ch = readb(&channel->data);
1034         ZSDELAY();
1035 
1036         ch &= up->parity_mask;
1037         return ch;
1038 }
1039 
1040 static void sunzilog_put_poll_char(struct uart_port *port,
1041                         unsigned char ch)
1042 {
1043         struct uart_sunzilog_port *up =
1044                 container_of(port, struct uart_sunzilog_port, port);
1045 
1046         sunzilog_putchar(&up->port, ch);
1047 }
1048 #endif /* CONFIG_CONSOLE_POLL */
1049 
1050 static const struct uart_ops sunzilog_pops = {
1051         .tx_empty       =       sunzilog_tx_empty,
1052         .set_mctrl      =       sunzilog_set_mctrl,
1053         .get_mctrl      =       sunzilog_get_mctrl,
1054         .stop_tx        =       sunzilog_stop_tx,
1055         .start_tx       =       sunzilog_start_tx,
1056         .stop_rx        =       sunzilog_stop_rx,
1057         .enable_ms      =       sunzilog_enable_ms,
1058         .break_ctl      =       sunzilog_break_ctl,
1059         .startup        =       sunzilog_startup,
1060         .shutdown       =       sunzilog_shutdown,
1061         .set_termios    =       sunzilog_set_termios,
1062         .type           =       sunzilog_type,
1063         .release_port   =       sunzilog_release_port,
1064         .request_port   =       sunzilog_request_port,
1065         .config_port    =       sunzilog_config_port,
1066         .verify_port    =       sunzilog_verify_port,
1067 #ifdef CONFIG_CONSOLE_POLL
1068         .poll_get_char  =       sunzilog_get_poll_char,
1069         .poll_put_char  =       sunzilog_put_poll_char,
1070 #endif
1071 };
1072 
1073 static int uart_chip_count;
1074 static struct uart_sunzilog_port *sunzilog_port_table;
1075 static struct zilog_layout __iomem **sunzilog_chip_regs;
1076 
1077 static struct uart_sunzilog_port *sunzilog_irq_chain;
1078 
1079 static struct uart_driver sunzilog_reg = {
1080         .owner          =       THIS_MODULE,
1081         .driver_name    =       "sunzilog",
1082         .dev_name       =       "ttyS",
1083         .major          =       TTY_MAJOR,
1084 };
1085 
1086 static int __init sunzilog_alloc_tables(int num_sunzilog)
1087 {
1088         struct uart_sunzilog_port *up;
1089         unsigned long size;
1090         int num_channels = num_sunzilog * 2;
1091         int i;
1092 
1093         size = num_channels * sizeof(struct uart_sunzilog_port);
1094         sunzilog_port_table = kzalloc(size, GFP_KERNEL);
1095         if (!sunzilog_port_table)
1096                 return -ENOMEM;
1097 
1098         for (i = 0; i < num_channels; i++) {
1099                 up = &sunzilog_port_table[i];
1100 
1101                 spin_lock_init(&up->port.lock);
1102 
1103                 if (i == 0)
1104                         sunzilog_irq_chain = up;
1105 
1106                 if (i < num_channels - 1)
1107                         up->next = up + 1;
1108                 else
1109                         up->next = NULL;
1110         }
1111 
1112         size = num_sunzilog * sizeof(struct zilog_layout __iomem *);
1113         sunzilog_chip_regs = kzalloc(size, GFP_KERNEL);
1114         if (!sunzilog_chip_regs) {
1115                 kfree(sunzilog_port_table);
1116                 sunzilog_irq_chain = NULL;
1117                 return -ENOMEM;
1118         }
1119 
1120         return 0;
1121 }
1122 
1123 static void sunzilog_free_tables(void)
1124 {
1125         kfree(sunzilog_port_table);
1126         sunzilog_irq_chain = NULL;
1127         kfree(sunzilog_chip_regs);
1128 }
1129 
1130 #define ZS_PUT_CHAR_MAX_DELAY   2000    /* 10 ms */
1131 
1132 static void sunzilog_putchar(struct uart_port *port, int ch)
1133 {
1134         struct zilog_channel __iomem *channel = ZILOG_CHANNEL_FROM_PORT(port);
1135         int loops = ZS_PUT_CHAR_MAX_DELAY;
1136 
1137         /* This is a timed polling loop so do not switch the explicit
1138          * udelay with ZSDELAY as that is a NOP on some platforms.  -DaveM
1139          */
1140         do {
1141                 unsigned char val = readb(&channel->control);
1142                 if (val & Tx_BUF_EMP) {
1143                         ZSDELAY();
1144                         break;
1145                 }
1146                 udelay(5);
1147         } while (--loops);
1148 
1149         writeb(ch, &channel->data);
1150         ZSDELAY();
1151         ZS_WSYNC(channel);
1152 }
1153 
1154 #ifdef CONFIG_SERIO
1155 
1156 static DEFINE_SPINLOCK(sunzilog_serio_lock);
1157 
1158 static int sunzilog_serio_write(struct serio *serio, unsigned char ch)
1159 {
1160         struct uart_sunzilog_port *up = serio->port_data;
1161         unsigned long flags;
1162 
1163         spin_lock_irqsave(&sunzilog_serio_lock, flags);
1164 
1165         sunzilog_putchar(&up->port, ch);
1166 
1167         spin_unlock_irqrestore(&sunzilog_serio_lock, flags);
1168 
1169         return 0;
1170 }
1171 
1172 static int sunzilog_serio_open(struct serio *serio)
1173 {
1174         struct uart_sunzilog_port *up = serio->port_data;
1175         unsigned long flags;
1176         int ret;
1177 
1178         spin_lock_irqsave(&sunzilog_serio_lock, flags);
1179         if (!up->serio_open) {
1180                 up->serio_open = 1;
1181                 ret = 0;
1182         } else
1183                 ret = -EBUSY;
1184         spin_unlock_irqrestore(&sunzilog_serio_lock, flags);
1185 
1186         return ret;
1187 }
1188 
1189 static void sunzilog_serio_close(struct serio *serio)
1190 {
1191         struct uart_sunzilog_port *up = serio->port_data;
1192         unsigned long flags;
1193 
1194         spin_lock_irqsave(&sunzilog_serio_lock, flags);
1195         up->serio_open = 0;
1196         spin_unlock_irqrestore(&sunzilog_serio_lock, flags);
1197 }
1198 
1199 #endif /* CONFIG_SERIO */
1200 
1201 #ifdef CONFIG_SERIAL_SUNZILOG_CONSOLE
1202 static void
1203 sunzilog_console_write(struct console *con, const char *s, unsigned int count)
1204 {
1205         struct uart_sunzilog_port *up = &sunzilog_port_table[con->index];
1206         unsigned long flags;
1207         int locked = 1;
1208 
1209         if (up->port.sysrq || oops_in_progress)
1210                 locked = spin_trylock_irqsave(&up->port.lock, flags);
1211         else
1212                 spin_lock_irqsave(&up->port.lock, flags);
1213 
1214         uart_console_write(&up->port, s, count, sunzilog_putchar);
1215         udelay(2);
1216 
1217         if (locked)
1218                 spin_unlock_irqrestore(&up->port.lock, flags);
1219 }
1220 
1221 static int __init sunzilog_console_setup(struct console *con, char *options)
1222 {
1223         struct uart_sunzilog_port *up = &sunzilog_port_table[con->index];
1224         unsigned long flags;
1225         int baud, brg;
1226 
1227         if (up->port.type != PORT_SUNZILOG)
1228                 return -1;
1229 
1230         printk(KERN_INFO "Console: ttyS%d (SunZilog zs%d)\n",
1231                (sunzilog_reg.minor - 64) + con->index, con->index);
1232 
1233         /* Get firmware console settings.  */
1234         sunserial_console_termios(con, up->port.dev->of_node);
1235 
1236         /* Firmware console speed is limited to 150-->38400 baud so
1237          * this hackish cflag thing is OK.
1238          */
1239         switch (con->cflag & CBAUD) {
1240         case B150: baud = 150; break;
1241         case B300: baud = 300; break;
1242         case B600: baud = 600; break;
1243         case B1200: baud = 1200; break;
1244         case B2400: baud = 2400; break;
1245         case B4800: baud = 4800; break;
1246         default: case B9600: baud = 9600; break;
1247         case B19200: baud = 19200; break;
1248         case B38400: baud = 38400; break;
1249         }
1250 
1251         brg = BPS_TO_BRG(baud, ZS_CLOCK / ZS_CLOCK_DIVISOR);
1252 
1253         spin_lock_irqsave(&up->port.lock, flags);
1254 
1255         up->curregs[R15] |= BRKIE;
1256         sunzilog_convert_to_zs(up, con->cflag, 0, brg);
1257 
1258         sunzilog_set_mctrl(&up->port, TIOCM_DTR | TIOCM_RTS);
1259         __sunzilog_startup(up);
1260 
1261         spin_unlock_irqrestore(&up->port.lock, flags);
1262 
1263         return 0;
1264 }
1265 
1266 static struct console sunzilog_console_ops = {
1267         .name   =       "ttyS",
1268         .write  =       sunzilog_console_write,
1269         .device =       uart_console_device,
1270         .setup  =       sunzilog_console_setup,
1271         .flags  =       CON_PRINTBUFFER,
1272         .index  =       -1,
1273         .data   =       &sunzilog_reg,
1274 };
1275 
1276 static inline struct console *SUNZILOG_CONSOLE(void)
1277 {
1278         return &sunzilog_console_ops;
1279 }
1280 
1281 #else
1282 #define SUNZILOG_CONSOLE()      (NULL)
1283 #endif
1284 
1285 static void sunzilog_init_kbdms(struct uart_sunzilog_port *up)
1286 {
1287         int baud, brg;
1288 
1289         if (up->flags & SUNZILOG_FLAG_CONS_KEYB) {
1290                 up->cflag = B1200 | CS8 | CLOCAL | CREAD;
1291                 baud = 1200;
1292         } else {
1293                 up->cflag = B4800 | CS8 | CLOCAL | CREAD;
1294                 baud = 4800;
1295         }
1296 
1297         up->curregs[R15] |= BRKIE;
1298         brg = BPS_TO_BRG(baud, ZS_CLOCK / ZS_CLOCK_DIVISOR);
1299         sunzilog_convert_to_zs(up, up->cflag, 0, brg);
1300         sunzilog_set_mctrl(&up->port, TIOCM_DTR | TIOCM_RTS);
1301         __sunzilog_startup(up);
1302 }
1303 
1304 #ifdef CONFIG_SERIO
1305 static void sunzilog_register_serio(struct uart_sunzilog_port *up)
1306 {
1307         struct serio *serio = &up->serio;
1308 
1309         serio->port_data = up;
1310 
1311         serio->id.type = SERIO_RS232;
1312         if (up->flags & SUNZILOG_FLAG_CONS_KEYB) {
1313                 serio->id.proto = SERIO_SUNKBD;
1314                 strlcpy(serio->name, "zskbd", sizeof(serio->name));
1315         } else {
1316                 serio->id.proto = SERIO_SUN;
1317                 serio->id.extra = 1;
1318                 strlcpy(serio->name, "zsms", sizeof(serio->name));
1319         }
1320         strlcpy(serio->phys,
1321                 ((up->flags & SUNZILOG_FLAG_CONS_KEYB) ?
1322                  "zs/serio0" : "zs/serio1"),
1323                 sizeof(serio->phys));
1324 
1325         serio->write = sunzilog_serio_write;
1326         serio->open = sunzilog_serio_open;
1327         serio->close = sunzilog_serio_close;
1328         serio->dev.parent = up->port.dev;
1329 
1330         serio_register_port(serio);
1331 }
1332 #endif
1333 
1334 static void sunzilog_init_hw(struct uart_sunzilog_port *up)
1335 {
1336         struct zilog_channel __iomem *channel;
1337         unsigned long flags;
1338         int baud, brg;
1339 
1340         channel = ZILOG_CHANNEL_FROM_PORT(&up->port);
1341 
1342         spin_lock_irqsave(&up->port.lock, flags);
1343         if (ZS_IS_CHANNEL_A(up)) {
1344                 write_zsreg(channel, R9, FHWRES);
1345                 ZSDELAY_LONG();
1346                 (void) read_zsreg(channel, R0);
1347         }
1348 
1349         if (up->flags & (SUNZILOG_FLAG_CONS_KEYB |
1350                          SUNZILOG_FLAG_CONS_MOUSE)) {
1351                 up->curregs[R1] = EXT_INT_ENAB | INT_ALL_Rx | TxINT_ENAB;
1352                 up->curregs[R4] = PAR_EVEN | X16CLK | SB1;
1353                 up->curregs[R3] = RxENAB | Rx8;
1354                 up->curregs[R5] = TxENAB | Tx8;
1355                 up->curregs[R6] = 0x00; /* SDLC Address */
1356                 up->curregs[R7] = 0x7E; /* SDLC Flag    */
1357                 up->curregs[R9] = NV;
1358                 up->curregs[R7p] = 0x00;
1359                 sunzilog_init_kbdms(up);
1360                 /* Only enable interrupts if an ISR handler available */
1361                 if (up->flags & SUNZILOG_FLAG_ISR_HANDLER)
1362                         up->curregs[R9] |= MIE;
1363                 write_zsreg(channel, R9, up->curregs[R9]);
1364         } else {
1365                 /* Normal serial TTY. */
1366                 up->parity_mask = 0xff;
1367                 up->curregs[R1] = EXT_INT_ENAB | INT_ALL_Rx | TxINT_ENAB;
1368                 up->curregs[R4] = PAR_EVEN | X16CLK | SB1;
1369                 up->curregs[R3] = RxENAB | Rx8;
1370                 up->curregs[R5] = TxENAB | Tx8;
1371                 up->curregs[R6] = 0x00; /* SDLC Address */
1372                 up->curregs[R7] = 0x7E; /* SDLC Flag    */
1373                 up->curregs[R9] = NV;
1374                 up->curregs[R10] = NRZ;
1375                 up->curregs[R11] = TCBR | RCBR;
1376                 baud = 9600;
1377                 brg = BPS_TO_BRG(baud, ZS_CLOCK / ZS_CLOCK_DIVISOR);
1378                 up->curregs[R12] = (brg & 0xff);
1379                 up->curregs[R13] = (brg >> 8) & 0xff;
1380                 up->curregs[R14] = BRSRC | BRENAB;
1381                 up->curregs[R15] = FIFOEN; /* Use FIFO if on ESCC */
1382                 up->curregs[R7p] = TxFIFO_LVL | RxFIFO_LVL;
1383                 if (__load_zsregs(channel, up->curregs)) {
1384                         up->flags |= SUNZILOG_FLAG_ESCC;
1385                 }
1386                 /* Only enable interrupts if an ISR handler available */
1387                 if (up->flags & SUNZILOG_FLAG_ISR_HANDLER)
1388                         up->curregs[R9] |= MIE;
1389                 write_zsreg(channel, R9, up->curregs[R9]);
1390         }
1391 
1392         spin_unlock_irqrestore(&up->port.lock, flags);
1393 
1394 #ifdef CONFIG_SERIO
1395         if (up->flags & (SUNZILOG_FLAG_CONS_KEYB |
1396                          SUNZILOG_FLAG_CONS_MOUSE))
1397                 sunzilog_register_serio(up);
1398 #endif
1399 }
1400 
1401 static int zilog_irq;
1402 
1403 static int zs_probe(struct platform_device *op)
1404 {
1405         static int kbm_inst, uart_inst;
1406         int inst;
1407         struct uart_sunzilog_port *up;
1408         struct zilog_layout __iomem *rp;
1409         int keyboard_mouse = 0;
1410         int err;
1411 
1412         if (of_find_property(op->dev.of_node, "keyboard", NULL))
1413                 keyboard_mouse = 1;
1414 
1415         /* uarts must come before keyboards/mice */
1416         if (keyboard_mouse)
1417                 inst = uart_chip_count + kbm_inst;
1418         else
1419                 inst = uart_inst;
1420 
1421         sunzilog_chip_regs[inst] = of_ioremap(&op->resource[0], 0,
1422                                               sizeof(struct zilog_layout),
1423                                               "zs");
1424         if (!sunzilog_chip_regs[inst])
1425                 return -ENOMEM;
1426 
1427         rp = sunzilog_chip_regs[inst];
1428 
1429         if (!zilog_irq)
1430                 zilog_irq = op->archdata.irqs[0];
1431 
1432         up = &sunzilog_port_table[inst * 2];
1433 
1434         /* Channel A */
1435         up[0].port.mapbase = op->resource[0].start + 0x00;
1436         up[0].port.membase = (void __iomem *) &rp->channelA;
1437         up[0].port.iotype = UPIO_MEM;
1438         up[0].port.irq = op->archdata.irqs[0];
1439         up[0].port.uartclk = ZS_CLOCK;
1440         up[0].port.fifosize = 1;
1441         up[0].port.ops = &sunzilog_pops;
1442         up[0].port.type = PORT_SUNZILOG;
1443         up[0].port.flags = 0;
1444         up[0].port.line = (inst * 2) + 0;
1445         up[0].port.dev = &op->dev;
1446         up[0].flags |= SUNZILOG_FLAG_IS_CHANNEL_A;
1447         if (keyboard_mouse)
1448                 up[0].flags |= SUNZILOG_FLAG_CONS_KEYB;
1449         sunzilog_init_hw(&up[0]);
1450 
1451         /* Channel B */
1452         up[1].port.mapbase = op->resource[0].start + 0x04;
1453         up[1].port.membase = (void __iomem *) &rp->channelB;
1454         up[1].port.iotype = UPIO_MEM;
1455         up[1].port.irq = op->archdata.irqs[0];
1456         up[1].port.uartclk = ZS_CLOCK;
1457         up[1].port.fifosize = 1;
1458         up[1].port.ops = &sunzilog_pops;
1459         up[1].port.type = PORT_SUNZILOG;
1460         up[1].port.flags = 0;
1461         up[1].port.line = (inst * 2) + 1;
1462         up[1].port.dev = &op->dev;
1463         up[1].flags |= 0;
1464         if (keyboard_mouse)
1465                 up[1].flags |= SUNZILOG_FLAG_CONS_MOUSE;
1466         sunzilog_init_hw(&up[1]);
1467 
1468         if (!keyboard_mouse) {
1469                 if (sunserial_console_match(SUNZILOG_CONSOLE(), op->dev.of_node,
1470                                             &sunzilog_reg, up[0].port.line,
1471                                             false))
1472                         up->flags |= SUNZILOG_FLAG_IS_CONS;
1473                 err = uart_add_one_port(&sunzilog_reg, &up[0].port);
1474                 if (err) {
1475                         of_iounmap(&op->resource[0],
1476                                    rp, sizeof(struct zilog_layout));
1477                         return err;
1478                 }
1479                 if (sunserial_console_match(SUNZILOG_CONSOLE(), op->dev.of_node,
1480                                             &sunzilog_reg, up[1].port.line,
1481                                             false))
1482                         up->flags |= SUNZILOG_FLAG_IS_CONS;
1483                 err = uart_add_one_port(&sunzilog_reg, &up[1].port);
1484                 if (err) {
1485                         uart_remove_one_port(&sunzilog_reg, &up[0].port);
1486                         of_iounmap(&op->resource[0],
1487                                    rp, sizeof(struct zilog_layout));
1488                         return err;
1489                 }
1490                 uart_inst++;
1491         } else {
1492                 printk(KERN_INFO "%s: Keyboard at MMIO 0x%llx (irq = %d) "
1493                        "is a %s\n",
1494                        dev_name(&op->dev),
1495                        (unsigned long long) up[0].port.mapbase,
1496                        op->archdata.irqs[0], sunzilog_type(&up[0].port));
1497                 printk(KERN_INFO "%s: Mouse at MMIO 0x%llx (irq = %d) "
1498                        "is a %s\n",
1499                        dev_name(&op->dev),
1500                        (unsigned long long) up[1].port.mapbase,
1501                        op->archdata.irqs[0], sunzilog_type(&up[1].port));
1502                 kbm_inst++;
1503         }
1504 
1505         platform_set_drvdata(op, &up[0]);
1506 
1507         return 0;
1508 }
1509 
1510 static void zs_remove_one(struct uart_sunzilog_port *up)
1511 {
1512         if (ZS_IS_KEYB(up) || ZS_IS_MOUSE(up)) {
1513 #ifdef CONFIG_SERIO
1514                 serio_unregister_port(&up->serio);
1515 #endif
1516         } else
1517                 uart_remove_one_port(&sunzilog_reg, &up->port);
1518 }
1519 
1520 static int zs_remove(struct platform_device *op)
1521 {
1522         struct uart_sunzilog_port *up = platform_get_drvdata(op);
1523         struct zilog_layout __iomem *regs;
1524 
1525         zs_remove_one(&up[0]);
1526         zs_remove_one(&up[1]);
1527 
1528         regs = sunzilog_chip_regs[up[0].port.line / 2];
1529         of_iounmap(&op->resource[0], regs, sizeof(struct zilog_layout));
1530 
1531         return 0;
1532 }
1533 
1534 static const struct of_device_id zs_match[] = {
1535         {
1536                 .name = "zs",
1537         },
1538         {},
1539 };
1540 MODULE_DEVICE_TABLE(of, zs_match);
1541 
1542 static struct platform_driver zs_driver = {
1543         .driver = {
1544                 .name = "zs",
1545                 .of_match_table = zs_match,
1546         },
1547         .probe          = zs_probe,
1548         .remove         = zs_remove,
1549 };
1550 
1551 static int __init sunzilog_init(void)
1552 {
1553         struct device_node *dp;
1554         int err;
1555         int num_keybms = 0;
1556         int num_sunzilog = 0;
1557 
1558         for_each_node_by_name(dp, "zs") {
1559                 num_sunzilog++;
1560                 if (of_find_property(dp, "keyboard", NULL))
1561                         num_keybms++;
1562         }
1563 
1564         if (num_sunzilog) {
1565                 err = sunzilog_alloc_tables(num_sunzilog);
1566                 if (err)
1567                         goto out;
1568 
1569                 uart_chip_count = num_sunzilog - num_keybms;
1570 
1571                 err = sunserial_register_minors(&sunzilog_reg,
1572                                                 uart_chip_count * 2);
1573                 if (err)
1574                         goto out_free_tables;
1575         }
1576 
1577         err = platform_driver_register(&zs_driver);
1578         if (err)
1579                 goto out_unregister_uart;
1580 
1581         if (zilog_irq) {
1582                 struct uart_sunzilog_port *up = sunzilog_irq_chain;
1583                 err = request_irq(zilog_irq, sunzilog_interrupt, IRQF_SHARED,
1584                                   "zs", sunzilog_irq_chain);
1585                 if (err)
1586                         goto out_unregister_driver;
1587 
1588                 /* Enable Interrupts */
1589                 while (up) {
1590                         struct zilog_channel __iomem *channel;
1591 
1592                         /* printk (KERN_INFO "Enable IRQ for ZILOG Hardware %p\n", up); */
1593                         channel          = ZILOG_CHANNEL_FROM_PORT(&up->port);
1594                         up->flags       |= SUNZILOG_FLAG_ISR_HANDLER;
1595                         up->curregs[R9] |= MIE;
1596                         write_zsreg(channel, R9, up->curregs[R9]);
1597                         up = up->next;
1598                 }
1599         }
1600 
1601 out:
1602         return err;
1603 
1604 out_unregister_driver:
1605         platform_driver_unregister(&zs_driver);
1606 
1607 out_unregister_uart:
1608         if (num_sunzilog) {
1609                 sunserial_unregister_minors(&sunzilog_reg, num_sunzilog);
1610                 sunzilog_reg.cons = NULL;
1611         }
1612 
1613 out_free_tables:
1614         sunzilog_free_tables();
1615         goto out;
1616 }
1617 
1618 static void __exit sunzilog_exit(void)
1619 {
1620         platform_driver_unregister(&zs_driver);
1621 
1622         if (zilog_irq) {
1623                 struct uart_sunzilog_port *up = sunzilog_irq_chain;
1624 
1625                 /* Disable Interrupts */
1626                 while (up) {
1627                         struct zilog_channel __iomem *channel;
1628 
1629                         /* printk (KERN_INFO "Disable IRQ for ZILOG Hardware %p\n", up); */
1630                         channel          = ZILOG_CHANNEL_FROM_PORT(&up->port);
1631                         up->flags       &= ~SUNZILOG_FLAG_ISR_HANDLER;
1632                         up->curregs[R9] &= ~MIE;
1633                         write_zsreg(channel, R9, up->curregs[R9]);
1634                         up = up->next;
1635                 }
1636 
1637                 free_irq(zilog_irq, sunzilog_irq_chain);
1638                 zilog_irq = 0;
1639         }
1640 
1641         if (sunzilog_reg.nr) {
1642                 sunserial_unregister_minors(&sunzilog_reg, sunzilog_reg.nr);
1643                 sunzilog_free_tables();
1644         }
1645 }
1646 
1647 module_init(sunzilog_init);
1648 module_exit(sunzilog_exit);
1649 
1650 MODULE_AUTHOR("David S. Miller");
1651 MODULE_DESCRIPTION("Sun Zilog serial port driver");
1652 MODULE_VERSION("2.0");
1653 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */