#define SUNZILOG_FLAG_REGS_HELD                0x00000040
 #define SUNZILOG_FLAG_TX_STOPPED       0x00000080
 #define SUNZILOG_FLAG_TX_ACTIVE                0x00000100
+#define SUNZILOG_FLAG_ESCC             0x00000200
+#define SUNZILOG_FLAG_ISR_HANDLER      0x00000400
 
        unsigned int cflag;
 
 /* This function must only be called when the TX is not busy.  The UART
  * port lock must be held and local interrupts disabled.
  */
-static void __load_zsregs(struct zilog_channel __iomem *channel, unsigned char *regs)
+static int __load_zsregs(struct zilog_channel __iomem *channel, unsigned char *regs)
 {
        int i;
+       int escc;
+       unsigned char r15;
 
        /* Let pending transmits finish.  */
        for (i = 0; i < 1000; i++) {
        write_zsreg(channel, R14, regs[R14]);
 
        /* External status interrupt control.  */
-       write_zsreg(channel, R15, regs[R15]);
+       write_zsreg(channel, R15, (regs[R15] | WR7pEN) & ~FIFOEN);
+
+       /* ESCC Extension Register */
+       r15 = read_zsreg(channel, R15);
+       if (r15 & 0x01) {
+               write_zsreg(channel, R7,  regs[R7p]);
+
+               /* External status interrupt and FIFO control.  */
+               write_zsreg(channel, R15, regs[R15] & ~WR7pEN);
+               escc = 1;
+       } else {
+                /* Clear FIFO bit case it is an issue */
+               regs[R15] &= ~FIFOEN;
+               escc = 0;
+       }
 
        /* Reset external status interrupts.  */
-       write_zsreg(channel, R0, RES_EXT_INT);
-       write_zsreg(channel, R0, RES_EXT_INT);
+       write_zsreg(channel, R0, RES_EXT_INT); /* First Latch  */
+       write_zsreg(channel, R0, RES_EXT_INT); /* Second Latch */
 
        /* Rewrite R3/R5, this time without enables masked.  */
        write_zsreg(channel, R3, regs[R3]);
 
        /* Rewrite R1, this time without IRQ enabled masked.  */
        write_zsreg(channel, R1, regs[R1]);
+
+       return escc;
 }
 
 /* Reprogram the Zilog channel HW registers with the copies found in the
                up->curregs[R15] = new_reg;
 
                /* NOTE: Not subject to 'transmitter active' rule.  */ 
-               write_zsreg(channel, R15, up->curregs[R15]);
+               write_zsreg(channel, R15, up->curregs[R15] & ~WR7pEN);
        }
 }
 
        up->curregs[R14] = BRSRC | BRENAB;
 
        /* Character size, stop bits, and parity. */
-       up->curregs[3] &= ~RxN_MASK;
-       up->curregs[5] &= ~TxN_MASK;
+       up->curregs[R3] &= ~RxN_MASK;
+       up->curregs[R5] &= ~TxN_MASK;
        switch (cflag & CSIZE) {
        case CS5:
-               up->curregs[3] |= Rx5;
-               up->curregs[5] |= Tx5;
+               up->curregs[R3] |= Rx5;
+               up->curregs[R5] |= Tx5;
                up->parity_mask = 0x1f;
                break;
        case CS6:
-               up->curregs[3] |= Rx6;
-               up->curregs[5] |= Tx6;
+               up->curregs[R3] |= Rx6;
+               up->curregs[R5] |= Tx6;
                up->parity_mask = 0x3f;
                break;
        case CS7:
-               up->curregs[3] |= Rx7;
-               up->curregs[5] |= Tx7;
+               up->curregs[R3] |= Rx7;
+               up->curregs[R5] |= Tx7;
                up->parity_mask = 0x7f;
                break;
        case CS8:
        default:
-               up->curregs[3] |= Rx8;
-               up->curregs[5] |= Tx8;
+               up->curregs[R3] |= Rx8;
+               up->curregs[R5] |= Tx8;
                up->parity_mask = 0xff;
                break;
        };
-       up->curregs[4] &= ~0x0c;
+       up->curregs[R4] &= ~0x0c;
        if (cflag & CSTOPB)
-               up->curregs[4] |= SB2;
+               up->curregs[R4] |= SB2;
        else
-               up->curregs[4] |= SB1;
+               up->curregs[R4] |= SB1;
        if (cflag & PARENB)
-               up->curregs[4] |= PAR_ENAB;
+               up->curregs[R4] |= PAR_ENAB;
        else
-               up->curregs[4] &= ~PAR_ENAB;
+               up->curregs[R4] &= ~PAR_ENAB;
        if (!(cflag & PARODD))
