// SPDX-License-Identifier: GPL-2.0 /* * zs.c: Serial port driver for IOASIC DECstations. * * Derived from drivers/sbus/char/sunserial.c by Paul Mackerras. * Derived from drivers/macintosh/macserial.c by Harald Koerfgen. * * DECstation changes * Copyright (C) 1998-2000 Harald Koerfgen * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007 Maciej W. Rozycki * * For the rest of the code the original Copyright applies: * Copyright (C) 1996 Paul Mackerras (Paul.Mackerras@cs.anu.edu.au) * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) * * * Note: for IOASIC systems the wiring is as follows: * * mouse/keyboard: * DIN-7 MJ-4 signal SCC * 2 1 TxD <- A.TxD * 3 4 RxD -> A.RxD * * EIA-232/EIA-423: * DB-25 MMJ-6 signal SCC * 2 2 TxD <- B.TxD * 3 5 RxD -> B.RxD * 4 RTS <- ~A.RTS * 5 CTS -> ~B.CTS * 6 6 DSR -> ~A.SYNC * 8 CD -> ~B.DCD * 12 DSRS(DCE) -> ~A.CTS (*) * 15 TxC -> B.TxC * 17 RxC -> B.RxC * 20 1 DTR <- ~A.DTR * 22 RI -> ~A.DCD * 23 DSRS(DTE) <- ~B.RTS * * (*) EIA-232 defines the signal at this pin to be SCD, while DSRS(DCE) * is shared with DSRS(DTE) at pin 23. * * As you can immediately notice the wiring of the RTS, DTR and DSR signals * is a bit odd. This makes the handling of port B unnecessarily * complicated and prevents the use of some automatic modes of operation.
*/
MODULE_AUTHOR("Maciej W. Rozycki ");
MODULE_DESCRIPTION("DECstation Z85C30 serial driver");
MODULE_LICENSE("GPL");
staticchar zs_name[] __initdata = "DECstation Z85C30 serial driver version "; staticchar zs_version[] __initdata = "0.10";
/* * It would be nice to dynamically allocate everything that * depends on ZS_NUM_SCCS, so we could support any number of * Z85C30s, but for now...
*/ #define ZS_NUM_SCCS 2 /* Max # of ZS chips supported. */ #define ZS_NUM_CHAN 2 /* 2 channels per chip. */ #define ZS_CHAN_A 0 /* Index of the channel A. */ #define ZS_CHAN_B 1 /* Index of the channel B. */ #define ZS_CHAN_IO_SIZE 8 /* IOMEM space size. */ #define ZS_CHAN_IO_STRIDE 4 /* Register alignment. */ #define ZS_CHAN_IO_OFFSET 1 /* The SCC resides on the high byte
of the 16-bit IOBUS. */ #define ZS_CLOCK 7372800 /* Z85C30 PCLK input clock rate. */
/* * zs_tx_empty() -- get the transmitter empty status * * Purpose: Let user call ioctl() to get info when the UART physically * is emptied. On bus types like RS485, the transmitter must * release the bus after transmitting. This must be done when * the transmit shift register is empty, not be done when the * transmit holding register is empty. This functionality * allows an RS485 driver to be written in user space.
*/ staticunsignedint zs_tx_empty(struct uart_port *uport)
{ struct zs_port *zport = to_zport(uport); struct zs_scc *scc = zport->scc; unsignedlong flags;
u8 status;
spin_lock_irqsave(&scc->zlock, flags);
status = read_zsreg(zport, R1);
spin_unlock_irqrestore(&scc->zlock, flags);
if (status & (Rx_SYS | Rx_BRK)) {
icount->brk++; /* SysRq discards the null char. */ if (status & Rx_SYS) continue;
} elseif (status & FRM_ERR)
icount->frame++; elseif (status & PAR_ERR)
icount->parity++; if (status & Rx_OVR)
icount->overrun++;
status &= uport->read_status_mask; if (status & Rx_BRK)
flag = TTY_BREAK; elseif (status & FRM_ERR)
flag = TTY_FRAME; elseif (status & PAR_ERR)
flag = TTY_PARITY;
}
/* If nothing to do or stopped or hardware stopped. */ if (uart_tx_stopped(&zport->port) ||
!uart_fifo_get(&zport->port, &ch)) {
zs_raw_stop_tx(zport); return;
}
/* Send char. */
write_zsdata(zport, ch);
if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
uart_write_wakeup(&zport->port);
/* Are we are done? */ if (kfifo_is_empty(&tport->xmit_fifo))
zs_raw_stop_tx(zport);
}
/* Get status from Read Register 0. */
status = read_zsreg(zport, R0);
if (zport->regs[15] & BRKIE) {
brk = status & BRK_ABRT; if (brk && !zport->brk) {
spin_unlock(&scc->zlock); if (uart_handle_break(uport))
zport->tty_break = Rx_SYS; else
zport->tty_break = Rx_BRK;
spin_lock(&scc->zlock);
}
zport->brk = brk;
}
if (zport != zport_a) {
delta = zs_raw_xor_mctrl(zport);
spin_unlock(&scc->zlock);
if (delta & TIOCM_CTS)
uart_handle_cts_change(uport,
zport->mctrl & TIOCM_CTS); if (delta & TIOCM_CAR)
uart_handle_dcd_change(uport,
zport->mctrl & TIOCM_CAR); if (delta & TIOCM_RNG)
uport->icount.dsr++; if (delta & TIOCM_DSR)
uport->icount.rng++;
if (delta)
wake_up_interruptible(&uport->state->port.delta_msr_wait);
spin_lock(&scc->zlock);
}
/* Clear the status condition... */
write_zsreg(zport, R0, RES_EXT_INT);
spin_unlock(&scc->zlock);
}
/* * This is the Z85C30 driver's generic interrupt routine.
*/ static irqreturn_t zs_interrupt(int irq, void *dev_id)
{ struct zs_scc *scc = dev_id; struct zs_port *zport_a = &scc->zport[ZS_CHAN_A]; struct zs_port *zport_b = &scc->zport[ZS_CHAN_B];
irqreturn_t status = IRQ_NONE;
u8 zs_intreg; int count;
/* * NOTE: The read register 3, which holds the irq status, * does so for both channels on each chip. Although * the status value itself must be read from the A * channel and is only valid when read from channel A. * Yes... broken hardware...
*/ for (count = 16; count; count--) {
spin_lock(&scc->zlock);
zs_intreg = read_zsreg(zport_a, R3);
spin_unlock(&scc->zlock); if (!zs_intreg) break;
/* * We do not like losing characters, so we prioritise * interrupt sources a little bit differently than * the SCC would, was it allowed to.
*/ if (zs_intreg & CHBRxIP)
zs_receive_chars(zport_b); if (zs_intreg & CHARxIP)
zs_receive_chars(zport_a); if (zs_intreg & CHBEXT)
zs_status_handle(zport_b, zport_a); if (zs_intreg & CHAEXT)
zs_status_handle(zport_a, zport_a); if (zs_intreg & CHBTxIP)
zs_transmit_chars(zport_b); if (zs_intreg & CHATxIP)
zs_transmit_chars(zport_a);
status = IRQ_HANDLED;
}
return status;
}
/* * Finally, routines used to initialize the serial port.
*/ staticint zs_startup(struct uart_port *uport)
{ struct zs_port *zport = to_zport(uport); struct zs_scc *scc = zport->scc; unsignedlong flags; int irq_guard; int ret;
irq_guard = atomic_add_return(1, &scc->irq_guard); if (irq_guard == 1) {
ret = request_irq(zport->port.irq, zs_interrupt,
IRQF_SHARED, "scc", scc); if (ret) {
atomic_add(-1, &scc->irq_guard);
printk(KERN_ERR "zs: can't get irq %d\n",
zport->port.irq); return ret;
}
}
spin_lock_irqsave(&scc->zlock, flags);
/* Clear the receive FIFO. */
zs_receive_drain(zport);
/* Clear the interrupt registers. */
write_zsreg(zport, R0, ERR_RES);
write_zsreg(zport, R0, RES_Tx_P); /* But Ext only if not being handled already. */ if (!(zport->regs[1] & EXT_INT_ENAB))
write_zsreg(zport, R0, RES_EXT_INT);
/* * Print a string to the serial port trying not to disturb * any possible real use of the port...
*/ staticvoid zs_console_write(struct console *co, constchar *s, unsignedint count)
{ int chip = co->index / ZS_NUM_CHAN, side = co->index % ZS_NUM_CHAN; struct zs_port *zport = &zs_sccs[chip].zport[side]; struct zs_scc *scc = zport->scc; unsignedlong flags;
u8 txint, txenb; int irq;
/* Restore transmit interrupts and the transmitter enable. */
spin_lock_irqsave(&scc->zlock, flags);
irq = !irqs_disabled_flags(flags);
zs_line_drain(zport, irq); if (!(txenb & TxENAB)) {
zport->regs[5] &= ~TxENAB;
write_zsreg(zport, R5, zport->regs[5]);
} if (txint & TxINT_ENAB) {
zport->regs[1] |= TxINT_ENAB;
write_zsreg(zport, R1, zport->regs[1]);
/* Resume any transmission as the TxIP bit won't be set. */ if (!zport->tx_stopped)
zs_raw_transmit_chars(zport);
}
spin_unlock_irqrestore(&scc->zlock, flags);
}
/* * Setup serial console baud/bits/parity. We do two things here: * - construct a cflag setting for the first uart_open() * - initialise the serial port * Return non-zero if we didn't find a serial port.
*/ staticint __init zs_console_setup(struct console *co, char *options)
{ int chip = co->index / ZS_NUM_CHAN, side = co->index % ZS_NUM_CHAN; struct zs_port *zport = &zs_sccs[chip].zport[side]; struct uart_port *uport = &zport->port; int baud = 9600; int bits = 8; int parity = 'n'; int flow = 'n'; int ret;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.