^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) * Derived from many drivers using generic_serial interface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * especially serial_tx3912.c by Steven J. Hill and r39xx_serial.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * (was in Linux/VR tree) by Jim Pick.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (C) 1999 Harald Koerfgen
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright (C) 2000 Jim Pick <jim@jimpick.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Copyright (C) 2001 Steven J. Hill (sjhill@realitydiluted.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Copyright (C) 2000-2002 Toshiba Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * Serial driver for TX3927/TX4927/TX4925/TX4938 internal SIO controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^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/ioport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/console.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/serial_core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/serial.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/tty.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/tty_flip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) static char *serial_version = "1.11";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) static char *serial_name = "TX39/49 Serial driver";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define PASS_LIMIT 256
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #if !defined(CONFIG_SERIAL_TXX9_STDSERIAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) /* "ttyS" is used for standard serial driver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define TXX9_TTY_NAME "ttyTX"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define TXX9_TTY_MINOR_START 196
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define TXX9_TTY_MAJOR 204
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) /* acts like standard serial driver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define TXX9_TTY_NAME "ttyS"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define TXX9_TTY_MINOR_START 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define TXX9_TTY_MAJOR TTY_MAJOR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) /* flag aliases */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define UPF_TXX9_HAVE_CTS_LINE UPF_BUGGY_UART
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define UPF_TXX9_USE_SCLK UPF_MAGIC_MULTIPLIER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #ifdef CONFIG_PCI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) /* support for Toshiba TC86C001 SIO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define ENABLE_SERIAL_TXX9_PCI
^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * Number of serial ports
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define UART_NR CONFIG_SERIAL_TXX9_NR_UARTS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) struct uart_txx9_port {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) struct uart_port port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) /* No additional info for now */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define TXX9_REGION_SIZE 0x24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) /* TXX9 Serial Registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define TXX9_SILCR 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define TXX9_SIDICR 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define TXX9_SIDISR 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define TXX9_SICISR 0x0c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define TXX9_SIFCR 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define TXX9_SIFLCR 0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define TXX9_SIBGR 0x18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define TXX9_SITFIFO 0x1c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define TXX9_SIRFIFO 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) /* SILCR : Line Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define TXX9_SILCR_SCS_MASK 0x00000060
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define TXX9_SILCR_SCS_IMCLK 0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define TXX9_SILCR_SCS_IMCLK_BG 0x00000020
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define TXX9_SILCR_SCS_SCLK 0x00000040
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define TXX9_SILCR_SCS_SCLK_BG 0x00000060
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define TXX9_SILCR_UEPS 0x00000010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define TXX9_SILCR_UPEN 0x00000008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define TXX9_SILCR_USBL_MASK 0x00000004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define TXX9_SILCR_USBL_1BIT 0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define TXX9_SILCR_USBL_2BIT 0x00000004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define TXX9_SILCR_UMODE_MASK 0x00000003
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define TXX9_SILCR_UMODE_8BIT 0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define TXX9_SILCR_UMODE_7BIT 0x00000001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) /* SIDICR : DMA/Int. Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define TXX9_SIDICR_TDE 0x00008000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define TXX9_SIDICR_RDE 0x00004000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define TXX9_SIDICR_TIE 0x00002000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #define TXX9_SIDICR_RIE 0x00001000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define TXX9_SIDICR_SPIE 0x00000800
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #define TXX9_SIDICR_CTSAC 0x00000600
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define TXX9_SIDICR_STIE_MASK 0x0000003f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define TXX9_SIDICR_STIE_OERS 0x00000020
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #define TXX9_SIDICR_STIE_CTSS 0x00000010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define TXX9_SIDICR_STIE_RBRKD 0x00000008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define TXX9_SIDICR_STIE_TRDY 0x00000004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #define TXX9_SIDICR_STIE_TXALS 0x00000002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #define TXX9_SIDICR_STIE_UBRKD 0x00000001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) /* SIDISR : DMA/Int. Status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define TXX9_SIDISR_UBRK 0x00008000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #define TXX9_SIDISR_UVALID 0x00004000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) #define TXX9_SIDISR_UFER 0x00002000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) #define TXX9_SIDISR_UPER 0x00001000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) #define TXX9_SIDISR_UOER 0x00000800
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #define TXX9_SIDISR_ERI 0x00000400
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) #define TXX9_SIDISR_TOUT 0x00000200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) #define TXX9_SIDISR_TDIS 0x00000100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) #define TXX9_SIDISR_RDIS 0x00000080
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) #define TXX9_SIDISR_STIS 0x00000040
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) #define TXX9_SIDISR_RFDN_MASK 0x0000001f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) /* SICISR : Change Int. Status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) #define TXX9_SICISR_OERS 0x00000020
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) #define TXX9_SICISR_CTSS 0x00000010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) #define TXX9_SICISR_RBRKD 0x00000008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) #define TXX9_SICISR_TRDY 0x00000004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) #define TXX9_SICISR_TXALS 0x00000002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) #define TXX9_SICISR_UBRKD 0x00000001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) /* SIFCR : FIFO Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) #define TXX9_SIFCR_SWRST 0x00008000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) #define TXX9_SIFCR_RDIL_MASK 0x00000180
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) #define TXX9_SIFCR_RDIL_1 0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) #define TXX9_SIFCR_RDIL_4 0x00000080
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) #define TXX9_SIFCR_RDIL_8 0x00000100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) #define TXX9_SIFCR_RDIL_12 0x00000180
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) #define TXX9_SIFCR_RDIL_MAX 0x00000180
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) #define TXX9_SIFCR_TDIL_MASK 0x00000018
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) #define TXX9_SIFCR_TDIL_1 0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) #define TXX9_SIFCR_TDIL_4 0x00000001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) #define TXX9_SIFCR_TDIL_8 0x00000010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) #define TXX9_SIFCR_TDIL_MAX 0x00000010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) #define TXX9_SIFCR_TFRST 0x00000004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) #define TXX9_SIFCR_RFRST 0x00000002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) #define TXX9_SIFCR_FRSTE 0x00000001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) #define TXX9_SIO_TX_FIFO 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) #define TXX9_SIO_RX_FIFO 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) /* SIFLCR : Flow Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) #define TXX9_SIFLCR_RCS 0x00001000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) #define TXX9_SIFLCR_TES 0x00000800
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) #define TXX9_SIFLCR_RTSSC 0x00000200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) #define TXX9_SIFLCR_RSDE 0x00000100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) #define TXX9_SIFLCR_TSDE 0x00000080
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) #define TXX9_SIFLCR_RTSTL_MASK 0x0000001e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) #define TXX9_SIFLCR_RTSTL_MAX 0x0000001e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) #define TXX9_SIFLCR_TBRK 0x00000001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) /* SIBGR : Baudrate Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) #define TXX9_SIBGR_BCLK_MASK 0x00000300
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) #define TXX9_SIBGR_BCLK_T0 0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) #define TXX9_SIBGR_BCLK_T2 0x00000100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) #define TXX9_SIBGR_BCLK_T4 0x00000200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) #define TXX9_SIBGR_BCLK_T6 0x00000300
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) #define TXX9_SIBGR_BRD_MASK 0x000000ff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) static inline unsigned int sio_in(struct uart_txx9_port *up, int offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) switch (up->port.iotype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) return __raw_readl(up->port.membase + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) case UPIO_PORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) return inl(up->port.iobase + offset);
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) sio_out(struct uart_txx9_port *up, int offset, int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) switch (up->port.iotype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) __raw_writel(value, up->port.membase + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) case UPIO_PORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) outl(value, up->port.iobase + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) sio_mask(struct uart_txx9_port *up, int offset, unsigned int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) sio_out(up, offset, sio_in(up, offset) & ~value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) sio_set(struct uart_txx9_port *up, int offset, unsigned int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) sio_out(up, offset, sio_in(up, offset) | value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) sio_quot_set(struct uart_txx9_port *up, int quot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) quot >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) if (quot < 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) sio_out(up, TXX9_SIBGR, quot | TXX9_SIBGR_BCLK_T0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) else if (quot < (256 << 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) sio_out(up, TXX9_SIBGR, (quot >> 2) | TXX9_SIBGR_BCLK_T2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) else if (quot < (256 << 4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) sio_out(up, TXX9_SIBGR, (quot >> 4) | TXX9_SIBGR_BCLK_T4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) else if (quot < (256 << 6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) sio_out(up, TXX9_SIBGR, (quot >> 6) | TXX9_SIBGR_BCLK_T6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) sio_out(up, TXX9_SIBGR, 0xff | TXX9_SIBGR_BCLK_T6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) static struct uart_txx9_port *to_uart_txx9_port(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) return container_of(port, struct uart_txx9_port, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) static void serial_txx9_stop_tx(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) struct uart_txx9_port *up = to_uart_txx9_port(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) sio_mask(up, TXX9_SIDICR, TXX9_SIDICR_TIE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) static void serial_txx9_start_tx(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) struct uart_txx9_port *up = to_uart_txx9_port(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) sio_set(up, TXX9_SIDICR, TXX9_SIDICR_TIE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) static void serial_txx9_stop_rx(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) struct uart_txx9_port *up = to_uart_txx9_port(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) up->port.read_status_mask &= ~TXX9_SIDISR_RDIS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) static void serial_txx9_initialize(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) struct uart_txx9_port *up = to_uart_txx9_port(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) unsigned int tmout = 10000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) sio_out(up, TXX9_SIFCR, TXX9_SIFCR_SWRST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) /* TX4925 BUG WORKAROUND. Accessing SIOC register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) * immediately after soft reset causes bus error. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) while ((sio_in(up, TXX9_SIFCR) & TXX9_SIFCR_SWRST) && --tmout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) /* TX Int by FIFO Empty, RX Int by Receiving 1 char. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) sio_set(up, TXX9_SIFCR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) TXX9_SIFCR_TDIL_MAX | TXX9_SIFCR_RDIL_1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) /* initial settings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) sio_out(up, TXX9_SILCR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) TXX9_SILCR_UMODE_8BIT | TXX9_SILCR_USBL_1BIT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) ((up->port.flags & UPF_TXX9_USE_SCLK) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) TXX9_SILCR_SCS_SCLK_BG : TXX9_SILCR_SCS_IMCLK_BG));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) sio_quot_set(up, uart_get_divisor(port, 9600));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) sio_out(up, TXX9_SIFLCR, TXX9_SIFLCR_RTSTL_MAX /* 15 */);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) sio_out(up, TXX9_SIDICR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) receive_chars(struct uart_txx9_port *up, unsigned int *status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) unsigned char ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) unsigned int disr = *status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) int max_count = 256;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) char flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) unsigned int next_ignore_status_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) ch = sio_in(up, TXX9_SIRFIFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) flag = TTY_NORMAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) up->port.icount.rx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) /* mask out RFDN_MASK bit added by previous overrun */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) next_ignore_status_mask =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) up->port.ignore_status_mask & ~TXX9_SIDISR_RFDN_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) if (unlikely(disr & (TXX9_SIDISR_UBRK | TXX9_SIDISR_UPER |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) TXX9_SIDISR_UFER | TXX9_SIDISR_UOER))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) * For statistics only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) if (disr & TXX9_SIDISR_UBRK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) disr &= ~(TXX9_SIDISR_UFER | TXX9_SIDISR_UPER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) up->port.icount.brk++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) * We do the SysRQ and SAK checking
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) * here because otherwise the break
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) * may get masked by ignore_status_mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) * or read_status_mask.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) if (uart_handle_break(&up->port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) goto ignore_char;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) } else if (disr & TXX9_SIDISR_UPER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) up->port.icount.parity++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) else if (disr & TXX9_SIDISR_UFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) up->port.icount.frame++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) if (disr & TXX9_SIDISR_UOER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) up->port.icount.overrun++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) * The receiver read buffer still hold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) * a char which caused overrun.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) * Ignore next char by adding RFDN_MASK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) * to ignore_status_mask temporarily.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) next_ignore_status_mask |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) TXX9_SIDISR_RFDN_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) * Mask off conditions which should be ingored.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) disr &= up->port.read_status_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) if (disr & TXX9_SIDISR_UBRK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) flag = TTY_BREAK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) } else if (disr & TXX9_SIDISR_UPER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) flag = TTY_PARITY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) else if (disr & TXX9_SIDISR_UFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) flag = TTY_FRAME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) if (uart_handle_sysrq_char(&up->port, ch))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) goto ignore_char;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) uart_insert_char(&up->port, disr, TXX9_SIDISR_UOER, ch, flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) ignore_char:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) up->port.ignore_status_mask = next_ignore_status_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) disr = sio_in(up, TXX9_SIDISR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) } while (!(disr & TXX9_SIDISR_UVALID) && (max_count-- > 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) spin_unlock(&up->port.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) tty_flip_buffer_push(&up->port.state->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) spin_lock(&up->port.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) *status = disr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) static inline void transmit_chars(struct uart_txx9_port *up)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) struct circ_buf *xmit = &up->port.state->xmit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) if (up->port.x_char) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) sio_out(up, TXX9_SITFIFO, up->port.x_char);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) up->port.icount.tx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) up->port.x_char = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) serial_txx9_stop_tx(&up->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) return;
^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) count = TXX9_SIO_TX_FIFO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) sio_out(up, TXX9_SITFIFO, xmit->buf[xmit->tail]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) up->port.icount.tx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) if (uart_circ_empty(xmit))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) } while (--count > 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) uart_write_wakeup(&up->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) if (uart_circ_empty(xmit))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) serial_txx9_stop_tx(&up->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) static irqreturn_t serial_txx9_interrupt(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) int pass_counter = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) struct uart_txx9_port *up = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) unsigned int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) spin_lock(&up->port.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) status = sio_in(up, TXX9_SIDISR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) if (!(sio_in(up, TXX9_SIDICR) & TXX9_SIDICR_TIE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) status &= ~TXX9_SIDISR_TDIS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) if (!(status & (TXX9_SIDISR_TDIS | TXX9_SIDISR_RDIS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) TXX9_SIDISR_TOUT))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) spin_unlock(&up->port.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) if (status & TXX9_SIDISR_RDIS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) receive_chars(up, &status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) if (status & TXX9_SIDISR_TDIS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) transmit_chars(up);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) /* Clear TX/RX Int. Status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) sio_mask(up, TXX9_SIDISR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) TXX9_SIDISR_TDIS | TXX9_SIDISR_RDIS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) TXX9_SIDISR_TOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) spin_unlock(&up->port.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) if (pass_counter++ > PASS_LIMIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) return pass_counter ? IRQ_HANDLED : IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) static unsigned int serial_txx9_tx_empty(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) struct uart_txx9_port *up = to_uart_txx9_port(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) unsigned int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) spin_lock_irqsave(&up->port.lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) ret = (sio_in(up, TXX9_SICISR) & TXX9_SICISR_TXALS) ? TIOCSER_TEMT : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) spin_unlock_irqrestore(&up->port.lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) static unsigned int serial_txx9_get_mctrl(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) struct uart_txx9_port *up = to_uart_txx9_port(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) unsigned int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) /* no modem control lines */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) ret = TIOCM_CAR | TIOCM_DSR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) ret |= (sio_in(up, TXX9_SIFLCR) & TXX9_SIFLCR_RTSSC) ? 0 : TIOCM_RTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) ret |= (sio_in(up, TXX9_SICISR) & TXX9_SICISR_CTSS) ? 0 : TIOCM_CTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) static void serial_txx9_set_mctrl(struct uart_port *port, unsigned int mctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) struct uart_txx9_port *up = to_uart_txx9_port(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) if (mctrl & TIOCM_RTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) sio_mask(up, TXX9_SIFLCR, TXX9_SIFLCR_RTSSC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) sio_set(up, TXX9_SIFLCR, TXX9_SIFLCR_RTSSC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) static void serial_txx9_break_ctl(struct uart_port *port, int break_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) struct uart_txx9_port *up = to_uart_txx9_port(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) spin_lock_irqsave(&up->port.lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) if (break_state == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) sio_set(up, TXX9_SIFLCR, TXX9_SIFLCR_TBRK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) sio_mask(up, TXX9_SIFLCR, TXX9_SIFLCR_TBRK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) spin_unlock_irqrestore(&up->port.lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) #if defined(CONFIG_SERIAL_TXX9_CONSOLE) || defined(CONFIG_CONSOLE_POLL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) * Wait for transmitter & holding register to empty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) static void wait_for_xmitr(struct uart_txx9_port *up)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) unsigned int tmout = 10000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) /* Wait up to 10ms for the character(s) to be sent. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) while (--tmout &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) !(sio_in(up, TXX9_SICISR) & TXX9_SICISR_TXALS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) /* Wait up to 1s for flow control if necessary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) if (up->port.flags & UPF_CONS_FLOW) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) tmout = 1000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) while (--tmout &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) (sio_in(up, TXX9_SICISR) & TXX9_SICISR_CTSS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) #ifdef CONFIG_CONSOLE_POLL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) * Console polling routines for writing and reading from the uart while
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) * in an interrupt or debug context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) static int serial_txx9_get_poll_char(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) unsigned int ier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) unsigned char c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) struct uart_txx9_port *up = to_uart_txx9_port(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) * First save the IER then disable the interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) ier = sio_in(up, TXX9_SIDICR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) sio_out(up, TXX9_SIDICR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) while (sio_in(up, TXX9_SIDISR) & TXX9_SIDISR_UVALID)
^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) c = sio_in(up, TXX9_SIRFIFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) * Finally, clear RX interrupt status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) * and restore the IER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) sio_mask(up, TXX9_SIDISR, TXX9_SIDISR_RDIS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) sio_out(up, TXX9_SIDICR, ier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) return c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) static void serial_txx9_put_poll_char(struct uart_port *port, unsigned char c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) unsigned int ier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) struct uart_txx9_port *up = to_uart_txx9_port(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) * First save the IER then disable the interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) ier = sio_in(up, TXX9_SIDICR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) sio_out(up, TXX9_SIDICR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) wait_for_xmitr(up);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) * Send the character out.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) sio_out(up, TXX9_SITFIFO, c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) * Finally, wait for transmitter to become empty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) * and restore the IER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) wait_for_xmitr(up);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) sio_out(up, TXX9_SIDICR, ier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) #endif /* CONFIG_CONSOLE_POLL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) static int serial_txx9_startup(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) struct uart_txx9_port *up = to_uart_txx9_port(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) * Clear the FIFO buffers and disable them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) * (they will be reenabled in set_termios())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) sio_set(up, TXX9_SIFCR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) TXX9_SIFCR_TFRST | TXX9_SIFCR_RFRST | TXX9_SIFCR_FRSTE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) /* clear reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) sio_mask(up, TXX9_SIFCR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) TXX9_SIFCR_TFRST | TXX9_SIFCR_RFRST | TXX9_SIFCR_FRSTE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) sio_out(up, TXX9_SIDICR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) * Clear the interrupt registers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) sio_out(up, TXX9_SIDISR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) retval = request_irq(up->port.irq, serial_txx9_interrupt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) IRQF_SHARED, "serial_txx9", up);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) * Now, initialize the UART
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) spin_lock_irqsave(&up->port.lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) serial_txx9_set_mctrl(&up->port, up->port.mctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) spin_unlock_irqrestore(&up->port.lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) /* Enable RX/TX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) sio_mask(up, TXX9_SIFLCR, TXX9_SIFLCR_RSDE | TXX9_SIFLCR_TSDE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) * Finally, enable interrupts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) sio_set(up, TXX9_SIDICR, TXX9_SIDICR_RIE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) static void serial_txx9_shutdown(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) struct uart_txx9_port *up = to_uart_txx9_port(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) * Disable interrupts from this port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) sio_out(up, TXX9_SIDICR, 0); /* disable all intrs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) spin_lock_irqsave(&up->port.lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) serial_txx9_set_mctrl(&up->port, up->port.mctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) spin_unlock_irqrestore(&up->port.lock, flags);
^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) * Disable break condition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) sio_mask(up, TXX9_SIFLCR, TXX9_SIFLCR_TBRK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) #ifdef CONFIG_SERIAL_TXX9_CONSOLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) if (up->port.cons && up->port.line == up->port.cons->index) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) free_irq(up->port.irq, up);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) /* reset FIFOs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) sio_set(up, TXX9_SIFCR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) TXX9_SIFCR_TFRST | TXX9_SIFCR_RFRST | TXX9_SIFCR_FRSTE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) /* clear reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) sio_mask(up, TXX9_SIFCR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) TXX9_SIFCR_TFRST | TXX9_SIFCR_RFRST | TXX9_SIFCR_FRSTE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) /* Disable RX/TX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) sio_set(up, TXX9_SIFLCR, TXX9_SIFLCR_RSDE | TXX9_SIFLCR_TSDE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) free_irq(up->port.irq, up);
^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) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) serial_txx9_set_termios(struct uart_port *port, struct ktermios *termios,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) struct ktermios *old)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) struct uart_txx9_port *up = to_uart_txx9_port(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) unsigned int cval, fcr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) unsigned int baud, quot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) * We don't support modem control lines.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) termios->c_cflag &= ~(HUPCL | CMSPAR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) termios->c_cflag |= CLOCAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) cval = sio_in(up, TXX9_SILCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) /* byte size and parity */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) cval &= ~TXX9_SILCR_UMODE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) switch (termios->c_cflag & CSIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) case CS7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) cval |= TXX9_SILCR_UMODE_7BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) case CS5: /* not supported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) case CS6: /* not supported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) case CS8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) cval |= TXX9_SILCR_UMODE_8BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) cval &= ~TXX9_SILCR_USBL_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) if (termios->c_cflag & CSTOPB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) cval |= TXX9_SILCR_USBL_2BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) cval |= TXX9_SILCR_USBL_1BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) cval &= ~(TXX9_SILCR_UPEN | TXX9_SILCR_UEPS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) if (termios->c_cflag & PARENB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) cval |= TXX9_SILCR_UPEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) if (!(termios->c_cflag & PARODD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) cval |= TXX9_SILCR_UEPS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) * Ask the core to calculate the divisor for us.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16/2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) quot = uart_get_divisor(port, baud);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) /* Set up FIFOs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) /* TX Int by FIFO Empty, RX Int by Receiving 1 char. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) fcr = TXX9_SIFCR_TDIL_MAX | TXX9_SIFCR_RDIL_1;
^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) * Ok, we're now changing the port state. Do it with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) * interrupts disabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) spin_lock_irqsave(&up->port.lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) * Update the per-port timeout.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) uart_update_timeout(port, termios->c_cflag, baud);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) up->port.read_status_mask = TXX9_SIDISR_UOER |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) TXX9_SIDISR_TDIS | TXX9_SIDISR_RDIS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) if (termios->c_iflag & INPCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) up->port.read_status_mask |= TXX9_SIDISR_UFER | TXX9_SIDISR_UPER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) up->port.read_status_mask |= TXX9_SIDISR_UBRK;
^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) * Characteres to ignore
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) up->port.ignore_status_mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) if (termios->c_iflag & IGNPAR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) up->port.ignore_status_mask |= TXX9_SIDISR_UPER | TXX9_SIDISR_UFER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) if (termios->c_iflag & IGNBRK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) up->port.ignore_status_mask |= TXX9_SIDISR_UBRK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) * If we're ignoring parity and break indicators,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) * ignore overruns too (for real raw support).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) if (termios->c_iflag & IGNPAR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) up->port.ignore_status_mask |= TXX9_SIDISR_UOER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) * ignore all characters if CREAD is not set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) if ((termios->c_cflag & CREAD) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) up->port.ignore_status_mask |= TXX9_SIDISR_RDIS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) /* CTS flow control flag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) if ((termios->c_cflag & CRTSCTS) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) (up->port.flags & UPF_TXX9_HAVE_CTS_LINE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) sio_set(up, TXX9_SIFLCR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) TXX9_SIFLCR_RCS | TXX9_SIFLCR_TES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) sio_mask(up, TXX9_SIFLCR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) TXX9_SIFLCR_RCS | TXX9_SIFLCR_TES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) sio_out(up, TXX9_SILCR, cval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) sio_quot_set(up, quot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) sio_out(up, TXX9_SIFCR, fcr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) serial_txx9_set_mctrl(&up->port, up->port.mctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) spin_unlock_irqrestore(&up->port.lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) serial_txx9_pm(struct uart_port *port, unsigned int state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) unsigned int oldstate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) * If oldstate was -1 this is called from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) * uart_configure_port(). In this case do not initialize the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) * port now, because the port was already initialized (for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) * non-console port) or should not be initialized here (for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) * console port). If we initialized the port here we lose
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) * serial console settings.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) if (state == 0 && oldstate != -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) serial_txx9_initialize(port);
^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) static int serial_txx9_request_resource(struct uart_txx9_port *up)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) unsigned int size = TXX9_REGION_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) switch (up->port.iotype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) if (!up->port.mapbase)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) if (!request_mem_region(up->port.mapbase, size, "serial_txx9")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) ret = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) if (up->port.flags & UPF_IOREMAP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) up->port.membase = ioremap(up->port.mapbase, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) if (!up->port.membase) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) release_mem_region(up->port.mapbase, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) case UPIO_PORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) if (!request_region(up->port.iobase, size, "serial_txx9"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) ret = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) static void serial_txx9_release_resource(struct uart_txx9_port *up)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) unsigned int size = TXX9_REGION_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) switch (up->port.iotype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) if (!up->port.mapbase)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) if (up->port.flags & UPF_IOREMAP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) iounmap(up->port.membase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) up->port.membase = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) release_mem_region(up->port.mapbase, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) case UPIO_PORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) release_region(up->port.iobase, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) static void serial_txx9_release_port(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) struct uart_txx9_port *up = to_uart_txx9_port(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) serial_txx9_release_resource(up);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) static int serial_txx9_request_port(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) struct uart_txx9_port *up = to_uart_txx9_port(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) return serial_txx9_request_resource(up);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) static void serial_txx9_config_port(struct uart_port *port, int uflags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) struct uart_txx9_port *up = to_uart_txx9_port(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) * Find the region that we can probe for. This in turn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) * tells us whether we can probe for the type of port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) ret = serial_txx9_request_resource(up);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) port->type = PORT_TXX9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) up->port.fifosize = TXX9_SIO_TX_FIFO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) #ifdef CONFIG_SERIAL_TXX9_CONSOLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) if (up->port.line == up->port.cons->index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) serial_txx9_initialize(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) static const char *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) serial_txx9_type(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) return "txx9";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) static const struct uart_ops serial_txx9_pops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) .tx_empty = serial_txx9_tx_empty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) .set_mctrl = serial_txx9_set_mctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) .get_mctrl = serial_txx9_get_mctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) .stop_tx = serial_txx9_stop_tx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) .start_tx = serial_txx9_start_tx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) .stop_rx = serial_txx9_stop_rx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) .break_ctl = serial_txx9_break_ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) .startup = serial_txx9_startup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) .shutdown = serial_txx9_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) .set_termios = serial_txx9_set_termios,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) .pm = serial_txx9_pm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) .type = serial_txx9_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) .release_port = serial_txx9_release_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) .request_port = serial_txx9_request_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) .config_port = serial_txx9_config_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) #ifdef CONFIG_CONSOLE_POLL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) .poll_get_char = serial_txx9_get_poll_char,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) .poll_put_char = serial_txx9_put_poll_char,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) static struct uart_txx9_port serial_txx9_ports[UART_NR];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) static void __init serial_txx9_register_ports(struct uart_driver *drv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) for (i = 0; i < UART_NR; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) struct uart_txx9_port *up = &serial_txx9_ports[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) up->port.line = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) up->port.ops = &serial_txx9_pops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) up->port.dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) if (up->port.iobase || up->port.mapbase)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) uart_add_one_port(drv, &up->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) #ifdef CONFIG_SERIAL_TXX9_CONSOLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) static void serial_txx9_console_putchar(struct uart_port *port, int ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) struct uart_txx9_port *up = to_uart_txx9_port(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) wait_for_xmitr(up);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) sio_out(up, TXX9_SITFIFO, ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) * Print a string to the serial port trying not to disturb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) * any possible real use of the port...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) * The console_lock must be held when we get here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) serial_txx9_console_write(struct console *co, const char *s, unsigned int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) struct uart_txx9_port *up = &serial_txx9_ports[co->index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) unsigned int ier, flcr;
^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) * First save the UER then disable the interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) ier = sio_in(up, TXX9_SIDICR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) sio_out(up, TXX9_SIDICR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) * Disable flow-control if enabled (and unnecessary)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) flcr = sio_in(up, TXX9_SIFLCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) if (!(up->port.flags & UPF_CONS_FLOW) && (flcr & TXX9_SIFLCR_TES))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) sio_out(up, TXX9_SIFLCR, flcr & ~TXX9_SIFLCR_TES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) uart_console_write(&up->port, s, count, serial_txx9_console_putchar);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) * Finally, wait for transmitter to become empty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) * and restore the IER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) wait_for_xmitr(up);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) sio_out(up, TXX9_SIFLCR, flcr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) sio_out(up, TXX9_SIDICR, ier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) static int __init serial_txx9_console_setup(struct console *co, char *options)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) struct uart_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) struct uart_txx9_port *up;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) int baud = 9600;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) int bits = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) int parity = 'n';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) int flow = 'n';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) * Check whether an invalid uart number has been specified, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) * if so, search for the first available port that does have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) * console support.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) if (co->index >= UART_NR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) co->index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) up = &serial_txx9_ports[co->index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) port = &up->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) if (!port->ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) serial_txx9_initialize(&up->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) if (options)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) uart_parse_options(options, &baud, &parity, &bits, &flow);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) return uart_set_options(port, co, baud, parity, bits, flow);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) static struct uart_driver serial_txx9_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) static struct console serial_txx9_console = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) .name = TXX9_TTY_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) .write = serial_txx9_console_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) .device = uart_console_device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) .setup = serial_txx9_console_setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) .flags = CON_PRINTBUFFER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) .index = -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) .data = &serial_txx9_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) static int __init serial_txx9_console_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) register_console(&serial_txx9_console);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) console_initcall(serial_txx9_console_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) #define SERIAL_TXX9_CONSOLE &serial_txx9_console
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) #define SERIAL_TXX9_CONSOLE NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) static struct uart_driver serial_txx9_reg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) .driver_name = "serial_txx9",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) .dev_name = TXX9_TTY_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) .major = TXX9_TTY_MAJOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) .minor = TXX9_TTY_MINOR_START,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) .nr = UART_NR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) .cons = SERIAL_TXX9_CONSOLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) int __init early_serial_txx9_setup(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) if (port->line >= ARRAY_SIZE(serial_txx9_ports))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) serial_txx9_ports[port->line].port = *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) serial_txx9_ports[port->line].port.ops = &serial_txx9_pops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) serial_txx9_ports[port->line].port.flags |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) UPF_BOOT_AUTOCONF | UPF_FIXED_PORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) static DEFINE_MUTEX(serial_txx9_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) * serial_txx9_register_port - register a serial port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) * @port: serial port template
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) * Configure the serial port specified by the request.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) * The port is then probed and if necessary the IRQ is autodetected
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) * If this fails an error is returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) * On success the port is ready to use and the line number is returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) static int serial_txx9_register_port(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) struct uart_txx9_port *uart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) int ret = -ENOSPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) mutex_lock(&serial_txx9_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) for (i = 0; i < UART_NR; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) uart = &serial_txx9_ports[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) if (uart_match_port(&uart->port, port)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) uart_remove_one_port(&serial_txx9_reg, &uart->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) if (i == UART_NR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) /* Find unused port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) for (i = 0; i < UART_NR; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) uart = &serial_txx9_ports[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) if (!(uart->port.iobase || uart->port.mapbase))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) if (i < UART_NR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) uart->port.iobase = port->iobase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) uart->port.membase = port->membase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) uart->port.irq = port->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) uart->port.uartclk = port->uartclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) uart->port.iotype = port->iotype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) uart->port.flags = port->flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) | UPF_BOOT_AUTOCONF | UPF_FIXED_PORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) uart->port.mapbase = port->mapbase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) if (port->dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) uart->port.dev = port->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) ret = uart_add_one_port(&serial_txx9_reg, &uart->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) if (ret == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) ret = uart->port.line;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) mutex_unlock(&serial_txx9_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) * serial_txx9_unregister_port - remove a txx9 serial port at runtime
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) * @line: serial line number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) * Remove one serial port. This may not be called from interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) * context. We hand the port back to the our control.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) static void serial_txx9_unregister_port(int line)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) struct uart_txx9_port *uart = &serial_txx9_ports[line];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) mutex_lock(&serial_txx9_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) uart_remove_one_port(&serial_txx9_reg, &uart->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) uart->port.flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) uart->port.type = PORT_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) uart->port.iobase = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) uart->port.mapbase = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) uart->port.membase = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) uart->port.dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) mutex_unlock(&serial_txx9_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) * Register a set of serial devices attached to a platform device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) static int serial_txx9_probe(struct platform_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) struct uart_port *p = dev_get_platdata(&dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) struct uart_port port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) memset(&port, 0, sizeof(struct uart_port));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) for (i = 0; p && p->uartclk != 0; p++, i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) port.iobase = p->iobase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) port.membase = p->membase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) port.irq = p->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) port.uartclk = p->uartclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) port.iotype = p->iotype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) port.flags = p->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) port.mapbase = p->mapbase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) port.dev = &dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) port.has_sysrq = IS_ENABLED(CONFIG_SERIAL_TXX9_CONSOLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) ret = serial_txx9_register_port(&port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) dev_err(&dev->dev, "unable to register port at index %d "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) "(IO%lx MEM%llx IRQ%d): %d\n", i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) p->iobase, (unsigned long long)p->mapbase,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) p->irq, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) * Remove serial ports registered against a platform device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) static int serial_txx9_remove(struct platform_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) for (i = 0; i < UART_NR; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) struct uart_txx9_port *up = &serial_txx9_ports[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) if (up->port.dev == &dev->dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) serial_txx9_unregister_port(i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) static int serial_txx9_suspend(struct platform_device *dev, pm_message_t state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) for (i = 0; i < UART_NR; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) struct uart_txx9_port *up = &serial_txx9_ports[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) if (up->port.type != PORT_UNKNOWN && up->port.dev == &dev->dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) uart_suspend_port(&serial_txx9_reg, &up->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) static int serial_txx9_resume(struct platform_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) for (i = 0; i < UART_NR; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) struct uart_txx9_port *up = &serial_txx9_ports[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) if (up->port.type != PORT_UNKNOWN && up->port.dev == &dev->dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) uart_resume_port(&serial_txx9_reg, &up->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) static struct platform_driver serial_txx9_plat_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) .probe = serial_txx9_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) .remove = serial_txx9_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) .suspend = serial_txx9_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) .resume = serial_txx9_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) .name = "serial_txx9",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) #ifdef ENABLE_SERIAL_TXX9_PCI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) * Probe one serial board. Unfortunately, there is no rhyme nor reason
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) * to the arrangement of serial ports on a PCI card.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) pciserial_txx9_init_one(struct pci_dev *dev, const struct pci_device_id *ent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) struct uart_port port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) int line;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) rc = pci_enable_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) memset(&port, 0, sizeof(port));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) port.ops = &serial_txx9_pops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) port.flags |= UPF_TXX9_HAVE_CTS_LINE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) port.uartclk = 66670000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) port.irq = dev->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) port.iotype = UPIO_PORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) port.iobase = pci_resource_start(dev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) port.dev = &dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) line = serial_txx9_register_port(&port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) if (line < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) printk(KERN_WARNING "Couldn't register serial port %s: %d\n", pci_name(dev), line);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) pci_disable_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) return line;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) pci_set_drvdata(dev, &serial_txx9_ports[line]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) static void pciserial_txx9_remove_one(struct pci_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) struct uart_txx9_port *up = pci_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) if (up) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) serial_txx9_unregister_port(up->port.line);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) pci_disable_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) static int pciserial_txx9_suspend_one(struct pci_dev *dev, pm_message_t state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) struct uart_txx9_port *up = pci_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) if (up)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) uart_suspend_port(&serial_txx9_reg, &up->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) pci_save_state(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) pci_set_power_state(dev, pci_choose_state(dev, state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) static int pciserial_txx9_resume_one(struct pci_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) struct uart_txx9_port *up = pci_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) pci_set_power_state(dev, PCI_D0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) pci_restore_state(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) if (up)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) uart_resume_port(&serial_txx9_reg, &up->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) static const struct pci_device_id serial_txx9_pci_tbl[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) { PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA_2, PCI_DEVICE_ID_TOSHIBA_TC86C001_MISC) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) { 0, }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) static struct pci_driver serial_txx9_pci_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) .name = "serial_txx9",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) .probe = pciserial_txx9_init_one,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) .remove = pciserial_txx9_remove_one,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) .suspend = pciserial_txx9_suspend_one,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) .resume = pciserial_txx9_resume_one,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) .id_table = serial_txx9_pci_tbl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) MODULE_DEVICE_TABLE(pci, serial_txx9_pci_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) #endif /* ENABLE_SERIAL_TXX9_PCI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) static struct platform_device *serial_txx9_plat_devs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) static int __init serial_txx9_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) printk(KERN_INFO "%s version %s\n", serial_name, serial_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) ret = uart_register_driver(&serial_txx9_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) serial_txx9_plat_devs = platform_device_alloc("serial_txx9", -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) if (!serial_txx9_plat_devs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) goto unreg_uart_drv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) ret = platform_device_add(serial_txx9_plat_devs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) goto put_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) serial_txx9_register_ports(&serial_txx9_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) &serial_txx9_plat_devs->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) ret = platform_driver_register(&serial_txx9_plat_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) goto del_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) #ifdef ENABLE_SERIAL_TXX9_PCI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) ret = pci_register_driver(&serial_txx9_pci_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) platform_driver_unregister(&serial_txx9_plat_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) if (ret == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) del_dev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) platform_device_del(serial_txx9_plat_devs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) put_dev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) platform_device_put(serial_txx9_plat_devs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) unreg_uart_drv:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) uart_unregister_driver(&serial_txx9_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) static void __exit serial_txx9_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) #ifdef ENABLE_SERIAL_TXX9_PCI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) pci_unregister_driver(&serial_txx9_pci_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) platform_driver_unregister(&serial_txx9_plat_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) platform_device_unregister(serial_txx9_plat_devs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) for (i = 0; i < UART_NR; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) struct uart_txx9_port *up = &serial_txx9_ports[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) if (up->port.iobase || up->port.mapbase)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) uart_remove_one_port(&serial_txx9_reg, &up->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) uart_unregister_driver(&serial_txx9_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) module_init(serial_txx9_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) module_exit(serial_txx9_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) MODULE_DESCRIPTION("TX39/49 serial driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) MODULE_ALIAS_CHARDEV_MAJOR(TXX9_TTY_MAJOR);