^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Driver for Zilog serial chips found on SGI workstations and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * servers. This driver could actually be made more generic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * This is based on the drivers/serial/sunzilog.c code as of 2.6.0-test7 and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * old drivers/sgi/char/sgiserial.c code which itself is based of the original
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * drivers/sbus/char/zs.c code. A lot of code has been simply moved over
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * directly from there but much has been rewritten. Credits therefore go out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * to David S. Miller, Eddie C. Dost, Pete Zaitcev, Ted Ts'o and Alex Buell
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * for their work there.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * Copyright (C) 2002 Ralf Baechle (ralf@linux-mips.org)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * Copyright (C) 2002 David S. Miller (davem@redhat.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/tty.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/tty_flip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/major.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/ptrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/ioport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/circ_buf.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/serial.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/sysrq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/console.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <asm/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <asm/sgialib.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <asm/sgi/ioc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <asm/sgi/hpc3.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <asm/sgi/ip22.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <linux/serial_core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include "ip22zilog.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * On IP22 we need to delay after register accesses but we do not need to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * flush writes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define ZSDELAY() udelay(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define ZSDELAY_LONG() udelay(20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define ZS_WSYNC(channel) do { } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define NUM_IP22ZILOG 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define NUM_CHANNELS (NUM_IP22ZILOG * 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define ZS_CLOCK 3672000 /* Zilog input clock rate. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define ZS_CLOCK_DIVISOR 16 /* Divisor this driver uses. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * We wrap our port structure around the generic uart_port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) struct uart_ip22zilog_port {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) struct uart_port port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) /* IRQ servicing chain. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) struct uart_ip22zilog_port *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) /* Current values of Zilog write registers. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) unsigned char curregs[NUM_ZSREGS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) unsigned int flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define IP22ZILOG_FLAG_IS_CONS 0x00000004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define IP22ZILOG_FLAG_IS_KGDB 0x00000008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define IP22ZILOG_FLAG_MODEM_STATUS 0x00000010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define IP22ZILOG_FLAG_IS_CHANNEL_A 0x00000020
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define IP22ZILOG_FLAG_REGS_HELD 0x00000040
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define IP22ZILOG_FLAG_TX_STOPPED 0x00000080
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define IP22ZILOG_FLAG_TX_ACTIVE 0x00000100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define IP22ZILOG_FLAG_RESET_DONE 0x00000200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) unsigned int tty_break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) unsigned char parity_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) unsigned char prev_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define ZILOG_CHANNEL_FROM_PORT(PORT) ((struct zilog_channel *)((PORT)->membase))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define UART_ZILOG(PORT) ((struct uart_ip22zilog_port *)(PORT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define IP22ZILOG_GET_CURR_REG(PORT, REGNUM) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) (UART_ZILOG(PORT)->curregs[REGNUM])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define IP22ZILOG_SET_CURR_REG(PORT, REGNUM, REGVAL) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) ((UART_ZILOG(PORT)->curregs[REGNUM]) = (REGVAL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define ZS_IS_CONS(UP) ((UP)->flags & IP22ZILOG_FLAG_IS_CONS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define ZS_IS_KGDB(UP) ((UP)->flags & IP22ZILOG_FLAG_IS_KGDB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define ZS_WANTS_MODEM_STATUS(UP) ((UP)->flags & IP22ZILOG_FLAG_MODEM_STATUS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define ZS_IS_CHANNEL_A(UP) ((UP)->flags & IP22ZILOG_FLAG_IS_CHANNEL_A)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #define ZS_REGS_HELD(UP) ((UP)->flags & IP22ZILOG_FLAG_REGS_HELD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define ZS_TX_STOPPED(UP) ((UP)->flags & IP22ZILOG_FLAG_TX_STOPPED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #define ZS_TX_ACTIVE(UP) ((UP)->flags & IP22ZILOG_FLAG_TX_ACTIVE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) /* Reading and writing Zilog8530 registers. The delays are to make this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) * driver work on the IP22 which needs a settling delay after each chip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * register access, other machines handle this in hardware via auxiliary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) * flip-flops which implement the settle time we do in software.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * The port lock must be held and local IRQs must be disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * when {read,write}_zsreg is invoked.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) static unsigned char read_zsreg(struct zilog_channel *channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) unsigned char reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) unsigned char retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) writeb(reg, &channel->control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) ZSDELAY();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) retval = readb(&channel->control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) ZSDELAY();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) static void write_zsreg(struct zilog_channel *channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) unsigned char reg, unsigned char value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) writeb(reg, &channel->control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) ZSDELAY();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) writeb(value, &channel->control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) ZSDELAY();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) static void ip22zilog_clear_fifo(struct zilog_channel *channel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) for (i = 0; i < 32; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) unsigned char regval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) regval = readb(&channel->control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) ZSDELAY();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) if (regval & Rx_CH_AV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) regval = read_zsreg(channel, R1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) readb(&channel->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) ZSDELAY();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) if (regval & (PAR_ERR | Rx_OVR | CRC_ERR)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) writeb(ERR_RES, &channel->control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) ZSDELAY();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) ZS_WSYNC(channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) /* This function must only be called when the TX is not busy. The UART
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) * port lock must be held and local interrupts disabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) static void __load_zsregs(struct zilog_channel *channel, unsigned char *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) /* Let pending transmits finish. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) for (i = 0; i < 1000; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) unsigned char stat = read_zsreg(channel, R1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) if (stat & ALL_SNT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) udelay(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) writeb(ERR_RES, &channel->control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) ZSDELAY();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) ZS_WSYNC(channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) ip22zilog_clear_fifo(channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) /* Disable all interrupts. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) write_zsreg(channel, R1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) regs[R1] & ~(RxINT_MASK | TxINT_ENAB | EXT_INT_ENAB));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) /* Set parity, sync config, stop bits, and clock divisor. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) write_zsreg(channel, R4, regs[R4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) /* Set misc. TX/RX control bits. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) write_zsreg(channel, R10, regs[R10]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) /* Set TX/RX controls sans the enable bits. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) write_zsreg(channel, R3, regs[R3] & ~RxENAB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) write_zsreg(channel, R5, regs[R5] & ~TxENAB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) /* Synchronous mode config. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) write_zsreg(channel, R6, regs[R6]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) write_zsreg(channel, R7, regs[R7]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) /* Don't mess with the interrupt vector (R2, unused by us) and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * master interrupt control (R9). We make sure this is setup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) * properly at probe time then never touch it again.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) /* Disable baud generator. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) write_zsreg(channel, R14, regs[R14] & ~BRENAB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) /* Clock mode control. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) write_zsreg(channel, R11, regs[R11]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) /* Lower and upper byte of baud rate generator divisor. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) write_zsreg(channel, R12, regs[R12]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) write_zsreg(channel, R13, regs[R13]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) /* Now rewrite R14, with BRENAB (if set). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) write_zsreg(channel, R14, regs[R14]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) /* External status interrupt control. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) write_zsreg(channel, R15, regs[R15]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) /* Reset external status interrupts. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) write_zsreg(channel, R0, RES_EXT_INT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) write_zsreg(channel, R0, RES_EXT_INT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) /* Rewrite R3/R5, this time without enables masked. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) write_zsreg(channel, R3, regs[R3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) write_zsreg(channel, R5, regs[R5]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) /* Rewrite R1, this time without IRQ enabled masked. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) write_zsreg(channel, R1, regs[R1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) /* Reprogram the Zilog channel HW registers with the copies found in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) * software state struct. If the transmitter is busy, we defer this update
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) * until the next TX complete interrupt. Else, we do it right now.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) * The UART port lock must be held and local interrupts disabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) static void ip22zilog_maybe_update_regs(struct uart_ip22zilog_port *up,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) struct zilog_channel *channel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) if (!ZS_REGS_HELD(up)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) if (ZS_TX_ACTIVE(up)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) up->flags |= IP22ZILOG_FLAG_REGS_HELD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) __load_zsregs(channel, up->curregs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) #define Rx_BRK 0x0100 /* BREAK event software flag. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) #define Rx_SYS 0x0200 /* SysRq event software flag. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) static bool ip22zilog_receive_chars(struct uart_ip22zilog_port *up,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) struct zilog_channel *channel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) unsigned char ch, flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) unsigned int r1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) bool push = up->port.state != NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) ch = readb(&channel->control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) ZSDELAY();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) if (!(ch & Rx_CH_AV))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) r1 = read_zsreg(channel, R1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) if (r1 & (PAR_ERR | Rx_OVR | CRC_ERR)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) writeb(ERR_RES, &channel->control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) ZSDELAY();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) ZS_WSYNC(channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) ch = readb(&channel->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) ZSDELAY();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) ch &= up->parity_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) /* Handle the null char got when BREAK is removed. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) if (!ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) r1 |= up->tty_break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) /* A real serial line, record the character and status. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) flag = TTY_NORMAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) up->port.icount.rx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) if (r1 & (PAR_ERR | Rx_OVR | CRC_ERR | Rx_SYS | Rx_BRK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) up->tty_break = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) if (r1 & (Rx_SYS | Rx_BRK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) up->port.icount.brk++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) if (r1 & Rx_SYS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) r1 &= ~(PAR_ERR | CRC_ERR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) else if (r1 & PAR_ERR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) up->port.icount.parity++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) else if (r1 & CRC_ERR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) up->port.icount.frame++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) if (r1 & Rx_OVR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) up->port.icount.overrun++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) r1 &= up->port.read_status_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) if (r1 & Rx_BRK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) flag = TTY_BREAK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) else if (r1 & PAR_ERR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) flag = TTY_PARITY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) else if (r1 & CRC_ERR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) flag = TTY_FRAME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) if (uart_handle_sysrq_char(&up->port, ch))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) if (push)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) uart_insert_char(&up->port, r1, Rx_OVR, ch, flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) return push;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) static void ip22zilog_status_handle(struct uart_ip22zilog_port *up,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) struct zilog_channel *channel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) unsigned char status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) status = readb(&channel->control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) ZSDELAY();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) writeb(RES_EXT_INT, &channel->control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) ZSDELAY();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) ZS_WSYNC(channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) if (up->curregs[R15] & BRKIE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) if ((status & BRK_ABRT) && !(up->prev_status & BRK_ABRT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) if (uart_handle_break(&up->port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) up->tty_break = Rx_SYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) up->tty_break = Rx_BRK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) if (ZS_WANTS_MODEM_STATUS(up)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) if (status & SYNC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) up->port.icount.dsr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) /* The Zilog just gives us an interrupt when DCD/CTS/etc. change.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) * But it does not tell us which bit has changed, we have to keep
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) * track of this ourselves.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) if ((status ^ up->prev_status) ^ DCD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) uart_handle_dcd_change(&up->port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) (status & DCD));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) if ((status ^ up->prev_status) ^ CTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) uart_handle_cts_change(&up->port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) (status & CTS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) wake_up_interruptible(&up->port.state->port.delta_msr_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) up->prev_status = status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) static void ip22zilog_transmit_chars(struct uart_ip22zilog_port *up,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) struct zilog_channel *channel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) struct circ_buf *xmit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) if (ZS_IS_CONS(up)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) unsigned char status = readb(&channel->control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) ZSDELAY();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) /* TX still busy? Just wait for the next TX done interrupt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) * It can occur because of how we do serial console writes. It would
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) * be nice to transmit console writes just like we normally would for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) * a TTY line. (ie. buffered and TX interrupt driven). That is not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) * easy because console writes cannot sleep. One solution might be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) * to poll on enough port->xmit space becoming free. -DaveM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) if (!(status & Tx_BUF_EMP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) up->flags &= ~IP22ZILOG_FLAG_TX_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) if (ZS_REGS_HELD(up)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) __load_zsregs(channel, up->curregs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) up->flags &= ~IP22ZILOG_FLAG_REGS_HELD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) if (ZS_TX_STOPPED(up)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) up->flags &= ~IP22ZILOG_FLAG_TX_STOPPED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) goto ack_tx_int;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) if (up->port.x_char) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) up->flags |= IP22ZILOG_FLAG_TX_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) writeb(up->port.x_char, &channel->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) ZSDELAY();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) ZS_WSYNC(channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) up->port.icount.tx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) up->port.x_char = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) if (up->port.state == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) goto ack_tx_int;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) xmit = &up->port.state->xmit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) if (uart_circ_empty(xmit))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) goto ack_tx_int;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) if (uart_tx_stopped(&up->port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) goto ack_tx_int;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) up->flags |= IP22ZILOG_FLAG_TX_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) writeb(xmit->buf[xmit->tail], &channel->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) ZSDELAY();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) ZS_WSYNC(channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) up->port.icount.tx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) uart_write_wakeup(&up->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) ack_tx_int:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) writeb(RES_Tx_P, &channel->control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) ZSDELAY();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) ZS_WSYNC(channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) static irqreturn_t ip22zilog_interrupt(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) struct uart_ip22zilog_port *up = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) while (up) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) struct zilog_channel *channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) = ZILOG_CHANNEL_FROM_PORT(&up->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) unsigned char r3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) bool push = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) spin_lock(&up->port.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) r3 = read_zsreg(channel, R3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) /* Channel A */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) if (r3 & (CHAEXT | CHATxIP | CHARxIP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) writeb(RES_H_IUS, &channel->control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) ZSDELAY();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) ZS_WSYNC(channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) if (r3 & CHARxIP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) push = ip22zilog_receive_chars(up, channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) if (r3 & CHAEXT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) ip22zilog_status_handle(up, channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) if (r3 & CHATxIP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) ip22zilog_transmit_chars(up, channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) spin_unlock(&up->port.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) if (push)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) tty_flip_buffer_push(&up->port.state->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) /* Channel B */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) up = up->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) channel = ZILOG_CHANNEL_FROM_PORT(&up->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) push = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) spin_lock(&up->port.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) writeb(RES_H_IUS, &channel->control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) ZSDELAY();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) ZS_WSYNC(channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) if (r3 & CHBRxIP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) push = ip22zilog_receive_chars(up, channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) if (r3 & CHBEXT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) ip22zilog_status_handle(up, channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) if (r3 & CHBTxIP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) ip22zilog_transmit_chars(up, channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) spin_unlock(&up->port.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) if (push)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) tty_flip_buffer_push(&up->port.state->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) up = up->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) /* A convenient way to quickly get R0 status. The caller must _not_ hold the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) * port lock, it is acquired here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) static __inline__ unsigned char ip22zilog_read_channel_status(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) struct zilog_channel *channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) unsigned char status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) channel = ZILOG_CHANNEL_FROM_PORT(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) status = readb(&channel->control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) ZSDELAY();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) /* The port lock is not held. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) static unsigned int ip22zilog_tx_empty(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) unsigned char status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) unsigned int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) status = ip22zilog_read_channel_status(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) if (status & Tx_BUF_EMP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) ret = TIOCSER_TEMT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) /* The port lock is held and interrupts are disabled. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) static unsigned int ip22zilog_get_mctrl(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) unsigned char status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) unsigned int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) status = ip22zilog_read_channel_status(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) if (status & DCD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) ret |= TIOCM_CAR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) if (status & SYNC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) ret |= TIOCM_DSR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) if (status & CTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) ret |= TIOCM_CTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) /* The port lock is held and interrupts are disabled. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) static void ip22zilog_set_mctrl(struct uart_port *port, unsigned int mctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) struct uart_ip22zilog_port *up =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) container_of(port, struct uart_ip22zilog_port, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) struct zilog_channel *channel = ZILOG_CHANNEL_FROM_PORT(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) unsigned char set_bits, clear_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) set_bits = clear_bits = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) if (mctrl & TIOCM_RTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) set_bits |= RTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) clear_bits |= RTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) if (mctrl & TIOCM_DTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) set_bits |= DTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) clear_bits |= DTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) /* NOTE: Not subject to 'transmitter active' rule. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) up->curregs[R5] |= set_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) up->curregs[R5] &= ~clear_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) write_zsreg(channel, R5, up->curregs[R5]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) /* The port lock is held and interrupts are disabled. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) static void ip22zilog_stop_tx(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) struct uart_ip22zilog_port *up =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) container_of(port, struct uart_ip22zilog_port, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) up->flags |= IP22ZILOG_FLAG_TX_STOPPED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) /* The port lock is held and interrupts are disabled. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) static void ip22zilog_start_tx(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) struct uart_ip22zilog_port *up =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) container_of(port, struct uart_ip22zilog_port, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) struct zilog_channel *channel = ZILOG_CHANNEL_FROM_PORT(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) unsigned char status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) up->flags |= IP22ZILOG_FLAG_TX_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) up->flags &= ~IP22ZILOG_FLAG_TX_STOPPED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) status = readb(&channel->control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) ZSDELAY();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) /* TX busy? Just wait for the TX done interrupt. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) if (!(status & Tx_BUF_EMP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) /* Send the first character to jump-start the TX done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) * IRQ sending engine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) if (port->x_char) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) writeb(port->x_char, &channel->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) ZSDELAY();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) ZS_WSYNC(channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) port->icount.tx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) port->x_char = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) struct circ_buf *xmit = &port->state->xmit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) if (uart_circ_empty(xmit))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) writeb(xmit->buf[xmit->tail], &channel->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) ZSDELAY();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) ZS_WSYNC(channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) port->icount.tx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) uart_write_wakeup(&up->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) /* The port lock is held and interrupts are disabled. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) static void ip22zilog_stop_rx(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) struct uart_ip22zilog_port *up = UART_ZILOG(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) struct zilog_channel *channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) if (ZS_IS_CONS(up))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) channel = ZILOG_CHANNEL_FROM_PORT(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) /* Disable all RX interrupts. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) up->curregs[R1] &= ~RxINT_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) ip22zilog_maybe_update_regs(up, channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) /* The port lock is held. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) static void ip22zilog_enable_ms(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) struct uart_ip22zilog_port *up =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) container_of(port, struct uart_ip22zilog_port, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) struct zilog_channel *channel = ZILOG_CHANNEL_FROM_PORT(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) unsigned char new_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) new_reg = up->curregs[R15] | (DCDIE | SYNCIE | CTSIE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) if (new_reg != up->curregs[R15]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) up->curregs[R15] = new_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) /* NOTE: Not subject to 'transmitter active' rule. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) write_zsreg(channel, R15, up->curregs[R15]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) /* The port lock is not held. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) static void ip22zilog_break_ctl(struct uart_port *port, int break_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) struct uart_ip22zilog_port *up =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) container_of(port, struct uart_ip22zilog_port, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) struct zilog_channel *channel = ZILOG_CHANNEL_FROM_PORT(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) unsigned char set_bits, clear_bits, new_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) set_bits = clear_bits = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) if (break_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) set_bits |= SND_BRK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) clear_bits |= SND_BRK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) new_reg = (up->curregs[R5] | set_bits) & ~clear_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) if (new_reg != up->curregs[R5]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) up->curregs[R5] = new_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) /* NOTE: Not subject to 'transmitter active' rule. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) write_zsreg(channel, R5, up->curregs[R5]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) static void __ip22zilog_reset(struct uart_ip22zilog_port *up)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) struct zilog_channel *channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) if (up->flags & IP22ZILOG_FLAG_RESET_DONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) /* Let pending transmits finish. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) channel = ZILOG_CHANNEL_FROM_PORT(&up->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) for (i = 0; i < 1000; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) unsigned char stat = read_zsreg(channel, R1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) if (stat & ALL_SNT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) udelay(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) if (!ZS_IS_CHANNEL_A(up)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) up++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) channel = ZILOG_CHANNEL_FROM_PORT(&up->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) write_zsreg(channel, R9, FHWRES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) ZSDELAY_LONG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) (void) read_zsreg(channel, R0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) up->flags |= IP22ZILOG_FLAG_RESET_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) up->next->flags |= IP22ZILOG_FLAG_RESET_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) static void __ip22zilog_startup(struct uart_ip22zilog_port *up)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) struct zilog_channel *channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) channel = ZILOG_CHANNEL_FROM_PORT(&up->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) __ip22zilog_reset(up);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) __load_zsregs(channel, up->curregs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) /* set master interrupt enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) write_zsreg(channel, R9, up->curregs[R9]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) up->prev_status = readb(&channel->control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) /* Enable receiver and transmitter. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) up->curregs[R3] |= RxENAB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) up->curregs[R5] |= TxENAB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) up->curregs[R1] |= EXT_INT_ENAB | INT_ALL_Rx | TxINT_ENAB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) ip22zilog_maybe_update_regs(up, channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) static int ip22zilog_startup(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) struct uart_ip22zilog_port *up = UART_ZILOG(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) if (ZS_IS_CONS(up))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) __ip22zilog_startup(up);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) * The test for ZS_IS_CONS is explained by the following e-mail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) *****
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) * From: Russell King <rmk@arm.linux.org.uk>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) * Date: Sun, 8 Dec 2002 10:18:38 +0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) * On Sun, Dec 08, 2002 at 02:43:36AM -0500, Pete Zaitcev wrote:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) * > I boot my 2.5 boxes using "console=ttyS0,9600" argument,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) * > and I noticed that something is not right with reference
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) * > counting in this case. It seems that when the console
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) * > is open by kernel initially, this is not accounted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) * > as an open, and uart_startup is not called.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) * That is correct. We are unable to call uart_startup when the serial
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) * console is initialised because it may need to allocate memory (as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) * request_irq does) and the memory allocators may not have been
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) * initialised.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) * 1. initialise the port into a state where it can send characters in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) * console write method.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) * 2. don't do the actual hardware shutdown in your shutdown() method (but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) * do the normal software shutdown - ie, free irqs etc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) *****
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) static void ip22zilog_shutdown(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) struct uart_ip22zilog_port *up = UART_ZILOG(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) struct zilog_channel *channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) if (ZS_IS_CONS(up))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) channel = ZILOG_CHANNEL_FROM_PORT(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) /* Disable receiver and transmitter. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) up->curregs[R3] &= ~RxENAB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) up->curregs[R5] &= ~TxENAB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) /* Disable all interrupts and BRK assertion. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) up->curregs[R1] &= ~(EXT_INT_ENAB | TxINT_ENAB | RxINT_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) up->curregs[R5] &= ~SND_BRK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) ip22zilog_maybe_update_regs(up, channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) /* Shared by TTY driver and serial console setup. The port lock is held
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) * and local interrupts are disabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) ip22zilog_convert_to_zs(struct uart_ip22zilog_port *up, unsigned int cflag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) unsigned int iflag, int brg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) up->curregs[R10] = NRZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) up->curregs[R11] = TCBR | RCBR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) /* Program BAUD and clock source. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) up->curregs[R4] &= ~XCLK_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) up->curregs[R4] |= X16CLK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) up->curregs[R12] = brg & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) up->curregs[R13] = (brg >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) up->curregs[R14] = BRENAB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) /* Character size, stop bits, and parity. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) up->curregs[3] &= ~RxN_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) up->curregs[5] &= ~TxN_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) switch (cflag & CSIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) case CS5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) up->curregs[3] |= Rx5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) up->curregs[5] |= Tx5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) up->parity_mask = 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) case CS6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) up->curregs[3] |= Rx6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) up->curregs[5] |= Tx6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) up->parity_mask = 0x3f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) case CS7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) up->curregs[3] |= Rx7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) up->curregs[5] |= Tx7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) up->parity_mask = 0x7f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) case CS8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) up->curregs[3] |= Rx8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) up->curregs[5] |= Tx8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) up->parity_mask = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) up->curregs[4] &= ~0x0c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) if (cflag & CSTOPB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) up->curregs[4] |= SB2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) up->curregs[4] |= SB1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) if (cflag & PARENB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) up->curregs[4] |= PAR_ENAB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) up->curregs[4] &= ~PAR_ENAB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) if (!(cflag & PARODD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) up->curregs[4] |= PAR_EVEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) up->curregs[4] &= ~PAR_EVEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) up->port.read_status_mask = Rx_OVR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) if (iflag & INPCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) up->port.read_status_mask |= CRC_ERR | PAR_ERR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) if (iflag & (IGNBRK | BRKINT | PARMRK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) up->port.read_status_mask |= BRK_ABRT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) up->port.ignore_status_mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) if (iflag & IGNPAR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) up->port.ignore_status_mask |= CRC_ERR | PAR_ERR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) if (iflag & IGNBRK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) up->port.ignore_status_mask |= BRK_ABRT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) if (iflag & IGNPAR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) up->port.ignore_status_mask |= Rx_OVR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) if ((cflag & CREAD) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) up->port.ignore_status_mask = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) /* The port lock is not held. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) ip22zilog_set_termios(struct uart_port *port, struct ktermios *termios,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) struct ktermios *old)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) struct uart_ip22zilog_port *up =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) container_of(port, struct uart_ip22zilog_port, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) int baud, brg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) baud = uart_get_baud_rate(port, termios, old, 1200, 76800);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) spin_lock_irqsave(&up->port.lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) brg = BPS_TO_BRG(baud, ZS_CLOCK / ZS_CLOCK_DIVISOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) ip22zilog_convert_to_zs(up, termios->c_cflag, termios->c_iflag, brg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) if (UART_ENABLE_MS(&up->port, termios->c_cflag))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) up->flags |= IP22ZILOG_FLAG_MODEM_STATUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) up->flags &= ~IP22ZILOG_FLAG_MODEM_STATUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) ip22zilog_maybe_update_regs(up, ZILOG_CHANNEL_FROM_PORT(port));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) uart_update_timeout(port, termios->c_cflag, baud);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) spin_unlock_irqrestore(&up->port.lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) static const char *ip22zilog_type(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) return "IP22-Zilog";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) /* We do not request/release mappings of the registers here, this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) * happens at early serial probe time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) static void ip22zilog_release_port(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) static int ip22zilog_request_port(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) /* These do not need to do anything interesting either. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) static void ip22zilog_config_port(struct uart_port *port, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) /* We do not support letting the user mess with the divisor, IRQ, etc. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) static int ip22zilog_verify_port(struct uart_port *port, struct serial_struct *ser)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) static const struct uart_ops ip22zilog_pops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) .tx_empty = ip22zilog_tx_empty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) .set_mctrl = ip22zilog_set_mctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) .get_mctrl = ip22zilog_get_mctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) .stop_tx = ip22zilog_stop_tx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) .start_tx = ip22zilog_start_tx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) .stop_rx = ip22zilog_stop_rx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) .enable_ms = ip22zilog_enable_ms,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) .break_ctl = ip22zilog_break_ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) .startup = ip22zilog_startup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) .shutdown = ip22zilog_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) .set_termios = ip22zilog_set_termios,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) .type = ip22zilog_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) .release_port = ip22zilog_release_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) .request_port = ip22zilog_request_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) .config_port = ip22zilog_config_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) .verify_port = ip22zilog_verify_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) static struct uart_ip22zilog_port *ip22zilog_port_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) static struct zilog_layout **ip22zilog_chip_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) static struct uart_ip22zilog_port *ip22zilog_irq_chain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) static int zilog_irq = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) static void * __init alloc_one_table(unsigned long size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) return kzalloc(size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) static void __init ip22zilog_alloc_tables(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) ip22zilog_port_table = (struct uart_ip22zilog_port *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) alloc_one_table(NUM_CHANNELS * sizeof(struct uart_ip22zilog_port));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) ip22zilog_chip_regs = (struct zilog_layout **)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) alloc_one_table(NUM_IP22ZILOG * sizeof(struct zilog_layout *));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) if (ip22zilog_port_table == NULL || ip22zilog_chip_regs == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) panic("IP22-Zilog: Cannot allocate IP22-Zilog tables.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) /* Get the address of the registers for IP22-Zilog instance CHIP. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) static struct zilog_layout * __init get_zs(int chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) unsigned long base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) if (chip < 0 || chip >= NUM_IP22ZILOG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) panic("IP22-Zilog: Illegal chip number %d in get_zs.", chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) /* Not probe-able, hard code it. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) base = (unsigned long) &sgioc->uart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) zilog_irq = SGI_SERIAL_IRQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) request_mem_region(base, 8, "IP22-Zilog");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) return (struct zilog_layout *) base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) #define ZS_PUT_CHAR_MAX_DELAY 2000 /* 10 ms */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) #ifdef CONFIG_SERIAL_IP22_ZILOG_CONSOLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) static void ip22zilog_put_char(struct uart_port *port, int ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) struct zilog_channel *channel = ZILOG_CHANNEL_FROM_PORT(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) int loops = ZS_PUT_CHAR_MAX_DELAY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) /* This is a timed polling loop so do not switch the explicit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) * udelay with ZSDELAY as that is a NOP on some platforms. -DaveM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) unsigned char val = readb(&channel->control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) if (val & Tx_BUF_EMP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) ZSDELAY();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) udelay(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) } while (--loops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) writeb(ch, &channel->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) ZSDELAY();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) ZS_WSYNC(channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) ip22zilog_console_write(struct console *con, const char *s, unsigned int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) struct uart_ip22zilog_port *up = &ip22zilog_port_table[con->index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) spin_lock_irqsave(&up->port.lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) uart_console_write(&up->port, s, count, ip22zilog_put_char);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) udelay(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) spin_unlock_irqrestore(&up->port.lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) static int __init ip22zilog_console_setup(struct console *con, char *options)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) struct uart_ip22zilog_port *up = &ip22zilog_port_table[con->index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) int baud = 9600, bits = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) int parity = 'n';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) int flow = 'n';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) up->flags |= IP22ZILOG_FLAG_IS_CONS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) printk(KERN_INFO "Console: ttyS%d (IP22-Zilog)\n", con->index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) spin_lock_irqsave(&up->port.lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) up->curregs[R15] |= BRKIE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) __ip22zilog_startup(up);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) spin_unlock_irqrestore(&up->port.lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) if (options)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) uart_parse_options(options, &baud, &parity, &bits, &flow);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) return uart_set_options(&up->port, con, baud, parity, bits, flow);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) static struct uart_driver ip22zilog_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) static struct console ip22zilog_console = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) .name = "ttyS",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) .write = ip22zilog_console_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) .device = uart_console_device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) .setup = ip22zilog_console_setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) .flags = CON_PRINTBUFFER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) .index = -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) .data = &ip22zilog_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) #endif /* CONFIG_SERIAL_IP22_ZILOG_CONSOLE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) static struct uart_driver ip22zilog_reg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) .driver_name = "serial",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) .dev_name = "ttyS",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) .major = TTY_MAJOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) .minor = 64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) .nr = NUM_CHANNELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) #ifdef CONFIG_SERIAL_IP22_ZILOG_CONSOLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) .cons = &ip22zilog_console,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) static void __init ip22zilog_prepare(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) unsigned char sysrq_on = IS_ENABLED(CONFIG_SERIAL_IP22_ZILOG_CONSOLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) struct uart_ip22zilog_port *up;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) struct zilog_layout *rp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) int channel, chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) * Temporary fix.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) for (channel = 0; channel < NUM_CHANNELS; channel++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) spin_lock_init(&ip22zilog_port_table[channel].port.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) ip22zilog_irq_chain = &ip22zilog_port_table[NUM_CHANNELS - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) up = &ip22zilog_port_table[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) for (channel = NUM_CHANNELS - 1 ; channel > 0; channel--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) up[channel].next = &up[channel - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) up[channel].next = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) for (chip = 0; chip < NUM_IP22ZILOG; chip++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) if (!ip22zilog_chip_regs[chip]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) ip22zilog_chip_regs[chip] = rp = get_zs(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) up[(chip * 2) + 0].port.membase = (char *) &rp->channelB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) up[(chip * 2) + 1].port.membase = (char *) &rp->channelA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) /* In theory mapbase is the physical address ... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) up[(chip * 2) + 0].port.mapbase =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) (unsigned long) ioremap((unsigned long) &rp->channelB, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) up[(chip * 2) + 1].port.mapbase =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) (unsigned long) ioremap((unsigned long) &rp->channelA, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) /* Channel A */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) up[(chip * 2) + 0].port.iotype = UPIO_MEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) up[(chip * 2) + 0].port.irq = zilog_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) up[(chip * 2) + 0].port.uartclk = ZS_CLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) up[(chip * 2) + 0].port.fifosize = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) up[(chip * 2) + 0].port.has_sysrq = sysrq_on;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) up[(chip * 2) + 0].port.ops = &ip22zilog_pops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) up[(chip * 2) + 0].port.type = PORT_IP22ZILOG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) up[(chip * 2) + 0].port.flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) up[(chip * 2) + 0].port.line = (chip * 2) + 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) up[(chip * 2) + 0].flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) /* Channel B */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) up[(chip * 2) + 1].port.iotype = UPIO_MEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) up[(chip * 2) + 1].port.irq = zilog_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) up[(chip * 2) + 1].port.uartclk = ZS_CLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) up[(chip * 2) + 1].port.fifosize = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) up[(chip * 2) + 1].port.has_sysrq = sysrq_on;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) up[(chip * 2) + 1].port.ops = &ip22zilog_pops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) up[(chip * 2) + 1].port.type = PORT_IP22ZILOG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) up[(chip * 2) + 1].port.line = (chip * 2) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) up[(chip * 2) + 1].flags |= IP22ZILOG_FLAG_IS_CHANNEL_A;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) for (channel = 0; channel < NUM_CHANNELS; channel++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) struct uart_ip22zilog_port *up = &ip22zilog_port_table[channel];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) int brg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) /* Normal serial TTY. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) up->parity_mask = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) up->curregs[R1] = EXT_INT_ENAB | INT_ALL_Rx | TxINT_ENAB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) up->curregs[R4] = PAR_EVEN | X16CLK | SB1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) up->curregs[R3] = RxENAB | Rx8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) up->curregs[R5] = TxENAB | Tx8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) up->curregs[R9] = NV | MIE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) up->curregs[R10] = NRZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) up->curregs[R11] = TCBR | RCBR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) brg = BPS_TO_BRG(9600, ZS_CLOCK / ZS_CLOCK_DIVISOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) up->curregs[R12] = (brg & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) up->curregs[R13] = (brg >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) up->curregs[R14] = BRENAB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) static int __init ip22zilog_ports_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) printk(KERN_INFO "Serial: IP22 Zilog driver (%d chips).\n", NUM_IP22ZILOG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) ip22zilog_prepare();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) if (request_irq(zilog_irq, ip22zilog_interrupt, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) "IP22-Zilog", ip22zilog_irq_chain)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) panic("IP22-Zilog: Unable to register zs interrupt handler.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) ret = uart_register_driver(&ip22zilog_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) if (ret == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) for (i = 0; i < NUM_CHANNELS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) struct uart_ip22zilog_port *up = &ip22zilog_port_table[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) uart_add_one_port(&ip22zilog_reg, &up->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) static int __init ip22zilog_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) /* IP22 Zilog setup is hard coded, no probing to do. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) ip22zilog_alloc_tables();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) ip22zilog_ports_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) static void __exit ip22zilog_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) struct uart_ip22zilog_port *up;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) for (i = 0; i < NUM_CHANNELS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) up = &ip22zilog_port_table[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) uart_remove_one_port(&ip22zilog_reg, &up->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) /* Free IO mem */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) up = &ip22zilog_port_table[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) for (i = 0; i < NUM_IP22ZILOG; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) if (up[(i * 2) + 0].port.mapbase) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) iounmap((void*)up[(i * 2) + 0].port.mapbase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) up[(i * 2) + 0].port.mapbase = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) if (up[(i * 2) + 1].port.mapbase) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) iounmap((void*)up[(i * 2) + 1].port.mapbase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) up[(i * 2) + 1].port.mapbase = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) uart_unregister_driver(&ip22zilog_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) module_init(ip22zilog_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) module_exit(ip22zilog_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) /* David wrote it but I'm to blame for the bugs ... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) MODULE_AUTHOR("Ralf Baechle <ralf@linux-mips.org>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) MODULE_DESCRIPTION("SGI Zilog serial port driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) MODULE_LICENSE("GPL");