-               up->curregs[4] |= PAR_EVEN;
+               up->curregs[R4] |= PAR_EVEN;
        else
-               up->curregs[4] &= ~PAR_EVEN;
+               up->curregs[R4] &= ~PAR_EVEN;
 
        up->port.read_status_mask = Rx_OVR;
        if (iflag & INPCK)
 
 static const char *sunzilog_type(struct uart_port *port)
 {
-       return "zs";
+       struct uart_sunzilog_port *up = UART_ZILOG(port);
+
+       return (up->flags & SUNZILOG_FLAG_ESCC) ? "zs (ESCC)" : "zs";
 }
 
 /* We do not request/release mappings of the registers here, this
 
        spin_lock_irqsave(&up->port.lock, flags);
 
-       up->curregs[R15] = BRKIE;
+       up->curregs[R15] |= BRKIE;
        sunzilog_convert_to_zs(up, con->cflag, 0, brg);
 
        sunzilog_set_mctrl(&up->port, TIOCM_DTR | TIOCM_RTS);
                baud = 4800;
        }
 
-       up->curregs[R15] = BRKIE;
+       up->curregs[R15] |= BRKIE;
        brg = BPS_TO_BRG(baud, ZS_CLOCK / ZS_CLOCK_DIVISOR);
        sunzilog_convert_to_zs(up, up->cflag, 0, brg);
        sunzilog_set_mctrl(&up->port, TIOCM_DTR | TIOCM_RTS);
 
        if (up->flags & (SUNZILOG_FLAG_CONS_KEYB |
                         SUNZILOG_FLAG_CONS_MOUSE)) {
+               up->curregs[R1] = EXT_INT_ENAB | INT_ALL_Rx | TxINT_ENAB;
+               up->curregs[R4] = PAR_EVEN | X16CLK | SB1;
+               up->curregs[R3] = RxENAB | Rx8;
+               up->curregs[R5] = TxENAB | Tx8;
+               up->curregs[R6] = 0x00; /* SDLC Address */
+               up->curregs[R7] = 0x7E; /* SDLC Flag    */
+               up->curregs[R9] = NV;
+               up->curregs[R7p] = 0x00;
                sunzilog_init_kbdms(up, up->port.line);
-               up->curregs[R9] |= (NV | MIE);
+               /* Only enable interrupts if an ISR handler available */
+               if (up->flags & SUNZILOG_FLAG_ISR_HANDLER)
+                       up->curregs[R9] |= MIE;
                write_zsreg(channel, R9, up->curregs[R9]);
        } else {
                /* Normal serial TTY. */
                up->curregs[R4] = PAR_EVEN | X16CLK | SB1;
                up->curregs[R3] = RxENAB | Rx8;
                up->curregs[R5] = TxENAB | Tx8;
-               up->curregs[R9] = NV | MIE;
+               up->curregs[R6] = 0x00; /* SDLC Address */
+               up->curregs[R7] = 0x7E; /* SDLC Flag    */
+               up->curregs[R9] = NV;
                up->curregs[R10] = NRZ;
                up->curregs[R11] = TCBR | RCBR;
                baud = 9600;
                up->curregs[R12] = (brg & 0xff);
                up->curregs[R13] = (brg >> 8) & 0xff;
                up->curregs[R14] = BRSRC | BRENAB;
-               __load_zsregs(channel, up->curregs);
+               up->curregs[R15] = FIFOEN; /* Use FIFO if on ESCC */
+               up->curregs[R7p] = TxFIFO_LVL | RxFIFO_LVL;
+               if (__load_zsregs(channel, up->curregs)) {
+                       up->flags |= SUNZILOG_FLAG_ESCC;
+               }
+               /* Only enable interrupts if an ISR handler available */
+               if (up->flags & SUNZILOG_FLAG_ISR_HANDLER)
+                       up->curregs[R9] |= MIE;
                write_zsreg(channel, R9, up->curregs[R9]);
        }
 
                        return err;
                }
        } else {
-               printk(KERN_INFO "%s: Keyboard at MMIO %lx (irq = %d) "
-                      "is a zs\n",
-                      op->dev.bus_id, up[0].port.mapbase, op->irqs[0]);
-               printk(KERN_INFO "%s: Mouse at MMIO %lx (irq = %d) "
-                      "is a zs\n",
-                      op->dev.bus_id, up[1].port.mapbase, op->irqs[0]);
+               printk(KERN_INFO "%s: Keyboard at MMIO 0x%lx (irq = %d) "
+                      "is a %s\n",
+                      op->dev.bus_id, up[0].port.mapbase, op->irqs[0],
+                      sunzilog_type (&up[0].port));
+               printk(KERN_INFO "%s: Mouse at MMIO 0x%lx (irq = %d) "
+                      "is a %s\n",
+                      op->dev.bus_id, up[1].port.mapbase, op->irqs[0],
+                      sunzilog_type (&up[1].port));
        }
 
        dev_set_drvdata(&op->dev, &up[0]);
                goto out_unregister_uart;
 
        if (zilog_irq != -1) {
+               struct uart_sunzilog_port *up = sunzilog_irq_chain;
                err = request_irq(zilog_irq, sunzilog_interrupt, IRQF_SHARED,
                                  "zs", sunzilog_irq_chain);
                if (err)
                        goto out_unregister_driver;
+
+               /* Enable Interrupts */
+               while (up) {
+                       struct zilog_channel __iomem *channel;
+
+                       /* printk (KERN_INFO "Enable IRQ for ZILOG Hardware %p\n", up); */
+                       channel          = ZILOG_CHANNEL_FROM_PORT(&up->port);
+                       up->flags       |= SUNZILOG_FLAG_ISR_HANDLER;
+                       up->curregs[R9] |= MIE;
+                       write_zsreg(channel, R9, up->curregs[R9]);
+                       up = up->next;
+               }
        }
 
 out:
        of_unregister_driver(&zs_driver);
 
        if (zilog_irq != -1) {
+               struct uart_sunzilog_port *up = sunzilog_irq_chain;
+
+               /* Disable Interrupts */
+               while (up) {
+                       struct zilog_channel __iomem *channel;
+
+                       /* printk (KERN_INFO "Disable IRQ for ZILOG Hardware %p\n", up); */
+                       channel          = ZILOG_CHANNEL_FROM_PORT(&up->port);
+                       up->flags       &= ~SUNZILOG_FLAG_ISR_HANDLER;
+                       up->curregs[R9] &= ~MIE;
+                       write_zsreg(channel, R9, up->curregs[R9]);
+                       up = up->next;
+               }
+
                free_irq(zilog_irq, sunzilog_irq_chain);
                zilog_irq = -1;
        }
 
        struct zilog_channel channelA;
 };
 
