^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 PowerMac Z85c30 based ESCC cell found in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * "macio" ASICs of various PowerMac models
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2003 Ben. Herrenschmidt (benh@kernel.crashing.org)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Derived from drivers/macintosh/macserial.c by Paul Mackerras
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * and drivers/serial/sunzilog.c by David S. Miller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Hrm... actually, I ripped most of sunzilog (Thanks David !) and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * adapted special tweaks needed for us. I don't think it's worth
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * merging back those though. The DMA code still has to get in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * and once done, I expect that driver to remain fairly stable in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * the long term, unless we change the driver model again...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * 2004-08-06 Harald Welte <laforge@gnumonks.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * - Enable BREAK interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * - Add support for sysreq
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * TODO: - Add DMA support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * - Defer port shutdown to a few seconds after close
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * - maybe put something right into uap->clk_divisor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #undef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #undef DEBUG_HARD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #undef USE_CTRL_O_SYSRQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/tty.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/tty_flip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/major.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <linux/fcntl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <linux/console.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include <linux/adb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include <linux/pmu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include <linux/sysrq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #include <linux/of_address.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #include <linux/of_irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #include <asm/sections.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #include <asm/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #ifdef CONFIG_PPC_PMAC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #include <asm/prom.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #include <asm/machdep.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #include <asm/pmac_feature.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #include <asm/dbdma.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #include <asm/macio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define of_machine_is_compatible(x) (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #include <linux/serial.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #include <linux/serial_core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #include "pmac_zilog.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) /* Not yet implemented */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #undef HAS_DBDMA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) static char version[] __initdata = "pmac_zilog: 0.6 (Benjamin Herrenschmidt <benh@kernel.crashing.org>)";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) MODULE_DESCRIPTION("Driver for the Mac and PowerMac serial ports.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #ifdef CONFIG_SERIAL_PMACZILOG_TTYS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define PMACZILOG_MAJOR TTY_MAJOR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define PMACZILOG_MINOR 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define PMACZILOG_NAME "ttyS"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define PMACZILOG_MAJOR 204
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define PMACZILOG_MINOR 192
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define PMACZILOG_NAME "ttyPZ"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define pmz_debug(fmt, arg...) pr_debug("ttyPZ%d: " fmt, uap->port.line, ## arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define pmz_error(fmt, arg...) pr_err("ttyPZ%d: " fmt, uap->port.line, ## arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define pmz_info(fmt, arg...) pr_info("ttyPZ%d: " fmt, uap->port.line, ## arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * For the sake of early serial console, we can do a pre-probe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) * (optional) of the ports at rather early boot time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) static struct uart_pmac_port pmz_ports[MAX_ZS_PORTS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) static int pmz_ports_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) static struct uart_driver pmz_uart_reg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) .driver_name = PMACZILOG_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) .dev_name = PMACZILOG_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) .major = PMACZILOG_MAJOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) .minor = PMACZILOG_MINOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * Load all registers to reprogram the port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) * This function must only be called when the TX is not busy. The UART
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * port lock must be held and local interrupts disabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) static void pmz_load_zsregs(struct uart_pmac_port *uap, u8 *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) /* Let pending transmits finish. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) for (i = 0; i < 1000; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) unsigned char stat = read_zsreg(uap, R1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) if (stat & ALL_SNT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) udelay(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) ZS_CLEARERR(uap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) zssync(uap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) ZS_CLEARFIFO(uap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) zssync(uap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) ZS_CLEARERR(uap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) /* Disable all interrupts. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) write_zsreg(uap, R1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) regs[R1] & ~(RxINT_MASK | TxINT_ENAB | EXT_INT_ENAB));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) /* Set parity, sync config, stop bits, and clock divisor. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) write_zsreg(uap, R4, regs[R4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) /* Set misc. TX/RX control bits. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) write_zsreg(uap, R10, regs[R10]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) /* Set TX/RX controls sans the enable bits. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) write_zsreg(uap, R3, regs[R3] & ~RxENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) write_zsreg(uap, R5, regs[R5] & ~TxENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) /* now set R7 "prime" on ESCC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) write_zsreg(uap, R15, regs[R15] | EN85C30);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) write_zsreg(uap, R7, regs[R7P]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) /* make sure we use R7 "non-prime" on ESCC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) write_zsreg(uap, R15, regs[R15] & ~EN85C30);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) /* Synchronous mode config. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) write_zsreg(uap, R6, regs[R6]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) write_zsreg(uap, R7, regs[R7]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) /* Disable baud generator. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) write_zsreg(uap, R14, regs[R14] & ~BRENAB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) /* Clock mode control. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) write_zsreg(uap, R11, regs[R11]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) /* Lower and upper byte of baud rate generator divisor. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) write_zsreg(uap, R12, regs[R12]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) write_zsreg(uap, R13, regs[R13]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) /* Now rewrite R14, with BRENAB (if set). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) write_zsreg(uap, R14, regs[R14]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) /* Reset external status interrupts. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) write_zsreg(uap, R0, RES_EXT_INT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) write_zsreg(uap, R0, RES_EXT_INT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) /* Rewrite R3/R5, this time without enables masked. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) write_zsreg(uap, R3, regs[R3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) write_zsreg(uap, R5, regs[R5]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) /* Rewrite R1, this time without IRQ enabled masked. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) write_zsreg(uap, R1, regs[R1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) /* Enable interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) write_zsreg(uap, R9, regs[R9]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) * We do like sunzilog to avoid disrupting pending Tx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) * Reprogram the Zilog channel HW registers with the copies found in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) * software state struct. If the transmitter is busy, we defer this update
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) * until the next TX complete interrupt. Else, we do it right now.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) * The UART port lock must be held and local interrupts disabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) static void pmz_maybe_update_regs(struct uart_pmac_port *uap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) if (!ZS_REGS_HELD(uap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) if (ZS_TX_ACTIVE(uap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) uap->flags |= PMACZILOG_FLAG_REGS_HELD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) pmz_debug("pmz: maybe_update_regs: updating\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) pmz_load_zsregs(uap, uap->curregs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) static void pmz_interrupt_control(struct uart_pmac_port *uap, int enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) if (enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) uap->curregs[1] |= INT_ALL_Rx | TxINT_ENAB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) if (!ZS_IS_EXTCLK(uap))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) uap->curregs[1] |= EXT_INT_ENAB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) uap->curregs[1] &= ~(EXT_INT_ENAB | TxINT_ENAB | RxINT_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) write_zsreg(uap, R1, uap->curregs[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) static bool pmz_receive_chars(struct uart_pmac_port *uap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) __must_hold(&uap->port.lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) struct tty_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) unsigned char ch, r1, drop, flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) int loops = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) /* Sanity check, make sure the old bug is no longer happening */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) if (uap->port.state == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) WARN_ON(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) (void)read_zsdata(uap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) port = &uap->port.state->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) drop = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) r1 = read_zsreg(uap, R1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) ch = read_zsdata(uap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) if (r1 & (PAR_ERR | Rx_OVR | CRC_ERR)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) write_zsreg(uap, R0, ERR_RES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) zssync(uap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) ch &= uap->parity_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) if (ch == 0 && uap->flags & PMACZILOG_FLAG_BREAK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) uap->flags &= ~PMACZILOG_FLAG_BREAK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) #if defined(CONFIG_MAGIC_SYSRQ) && defined(CONFIG_SERIAL_CORE_CONSOLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) #ifdef USE_CTRL_O_SYSRQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) /* Handle the SysRq ^O Hack */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) if (ch == '\x0f') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) uap->port.sysrq = jiffies + HZ*5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) goto next_char;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) #endif /* USE_CTRL_O_SYSRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) if (uap->port.sysrq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) int swallow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) spin_unlock(&uap->port.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) swallow = uart_handle_sysrq_char(&uap->port, ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) spin_lock(&uap->port.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) if (swallow)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) goto next_char;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) #endif /* CONFIG_MAGIC_SYSRQ && CONFIG_SERIAL_CORE_CONSOLE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) /* A real serial line, record the character and status. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) if (drop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) goto next_char;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) flag = TTY_NORMAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) uap->port.icount.rx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) if (r1 & (PAR_ERR | Rx_OVR | CRC_ERR | BRK_ABRT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) if (r1 & BRK_ABRT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) pmz_debug("pmz: got break !\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) r1 &= ~(PAR_ERR | CRC_ERR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) uap->port.icount.brk++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) if (uart_handle_break(&uap->port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) goto next_char;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) else if (r1 & PAR_ERR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) uap->port.icount.parity++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) else if (r1 & CRC_ERR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) uap->port.icount.frame++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) if (r1 & Rx_OVR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) uap->port.icount.overrun++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) r1 &= uap->port.read_status_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) if (r1 & BRK_ABRT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) flag = TTY_BREAK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) else if (r1 & PAR_ERR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) flag = TTY_PARITY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) else if (r1 & CRC_ERR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) flag = TTY_FRAME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) if (uap->port.ignore_status_mask == 0xff ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) (r1 & uap->port.ignore_status_mask) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) tty_insert_flip_char(port, ch, flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) if (r1 & Rx_OVR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) tty_insert_flip_char(port, 0, TTY_OVERRUN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) next_char:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) /* We can get stuck in an infinite loop getting char 0 when the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) * line is in a wrong HW state, we break that here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) * When that happens, I disable the receive side of the driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) * Note that what I've been experiencing is a real irq loop where
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) * I'm getting flooded regardless of the actual port speed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) * Something strange is going on with the HW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) if ((++loops) > 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) goto flood;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) ch = read_zsreg(uap, R0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) if (!(ch & Rx_CH_AV))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) flood:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) pmz_interrupt_control(uap, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) pmz_error("pmz: rx irq flood !\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) static void pmz_status_handle(struct uart_pmac_port *uap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) unsigned char status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) status = read_zsreg(uap, R0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) write_zsreg(uap, R0, RES_EXT_INT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) zssync(uap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) if (ZS_IS_OPEN(uap) && ZS_WANTS_MODEM_STATUS(uap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) if (status & SYNC_HUNT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) uap->port.icount.dsr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) /* The Zilog just gives us an interrupt when DCD/CTS/etc. change.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) * But it does not tell us which bit has changed, we have to keep
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) * track of this ourselves.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) * The CTS input is inverted for some reason. -- paulus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) if ((status ^ uap->prev_status) & DCD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) uart_handle_dcd_change(&uap->port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) (status & DCD));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) if ((status ^ uap->prev_status) & CTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) uart_handle_cts_change(&uap->port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) !(status & CTS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) wake_up_interruptible(&uap->port.state->port.delta_msr_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) if (status & BRK_ABRT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) uap->flags |= PMACZILOG_FLAG_BREAK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) uap->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 pmz_transmit_chars(struct uart_pmac_port *uap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) struct circ_buf *xmit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) if (ZS_IS_CONS(uap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) unsigned char status = read_zsreg(uap, R0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) /* TX still busy? Just wait for the next TX done interrupt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) * It can occur because of how we do serial console writes. It would
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) * be nice to transmit console writes just like we normally would for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) * a TTY line. (ie. buffered and TX interrupt driven). That is not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) * easy because console writes cannot sleep. One solution might be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) * to poll on enough port->xmit space becoming free. -DaveM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) if (!(status & Tx_BUF_EMP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) uap->flags &= ~PMACZILOG_FLAG_TX_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) if (ZS_REGS_HELD(uap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) pmz_load_zsregs(uap, uap->curregs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) uap->flags &= ~PMACZILOG_FLAG_REGS_HELD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) if (ZS_TX_STOPPED(uap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) uap->flags &= ~PMACZILOG_FLAG_TX_STOPPED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) goto ack_tx_int;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) /* Under some circumstances, we see interrupts reported for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) * a closed channel. The interrupt mask in R1 is clear, but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) * R3 still signals the interrupts and we see them when taking
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) * an interrupt for the other channel (this could be a qemu
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) * bug but since the ESCC doc doesn't specify precsiely whether
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) * R3 interrup status bits are masked by R1 interrupt enable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) * bits, better safe than sorry). --BenH.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) if (!ZS_IS_OPEN(uap))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) goto ack_tx_int;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) if (uap->port.x_char) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) uap->flags |= PMACZILOG_FLAG_TX_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) write_zsdata(uap, uap->port.x_char);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) zssync(uap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) uap->port.icount.tx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) uap->port.x_char = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) if (uap->port.state == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) goto ack_tx_int;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) xmit = &uap->port.state->xmit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) if (uart_circ_empty(xmit)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) uart_write_wakeup(&uap->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) goto ack_tx_int;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) if (uart_tx_stopped(&uap->port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) goto ack_tx_int;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) uap->flags |= PMACZILOG_FLAG_TX_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) write_zsdata(uap, xmit->buf[xmit->tail]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) zssync(uap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) uap->port.icount.tx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) uart_write_wakeup(&uap->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) ack_tx_int:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) write_zsreg(uap, R0, RES_Tx_P);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) zssync(uap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) /* Hrm... we register that twice, fixme later.... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) static irqreturn_t pmz_interrupt(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) struct uart_pmac_port *uap = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) struct uart_pmac_port *uap_a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) struct uart_pmac_port *uap_b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) int rc = IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) bool push;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) u8 r3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) uap_a = pmz_get_port_A(uap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) uap_b = uap_a->mate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) spin_lock(&uap_a->port.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) r3 = read_zsreg(uap_a, R3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) #ifdef DEBUG_HARD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) pmz_debug("irq, r3: %x\n", r3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) /* Channel A */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) push = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) if (r3 & (CHAEXT | CHATxIP | CHARxIP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) if (!ZS_IS_OPEN(uap_a)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) pmz_debug("ChanA interrupt while not open !\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) goto skip_a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) write_zsreg(uap_a, R0, RES_H_IUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) zssync(uap_a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) if (r3 & CHAEXT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) pmz_status_handle(uap_a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) if (r3 & CHARxIP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) push = pmz_receive_chars(uap_a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) if (r3 & CHATxIP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) pmz_transmit_chars(uap_a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) rc = IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) skip_a:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) spin_unlock(&uap_a->port.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) if (push)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) tty_flip_buffer_push(&uap->port.state->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) if (!uap_b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) spin_lock(&uap_b->port.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) push = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) if (!ZS_IS_OPEN(uap_b)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) pmz_debug("ChanB interrupt while not open !\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) goto skip_b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) write_zsreg(uap_b, R0, RES_H_IUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) zssync(uap_b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) if (r3 & CHBEXT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) pmz_status_handle(uap_b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) if (r3 & CHBRxIP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) push = pmz_receive_chars(uap_b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) if (r3 & CHBTxIP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) pmz_transmit_chars(uap_b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) rc = IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) skip_b:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) spin_unlock(&uap_b->port.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) if (push)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) tty_flip_buffer_push(&uap->port.state->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) * Peek the status register, lock not held by caller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) static inline u8 pmz_peek_status(struct uart_pmac_port *uap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) u8 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) spin_lock_irqsave(&uap->port.lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) status = read_zsreg(uap, R0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) spin_unlock_irqrestore(&uap->port.lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) * Check if transmitter is empty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) * The port lock is not held.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) static unsigned int pmz_tx_empty(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) unsigned char status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) status = pmz_peek_status(to_pmz(port));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) if (status & Tx_BUF_EMP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) return TIOCSER_TEMT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) * Set Modem Control (RTS & DTR) bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) * The port lock is held and interrupts are disabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) * Note: Shall we really filter out RTS on external ports or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) * should that be dealt at higher level only ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) static void pmz_set_mctrl(struct uart_port *port, unsigned int mctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) struct uart_pmac_port *uap = to_pmz(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) unsigned char set_bits, clear_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) /* Do nothing for irda for now... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) if (ZS_IS_IRDA(uap))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) /* We get called during boot with a port not up yet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) if (!(ZS_IS_OPEN(uap) || ZS_IS_CONS(uap)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) set_bits = clear_bits = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) if (ZS_IS_INTMODEM(uap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) if (mctrl & TIOCM_RTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) set_bits |= RTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) clear_bits |= RTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) if (mctrl & TIOCM_DTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) set_bits |= DTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) clear_bits |= DTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) /* NOTE: Not subject to 'transmitter active' rule. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) uap->curregs[R5] |= set_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) uap->curregs[R5] &= ~clear_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) write_zsreg(uap, R5, uap->curregs[R5]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) pmz_debug("pmz_set_mctrl: set bits: %x, clear bits: %x -> %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) set_bits, clear_bits, uap->curregs[R5]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) zssync(uap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) * Get Modem Control bits (only the input ones, the core will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) * or that with a cached value of the control ones)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) * The port lock is held and interrupts are disabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) static unsigned int pmz_get_mctrl(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) struct uart_pmac_port *uap = to_pmz(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) unsigned char status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) unsigned int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) status = read_zsreg(uap, R0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) if (status & DCD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) ret |= TIOCM_CAR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) if (status & SYNC_HUNT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) ret |= TIOCM_DSR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) if (!(status & CTS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) ret |= TIOCM_CTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) * Stop TX side. Dealt like sunzilog at next Tx interrupt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) * though for DMA, we will have to do a bit more.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) * The port lock is held and interrupts are disabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) static void pmz_stop_tx(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) to_pmz(port)->flags |= PMACZILOG_FLAG_TX_STOPPED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) * Kick the Tx side.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) * The port lock is held and interrupts are disabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) static void pmz_start_tx(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) struct uart_pmac_port *uap = to_pmz(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) unsigned char status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) pmz_debug("pmz: start_tx()\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) uap->flags |= PMACZILOG_FLAG_TX_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) uap->flags &= ~PMACZILOG_FLAG_TX_STOPPED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) status = read_zsreg(uap, R0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) /* TX busy? Just wait for the TX done interrupt. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) if (!(status & Tx_BUF_EMP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) /* Send the first character to jump-start the TX done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) * IRQ sending engine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) if (port->x_char) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) write_zsdata(uap, port->x_char);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) zssync(uap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) port->icount.tx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) port->x_char = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) struct circ_buf *xmit = &port->state->xmit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) if (uart_circ_empty(xmit))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) write_zsdata(uap, xmit->buf[xmit->tail]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) zssync(uap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) port->icount.tx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) uart_write_wakeup(&uap->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) pmz_debug("pmz: start_tx() done.\n");
^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) * Stop Rx side, basically disable emitting of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) * Rx interrupts on the port. We don't disable the rx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) * side of the chip proper though
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) * The port lock is held.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) static void pmz_stop_rx(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) struct uart_pmac_port *uap = to_pmz(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) pmz_debug("pmz: stop_rx()()\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) /* Disable all RX interrupts. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) uap->curregs[R1] &= ~RxINT_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) pmz_maybe_update_regs(uap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) pmz_debug("pmz: stop_rx() done.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) * Enable modem status change interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) * The port lock is held.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) static void pmz_enable_ms(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) struct uart_pmac_port *uap = to_pmz(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) unsigned char new_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) if (ZS_IS_IRDA(uap))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) new_reg = uap->curregs[R15] | (DCDIE | SYNCIE | CTSIE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) if (new_reg != uap->curregs[R15]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) uap->curregs[R15] = new_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) /* NOTE: Not subject to 'transmitter active' rule. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) write_zsreg(uap, R15, uap->curregs[R15]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) * Control break state emission
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) * The port lock is not held.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) static void pmz_break_ctl(struct uart_port *port, int break_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) struct uart_pmac_port *uap = to_pmz(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) unsigned char set_bits, clear_bits, new_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) set_bits = clear_bits = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) if (break_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) set_bits |= SND_BRK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) clear_bits |= SND_BRK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) new_reg = (uap->curregs[R5] | set_bits) & ~clear_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) if (new_reg != uap->curregs[R5]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) uap->curregs[R5] = new_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) write_zsreg(uap, R5, uap->curregs[R5]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) #ifdef CONFIG_PPC_PMAC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) * Turn power on or off to the SCC and associated stuff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) * (port drivers, modem, IR port, etc.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) * Returns the number of milliseconds we should wait before
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) * trying to use the port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) static int pmz_set_scc_power(struct uart_pmac_port *uap, int state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) int delay = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) if (state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) rc = pmac_call_feature(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) PMAC_FTR_SCC_ENABLE, uap->node, uap->port_type, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) pmz_debug("port power on result: %d\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) if (ZS_IS_INTMODEM(uap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) rc = pmac_call_feature(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) PMAC_FTR_MODEM_ENABLE, uap->node, 0, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) delay = 2500; /* wait for 2.5s before using */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) pmz_debug("modem power result: %d\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) /* TODO: Make that depend on a timer, don't power down
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) * immediately
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) if (ZS_IS_INTMODEM(uap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) rc = pmac_call_feature(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) PMAC_FTR_MODEM_ENABLE, uap->node, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) pmz_debug("port power off result: %d\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) pmac_call_feature(PMAC_FTR_SCC_ENABLE, uap->node, uap->port_type, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) return delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) static int pmz_set_scc_power(struct uart_pmac_port *uap, int state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) #endif /* !CONFIG_PPC_PMAC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) * FixZeroBug....Works around a bug in the SCC receiving channel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) * Inspired from Darwin code, 15 Sept. 2000 -DanM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) * The following sequence prevents a problem that is seen with O'Hare ASICs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) * (most versions -- also with some Heathrow and Hydra ASICs) where a zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) * at the input to the receiver becomes 'stuck' and locks up the receiver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) * This problem can occur as a result of a zero bit at the receiver input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) * coincident with any of the following events:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) * The SCC is initialized (hardware or software).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) * A framing error is detected.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) * The clocking option changes from synchronous or X1 asynchronous
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) * clocking to X16, X32, or X64 asynchronous clocking.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) * The decoding mode is changed among NRZ, NRZI, FM0, or FM1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) * This workaround attempts to recover from the lockup condition by placing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) * the SCC in synchronous loopback mode with a fast clock before programming
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) * any of the asynchronous modes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) static void pmz_fix_zero_bug_scc(struct uart_pmac_port *uap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) write_zsreg(uap, 9, ZS_IS_CHANNEL_A(uap) ? CHRA : CHRB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) zssync(uap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) write_zsreg(uap, 9, (ZS_IS_CHANNEL_A(uap) ? CHRA : CHRB) | NV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) zssync(uap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) write_zsreg(uap, 4, X1CLK | MONSYNC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) write_zsreg(uap, 3, Rx8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) write_zsreg(uap, 5, Tx8 | RTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) write_zsreg(uap, 9, NV); /* Didn't we already do this? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) write_zsreg(uap, 11, RCBR | TCBR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) write_zsreg(uap, 12, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) write_zsreg(uap, 13, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) write_zsreg(uap, 14, (LOOPBAK | BRSRC));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) write_zsreg(uap, 14, (LOOPBAK | BRSRC | BRENAB));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) write_zsreg(uap, 3, Rx8 | RxENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) write_zsreg(uap, 0, RES_EXT_INT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) write_zsreg(uap, 0, RES_EXT_INT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) write_zsreg(uap, 0, RES_EXT_INT); /* to kill some time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) /* The channel should be OK now, but it is probably receiving
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) * loopback garbage.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) * Switch to asynchronous mode, disable the receiver,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) * and discard everything in the receive buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) write_zsreg(uap, 9, NV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) write_zsreg(uap, 4, X16CLK | SB_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) write_zsreg(uap, 3, Rx8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) while (read_zsreg(uap, 0) & Rx_CH_AV) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) (void)read_zsreg(uap, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) write_zsreg(uap, 0, RES_EXT_INT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) write_zsreg(uap, 0, ERR_RES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) * Real startup routine, powers up the hardware and sets up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) * the SCC. Returns a delay in ms where you need to wait before
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) * actually using the port, this is typically the internal modem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) * powerup delay. This routine expect the lock to be taken.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) static int __pmz_startup(struct uart_pmac_port *uap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) int pwr_delay = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) memset(&uap->curregs, 0, sizeof(uap->curregs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) /* Power up the SCC & underlying hardware (modem/irda) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) pwr_delay = pmz_set_scc_power(uap, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) /* Nice buggy HW ... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) pmz_fix_zero_bug_scc(uap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) /* Reset the channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) uap->curregs[R9] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) write_zsreg(uap, 9, ZS_IS_CHANNEL_A(uap) ? CHRA : CHRB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) zssync(uap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) write_zsreg(uap, 9, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) zssync(uap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) /* Clear the interrupt registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) write_zsreg(uap, R1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) write_zsreg(uap, R0, ERR_RES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) write_zsreg(uap, R0, ERR_RES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) write_zsreg(uap, R0, RES_H_IUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) write_zsreg(uap, R0, RES_H_IUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) /* Setup some valid baud rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) uap->curregs[R4] = X16CLK | SB1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) uap->curregs[R3] = Rx8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) uap->curregs[R5] = Tx8 | RTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) if (!ZS_IS_IRDA(uap))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) uap->curregs[R5] |= DTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) uap->curregs[R12] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) uap->curregs[R13] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) uap->curregs[R14] = BRENAB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) /* Clear handshaking, enable BREAK interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) uap->curregs[R15] = BRKIE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) /* Master interrupt enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) uap->curregs[R9] |= NV | MIE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) pmz_load_zsregs(uap, uap->curregs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) /* Enable receiver and transmitter. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) write_zsreg(uap, R3, uap->curregs[R3] |= RxENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) write_zsreg(uap, R5, uap->curregs[R5] |= TxENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) /* Remember status for DCD/CTS changes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) uap->prev_status = read_zsreg(uap, R0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) return pwr_delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) static void pmz_irda_reset(struct uart_pmac_port *uap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) spin_lock_irqsave(&uap->port.lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) uap->curregs[R5] |= DTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) write_zsreg(uap, R5, uap->curregs[R5]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) zssync(uap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) spin_unlock_irqrestore(&uap->port.lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) msleep(110);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) spin_lock_irqsave(&uap->port.lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) uap->curregs[R5] &= ~DTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) write_zsreg(uap, R5, uap->curregs[R5]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) zssync(uap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) spin_unlock_irqrestore(&uap->port.lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) msleep(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) * This is the "normal" startup routine, using the above one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) * wrapped with the lock and doing a schedule delay
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) static int pmz_startup(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) struct uart_pmac_port *uap = to_pmz(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) int pwr_delay = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) pmz_debug("pmz: startup()\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) uap->flags |= PMACZILOG_FLAG_IS_OPEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) /* A console is never powered down. Else, power up and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) * initialize the chip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) if (!ZS_IS_CONS(uap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) pwr_delay = __pmz_startup(uap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) sprintf(uap->irq_name, PMACZILOG_NAME"%d", uap->port.line);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) if (request_irq(uap->port.irq, pmz_interrupt, IRQF_SHARED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) uap->irq_name, uap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) pmz_error("Unable to register zs interrupt handler.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) pmz_set_scc_power(uap, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) /* Right now, we deal with delay by blocking here, I'll be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) * smarter later on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) if (pwr_delay != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) pmz_debug("pmz: delaying %d ms\n", pwr_delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) msleep(pwr_delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) /* IrDA reset is done now */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) if (ZS_IS_IRDA(uap))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) pmz_irda_reset(uap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) /* Enable interrupt requests for the channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) pmz_interrupt_control(uap, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) pmz_debug("pmz: startup() done.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) static void pmz_shutdown(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) struct uart_pmac_port *uap = to_pmz(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) pmz_debug("pmz: shutdown()\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) /* Disable interrupt requests for the channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) pmz_interrupt_control(uap, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) if (!ZS_IS_CONS(uap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) /* Disable receiver and transmitter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) uap->curregs[R3] &= ~RxENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) uap->curregs[R5] &= ~TxENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) /* Disable break assertion */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) uap->curregs[R5] &= ~SND_BRK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) pmz_maybe_update_regs(uap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) /* Release interrupt handler */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) free_irq(uap->port.irq, uap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) uap->flags &= ~PMACZILOG_FLAG_IS_OPEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) if (!ZS_IS_CONS(uap))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) pmz_set_scc_power(uap, 0); /* Shut the chip down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) pmz_debug("pmz: shutdown() done.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) /* Shared by TTY driver and serial console setup. The port lock is held
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) * and local interrupts are disabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) static void pmz_convert_to_zs(struct uart_pmac_port *uap, unsigned int cflag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) unsigned int iflag, unsigned long baud)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) int brg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) /* Switch to external clocking for IrDA high clock rates. That
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) * code could be re-used for Midi interfaces with different
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) * multipliers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) if (baud >= 115200 && ZS_IS_IRDA(uap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) uap->curregs[R4] = X1CLK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) uap->curregs[R11] = RCTRxCP | TCTRxCP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) uap->curregs[R14] = 0; /* BRG off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) uap->curregs[R12] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) uap->curregs[R13] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) uap->flags |= PMACZILOG_FLAG_IS_EXTCLK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) switch (baud) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) case ZS_CLOCK/16: /* 230400 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) uap->curregs[R4] = X16CLK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) uap->curregs[R11] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) uap->curregs[R14] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) case ZS_CLOCK/32: /* 115200 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) uap->curregs[R4] = X32CLK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) uap->curregs[R11] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) uap->curregs[R14] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) uap->curregs[R4] = X16CLK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) uap->curregs[R11] = TCBR | RCBR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) brg = BPS_TO_BRG(baud, ZS_CLOCK / 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) uap->curregs[R12] = (brg & 255);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) uap->curregs[R13] = ((brg >> 8) & 255);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) uap->curregs[R14] = BRENAB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) uap->flags &= ~PMACZILOG_FLAG_IS_EXTCLK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) /* Character size, stop bits, and parity. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) uap->curregs[3] &= ~RxN_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) uap->curregs[5] &= ~TxN_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) switch (cflag & CSIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) case CS5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) uap->curregs[3] |= Rx5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) uap->curregs[5] |= Tx5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) uap->parity_mask = 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) case CS6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) uap->curregs[3] |= Rx6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) uap->curregs[5] |= Tx6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) uap->parity_mask = 0x3f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) case CS7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) uap->curregs[3] |= Rx7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) uap->curregs[5] |= Tx7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) uap->parity_mask = 0x7f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) case CS8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) uap->curregs[3] |= Rx8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) uap->curregs[5] |= Tx8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) uap->parity_mask = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) uap->curregs[4] &= ~(SB_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) if (cflag & CSTOPB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) uap->curregs[4] |= SB2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) uap->curregs[4] |= SB1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) if (cflag & PARENB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) uap->curregs[4] |= PAR_ENAB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) uap->curregs[4] &= ~PAR_ENAB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) if (!(cflag & PARODD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) uap->curregs[4] |= PAR_EVEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) uap->curregs[4] &= ~PAR_EVEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) uap->port.read_status_mask = Rx_OVR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) if (iflag & INPCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) uap->port.read_status_mask |= CRC_ERR | PAR_ERR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) if (iflag & (IGNBRK | BRKINT | PARMRK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) uap->port.read_status_mask |= BRK_ABRT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) uap->port.ignore_status_mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) if (iflag & IGNPAR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) uap->port.ignore_status_mask |= CRC_ERR | PAR_ERR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) if (iflag & IGNBRK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) uap->port.ignore_status_mask |= BRK_ABRT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) if (iflag & IGNPAR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) uap->port.ignore_status_mask |= Rx_OVR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) if ((cflag & CREAD) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) uap->port.ignore_status_mask = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) * Set the irda codec on the imac to the specified baud rate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) static void pmz_irda_setup(struct uart_pmac_port *uap, unsigned long *baud)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) u8 cmdbyte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) int t, version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) switch (*baud) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) /* SIR modes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) case 2400:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) cmdbyte = 0x53;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) case 4800:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) cmdbyte = 0x52;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) case 9600:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) cmdbyte = 0x51;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) case 19200:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) cmdbyte = 0x50;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) case 38400:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) cmdbyte = 0x4f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) case 57600:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) cmdbyte = 0x4e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) case 115200:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) cmdbyte = 0x4d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) /* The FIR modes aren't really supported at this point, how
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) * do we select the speed ? via the FCR on KeyLargo ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) case 1152000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) cmdbyte = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) case 4000000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) cmdbyte = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) default: /* 9600 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) cmdbyte = 0x51;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) *baud = 9600;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) /* Wait for transmitter to drain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) t = 10000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) while ((read_zsreg(uap, R0) & Tx_BUF_EMP) == 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) || (read_zsreg(uap, R1) & ALL_SNT) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) if (--t <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) pmz_error("transmitter didn't drain\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) udelay(10);
^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) /* Drain the receiver too */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) t = 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) (void)read_zsdata(uap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) (void)read_zsdata(uap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) (void)read_zsdata(uap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) mdelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) while (read_zsreg(uap, R0) & Rx_CH_AV) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) read_zsdata(uap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) mdelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) if (--t <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) pmz_error("receiver didn't drain\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) /* Switch to command mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) uap->curregs[R5] |= DTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) write_zsreg(uap, R5, uap->curregs[R5]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) zssync(uap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) mdelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) /* Switch SCC to 19200 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) pmz_convert_to_zs(uap, CS8, 0, 19200);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) pmz_load_zsregs(uap, uap->curregs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) mdelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) /* Write get_version command byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) write_zsdata(uap, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) t = 5000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) while ((read_zsreg(uap, R0) & Rx_CH_AV) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) if (--t <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) pmz_error("irda_setup timed out on get_version byte\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) version = read_zsdata(uap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) if (version < 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) pmz_info("IrDA: dongle version %d not supported\n", version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) /* Send speed mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) write_zsdata(uap, cmdbyte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) t = 5000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) while ((read_zsreg(uap, R0) & Rx_CH_AV) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) if (--t <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) pmz_error("irda_setup timed out on speed mode byte\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) t = read_zsdata(uap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) if (t != cmdbyte)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) pmz_error("irda_setup speed mode byte = %x (%x)\n", t, cmdbyte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) pmz_info("IrDA setup for %ld bps, dongle version: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) *baud, version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) (void)read_zsdata(uap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) (void)read_zsdata(uap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) (void)read_zsdata(uap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) /* Switch back to data mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) uap->curregs[R5] &= ~DTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) write_zsreg(uap, R5, uap->curregs[R5]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) zssync(uap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) (void)read_zsdata(uap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) (void)read_zsdata(uap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) (void)read_zsdata(uap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) static void __pmz_set_termios(struct uart_port *port, struct ktermios *termios,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) struct ktermios *old)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) struct uart_pmac_port *uap = to_pmz(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) unsigned long baud;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) pmz_debug("pmz: set_termios()\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) memcpy(&uap->termios_cache, termios, sizeof(struct ktermios));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) /* XXX Check which revs of machines actually allow 1 and 4Mb speeds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) * on the IR dongle. Note that the IRTTY driver currently doesn't know
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) * about the FIR mode and high speed modes. So these are unused. For
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) * implementing proper support for these, we should probably add some
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) * DMA as well, at least on the Rx side, which isn't a simple thing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) * at this point.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) if (ZS_IS_IRDA(uap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) /* Calc baud rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) baud = uart_get_baud_rate(port, termios, old, 1200, 4000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) pmz_debug("pmz: switch IRDA to %ld bauds\n", baud);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) /* Cet the irda codec to the right rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) pmz_irda_setup(uap, &baud);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) /* Set final baud rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) pmz_convert_to_zs(uap, termios->c_cflag, termios->c_iflag, baud);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) pmz_load_zsregs(uap, uap->curregs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) zssync(uap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) baud = uart_get_baud_rate(port, termios, old, 1200, 230400);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) pmz_convert_to_zs(uap, termios->c_cflag, termios->c_iflag, baud);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) /* Make sure modem status interrupts are correctly configured */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) if (UART_ENABLE_MS(&uap->port, termios->c_cflag)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) uap->curregs[R15] |= DCDIE | SYNCIE | CTSIE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) uap->flags |= PMACZILOG_FLAG_MODEM_STATUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) uap->curregs[R15] &= ~(DCDIE | SYNCIE | CTSIE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) uap->flags &= ~PMACZILOG_FLAG_MODEM_STATUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) /* Load registers to the chip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) pmz_maybe_update_regs(uap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) uart_update_timeout(port, termios->c_cflag, baud);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) pmz_debug("pmz: set_termios() done.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) /* The port lock is not held. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) static void pmz_set_termios(struct uart_port *port, struct ktermios *termios,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) struct ktermios *old)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) struct uart_pmac_port *uap = to_pmz(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) /* Disable IRQs on the port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) pmz_interrupt_control(uap, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) /* Setup new port configuration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) __pmz_set_termios(port, termios, old);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) /* Re-enable IRQs on the port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) if (ZS_IS_OPEN(uap))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) pmz_interrupt_control(uap, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) static const char *pmz_type(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) struct uart_pmac_port *uap = to_pmz(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) if (ZS_IS_IRDA(uap))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) return "Z85c30 ESCC - Infrared port";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) else if (ZS_IS_INTMODEM(uap))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) return "Z85c30 ESCC - Internal modem";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) return "Z85c30 ESCC - Serial port";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) /* We do not request/release mappings of the registers here, this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) * happens at early serial probe time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) static void pmz_release_port(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) static int pmz_request_port(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) /* These do not need to do anything interesting either. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) static void pmz_config_port(struct uart_port *port, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) /* We do not support letting the user mess with the divisor, IRQ, etc. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) static int pmz_verify_port(struct uart_port *port, struct serial_struct *ser)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) #ifdef CONFIG_CONSOLE_POLL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) static int pmz_poll_get_char(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) struct uart_pmac_port *uap =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) container_of(port, struct uart_pmac_port, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) int tries = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) while (tries) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) if ((read_zsreg(uap, R0) & Rx_CH_AV) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) return read_zsdata(uap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) if (tries--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) udelay(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) return NO_POLL_CHAR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) static void pmz_poll_put_char(struct uart_port *port, unsigned char c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) struct uart_pmac_port *uap =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) container_of(port, struct uart_pmac_port, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) /* Wait for the transmit buffer to empty. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) while ((read_zsreg(uap, R0) & Tx_BUF_EMP) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) udelay(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) write_zsdata(uap, c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) #endif /* CONFIG_CONSOLE_POLL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) static const struct uart_ops pmz_pops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) .tx_empty = pmz_tx_empty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) .set_mctrl = pmz_set_mctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) .get_mctrl = pmz_get_mctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) .stop_tx = pmz_stop_tx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) .start_tx = pmz_start_tx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) .stop_rx = pmz_stop_rx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) .enable_ms = pmz_enable_ms,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) .break_ctl = pmz_break_ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) .startup = pmz_startup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) .shutdown = pmz_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) .set_termios = pmz_set_termios,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) .type = pmz_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) .release_port = pmz_release_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) .request_port = pmz_request_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) .config_port = pmz_config_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) .verify_port = pmz_verify_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) #ifdef CONFIG_CONSOLE_POLL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) .poll_get_char = pmz_poll_get_char,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) .poll_put_char = pmz_poll_put_char,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) #ifdef CONFIG_PPC_PMAC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) * Setup one port structure after probing, HW is down at this point,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) * Unlike sunzilog, we don't need to pre-init the spinlock as we don't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) * register our console before uart_add_one_port() is called
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) static int __init pmz_init_port(struct uart_pmac_port *uap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) struct device_node *np = uap->node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) const char *conn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) const struct slot_names_prop {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) char name[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) } *slots;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) struct resource r_ports, r_rxdma, r_txdma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) * Request & map chip registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) if (of_address_to_resource(np, 0, &r_ports))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) uap->port.mapbase = r_ports.start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) uap->port.membase = ioremap(uap->port.mapbase, 0x1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) uap->control_reg = uap->port.membase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) uap->data_reg = uap->control_reg + 0x10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) * Request & map DBDMA registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) #ifdef HAS_DBDMA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) if (of_address_to_resource(np, 1, &r_txdma) == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) of_address_to_resource(np, 2, &r_rxdma) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) uap->flags |= PMACZILOG_FLAG_HAS_DMA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) memset(&r_txdma, 0, sizeof(struct resource));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) memset(&r_rxdma, 0, sizeof(struct resource));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) if (ZS_HAS_DMA(uap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) uap->tx_dma_regs = ioremap(r_txdma.start, 0x100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) if (uap->tx_dma_regs == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) uap->flags &= ~PMACZILOG_FLAG_HAS_DMA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) goto no_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) uap->rx_dma_regs = ioremap(r_rxdma.start, 0x100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) if (uap->rx_dma_regs == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) iounmap(uap->tx_dma_regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) uap->tx_dma_regs = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) uap->flags &= ~PMACZILOG_FLAG_HAS_DMA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) goto no_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) uap->tx_dma_irq = irq_of_parse_and_map(np, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) uap->rx_dma_irq = irq_of_parse_and_map(np, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) no_dma:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) * Detect port type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) if (of_device_is_compatible(np, "cobalt"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) uap->flags |= PMACZILOG_FLAG_IS_INTMODEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) conn = of_get_property(np, "AAPL,connector", &len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) if (conn && (strcmp(conn, "infrared") == 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) uap->flags |= PMACZILOG_FLAG_IS_IRDA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) uap->port_type = PMAC_SCC_ASYNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) /* 1999 Powerbook G3 has slot-names property instead */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) slots = of_get_property(np, "slot-names", &len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) if (slots && slots->count > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) if (strcmp(slots->name, "IrDA") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) uap->flags |= PMACZILOG_FLAG_IS_IRDA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) else if (strcmp(slots->name, "Modem") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) uap->flags |= PMACZILOG_FLAG_IS_INTMODEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) if (ZS_IS_IRDA(uap))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) uap->port_type = PMAC_SCC_IRDA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) if (ZS_IS_INTMODEM(uap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) struct device_node* i2c_modem =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) of_find_node_by_name(NULL, "i2c-modem");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) if (i2c_modem) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) const char* mid =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) of_get_property(i2c_modem, "modem-id", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) if (mid) switch(*mid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) case 0x04 :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) case 0x05 :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) case 0x07 :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) case 0x08 :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) case 0x0b :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) case 0x0c :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) uap->port_type = PMAC_SCC_I2S1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) printk(KERN_INFO "pmac_zilog: i2c-modem detected, id: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) mid ? (*mid) : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) of_node_put(i2c_modem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) printk(KERN_INFO "pmac_zilog: serial modem detected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) * Init remaining bits of "port" structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) uap->port.iotype = UPIO_MEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) uap->port.irq = irq_of_parse_and_map(np, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) uap->port.uartclk = ZS_CLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) uap->port.fifosize = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) uap->port.ops = &pmz_pops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) uap->port.type = PORT_PMAC_ZILOG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) uap->port.flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) * Fixup for the port on Gatwick for which the device-tree has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) * missing interrupts. Normally, the macio_dev would contain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) * fixed up interrupt info, but we use the device-tree directly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) * here due to early probing so we need the fixup too.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) if (uap->port.irq == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) np->parent && np->parent->parent &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) of_device_is_compatible(np->parent->parent, "gatwick")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) /* IRQs on gatwick are offset by 64 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) uap->port.irq = irq_create_mapping(NULL, 64 + 15);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) uap->tx_dma_irq = irq_create_mapping(NULL, 64 + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) uap->rx_dma_irq = irq_create_mapping(NULL, 64 + 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) /* Setup some valid baud rate information in the register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) * shadows so we don't write crap there before baud rate is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) * first initialized.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) pmz_convert_to_zs(uap, CS8, 0, 9600);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) * Get rid of a port on module removal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) static void pmz_dispose_port(struct uart_pmac_port *uap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) struct device_node *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) np = uap->node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) iounmap(uap->rx_dma_regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) iounmap(uap->tx_dma_regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) iounmap(uap->control_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) uap->node = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) of_node_put(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) memset(uap, 0, sizeof(struct uart_pmac_port));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) * Called upon match with an escc node in the device-tree.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) static int pmz_attach(struct macio_dev *mdev, const struct of_device_id *match)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) struct uart_pmac_port *uap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) /* Iterate the pmz_ports array to find a matching entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) for (i = 0; i < MAX_ZS_PORTS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) if (pmz_ports[i].node == mdev->ofdev.dev.of_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) if (i >= MAX_ZS_PORTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) uap = &pmz_ports[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) uap->dev = mdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) uap->port.dev = &mdev->ofdev.dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) dev_set_drvdata(&mdev->ofdev.dev, uap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) /* We still activate the port even when failing to request resources
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) * to work around bugs in ancient Apple device-trees
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) if (macio_request_resources(uap->dev, "pmac_zilog"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) printk(KERN_WARNING "%pOFn: Failed to request resource"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) ", port still active\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) uap->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) uap->flags |= PMACZILOG_FLAG_RSRC_REQUESTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) return uart_add_one_port(&pmz_uart_reg, &uap->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) * That one should not be called, macio isn't really a hotswap device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) * we don't expect one of those serial ports to go away...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) static int pmz_detach(struct macio_dev *mdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) struct uart_pmac_port *uap = dev_get_drvdata(&mdev->ofdev.dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) if (!uap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) uart_remove_one_port(&pmz_uart_reg, &uap->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) if (uap->flags & PMACZILOG_FLAG_RSRC_REQUESTED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) macio_release_resources(uap->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) uap->flags &= ~PMACZILOG_FLAG_RSRC_REQUESTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) dev_set_drvdata(&mdev->ofdev.dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) uap->dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) uap->port.dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) static int pmz_suspend(struct macio_dev *mdev, pm_message_t pm_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) struct uart_pmac_port *uap = dev_get_drvdata(&mdev->ofdev.dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) if (uap == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) printk("HRM... pmz_suspend with NULL uap\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) uart_suspend_port(&pmz_uart_reg, &uap->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) static int pmz_resume(struct macio_dev *mdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) struct uart_pmac_port *uap = dev_get_drvdata(&mdev->ofdev.dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) if (uap == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) uart_resume_port(&pmz_uart_reg, &uap->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) * Probe all ports in the system and build the ports array, we register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) * with the serial layer later, so we get a proper struct device which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) * allows the tty to attach properly. This is later than it used to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) * but the tty layer really wants it that way.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) static int __init pmz_probe(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) struct device_node *node_p, *node_a, *node_b, *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) int count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) * Find all escc chips in the system
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) for_each_node_by_name(node_p, "escc") {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) * First get channel A/B node pointers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) * TODO: Add routines with proper locking to do that...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) node_a = node_b = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) for_each_child_of_node(node_p, np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) if (of_node_name_prefix(np, "ch-a"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) node_a = of_node_get(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) else if (of_node_name_prefix(np, "ch-b"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) node_b = of_node_get(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) if (!node_a && !node_b) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) of_node_put(node_a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) of_node_put(node_b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) printk(KERN_ERR "pmac_zilog: missing node %c for escc %pOF\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) (!node_a) ? 'a' : 'b', node_p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) * Fill basic fields in the port structures
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) if (node_b != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) pmz_ports[count].mate = &pmz_ports[count+1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) pmz_ports[count+1].mate = &pmz_ports[count];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) pmz_ports[count].flags = PMACZILOG_FLAG_IS_CHANNEL_A;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) pmz_ports[count].node = node_a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) pmz_ports[count+1].node = node_b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) pmz_ports[count].port.line = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) pmz_ports[count+1].port.line = count+1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) * Setup the ports for real
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) rc = pmz_init_port(&pmz_ports[count]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) if (rc == 0 && node_b != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) rc = pmz_init_port(&pmz_ports[count+1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) if (rc != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) of_node_put(node_a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) of_node_put(node_b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) memset(&pmz_ports[count], 0, sizeof(struct uart_pmac_port));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) memset(&pmz_ports[count+1], 0, sizeof(struct uart_pmac_port));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) count += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) pmz_ports_count = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) /* On PCI PowerMacs, pmz_probe() does an explicit search of the OpenFirmware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) * tree to obtain the device_nodes needed to start the console before the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) * macio driver. On Macs without OpenFirmware, global platform_devices take
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) * the place of those device_nodes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) extern struct platform_device scc_a_pdev, scc_b_pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) static int __init pmz_init_port(struct uart_pmac_port *uap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) struct resource *r_ports, *r_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) r_ports = platform_get_resource(uap->pdev, IORESOURCE_MEM, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) r_irq = platform_get_resource(uap->pdev, IORESOURCE_IRQ, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) if (!r_ports || !r_irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) uap->port.mapbase = r_ports->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) uap->port.membase = (unsigned char __iomem *) r_ports->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) uap->port.iotype = UPIO_MEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) uap->port.irq = r_irq->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) uap->port.uartclk = ZS_CLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) uap->port.fifosize = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) uap->port.ops = &pmz_pops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) uap->port.type = PORT_PMAC_ZILOG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) uap->port.flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) uap->control_reg = uap->port.membase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) uap->data_reg = uap->control_reg + 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) uap->port_type = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) uap->port.has_sysrq = IS_ENABLED(CONFIG_SERIAL_PMACZILOG_CONSOLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) pmz_convert_to_zs(uap, CS8, 0, 9600);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) static int __init pmz_probe(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) pmz_ports_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) pmz_ports[0].port.line = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) pmz_ports[0].flags = PMACZILOG_FLAG_IS_CHANNEL_A;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) pmz_ports[0].pdev = &scc_a_pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) err = pmz_init_port(&pmz_ports[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) pmz_ports_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) pmz_ports[0].mate = &pmz_ports[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) pmz_ports[1].mate = &pmz_ports[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) pmz_ports[1].port.line = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) pmz_ports[1].flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) pmz_ports[1].pdev = &scc_b_pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) err = pmz_init_port(&pmz_ports[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) pmz_ports_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) static void pmz_dispose_port(struct uart_pmac_port *uap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) memset(uap, 0, sizeof(struct uart_pmac_port));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) static int __init pmz_attach(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) struct uart_pmac_port *uap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) /* Iterate the pmz_ports array to find a matching entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) for (i = 0; i < pmz_ports_count; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) if (pmz_ports[i].pdev == pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) if (i >= pmz_ports_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) uap = &pmz_ports[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) uap->port.dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) platform_set_drvdata(pdev, uap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) return uart_add_one_port(&pmz_uart_reg, &uap->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) static int __exit pmz_detach(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) struct uart_pmac_port *uap = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) if (!uap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) uart_remove_one_port(&pmz_uart_reg, &uap->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) uap->port.dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) #endif /* !CONFIG_PPC_PMAC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) #ifdef CONFIG_SERIAL_PMACZILOG_CONSOLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) static void pmz_console_write(struct console *con, const char *s, unsigned int count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) static int __init pmz_console_setup(struct console *co, char *options);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) static struct console pmz_console = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) .name = PMACZILOG_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) .write = pmz_console_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) .device = uart_console_device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) .setup = pmz_console_setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) .flags = CON_PRINTBUFFER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) .index = -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) .data = &pmz_uart_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) #define PMACZILOG_CONSOLE &pmz_console
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) #else /* CONFIG_SERIAL_PMACZILOG_CONSOLE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) #define PMACZILOG_CONSOLE (NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) #endif /* CONFIG_SERIAL_PMACZILOG_CONSOLE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) * Register the driver, console driver and ports with the serial
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) * core
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) static int __init pmz_register(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) pmz_uart_reg.nr = pmz_ports_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) pmz_uart_reg.cons = PMACZILOG_CONSOLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) * Register this driver with the serial core
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) return uart_register_driver(&pmz_uart_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) #ifdef CONFIG_PPC_PMAC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) static const struct of_device_id pmz_match[] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) .name = "ch-a",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) .name = "ch-b",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) {},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) MODULE_DEVICE_TABLE (of, pmz_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) static struct macio_driver pmz_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) .name = "pmac_zilog",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) .of_match_table = pmz_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) .probe = pmz_attach,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) .remove = pmz_detach,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) .suspend = pmz_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) .resume = pmz_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) static struct platform_driver pmz_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) .remove = __exit_p(pmz_detach),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) .name = "scc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) #endif /* !CONFIG_PPC_PMAC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) static int __init init_pmz(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) int rc, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) printk(KERN_INFO "%s\n", version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) * First, we need to do a direct OF-based probe pass. We
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) * do that because we want serial console up before the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) * macio stuffs calls us back, and since that makes it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) * easier to pass the proper number of channels to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) * uart_register_driver()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) if (pmz_ports_count == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) pmz_probe();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) * Bail early if no port found
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) if (pmz_ports_count == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) * Now we register with the serial layer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) rc = pmz_register();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) printk(KERN_ERR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) "pmac_zilog: Error registering serial device, disabling pmac_zilog.\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) "pmac_zilog: Did another serial driver already claim the minors?\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) /* effectively "pmz_unprobe()" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) for (i=0; i < pmz_ports_count; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) pmz_dispose_port(&pmz_ports[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) * Then we register the macio driver itself
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) #ifdef CONFIG_PPC_PMAC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) return macio_register_driver(&pmz_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) return platform_driver_probe(&pmz_driver, pmz_attach);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) static void __exit exit_pmz(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) #ifdef CONFIG_PPC_PMAC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) /* Get rid of macio-driver (detach from macio) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) macio_unregister_driver(&pmz_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) platform_driver_unregister(&pmz_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) for (i = 0; i < pmz_ports_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) struct uart_pmac_port *uport = &pmz_ports[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) #ifdef CONFIG_PPC_PMAC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) if (uport->node != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) pmz_dispose_port(uport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) if (uport->pdev != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) pmz_dispose_port(uport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) /* Unregister UART driver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) uart_unregister_driver(&pmz_uart_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) #ifdef CONFIG_SERIAL_PMACZILOG_CONSOLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) static void pmz_console_putchar(struct uart_port *port, int ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) struct uart_pmac_port *uap =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) container_of(port, struct uart_pmac_port, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) /* Wait for the transmit buffer to empty. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) while ((read_zsreg(uap, R0) & Tx_BUF_EMP) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) udelay(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) write_zsdata(uap, ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) * Print a string to the serial port trying not to disturb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) * any possible real use of the port...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) static void pmz_console_write(struct console *con, const char *s, unsigned int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) struct uart_pmac_port *uap = &pmz_ports[con->index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) spin_lock_irqsave(&uap->port.lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) /* Turn of interrupts and enable the transmitter. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) write_zsreg(uap, R1, uap->curregs[1] & ~TxINT_ENAB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) write_zsreg(uap, R5, uap->curregs[5] | TxENABLE | RTS | DTR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) uart_console_write(&uap->port, s, count, pmz_console_putchar);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) /* Restore the values in the registers. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) write_zsreg(uap, R1, uap->curregs[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) /* Don't disable the transmitter. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) spin_unlock_irqrestore(&uap->port.lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) * Setup the serial console
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) static int __init pmz_console_setup(struct console *co, char *options)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) struct uart_pmac_port *uap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) struct uart_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) int baud = 38400;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) int bits = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) int parity = 'n';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) int flow = 'n';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) unsigned long pwr_delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) * XServe's default to 57600 bps
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) if (of_machine_is_compatible("RackMac1,1")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) || of_machine_is_compatible("RackMac1,2")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) || of_machine_is_compatible("MacRISC4"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) baud = 57600;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) * Check whether an invalid uart number has been specified, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) * if so, search for the first available port that does have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) * console support.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) if (co->index >= pmz_ports_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) co->index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) uap = &pmz_ports[co->index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) #ifdef CONFIG_PPC_PMAC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) if (uap->node == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) if (uap->pdev == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) port = &uap->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) * Mark port as beeing a console
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) uap->flags |= PMACZILOG_FLAG_IS_CONS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) * Temporary fix for uart layer who didn't setup the spinlock yet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) spin_lock_init(&port->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) * Enable the hardware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) pwr_delay = __pmz_startup(uap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) if (pwr_delay)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) mdelay(pwr_delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) if (options)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) uart_parse_options(options, &baud, &parity, &bits, &flow);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) return uart_set_options(port, co, baud, parity, bits, flow);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) static int __init pmz_console_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) /* Probe ports */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) pmz_probe();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) if (pmz_ports_count == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) /* TODO: Autoprobe console based on OF */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) /* pmz_console.index = i; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) register_console(&pmz_console);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) console_initcall(pmz_console_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) #endif /* CONFIG_SERIAL_PMACZILOG_CONSOLE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) module_init(init_pmz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) module_exit(exit_pmz);