^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) * NXP (Philips) SCC+++(SCN+++) serial driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2012 Alexander Shiyan <shc_work@mail.ru>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Based on sc26xx.c, by Thomas Bogendörfer (tsbogend@alpha.franken.de)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/mod_devicetable.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/console.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/serial_core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/serial.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/tty.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/tty_flip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/platform_data/serial-sccnxp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/regulator/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define SCCNXP_NAME "uart-sccnxp"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define SCCNXP_MAJOR 204
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define SCCNXP_MINOR 205
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define SCCNXP_MR_REG (0x00)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) # define MR0_BAUD_NORMAL (0 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) # define MR0_BAUD_EXT1 (1 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) # define MR0_BAUD_EXT2 (5 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) # define MR0_FIFO (1 << 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) # define MR0_TXLVL (1 << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) # define MR1_BITS_5 (0 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) # define MR1_BITS_6 (1 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) # define MR1_BITS_7 (2 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) # define MR1_BITS_8 (3 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) # define MR1_PAR_EVN (0 << 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) # define MR1_PAR_ODD (1 << 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) # define MR1_PAR_NO (4 << 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) # define MR2_STOP1 (7 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) # define MR2_STOP2 (0xf << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define SCCNXP_SR_REG (0x01)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) # define SR_RXRDY (1 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) # define SR_FULL (1 << 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) # define SR_TXRDY (1 << 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) # define SR_TXEMT (1 << 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) # define SR_OVR (1 << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) # define SR_PE (1 << 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) # define SR_FE (1 << 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) # define SR_BRK (1 << 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define SCCNXP_CSR_REG (SCCNXP_SR_REG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) # define CSR_TIMER_MODE (0x0d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define SCCNXP_CR_REG (0x02)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) # define CR_RX_ENABLE (1 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) # define CR_RX_DISABLE (1 << 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) # define CR_TX_ENABLE (1 << 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) # define CR_TX_DISABLE (1 << 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) # define CR_CMD_MRPTR1 (0x01 << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) # define CR_CMD_RX_RESET (0x02 << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) # define CR_CMD_TX_RESET (0x03 << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) # define CR_CMD_STATUS_RESET (0x04 << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) # define CR_CMD_BREAK_RESET (0x05 << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) # define CR_CMD_START_BREAK (0x06 << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) # define CR_CMD_STOP_BREAK (0x07 << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) # define CR_CMD_MRPTR0 (0x0b << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define SCCNXP_RHR_REG (0x03)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define SCCNXP_THR_REG SCCNXP_RHR_REG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define SCCNXP_IPCR_REG (0x04)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define SCCNXP_ACR_REG SCCNXP_IPCR_REG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) # define ACR_BAUD0 (0 << 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) # define ACR_BAUD1 (1 << 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) # define ACR_TIMER_MODE (6 << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define SCCNXP_ISR_REG (0x05)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define SCCNXP_IMR_REG SCCNXP_ISR_REG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) # define IMR_TXRDY (1 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) # define IMR_RXRDY (1 << 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) # define ISR_TXRDY(x) (1 << ((x * 4) + 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) # define ISR_RXRDY(x) (1 << ((x * 4) + 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define SCCNXP_CTPU_REG (0x06)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define SCCNXP_CTPL_REG (0x07)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define SCCNXP_IPR_REG (0x0d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define SCCNXP_OPCR_REG SCCNXP_IPR_REG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define SCCNXP_SOP_REG (0x0e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define SCCNXP_START_COUNTER_REG SCCNXP_SOP_REG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define SCCNXP_ROP_REG (0x0f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) /* Route helpers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define MCTRL_MASK(sig) (0xf << (sig))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define MCTRL_IBIT(cfg, sig) ((((cfg) >> (sig)) & 0xf) - LINE_IP0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define MCTRL_OBIT(cfg, sig) ((((cfg) >> (sig)) & 0xf) - LINE_OP0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define SCCNXP_HAVE_IO 0x00000001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #define SCCNXP_HAVE_MR0 0x00000002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) struct sccnxp_chip {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) unsigned int nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) unsigned long freq_min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) unsigned long freq_std;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) unsigned long freq_max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) unsigned int flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) unsigned int fifosize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) /* Time between read/write cycles */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) unsigned int trwd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) struct sccnxp_port {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) struct uart_driver uart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) struct uart_port port[SCCNXP_MAX_UARTS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) bool opened[SCCNXP_MAX_UARTS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) u8 imr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) struct sccnxp_chip *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) #ifdef CONFIG_SERIAL_SCCNXP_CONSOLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) struct console console;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) spinlock_t lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) bool poll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) struct timer_list timer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) struct sccnxp_pdata pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) struct regulator *regulator;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) static const struct sccnxp_chip sc2681 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) .name = "SC2681",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) .nr = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) .freq_min = 1000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) .freq_std = 3686400,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) .freq_max = 4000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) .flags = SCCNXP_HAVE_IO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) .fifosize = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) .trwd = 200,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) static const struct sccnxp_chip sc2691 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) .name = "SC2691",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) .nr = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) .freq_min = 1000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) .freq_std = 3686400,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) .freq_max = 4000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) .flags = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) .fifosize = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) .trwd = 150,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) static const struct sccnxp_chip sc2692 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) .name = "SC2692",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) .nr = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) .freq_min = 1000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) .freq_std = 3686400,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) .freq_max = 4000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) .flags = SCCNXP_HAVE_IO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) .fifosize = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) .trwd = 30,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) static const struct sccnxp_chip sc2891 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) .name = "SC2891",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) .nr = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) .freq_min = 100000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) .freq_std = 3686400,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) .freq_max = 8000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) .flags = SCCNXP_HAVE_IO | SCCNXP_HAVE_MR0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) .fifosize = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) .trwd = 27,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) static const struct sccnxp_chip sc2892 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) .name = "SC2892",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) .nr = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) .freq_min = 100000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) .freq_std = 3686400,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) .freq_max = 8000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) .flags = SCCNXP_HAVE_IO | SCCNXP_HAVE_MR0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) .fifosize = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) .trwd = 17,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) static const struct sccnxp_chip sc28202 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) .name = "SC28202",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) .nr = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) .freq_min = 1000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) .freq_std = 14745600,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) .freq_max = 50000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) .flags = SCCNXP_HAVE_IO | SCCNXP_HAVE_MR0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) .fifosize = 256,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) .trwd = 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) static const struct sccnxp_chip sc68681 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) .name = "SC68681",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) .nr = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) .freq_min = 1000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) .freq_std = 3686400,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) .freq_max = 4000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) .flags = SCCNXP_HAVE_IO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) .fifosize = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) .trwd = 200,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) static const struct sccnxp_chip sc68692 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) .name = "SC68692",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) .nr = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) .freq_min = 1000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) .freq_std = 3686400,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) .freq_max = 4000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) .flags = SCCNXP_HAVE_IO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) .fifosize = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) .trwd = 200,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) static u8 sccnxp_read(struct uart_port *port, u8 reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) struct sccnxp_port *s = dev_get_drvdata(port->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) u8 ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) ret = readb(port->membase + (reg << port->regshift));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) ndelay(s->chip->trwd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) static void sccnxp_write(struct uart_port *port, u8 reg, u8 v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) struct sccnxp_port *s = dev_get_drvdata(port->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) writeb(v, port->membase + (reg << port->regshift));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) ndelay(s->chip->trwd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) static u8 sccnxp_port_read(struct uart_port *port, u8 reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) return sccnxp_read(port, (port->line << 3) + reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) static void sccnxp_port_write(struct uart_port *port, u8 reg, u8 v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) sccnxp_write(port, (port->line << 3) + reg, v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) static int sccnxp_update_best_err(int a, int b, int *besterr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) int err = abs(a - b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) if (*besterr > err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) *besterr = err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) return 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) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) static const struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) u8 csr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) u8 acr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) u8 mr0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) int baud;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) } baud_std[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) { 0, ACR_BAUD0, MR0_BAUD_NORMAL, 50, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) { 0, ACR_BAUD1, MR0_BAUD_NORMAL, 75, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) { 1, ACR_BAUD0, MR0_BAUD_NORMAL, 110, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) { 2, ACR_BAUD0, MR0_BAUD_NORMAL, 134, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) { 3, ACR_BAUD1, MR0_BAUD_NORMAL, 150, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) { 3, ACR_BAUD0, MR0_BAUD_NORMAL, 200, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) { 4, ACR_BAUD0, MR0_BAUD_NORMAL, 300, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) { 0, ACR_BAUD1, MR0_BAUD_EXT1, 450, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) { 1, ACR_BAUD0, MR0_BAUD_EXT2, 880, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) { 3, ACR_BAUD1, MR0_BAUD_EXT1, 900, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) { 5, ACR_BAUD0, MR0_BAUD_NORMAL, 600, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) { 7, ACR_BAUD0, MR0_BAUD_NORMAL, 1050, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) { 2, ACR_BAUD0, MR0_BAUD_EXT2, 1076, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) { 6, ACR_BAUD0, MR0_BAUD_NORMAL, 1200, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) { 10, ACR_BAUD1, MR0_BAUD_NORMAL, 1800, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) { 7, ACR_BAUD1, MR0_BAUD_NORMAL, 2000, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) { 8, ACR_BAUD0, MR0_BAUD_NORMAL, 2400, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) { 5, ACR_BAUD1, MR0_BAUD_EXT1, 3600, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) { 9, ACR_BAUD0, MR0_BAUD_NORMAL, 4800, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) { 10, ACR_BAUD0, MR0_BAUD_NORMAL, 7200, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) { 11, ACR_BAUD0, MR0_BAUD_NORMAL, 9600, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) { 8, ACR_BAUD0, MR0_BAUD_EXT1, 14400, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) { 12, ACR_BAUD1, MR0_BAUD_NORMAL, 19200, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) { 9, ACR_BAUD0, MR0_BAUD_EXT1, 28800, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) { 12, ACR_BAUD0, MR0_BAUD_NORMAL, 38400, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) { 11, ACR_BAUD0, MR0_BAUD_EXT1, 57600, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) { 12, ACR_BAUD1, MR0_BAUD_EXT1, 115200, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) { 12, ACR_BAUD0, MR0_BAUD_EXT1, 230400, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) { 0, 0, 0, 0 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) static int sccnxp_set_baud(struct uart_port *port, int baud)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) struct sccnxp_port *s = dev_get_drvdata(port->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) int div_std, tmp_baud, bestbaud = INT_MAX, besterr = INT_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) struct sccnxp_chip *chip = s->chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) u8 i, acr = 0, csr = 0, mr0 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) /* Find divisor to load to the timer preset registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) div_std = DIV_ROUND_CLOSEST(port->uartclk, 2 * 16 * baud);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) if ((div_std >= 2) && (div_std <= 0xffff)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) bestbaud = DIV_ROUND_CLOSEST(port->uartclk, 2 * 16 * div_std);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) sccnxp_update_best_err(baud, bestbaud, &besterr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) csr = CSR_TIMER_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) sccnxp_port_write(port, SCCNXP_CTPU_REG, div_std >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) sccnxp_port_write(port, SCCNXP_CTPL_REG, div_std);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) /* Issue start timer/counter command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) sccnxp_port_read(port, SCCNXP_START_COUNTER_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) /* Find best baud from table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) for (i = 0; baud_std[i].baud && besterr; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) if (baud_std[i].mr0 && !(chip->flags & SCCNXP_HAVE_MR0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) div_std = DIV_ROUND_CLOSEST(chip->freq_std, baud_std[i].baud);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) tmp_baud = DIV_ROUND_CLOSEST(port->uartclk, div_std);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) if (!sccnxp_update_best_err(baud, tmp_baud, &besterr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) acr = baud_std[i].acr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) csr = baud_std[i].csr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) mr0 = baud_std[i].mr0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) bestbaud = tmp_baud;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) if (chip->flags & SCCNXP_HAVE_MR0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) /* Enable FIFO, set half level for TX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) mr0 |= MR0_FIFO | MR0_TXLVL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) /* Update MR0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) sccnxp_port_write(port, SCCNXP_CR_REG, CR_CMD_MRPTR0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) sccnxp_port_write(port, SCCNXP_MR_REG, mr0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) sccnxp_port_write(port, SCCNXP_ACR_REG, acr | ACR_TIMER_MODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) sccnxp_port_write(port, SCCNXP_CSR_REG, (csr << 4) | csr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) if (baud != bestbaud)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) dev_dbg(port->dev, "Baudrate desired: %i, calculated: %i\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) baud, bestbaud);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) return bestbaud;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) static void sccnxp_enable_irq(struct uart_port *port, int mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) struct sccnxp_port *s = dev_get_drvdata(port->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) s->imr |= mask << (port->line * 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) sccnxp_write(port, SCCNXP_IMR_REG, s->imr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) static void sccnxp_disable_irq(struct uart_port *port, int mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) struct sccnxp_port *s = dev_get_drvdata(port->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) s->imr &= ~(mask << (port->line * 4));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) sccnxp_write(port, SCCNXP_IMR_REG, s->imr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) static void sccnxp_set_bit(struct uart_port *port, int sig, int state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) u8 bitmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) struct sccnxp_port *s = dev_get_drvdata(port->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) if (s->pdata.mctrl_cfg[port->line] & MCTRL_MASK(sig)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) bitmask = 1 << MCTRL_OBIT(s->pdata.mctrl_cfg[port->line], sig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) if (state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) sccnxp_write(port, SCCNXP_SOP_REG, bitmask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) sccnxp_write(port, SCCNXP_ROP_REG, bitmask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) static void sccnxp_handle_rx(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) u8 sr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) unsigned int ch, flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) sr = sccnxp_port_read(port, SCCNXP_SR_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) if (!(sr & SR_RXRDY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) sr &= SR_PE | SR_FE | SR_OVR | SR_BRK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) ch = sccnxp_port_read(port, SCCNXP_RHR_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) port->icount.rx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) flag = TTY_NORMAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) if (unlikely(sr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) if (sr & SR_BRK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) port->icount.brk++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) sccnxp_port_write(port, SCCNXP_CR_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) CR_CMD_BREAK_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) if (uart_handle_break(port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) } else if (sr & SR_PE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) port->icount.parity++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) else if (sr & SR_FE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) port->icount.frame++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) else if (sr & SR_OVR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) port->icount.overrun++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) sccnxp_port_write(port, SCCNXP_CR_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) CR_CMD_STATUS_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) sr &= port->read_status_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) if (sr & SR_BRK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) flag = TTY_BREAK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) else if (sr & SR_PE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) flag = TTY_PARITY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) else if (sr & SR_FE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) flag = TTY_FRAME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) else if (sr & SR_OVR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) flag = TTY_OVERRUN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) if (uart_handle_sysrq_char(port, ch))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) if (sr & port->ignore_status_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) uart_insert_char(port, sr, SR_OVR, ch, flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) tty_flip_buffer_push(&port->state->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) static void sccnxp_handle_tx(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) u8 sr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) struct circ_buf *xmit = &port->state->xmit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) struct sccnxp_port *s = dev_get_drvdata(port->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) if (unlikely(port->x_char)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) sccnxp_port_write(port, SCCNXP_THR_REG, port->x_char);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) port->icount.tx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) port->x_char = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) /* Disable TX if FIFO is empty */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) if (sccnxp_port_read(port, SCCNXP_SR_REG) & SR_TXEMT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) sccnxp_disable_irq(port, IMR_TXRDY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) /* Set direction to input */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) if (s->chip->flags & SCCNXP_HAVE_IO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) sccnxp_set_bit(port, DIR_OP, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) while (!uart_circ_empty(xmit)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) sr = sccnxp_port_read(port, SCCNXP_SR_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) if (!(sr & SR_TXRDY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) sccnxp_port_write(port, SCCNXP_THR_REG, xmit->buf[xmit->tail]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) port->icount.tx++;
^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) if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) uart_write_wakeup(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) static void sccnxp_handle_events(struct sccnxp_port *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) u8 isr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) isr = sccnxp_read(&s->port[0], SCCNXP_ISR_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) isr &= s->imr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) if (!isr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) for (i = 0; i < s->uart.nr; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) if (s->opened[i] && (isr & ISR_RXRDY(i)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) sccnxp_handle_rx(&s->port[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) if (s->opened[i] && (isr & ISR_TXRDY(i)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) sccnxp_handle_tx(&s->port[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) } while (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) static void sccnxp_timer(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) struct sccnxp_port *s = from_timer(s, t, timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) spin_lock_irqsave(&s->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) sccnxp_handle_events(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) spin_unlock_irqrestore(&s->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) mod_timer(&s->timer, jiffies + usecs_to_jiffies(s->pdata.poll_time_us));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) static irqreturn_t sccnxp_ist(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) struct sccnxp_port *s = (struct sccnxp_port *)dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) spin_lock_irqsave(&s->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) sccnxp_handle_events(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) spin_unlock_irqrestore(&s->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) static void sccnxp_start_tx(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) struct sccnxp_port *s = dev_get_drvdata(port->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) spin_lock_irqsave(&s->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) /* Set direction to output */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) if (s->chip->flags & SCCNXP_HAVE_IO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) sccnxp_set_bit(port, DIR_OP, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) sccnxp_enable_irq(port, IMR_TXRDY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) spin_unlock_irqrestore(&s->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) static void sccnxp_stop_tx(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) /* Do nothing */
^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) static void sccnxp_stop_rx(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) struct sccnxp_port *s = dev_get_drvdata(port->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) spin_lock_irqsave(&s->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) sccnxp_port_write(port, SCCNXP_CR_REG, CR_RX_DISABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) spin_unlock_irqrestore(&s->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) static unsigned int sccnxp_tx_empty(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) struct sccnxp_port *s = dev_get_drvdata(port->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) spin_lock_irqsave(&s->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) val = sccnxp_port_read(port, SCCNXP_SR_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) spin_unlock_irqrestore(&s->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) return (val & SR_TXEMT) ? TIOCSER_TEMT : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) static void sccnxp_set_mctrl(struct uart_port *port, unsigned int mctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) struct sccnxp_port *s = dev_get_drvdata(port->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) if (!(s->chip->flags & SCCNXP_HAVE_IO))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) spin_lock_irqsave(&s->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) sccnxp_set_bit(port, DTR_OP, mctrl & TIOCM_DTR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) sccnxp_set_bit(port, RTS_OP, mctrl & TIOCM_RTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) spin_unlock_irqrestore(&s->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) static unsigned int sccnxp_get_mctrl(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) u8 bitmask, ipr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) struct sccnxp_port *s = dev_get_drvdata(port->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) unsigned int mctrl = TIOCM_DSR | TIOCM_CTS | TIOCM_CAR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) if (!(s->chip->flags & SCCNXP_HAVE_IO))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) return mctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) spin_lock_irqsave(&s->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) ipr = ~sccnxp_read(port, SCCNXP_IPCR_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) if (s->pdata.mctrl_cfg[port->line] & MCTRL_MASK(DSR_IP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) bitmask = 1 << MCTRL_IBIT(s->pdata.mctrl_cfg[port->line],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) DSR_IP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) mctrl &= ~TIOCM_DSR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) mctrl |= (ipr & bitmask) ? TIOCM_DSR : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) if (s->pdata.mctrl_cfg[port->line] & MCTRL_MASK(CTS_IP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) bitmask = 1 << MCTRL_IBIT(s->pdata.mctrl_cfg[port->line],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) CTS_IP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) mctrl &= ~TIOCM_CTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) mctrl |= (ipr & bitmask) ? TIOCM_CTS : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) if (s->pdata.mctrl_cfg[port->line] & MCTRL_MASK(DCD_IP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) bitmask = 1 << MCTRL_IBIT(s->pdata.mctrl_cfg[port->line],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) DCD_IP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) mctrl &= ~TIOCM_CAR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) mctrl |= (ipr & bitmask) ? TIOCM_CAR : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) if (s->pdata.mctrl_cfg[port->line] & MCTRL_MASK(RNG_IP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) bitmask = 1 << MCTRL_IBIT(s->pdata.mctrl_cfg[port->line],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) RNG_IP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) mctrl &= ~TIOCM_RNG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) mctrl |= (ipr & bitmask) ? TIOCM_RNG : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) spin_unlock_irqrestore(&s->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) return mctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) static void sccnxp_break_ctl(struct uart_port *port, int break_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) struct sccnxp_port *s = dev_get_drvdata(port->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) spin_lock_irqsave(&s->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) sccnxp_port_write(port, SCCNXP_CR_REG, break_state ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) CR_CMD_START_BREAK : CR_CMD_STOP_BREAK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) spin_unlock_irqrestore(&s->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) static void sccnxp_set_termios(struct uart_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) struct ktermios *termios, struct ktermios *old)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) struct sccnxp_port *s = dev_get_drvdata(port->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) u8 mr1, mr2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) int baud;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) spin_lock_irqsave(&s->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) /* Mask termios capabilities we don't support */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) termios->c_cflag &= ~CMSPAR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) /* Disable RX & TX, reset break condition, status and FIFOs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) sccnxp_port_write(port, SCCNXP_CR_REG, CR_CMD_RX_RESET |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) CR_RX_DISABLE | CR_TX_DISABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) sccnxp_port_write(port, SCCNXP_CR_REG, CR_CMD_TX_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) sccnxp_port_write(port, SCCNXP_CR_REG, CR_CMD_STATUS_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) sccnxp_port_write(port, SCCNXP_CR_REG, CR_CMD_BREAK_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) /* Word size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) switch (termios->c_cflag & CSIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) case CS5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) mr1 = MR1_BITS_5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) case CS6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) mr1 = MR1_BITS_6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) case CS7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) mr1 = MR1_BITS_7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) case CS8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) mr1 = MR1_BITS_8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) /* Parity */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) if (termios->c_cflag & PARENB) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) if (termios->c_cflag & PARODD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) mr1 |= MR1_PAR_ODD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) mr1 |= MR1_PAR_NO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) /* Stop bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) mr2 = (termios->c_cflag & CSTOPB) ? MR2_STOP2 : MR2_STOP1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) /* Update desired format */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) sccnxp_port_write(port, SCCNXP_CR_REG, CR_CMD_MRPTR1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) sccnxp_port_write(port, SCCNXP_MR_REG, mr1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) sccnxp_port_write(port, SCCNXP_MR_REG, mr2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) /* Set read status mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) port->read_status_mask = SR_OVR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) if (termios->c_iflag & INPCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) port->read_status_mask |= SR_PE | SR_FE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) port->read_status_mask |= SR_BRK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) /* Set status ignore mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) port->ignore_status_mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) if (termios->c_iflag & IGNBRK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) port->ignore_status_mask |= SR_BRK;
^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) port->ignore_status_mask |= SR_PE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) if (!(termios->c_cflag & CREAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) port->ignore_status_mask |= SR_PE | SR_OVR | SR_FE | SR_BRK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) /* Setup baudrate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) baud = uart_get_baud_rate(port, termios, old, 50,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) (s->chip->flags & SCCNXP_HAVE_MR0) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 230400 : 38400);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) baud = sccnxp_set_baud(port, baud);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) /* Update timeout according to new baud rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) uart_update_timeout(port, termios->c_cflag, baud);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) /* Report actual baudrate back to core */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) if (tty_termios_baud_rate(termios))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) tty_termios_encode_baud_rate(termios, baud, baud);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) /* Enable RX & TX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) sccnxp_port_write(port, SCCNXP_CR_REG, CR_RX_ENABLE | CR_TX_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) spin_unlock_irqrestore(&s->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) static int sccnxp_startup(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) struct sccnxp_port *s = dev_get_drvdata(port->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) spin_lock_irqsave(&s->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) if (s->chip->flags & SCCNXP_HAVE_IO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) /* Outputs are controlled manually */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) sccnxp_write(port, SCCNXP_OPCR_REG, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) /* Reset break condition, status and FIFOs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) sccnxp_port_write(port, SCCNXP_CR_REG, CR_CMD_RX_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) sccnxp_port_write(port, SCCNXP_CR_REG, CR_CMD_TX_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) sccnxp_port_write(port, SCCNXP_CR_REG, CR_CMD_STATUS_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) sccnxp_port_write(port, SCCNXP_CR_REG, CR_CMD_BREAK_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) /* Enable RX & TX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) sccnxp_port_write(port, SCCNXP_CR_REG, CR_RX_ENABLE | CR_TX_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) /* Enable RX interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) sccnxp_enable_irq(port, IMR_RXRDY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) s->opened[port->line] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) spin_unlock_irqrestore(&s->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) static void sccnxp_shutdown(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) struct sccnxp_port *s = dev_get_drvdata(port->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) spin_lock_irqsave(&s->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) s->opened[port->line] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) /* Disable interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) sccnxp_disable_irq(port, IMR_TXRDY | IMR_RXRDY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) /* Disable TX & RX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) sccnxp_port_write(port, SCCNXP_CR_REG, CR_RX_DISABLE | CR_TX_DISABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) /* Leave direction to input */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) if (s->chip->flags & SCCNXP_HAVE_IO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) sccnxp_set_bit(port, DIR_OP, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) spin_unlock_irqrestore(&s->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) static const char *sccnxp_type(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) struct sccnxp_port *s = dev_get_drvdata(port->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) return (port->type == PORT_SC26XX) ? s->chip->name : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) static void sccnxp_release_port(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) /* Do nothing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) static int sccnxp_request_port(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) /* Do nothing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) static void sccnxp_config_port(struct uart_port *port, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) if (flags & UART_CONFIG_TYPE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) port->type = PORT_SC26XX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) static int sccnxp_verify_port(struct uart_port *port, struct serial_struct *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) if ((s->type == PORT_UNKNOWN) || (s->type == PORT_SC26XX))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) if (s->irq == port->irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) return -EINVAL;
^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 const struct uart_ops sccnxp_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) .tx_empty = sccnxp_tx_empty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) .set_mctrl = sccnxp_set_mctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) .get_mctrl = sccnxp_get_mctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) .stop_tx = sccnxp_stop_tx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) .start_tx = sccnxp_start_tx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) .stop_rx = sccnxp_stop_rx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) .break_ctl = sccnxp_break_ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) .startup = sccnxp_startup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) .shutdown = sccnxp_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) .set_termios = sccnxp_set_termios,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) .type = sccnxp_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) .release_port = sccnxp_release_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) .request_port = sccnxp_request_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) .config_port = sccnxp_config_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) .verify_port = sccnxp_verify_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) #ifdef CONFIG_SERIAL_SCCNXP_CONSOLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) static void sccnxp_console_putchar(struct uart_port *port, int c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) int tryes = 100000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) while (tryes--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) if (sccnxp_port_read(port, SCCNXP_SR_REG) & SR_TXRDY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) sccnxp_port_write(port, SCCNXP_THR_REG, c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) barrier();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) static void sccnxp_console_write(struct console *co, const char *c, unsigned n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) struct sccnxp_port *s = (struct sccnxp_port *)co->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) struct uart_port *port = &s->port[co->index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) spin_lock_irqsave(&s->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) uart_console_write(port, c, n, sccnxp_console_putchar);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) spin_unlock_irqrestore(&s->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) static int sccnxp_console_setup(struct console *co, char *options)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) struct sccnxp_port *s = (struct sccnxp_port *)co->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) struct uart_port *port = &s->port[(co->index > 0) ? co->index : 0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) int baud = 9600, bits = 8, parity = 'n', flow = 'n';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) if (options)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) uart_parse_options(options, &baud, &parity, &bits, &flow);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) return uart_set_options(port, co, baud, parity, bits, flow);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) static const struct platform_device_id sccnxp_id_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) { .name = "sc2681", .driver_data = (kernel_ulong_t)&sc2681, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) { .name = "sc2691", .driver_data = (kernel_ulong_t)&sc2691, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) { .name = "sc2692", .driver_data = (kernel_ulong_t)&sc2692, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) { .name = "sc2891", .driver_data = (kernel_ulong_t)&sc2891, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) { .name = "sc2892", .driver_data = (kernel_ulong_t)&sc2892, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) { .name = "sc28202", .driver_data = (kernel_ulong_t)&sc28202, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) { .name = "sc68681", .driver_data = (kernel_ulong_t)&sc68681, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) { .name = "sc68692", .driver_data = (kernel_ulong_t)&sc68692, },
^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) MODULE_DEVICE_TABLE(platform, sccnxp_id_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) static int sccnxp_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) struct sccnxp_pdata *pdata = dev_get_platdata(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) int i, ret, uartclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) struct sccnxp_port *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) void __iomem *membase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) membase = devm_ioremap_resource(&pdev->dev, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) if (IS_ERR(membase))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) return PTR_ERR(membase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) s = devm_kzalloc(&pdev->dev, sizeof(struct sccnxp_port), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) if (!s) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) dev_err(&pdev->dev, "Error allocating port structure\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) platform_set_drvdata(pdev, s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) spin_lock_init(&s->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) s->chip = (struct sccnxp_chip *)pdev->id_entry->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) s->regulator = devm_regulator_get(&pdev->dev, "vcc");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) if (!IS_ERR(s->regulator)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) ret = regulator_enable(s->regulator);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) dev_err(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) "Failed to enable regulator: %i\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) } else if (PTR_ERR(s->regulator) == -EPROBE_DEFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) return -EPROBE_DEFER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) clk = devm_clk_get(&pdev->dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) if (IS_ERR(clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) ret = PTR_ERR(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) if (ret == -EPROBE_DEFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) uartclk = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) ret = clk_prepare_enable(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) ret = devm_add_action_or_reset(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) (void(*)(void *))clk_disable_unprepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) uartclk = clk_get_rate(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) if (!uartclk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) dev_notice(&pdev->dev, "Using default clock frequency\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) uartclk = s->chip->freq_std;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) /* Check input frequency */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) if ((uartclk < s->chip->freq_min) || (uartclk > s->chip->freq_max)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) dev_err(&pdev->dev, "Frequency out of bounds\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) if (pdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) memcpy(&s->pdata, pdata, sizeof(struct sccnxp_pdata));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) if (s->pdata.poll_time_us) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) dev_info(&pdev->dev, "Using poll mode, resolution %u usecs\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) s->pdata.poll_time_us);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) s->poll = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) if (!s->poll) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) s->irq = platform_get_irq(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) if (s->irq < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) ret = -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) }
^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) s->uart.owner = THIS_MODULE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) s->uart.dev_name = "ttySC";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) s->uart.major = SCCNXP_MAJOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) s->uart.minor = SCCNXP_MINOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) s->uart.nr = s->chip->nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) #ifdef CONFIG_SERIAL_SCCNXP_CONSOLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) s->uart.cons = &s->console;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) s->uart.cons->device = uart_console_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) s->uart.cons->write = sccnxp_console_write;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) s->uart.cons->setup = sccnxp_console_setup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) s->uart.cons->flags = CON_PRINTBUFFER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) s->uart.cons->index = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) s->uart.cons->data = s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) strcpy(s->uart.cons->name, "ttySC");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) ret = uart_register_driver(&s->uart);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) dev_err(&pdev->dev, "Registering UART driver failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) for (i = 0; i < s->uart.nr; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) s->port[i].line = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) s->port[i].dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) s->port[i].irq = s->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) s->port[i].type = PORT_SC26XX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) s->port[i].fifosize = s->chip->fifosize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) s->port[i].flags = UPF_SKIP_TEST | UPF_FIXED_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) s->port[i].iotype = UPIO_MEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) s->port[i].mapbase = res->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) s->port[i].membase = membase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) s->port[i].regshift = s->pdata.reg_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) s->port[i].uartclk = uartclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) s->port[i].ops = &sccnxp_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) s->port[i].has_sysrq = IS_ENABLED(CONFIG_SERIAL_SCCNXP_CONSOLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) uart_add_one_port(&s->uart, &s->port[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) /* Set direction to input */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) if (s->chip->flags & SCCNXP_HAVE_IO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) sccnxp_set_bit(&s->port[i], DIR_OP, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) /* Disable interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) s->imr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) sccnxp_write(&s->port[0], SCCNXP_IMR_REG, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) if (!s->poll) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) ret = devm_request_threaded_irq(&pdev->dev, s->irq, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) sccnxp_ist,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) IRQF_TRIGGER_FALLING |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) IRQF_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) dev_name(&pdev->dev), s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) dev_err(&pdev->dev, "Unable to reguest IRQ %i\n", s->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) timer_setup(&s->timer, sccnxp_timer, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) mod_timer(&s->timer, jiffies +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) usecs_to_jiffies(s->pdata.poll_time_us));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) uart_unregister_driver(&s->uart);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) err_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) if (!IS_ERR(s->regulator))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) regulator_disable(s->regulator);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) static int sccnxp_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) struct sccnxp_port *s = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) if (!s->poll)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) devm_free_irq(&pdev->dev, s->irq, s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) del_timer_sync(&s->timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) for (i = 0; i < s->uart.nr; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) uart_remove_one_port(&s->uart, &s->port[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) uart_unregister_driver(&s->uart);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) if (!IS_ERR(s->regulator))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) return regulator_disable(s->regulator);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) static struct platform_driver sccnxp_uart_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) .name = SCCNXP_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) .probe = sccnxp_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) .remove = sccnxp_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) .id_table = sccnxp_id_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) module_platform_driver(sccnxp_uart_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) MODULE_LICENSE("GPL v2");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) MODULE_AUTHOR("Alexander Shiyan <shc_work@mail.ru>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) MODULE_DESCRIPTION("SCCNXP serial driver");