-#define NUM_ZSREGS    16
+#define        NUM_ZSREGS      17
+#define        R7p             16 /* Written as R7 with P15 bit 0 set */
 
 /* Conversion routines to/from brg time constants from/to bits
  * per second.
 
 /* Write Register 7 (Sync bits 8-15/SDLC 01111110) */
 
+/* Write Register 7' (ESCC Only) */
+#define        AUTO_TxFLAG     1       /* Automatic Tx SDLC Flag */
+#define        AUTO_EOM_RST    2       /* Automatic EOM Reset */
+#define        AUTOnRTS        4       /* Automatic /RTS pin deactivation */
+#define        RxFIFO_LVL      8       /* Receive FIFO interrupt level */
+#define        nDTRnREQ        0x10    /* /DTR/REQ timing */
+#define        TxFIFO_LVL      0x20    /* Transmit FIFO interrupt level */
+#define        EXT_RD_EN       0x40    /* Extended read register enable */
+
 /* Write Register 8 (transmit buffer) */
 
 /* Write Register 9 (Master interrupt control) */
 #define        DLC     4       /* Disable Lower Chain */
 #define        MIE     8       /* Master Interrupt Enable */
 #define        STATHI  0x10    /* Status high */
+#define        SWIACK  0x20    /* Software Interrupt Ack (not on NMOS) */
 #define        NORESET 0       /* No reset on write to R9 */
 #define        CHRB    0x40    /* Reset channel B */
 #define        CHRA    0x80    /* Reset channel A */
 #define        SNRZI   0xe0    /* Set NRZI mode */
 
 /* Write Register 15 (external/status interrupt control) */
+#define        WR7pEN  1       /* WR7' Enable (ESCC only) */
 #define        ZCIE    2       /* Zero count IE */
+#define        FIFOEN  4       /* FIFO Enable (ESCC only) */
 #define        DCDIE   8       /* DCD IE */
 #define        SYNCIE  0x10    /* Sync/hunt IE */
 #define        CTSIE   0x20    /* CTS IE */
 #define        CHATxIP 0x10            /* Channel A Tx IP */
 #define        CHARxIP 0x20            /* Channel A Rx IP */
 
+/* Read Register 6 (LSB frame byte count [Not on NMOS]) */
+
+/* Read Register 7 (MSB frame byte count and FIFO status [Not on NMOS]) */
+
 /* Read Register 8 (receive data register) */
 
 /* Read Register 10  (misc status bits) */