^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 NEC VR4100 series Serial Interface Unit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2004-2008 Yoichi Yuasa <yuasa@linux-mips.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Based on drivers/serial/8250.c, by Russell King.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/console.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/ioport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/serial.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/serial_core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/serial_reg.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/tty.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/tty_flip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <asm/vr41xx/siu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <asm/vr41xx/vr41xx.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define SIU_BAUD_BASE 1152000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define SIU_MAJOR 204
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define SIU_MINOR_BASE 82
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define RX_MAX_COUNT 256
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define TX_MAX_COUNT 15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define SIUIRSEL 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define TMICMODE 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define TMICTX 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define IRMSEL 0x0c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define IRMSEL_HP 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define IRMSEL_TEMIC 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define IRMSEL_SHARP 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define IRUSESEL 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define SIRSEL 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) static struct uart_port siu_uart_ports[SIU_PORTS_MAX] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) [0 ... SIU_PORTS_MAX-1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) .lock = __SPIN_LOCK_UNLOCKED(siu_uart_ports->lock),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) .irq = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #ifdef CONFIG_SERIAL_VR41XX_CONSOLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) static uint8_t lsr_break_flag[SIU_PORTS_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define siu_read(port, offset) readb((port)->membase + (offset))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define siu_write(port, offset, value) writeb((value), (port)->membase + (offset))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) void vr41xx_select_siu_interface(siu_interface_t interface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) struct uart_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) uint8_t irsel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) port = &siu_uart_ports[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) irsel = siu_read(port, SIUIRSEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) if (interface == SIU_INTERFACE_IRDA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) irsel |= SIRSEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) irsel &= ~SIRSEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) siu_write(port, SIUIRSEL, irsel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) EXPORT_SYMBOL_GPL(vr41xx_select_siu_interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) void vr41xx_use_irda(irda_use_t use)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) struct uart_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) uint8_t irsel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) port = &siu_uart_ports[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) irsel = siu_read(port, SIUIRSEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) if (use == FIR_USE_IRDA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) irsel |= IRUSESEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) irsel &= ~IRUSESEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) siu_write(port, SIUIRSEL, irsel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) EXPORT_SYMBOL_GPL(vr41xx_use_irda);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) void vr41xx_select_irda_module(irda_module_t module, irda_speed_t speed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) struct uart_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) uint8_t irsel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) port = &siu_uart_ports[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) irsel = siu_read(port, SIUIRSEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) irsel &= ~(IRMSEL | TMICTX | TMICMODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) switch (module) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) case SHARP_IRDA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) irsel |= IRMSEL_SHARP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) case TEMIC_IRDA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) irsel |= IRMSEL_TEMIC | TMICMODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) if (speed == IRDA_TX_4MBPS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) irsel |= TMICTX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) case HP_IRDA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) irsel |= IRMSEL_HP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) siu_write(port, SIUIRSEL, irsel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) EXPORT_SYMBOL_GPL(vr41xx_select_irda_module);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) static inline void siu_clear_fifo(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) siu_write(port, UART_FCR, UART_FCR_ENABLE_FIFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) siu_write(port, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) UART_FCR_CLEAR_XMIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) siu_write(port, UART_FCR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) static inline unsigned long siu_port_size(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) switch (port->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) case PORT_VR41XX_SIU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) return 11UL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) case PORT_VR41XX_DSIU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) return 8UL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) static inline unsigned int siu_check_type(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) if (port->line == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) return PORT_VR41XX_SIU;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) if (port->line == 1 && port->irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) return PORT_VR41XX_DSIU;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) return PORT_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) static inline const char *siu_type_name(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) switch (port->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) case PORT_VR41XX_SIU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) return "SIU";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) case PORT_VR41XX_DSIU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) return "DSIU";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) static unsigned int siu_tx_empty(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) uint8_t lsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) lsr = siu_read(port, UART_LSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) if (lsr & UART_LSR_TEMT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) return TIOCSER_TEMT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) static void siu_set_mctrl(struct uart_port *port, unsigned int mctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) uint8_t mcr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) if (mctrl & TIOCM_DTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) mcr |= UART_MCR_DTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) if (mctrl & TIOCM_RTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) mcr |= UART_MCR_RTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) if (mctrl & TIOCM_OUT1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) mcr |= UART_MCR_OUT1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) if (mctrl & TIOCM_OUT2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) mcr |= UART_MCR_OUT2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) if (mctrl & TIOCM_LOOP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) mcr |= UART_MCR_LOOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) siu_write(port, UART_MCR, mcr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) static unsigned int siu_get_mctrl(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) uint8_t msr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) unsigned int mctrl = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) msr = siu_read(port, UART_MSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) if (msr & UART_MSR_DCD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) mctrl |= TIOCM_CAR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) if (msr & UART_MSR_RI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) mctrl |= TIOCM_RNG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) if (msr & UART_MSR_DSR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) mctrl |= TIOCM_DSR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) if (msr & UART_MSR_CTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) mctrl |= TIOCM_CTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) return mctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) static void siu_stop_tx(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) uint8_t ier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) ier = siu_read(port, UART_IER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) ier &= ~UART_IER_THRI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) siu_write(port, UART_IER, ier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) static void siu_start_tx(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) uint8_t ier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) ier = siu_read(port, UART_IER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) ier |= UART_IER_THRI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) siu_write(port, UART_IER, ier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) static void siu_stop_rx(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) uint8_t ier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) ier = siu_read(port, UART_IER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) ier &= ~UART_IER_RLSI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) siu_write(port, UART_IER, ier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) port->read_status_mask &= ~UART_LSR_DR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) static void siu_enable_ms(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) uint8_t ier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) ier = siu_read(port, UART_IER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) ier |= UART_IER_MSI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) siu_write(port, UART_IER, ier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) static void siu_break_ctl(struct uart_port *port, int ctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) uint8_t lcr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) lcr = siu_read(port, UART_LCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) if (ctl == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) lcr |= UART_LCR_SBC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) lcr &= ~UART_LCR_SBC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) siu_write(port, UART_LCR, lcr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) static inline void receive_chars(struct uart_port *port, uint8_t *status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) uint8_t lsr, ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) char flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) int max_count = RX_MAX_COUNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) lsr = *status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) ch = siu_read(port, UART_RX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) port->icount.rx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) flag = TTY_NORMAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) #ifdef CONFIG_SERIAL_VR41XX_CONSOLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) lsr |= lsr_break_flag[port->line];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) lsr_break_flag[port->line] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) if (unlikely(lsr & (UART_LSR_BI | UART_LSR_FE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) UART_LSR_PE | UART_LSR_OE))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) if (lsr & UART_LSR_BI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) lsr &= ~(UART_LSR_FE | UART_LSR_PE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) port->icount.brk++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) if (uart_handle_break(port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) goto ignore_char;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) if (lsr & UART_LSR_FE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) port->icount.frame++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) if (lsr & UART_LSR_PE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) port->icount.parity++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) if (lsr & UART_LSR_OE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) port->icount.overrun++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) lsr &= port->read_status_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) if (lsr & UART_LSR_BI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) flag = TTY_BREAK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) if (lsr & UART_LSR_FE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) flag = TTY_FRAME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) if (lsr & UART_LSR_PE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) flag = TTY_PARITY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) if (uart_handle_sysrq_char(port, ch))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) goto ignore_char;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) uart_insert_char(port, lsr, UART_LSR_OE, ch, flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) ignore_char:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) lsr = siu_read(port, UART_LSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) } while ((lsr & UART_LSR_DR) && (max_count-- > 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) tty_flip_buffer_push(&port->state->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) *status = lsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) static inline void check_modem_status(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) uint8_t msr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) msr = siu_read(port, UART_MSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) if ((msr & UART_MSR_ANY_DELTA) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) if (msr & UART_MSR_DDCD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) uart_handle_dcd_change(port, msr & UART_MSR_DCD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) if (msr & UART_MSR_TERI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) port->icount.rng++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) if (msr & UART_MSR_DDSR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) port->icount.dsr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) if (msr & UART_MSR_DCTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) uart_handle_cts_change(port, msr & UART_MSR_CTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) wake_up_interruptible(&port->state->port.delta_msr_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) static inline void transmit_chars(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) struct circ_buf *xmit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) int max_count = TX_MAX_COUNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) xmit = &port->state->xmit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) if (port->x_char) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) siu_write(port, UART_TX, port->x_char);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) port->icount.tx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) port->x_char = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) siu_stop_tx(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) siu_write(port, UART_TX, xmit->buf[xmit->tail]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) port->icount.tx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) if (uart_circ_empty(xmit))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) } while (max_count-- > 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) uart_write_wakeup(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) if (uart_circ_empty(xmit))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) siu_stop_tx(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) static irqreturn_t siu_interrupt(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) struct uart_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) uint8_t iir, lsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) port = (struct uart_port *)dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) iir = siu_read(port, UART_IIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) if (iir & UART_IIR_NO_INT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) lsr = siu_read(port, UART_LSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if (lsr & UART_LSR_DR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) receive_chars(port, &lsr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) check_modem_status(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) if (lsr & UART_LSR_THRE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) transmit_chars(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) static int siu_startup(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) if (port->membase == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) siu_clear_fifo(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) (void)siu_read(port, UART_LSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) (void)siu_read(port, UART_RX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) (void)siu_read(port, UART_IIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) (void)siu_read(port, UART_MSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) if (siu_read(port, UART_LSR) == 0xff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) retval = request_irq(port->irq, siu_interrupt, 0, siu_type_name(port), port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) if (port->type == PORT_VR41XX_DSIU)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) vr41xx_enable_dsiuint(DSIUINT_ALL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) siu_write(port, UART_LCR, UART_LCR_WLEN8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) spin_lock_irq(&port->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) siu_set_mctrl(port, port->mctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) spin_unlock_irq(&port->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) siu_write(port, UART_IER, UART_IER_RLSI | UART_IER_RDI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) (void)siu_read(port, UART_LSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) (void)siu_read(port, UART_RX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) (void)siu_read(port, UART_IIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) (void)siu_read(port, UART_MSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) static void siu_shutdown(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) uint8_t lcr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) siu_write(port, UART_IER, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) port->mctrl &= ~TIOCM_OUT2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) siu_set_mctrl(port, port->mctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) lcr = siu_read(port, UART_LCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) lcr &= ~UART_LCR_SBC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) siu_write(port, UART_LCR, lcr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) siu_clear_fifo(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) (void)siu_read(port, UART_RX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) if (port->type == PORT_VR41XX_DSIU)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) vr41xx_disable_dsiuint(DSIUINT_ALL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) free_irq(port->irq, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) static void siu_set_termios(struct uart_port *port, struct ktermios *new,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) struct ktermios *old)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) tcflag_t c_cflag, c_iflag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) uint8_t lcr, fcr, ier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) unsigned int baud, quot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) c_cflag = new->c_cflag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) switch (c_cflag & CSIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) case CS5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) lcr = UART_LCR_WLEN5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) case CS6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) lcr = UART_LCR_WLEN6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) case CS7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) lcr = UART_LCR_WLEN7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) lcr = UART_LCR_WLEN8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) if (c_cflag & CSTOPB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) lcr |= UART_LCR_STOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) if (c_cflag & PARENB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) lcr |= UART_LCR_PARITY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) if ((c_cflag & PARODD) != PARODD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) lcr |= UART_LCR_EPAR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) if (c_cflag & CMSPAR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) lcr |= UART_LCR_SPAR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) baud = uart_get_baud_rate(port, new, old, 0, port->uartclk/16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) quot = uart_get_divisor(port, baud);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) uart_update_timeout(port, c_cflag, baud);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) c_iflag = new->c_iflag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) port->read_status_mask = UART_LSR_THRE | UART_LSR_OE | UART_LSR_DR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) if (c_iflag & INPCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) port->read_status_mask |= UART_LSR_FE | UART_LSR_PE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) if (c_iflag & (IGNBRK | BRKINT | PARMRK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) port->read_status_mask |= UART_LSR_BI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) port->ignore_status_mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) if (c_iflag & IGNPAR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) port->ignore_status_mask |= UART_LSR_FE | UART_LSR_PE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) if (c_iflag & IGNBRK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) port->ignore_status_mask |= UART_LSR_BI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) if (c_iflag & IGNPAR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) port->ignore_status_mask |= UART_LSR_OE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) if ((c_cflag & CREAD) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) port->ignore_status_mask |= UART_LSR_DR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) ier = siu_read(port, UART_IER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) ier &= ~UART_IER_MSI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) if (UART_ENABLE_MS(port, c_cflag))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) ier |= UART_IER_MSI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) siu_write(port, UART_IER, ier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) siu_write(port, UART_LCR, lcr | UART_LCR_DLAB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) siu_write(port, UART_DLL, (uint8_t)quot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) siu_write(port, UART_DLM, (uint8_t)(quot >> 8));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) siu_write(port, UART_LCR, lcr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) siu_write(port, UART_FCR, fcr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) siu_set_mctrl(port, port->mctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) static void siu_pm(struct uart_port *port, unsigned int state, unsigned int oldstate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) switch (state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) switch (port->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) case PORT_VR41XX_SIU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) vr41xx_supply_clock(SIU_CLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) case PORT_VR41XX_DSIU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) vr41xx_supply_clock(DSIU_CLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) switch (port->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) case PORT_VR41XX_SIU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) vr41xx_mask_clock(SIU_CLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) case PORT_VR41XX_DSIU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) vr41xx_mask_clock(DSIU_CLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) static const char *siu_type(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) return siu_type_name(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) static void siu_release_port(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) unsigned long size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) if (port->flags & UPF_IOREMAP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) iounmap(port->membase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) port->membase = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) size = siu_port_size(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) release_mem_region(port->mapbase, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) static int siu_request_port(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) unsigned long size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) struct resource *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) size = siu_port_size(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) res = request_mem_region(port->mapbase, size, siu_type_name(port));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) if (res == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) if (port->flags & UPF_IOREMAP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) port->membase = ioremap(port->mapbase, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) if (port->membase == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) release_resource(res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) static void siu_config_port(struct uart_port *port, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) if (flags & UART_CONFIG_TYPE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) port->type = siu_check_type(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) (void)siu_request_port(port);
^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) static int siu_verify_port(struct uart_port *port, struct serial_struct *serial)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) if (port->type != PORT_VR41XX_SIU && port->type != PORT_VR41XX_DSIU)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) if (port->irq != serial->irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) if (port->iotype != serial->io_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) if (port->mapbase != (unsigned long)serial->iomem_base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) static const struct uart_ops siu_uart_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) .tx_empty = siu_tx_empty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) .set_mctrl = siu_set_mctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) .get_mctrl = siu_get_mctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) .stop_tx = siu_stop_tx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) .start_tx = siu_start_tx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) .stop_rx = siu_stop_rx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) .enable_ms = siu_enable_ms,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) .break_ctl = siu_break_ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) .startup = siu_startup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) .shutdown = siu_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) .set_termios = siu_set_termios,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) .pm = siu_pm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) .type = siu_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) .release_port = siu_release_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) .request_port = siu_request_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) .config_port = siu_config_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) .verify_port = siu_verify_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) static int siu_init_ports(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) struct uart_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) struct resource *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) int *type = dev_get_platdata(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) if (!type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) port = siu_uart_ports;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) for (i = 0; i < SIU_PORTS_MAX; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) port->type = type[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) if (port->type == PORT_UNKNOWN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) port->irq = platform_get_irq(pdev, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) port->uartclk = SIU_BAUD_BASE * 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) port->fifosize = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) port->regshift = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) port->iotype = UPIO_MEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) port->flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) port->line = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) res = platform_get_resource(pdev, IORESOURCE_MEM, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) port->mapbase = res->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) port++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) #ifdef CONFIG_SERIAL_VR41XX_CONSOLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) static void wait_for_xmitr(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) int timeout = 10000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) uint8_t lsr, msr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) lsr = siu_read(port, UART_LSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) if (lsr & UART_LSR_BI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) lsr_break_flag[port->line] = UART_LSR_BI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) if ((lsr & BOTH_EMPTY) == BOTH_EMPTY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) } while (timeout-- > 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) if (port->flags & UPF_CONS_FLOW) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) timeout = 1000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) msr = siu_read(port, UART_MSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) if ((msr & UART_MSR_CTS) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) } while (timeout-- > 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) static void siu_console_putchar(struct uart_port *port, int ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) wait_for_xmitr(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) siu_write(port, UART_TX, ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) static void siu_console_write(struct console *con, const char *s, unsigned count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) struct uart_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) uint8_t ier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) port = &siu_uart_ports[con->index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) ier = siu_read(port, UART_IER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) siu_write(port, UART_IER, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) uart_console_write(port, s, count, siu_console_putchar);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) wait_for_xmitr(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) siu_write(port, UART_IER, ier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) static int __init siu_console_setup(struct console *con, char *options)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) struct uart_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) int baud = 9600;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) int parity = 'n';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) int bits = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) int flow = 'n';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) if (con->index >= SIU_PORTS_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) con->index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) port = &siu_uart_ports[con->index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) if (port->membase == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) if (port->mapbase == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) port->membase = ioremap(port->mapbase, siu_port_size(port));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) if (port->type == PORT_VR41XX_SIU)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) vr41xx_select_siu_interface(SIU_INTERFACE_RS232C);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) if (options != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) uart_parse_options(options, &baud, &parity, &bits, &flow);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) return uart_set_options(port, con, baud, parity, bits, flow);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) static struct uart_driver siu_uart_driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) static struct console siu_console = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) .name = "ttyVR",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) .write = siu_console_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) .device = uart_console_device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) .setup = siu_console_setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) .flags = CON_PRINTBUFFER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) .index = -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) .data = &siu_uart_driver,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) static int siu_console_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) struct uart_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) for (i = 0; i < SIU_PORTS_MAX; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) port = &siu_uart_ports[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) port->ops = &siu_uart_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) register_console(&siu_console);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) return 0;
^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) console_initcall(siu_console_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) void __init vr41xx_siu_early_setup(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) if (port->type == PORT_UNKNOWN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) siu_uart_ports[port->line].line = port->line;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) siu_uart_ports[port->line].type = port->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) siu_uart_ports[port->line].uartclk = SIU_BAUD_BASE * 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) siu_uart_ports[port->line].mapbase = port->mapbase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) siu_uart_ports[port->line].ops = &siu_uart_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) #define SERIAL_VR41XX_CONSOLE &siu_console
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) #define SERIAL_VR41XX_CONSOLE NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) static struct uart_driver siu_uart_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) .driver_name = "SIU",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) .dev_name = "ttyVR",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) .major = SIU_MAJOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) .minor = SIU_MINOR_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) .cons = SERIAL_VR41XX_CONSOLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) static int siu_probe(struct platform_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) struct uart_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) int num, i, retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) num = siu_init_ports(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) if (num <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) siu_uart_driver.nr = num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) retval = uart_register_driver(&siu_uart_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) for (i = 0; i < num; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) port = &siu_uart_ports[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) port->ops = &siu_uart_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) port->dev = &dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) port->has_sysrq = IS_ENABLED(CONFIG_SERIAL_VR41XX_CONSOLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) retval = uart_add_one_port(&siu_uart_driver, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) if (retval < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) port->dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) if (i == 0 && retval < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) uart_unregister_driver(&siu_uart_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) static int siu_remove(struct platform_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) struct uart_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) for (i = 0; i < siu_uart_driver.nr; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) port = &siu_uart_ports[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) if (port->dev == &dev->dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) uart_remove_one_port(&siu_uart_driver, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) port->dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) uart_unregister_driver(&siu_uart_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) return 0;
^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) static int siu_suspend(struct platform_device *dev, pm_message_t state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) struct uart_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) for (i = 0; i < siu_uart_driver.nr; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) port = &siu_uart_ports[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) if ((port->type == PORT_VR41XX_SIU ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) port->type == PORT_VR41XX_DSIU) && port->dev == &dev->dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) uart_suspend_port(&siu_uart_driver, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) static int siu_resume(struct platform_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) struct uart_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) for (i = 0; i < siu_uart_driver.nr; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) port = &siu_uart_ports[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) if ((port->type == PORT_VR41XX_SIU ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) port->type == PORT_VR41XX_DSIU) && port->dev == &dev->dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) uart_resume_port(&siu_uart_driver, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) static struct platform_driver siu_device_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) .probe = siu_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) .remove = siu_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) .suspend = siu_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) .resume = siu_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) .name = "SIU",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) module_platform_driver(siu_device_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) MODULE_ALIAS("platform:SIU");