148a6092fSMaxime Coquelin /* 248a6092fSMaxime Coquelin * Copyright (C) Maxime Coquelin 2015 3*ada8618fSAlexandre TORGUE * Authors: Maxime Coquelin <mcoquelin.stm32@gmail.com> 4*ada8618fSAlexandre TORGUE * Gerald Baeza <gerald.baeza@st.com> 548a6092fSMaxime Coquelin * License terms: GNU General Public License (GPL), version 2 648a6092fSMaxime Coquelin * 748a6092fSMaxime Coquelin * Inspired by st-asc.c from STMicroelectronics (c) 848a6092fSMaxime Coquelin */ 948a6092fSMaxime Coquelin 106b596a83SMaxime Coquelin #if defined(CONFIG_SERIAL_STM32_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) 1148a6092fSMaxime Coquelin #define SUPPORT_SYSRQ 1248a6092fSMaxime Coquelin #endif 1348a6092fSMaxime Coquelin 1448a6092fSMaxime Coquelin #include <linux/module.h> 1548a6092fSMaxime Coquelin #include <linux/serial.h> 1648a6092fSMaxime Coquelin #include <linux/console.h> 1748a6092fSMaxime Coquelin #include <linux/sysrq.h> 1848a6092fSMaxime Coquelin #include <linux/platform_device.h> 1948a6092fSMaxime Coquelin #include <linux/io.h> 2048a6092fSMaxime Coquelin #include <linux/irq.h> 2148a6092fSMaxime Coquelin #include <linux/tty.h> 2248a6092fSMaxime Coquelin #include <linux/tty_flip.h> 2348a6092fSMaxime Coquelin #include <linux/delay.h> 2448a6092fSMaxime Coquelin #include <linux/spinlock.h> 2548a6092fSMaxime Coquelin #include <linux/pm_runtime.h> 2648a6092fSMaxime Coquelin #include <linux/of.h> 2748a6092fSMaxime Coquelin #include <linux/of_platform.h> 2848a6092fSMaxime Coquelin #include <linux/serial_core.h> 2948a6092fSMaxime Coquelin #include <linux/clk.h> 3048a6092fSMaxime Coquelin 3148a6092fSMaxime Coquelin #define DRIVER_NAME "stm32-usart" 3248a6092fSMaxime Coquelin 33*ada8618fSAlexandre TORGUE struct stm32_usart_offsets { 34*ada8618fSAlexandre TORGUE u8 cr1; 35*ada8618fSAlexandre TORGUE u8 cr2; 36*ada8618fSAlexandre TORGUE u8 cr3; 37*ada8618fSAlexandre TORGUE u8 brr; 38*ada8618fSAlexandre TORGUE u8 gtpr; 39*ada8618fSAlexandre TORGUE u8 rtor; 40*ada8618fSAlexandre TORGUE u8 rqr; 41*ada8618fSAlexandre TORGUE u8 isr; 42*ada8618fSAlexandre TORGUE u8 icr; 43*ada8618fSAlexandre TORGUE u8 rdr; 44*ada8618fSAlexandre TORGUE u8 tdr; 45*ada8618fSAlexandre TORGUE }; 4648a6092fSMaxime Coquelin 47*ada8618fSAlexandre TORGUE struct stm32_usart_config { 48*ada8618fSAlexandre TORGUE u8 uart_enable_bit; /* USART_CR1_UE */ 49*ada8618fSAlexandre TORGUE bool has_7bits_data; 50*ada8618fSAlexandre TORGUE }; 51*ada8618fSAlexandre TORGUE 52*ada8618fSAlexandre TORGUE struct stm32_usart_info { 53*ada8618fSAlexandre TORGUE struct stm32_usart_offsets ofs; 54*ada8618fSAlexandre TORGUE struct stm32_usart_config cfg; 55*ada8618fSAlexandre TORGUE }; 56*ada8618fSAlexandre TORGUE 57*ada8618fSAlexandre TORGUE #define UNDEF_REG ~0 58*ada8618fSAlexandre TORGUE 59*ada8618fSAlexandre TORGUE /* Register offsets */ 60*ada8618fSAlexandre TORGUE struct stm32_usart_info stm32f4_info = { 61*ada8618fSAlexandre TORGUE .ofs = { 62*ada8618fSAlexandre TORGUE .isr = 0x00, 63*ada8618fSAlexandre TORGUE .rdr = 0x04, 64*ada8618fSAlexandre TORGUE .tdr = 0x04, 65*ada8618fSAlexandre TORGUE .brr = 0x08, 66*ada8618fSAlexandre TORGUE .cr1 = 0x0c, 67*ada8618fSAlexandre TORGUE .cr2 = 0x10, 68*ada8618fSAlexandre TORGUE .cr3 = 0x14, 69*ada8618fSAlexandre TORGUE .gtpr = 0x18, 70*ada8618fSAlexandre TORGUE .rtor = UNDEF_REG, 71*ada8618fSAlexandre TORGUE .rqr = UNDEF_REG, 72*ada8618fSAlexandre TORGUE .icr = UNDEF_REG, 73*ada8618fSAlexandre TORGUE }, 74*ada8618fSAlexandre TORGUE .cfg = { 75*ada8618fSAlexandre TORGUE .uart_enable_bit = 13, 76*ada8618fSAlexandre TORGUE .has_7bits_data = false, 77*ada8618fSAlexandre TORGUE } 78*ada8618fSAlexandre TORGUE }; 79*ada8618fSAlexandre TORGUE 80*ada8618fSAlexandre TORGUE struct stm32_usart_info stm32f7_info = { 81*ada8618fSAlexandre TORGUE .ofs = { 82*ada8618fSAlexandre TORGUE .cr1 = 0x00, 83*ada8618fSAlexandre TORGUE .cr2 = 0x04, 84*ada8618fSAlexandre TORGUE .cr3 = 0x08, 85*ada8618fSAlexandre TORGUE .brr = 0x0c, 86*ada8618fSAlexandre TORGUE .gtpr = 0x10, 87*ada8618fSAlexandre TORGUE .rtor = 0x14, 88*ada8618fSAlexandre TORGUE .rqr = 0x18, 89*ada8618fSAlexandre TORGUE .isr = 0x1c, 90*ada8618fSAlexandre TORGUE .icr = 0x20, 91*ada8618fSAlexandre TORGUE .rdr = 0x24, 92*ada8618fSAlexandre TORGUE .tdr = 0x28, 93*ada8618fSAlexandre TORGUE }, 94*ada8618fSAlexandre TORGUE .cfg = { 95*ada8618fSAlexandre TORGUE .uart_enable_bit = 0, 96*ada8618fSAlexandre TORGUE .has_7bits_data = true, 97*ada8618fSAlexandre TORGUE } 98*ada8618fSAlexandre TORGUE }; 99*ada8618fSAlexandre TORGUE 100*ada8618fSAlexandre TORGUE /* USART_SR (F4) / USART_ISR (F7) */ 10148a6092fSMaxime Coquelin #define USART_SR_PE BIT(0) 10248a6092fSMaxime Coquelin #define USART_SR_FE BIT(1) 10348a6092fSMaxime Coquelin #define USART_SR_NF BIT(2) 10448a6092fSMaxime Coquelin #define USART_SR_ORE BIT(3) 10548a6092fSMaxime Coquelin #define USART_SR_IDLE BIT(4) 10648a6092fSMaxime Coquelin #define USART_SR_RXNE BIT(5) 10748a6092fSMaxime Coquelin #define USART_SR_TC BIT(6) 10848a6092fSMaxime Coquelin #define USART_SR_TXE BIT(7) 10948a6092fSMaxime Coquelin #define USART_SR_LBD BIT(8) 110*ada8618fSAlexandre TORGUE #define USART_SR_CTSIF BIT(9) 111*ada8618fSAlexandre TORGUE #define USART_SR_CTS BIT(10) /* F7 */ 112*ada8618fSAlexandre TORGUE #define USART_SR_RTOF BIT(11) /* F7 */ 113*ada8618fSAlexandre TORGUE #define USART_SR_EOBF BIT(12) /* F7 */ 114*ada8618fSAlexandre TORGUE #define USART_SR_ABRE BIT(14) /* F7 */ 115*ada8618fSAlexandre TORGUE #define USART_SR_ABRF BIT(15) /* F7 */ 116*ada8618fSAlexandre TORGUE #define USART_SR_BUSY BIT(16) /* F7 */ 117*ada8618fSAlexandre TORGUE #define USART_SR_CMF BIT(17) /* F7 */ 118*ada8618fSAlexandre TORGUE #define USART_SR_SBKF BIT(18) /* F7 */ 119*ada8618fSAlexandre TORGUE #define USART_SR_TEACK BIT(21) /* F7 */ 12048a6092fSMaxime Coquelin #define USART_SR_ERR_MASK (USART_SR_LBD | USART_SR_ORE | \ 12148a6092fSMaxime Coquelin USART_SR_FE | USART_SR_PE) 12248a6092fSMaxime Coquelin /* Dummy bits */ 12348a6092fSMaxime Coquelin #define USART_SR_DUMMY_RX BIT(16) 12448a6092fSMaxime Coquelin 12548a6092fSMaxime Coquelin /* USART_DR */ 12648a6092fSMaxime Coquelin #define USART_DR_MASK GENMASK(8, 0) 12748a6092fSMaxime Coquelin 12848a6092fSMaxime Coquelin /* USART_BRR */ 12948a6092fSMaxime Coquelin #define USART_BRR_DIV_F_MASK GENMASK(3, 0) 13048a6092fSMaxime Coquelin #define USART_BRR_DIV_M_MASK GENMASK(15, 4) 13148a6092fSMaxime Coquelin #define USART_BRR_DIV_M_SHIFT 4 13248a6092fSMaxime Coquelin 13348a6092fSMaxime Coquelin /* USART_CR1 */ 13448a6092fSMaxime Coquelin #define USART_CR1_SBK BIT(0) 135*ada8618fSAlexandre TORGUE #define USART_CR1_RWU BIT(1) /* F4 */ 13648a6092fSMaxime Coquelin #define USART_CR1_RE BIT(2) 13748a6092fSMaxime Coquelin #define USART_CR1_TE BIT(3) 13848a6092fSMaxime Coquelin #define USART_CR1_IDLEIE BIT(4) 13948a6092fSMaxime Coquelin #define USART_CR1_RXNEIE BIT(5) 14048a6092fSMaxime Coquelin #define USART_CR1_TCIE BIT(6) 14148a6092fSMaxime Coquelin #define USART_CR1_TXEIE BIT(7) 14248a6092fSMaxime Coquelin #define USART_CR1_PEIE BIT(8) 14348a6092fSMaxime Coquelin #define USART_CR1_PS BIT(9) 14448a6092fSMaxime Coquelin #define USART_CR1_PCE BIT(10) 14548a6092fSMaxime Coquelin #define USART_CR1_WAKE BIT(11) 14648a6092fSMaxime Coquelin #define USART_CR1_M BIT(12) 147*ada8618fSAlexandre TORGUE #define USART_CR1_M0 BIT(12) /* F7 */ 148*ada8618fSAlexandre TORGUE #define USART_CR1_MME BIT(13) /* F7 */ 149*ada8618fSAlexandre TORGUE #define USART_CR1_CMIE BIT(14) /* F7 */ 15048a6092fSMaxime Coquelin #define USART_CR1_OVER8 BIT(15) 151*ada8618fSAlexandre TORGUE #define USART_CR1_DEDT_MASK GENMASK(20, 16) /* F7 */ 152*ada8618fSAlexandre TORGUE #define USART_CR1_DEAT_MASK GENMASK(25, 21) /* F7 */ 153*ada8618fSAlexandre TORGUE #define USART_CR1_RTOIE BIT(26) /* F7 */ 154*ada8618fSAlexandre TORGUE #define USART_CR1_EOBIE BIT(27) /* F7 */ 155*ada8618fSAlexandre TORGUE #define USART_CR1_M1 BIT(28) /* F7 */ 156*ada8618fSAlexandre TORGUE #define USART_CR1_IE_MASK (GENMASK(8, 4) | BIT(14) | BIT(26) | BIT(27)) 15748a6092fSMaxime Coquelin 15848a6092fSMaxime Coquelin /* USART_CR2 */ 159*ada8618fSAlexandre TORGUE #define USART_CR2_ADD_MASK GENMASK(3, 0) /* F4 */ 160*ada8618fSAlexandre TORGUE #define USART_CR2_ADDM7 BIT(4) /* F7 */ 16148a6092fSMaxime Coquelin #define USART_CR2_LBDL BIT(5) 16248a6092fSMaxime Coquelin #define USART_CR2_LBDIE BIT(6) 16348a6092fSMaxime Coquelin #define USART_CR2_LBCL BIT(8) 16448a6092fSMaxime Coquelin #define USART_CR2_CPHA BIT(9) 16548a6092fSMaxime Coquelin #define USART_CR2_CPOL BIT(10) 16648a6092fSMaxime Coquelin #define USART_CR2_CLKEN BIT(11) 16748a6092fSMaxime Coquelin #define USART_CR2_STOP_2B BIT(13) 16848a6092fSMaxime Coquelin #define USART_CR2_STOP_MASK GENMASK(13, 12) 16948a6092fSMaxime Coquelin #define USART_CR2_LINEN BIT(14) 170*ada8618fSAlexandre TORGUE #define USART_CR2_SWAP BIT(15) /* F7 */ 171*ada8618fSAlexandre TORGUE #define USART_CR2_RXINV BIT(16) /* F7 */ 172*ada8618fSAlexandre TORGUE #define USART_CR2_TXINV BIT(17) /* F7 */ 173*ada8618fSAlexandre TORGUE #define USART_CR2_DATAINV BIT(18) /* F7 */ 174*ada8618fSAlexandre TORGUE #define USART_CR2_MSBFIRST BIT(19) /* F7 */ 175*ada8618fSAlexandre TORGUE #define USART_CR2_ABREN BIT(20) /* F7 */ 176*ada8618fSAlexandre TORGUE #define USART_CR2_ABRMOD_MASK GENMASK(22, 21) /* F7 */ 177*ada8618fSAlexandre TORGUE #define USART_CR2_RTOEN BIT(23) /* F7 */ 178*ada8618fSAlexandre TORGUE #define USART_CR2_ADD_F7_MASK GENMASK(31, 24) /* F7 */ 17948a6092fSMaxime Coquelin 18048a6092fSMaxime Coquelin /* USART_CR3 */ 18148a6092fSMaxime Coquelin #define USART_CR3_EIE BIT(0) 18248a6092fSMaxime Coquelin #define USART_CR3_IREN BIT(1) 18348a6092fSMaxime Coquelin #define USART_CR3_IRLP BIT(2) 18448a6092fSMaxime Coquelin #define USART_CR3_HDSEL BIT(3) 18548a6092fSMaxime Coquelin #define USART_CR3_NACK BIT(4) 18648a6092fSMaxime Coquelin #define USART_CR3_SCEN BIT(5) 18748a6092fSMaxime Coquelin #define USART_CR3_DMAR BIT(6) 18848a6092fSMaxime Coquelin #define USART_CR3_DMAT BIT(7) 18948a6092fSMaxime Coquelin #define USART_CR3_RTSE BIT(8) 19048a6092fSMaxime Coquelin #define USART_CR3_CTSE BIT(9) 19148a6092fSMaxime Coquelin #define USART_CR3_CTSIE BIT(10) 19248a6092fSMaxime Coquelin #define USART_CR3_ONEBIT BIT(11) 193*ada8618fSAlexandre TORGUE #define USART_CR3_OVRDIS BIT(12) /* F7 */ 194*ada8618fSAlexandre TORGUE #define USART_CR3_DDRE BIT(13) /* F7 */ 195*ada8618fSAlexandre TORGUE #define USART_CR3_DEM BIT(14) /* F7 */ 196*ada8618fSAlexandre TORGUE #define USART_CR3_DEP BIT(15) /* F7 */ 197*ada8618fSAlexandre TORGUE #define USART_CR3_SCARCNT_MASK GENMASK(19, 17) /* F7 */ 19848a6092fSMaxime Coquelin 19948a6092fSMaxime Coquelin /* USART_GTPR */ 20048a6092fSMaxime Coquelin #define USART_GTPR_PSC_MASK GENMASK(7, 0) 20148a6092fSMaxime Coquelin #define USART_GTPR_GT_MASK GENMASK(15, 8) 20248a6092fSMaxime Coquelin 203*ada8618fSAlexandre TORGUE /* USART_RTOR */ 204*ada8618fSAlexandre TORGUE #define USART_RTOR_RTO_MASK GENMASK(23, 0) /* F7 */ 205*ada8618fSAlexandre TORGUE #define USART_RTOR_BLEN_MASK GENMASK(31, 24) /* F7 */ 206*ada8618fSAlexandre TORGUE 207*ada8618fSAlexandre TORGUE /* USART_RQR */ 208*ada8618fSAlexandre TORGUE #define USART_RQR_ABRRQ BIT(0) /* F7 */ 209*ada8618fSAlexandre TORGUE #define USART_RQR_SBKRQ BIT(1) /* F7 */ 210*ada8618fSAlexandre TORGUE #define USART_RQR_MMRQ BIT(2) /* F7 */ 211*ada8618fSAlexandre TORGUE #define USART_RQR_RXFRQ BIT(3) /* F7 */ 212*ada8618fSAlexandre TORGUE #define USART_RQR_TXFRQ BIT(4) /* F7 */ 213*ada8618fSAlexandre TORGUE 214*ada8618fSAlexandre TORGUE /* USART_ICR */ 215*ada8618fSAlexandre TORGUE #define USART_ICR_PECF BIT(0) /* F7 */ 216*ada8618fSAlexandre TORGUE #define USART_ICR_FFECF BIT(1) /* F7 */ 217*ada8618fSAlexandre TORGUE #define USART_ICR_NCF BIT(2) /* F7 */ 218*ada8618fSAlexandre TORGUE #define USART_ICR_ORECF BIT(3) /* F7 */ 219*ada8618fSAlexandre TORGUE #define USART_ICR_IDLECF BIT(4) /* F7 */ 220*ada8618fSAlexandre TORGUE #define USART_ICR_TCCF BIT(6) /* F7 */ 221*ada8618fSAlexandre TORGUE #define USART_ICR_LBDCF BIT(8) /* F7 */ 222*ada8618fSAlexandre TORGUE #define USART_ICR_CTSCF BIT(9) /* F7 */ 223*ada8618fSAlexandre TORGUE #define USART_ICR_RTOCF BIT(11) /* F7 */ 224*ada8618fSAlexandre TORGUE #define USART_ICR_EOBCF BIT(12) /* F7 */ 225*ada8618fSAlexandre TORGUE #define USART_ICR_CMCF BIT(17) /* F7 */ 226*ada8618fSAlexandre TORGUE 22748a6092fSMaxime Coquelin #define STM32_SERIAL_NAME "ttyS" 22848a6092fSMaxime Coquelin #define STM32_MAX_PORTS 6 22948a6092fSMaxime Coquelin 23048a6092fSMaxime Coquelin struct stm32_port { 23148a6092fSMaxime Coquelin struct uart_port port; 23248a6092fSMaxime Coquelin struct clk *clk; 233*ada8618fSAlexandre TORGUE struct stm32_usart_info *info; 23448a6092fSMaxime Coquelin bool hw_flow_control; 23548a6092fSMaxime Coquelin }; 23648a6092fSMaxime Coquelin 23748a6092fSMaxime Coquelin static struct stm32_port stm32_ports[STM32_MAX_PORTS]; 23848a6092fSMaxime Coquelin static struct uart_driver stm32_usart_driver; 23948a6092fSMaxime Coquelin 24048a6092fSMaxime Coquelin static void stm32_stop_tx(struct uart_port *port); 24148a6092fSMaxime Coquelin 24248a6092fSMaxime Coquelin static inline struct stm32_port *to_stm32_port(struct uart_port *port) 24348a6092fSMaxime Coquelin { 24448a6092fSMaxime Coquelin return container_of(port, struct stm32_port, port); 24548a6092fSMaxime Coquelin } 24648a6092fSMaxime Coquelin 24748a6092fSMaxime Coquelin static void stm32_set_bits(struct uart_port *port, u32 reg, u32 bits) 24848a6092fSMaxime Coquelin { 24948a6092fSMaxime Coquelin u32 val; 25048a6092fSMaxime Coquelin 25148a6092fSMaxime Coquelin val = readl_relaxed(port->membase + reg); 25248a6092fSMaxime Coquelin val |= bits; 25348a6092fSMaxime Coquelin writel_relaxed(val, port->membase + reg); 25448a6092fSMaxime Coquelin } 25548a6092fSMaxime Coquelin 25648a6092fSMaxime Coquelin static void stm32_clr_bits(struct uart_port *port, u32 reg, u32 bits) 25748a6092fSMaxime Coquelin { 25848a6092fSMaxime Coquelin u32 val; 25948a6092fSMaxime Coquelin 26048a6092fSMaxime Coquelin val = readl_relaxed(port->membase + reg); 26148a6092fSMaxime Coquelin val &= ~bits; 26248a6092fSMaxime Coquelin writel_relaxed(val, port->membase + reg); 26348a6092fSMaxime Coquelin } 26448a6092fSMaxime Coquelin 26548a6092fSMaxime Coquelin static void stm32_receive_chars(struct uart_port *port) 26648a6092fSMaxime Coquelin { 26748a6092fSMaxime Coquelin struct tty_port *tport = &port->state->port; 268*ada8618fSAlexandre TORGUE struct stm32_port *stm32_port = to_stm32_port(port); 269*ada8618fSAlexandre TORGUE struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; 27048a6092fSMaxime Coquelin unsigned long c; 27148a6092fSMaxime Coquelin u32 sr; 27248a6092fSMaxime Coquelin char flag; 27348a6092fSMaxime Coquelin 27448a6092fSMaxime Coquelin if (port->irq_wake) 27548a6092fSMaxime Coquelin pm_wakeup_event(tport->tty->dev, 0); 27648a6092fSMaxime Coquelin 277*ada8618fSAlexandre TORGUE while ((sr = readl_relaxed(port->membase + ofs->isr)) & USART_SR_RXNE) { 27848a6092fSMaxime Coquelin sr |= USART_SR_DUMMY_RX; 279*ada8618fSAlexandre TORGUE c = readl_relaxed(port->membase + ofs->rdr); 28048a6092fSMaxime Coquelin flag = TTY_NORMAL; 28148a6092fSMaxime Coquelin port->icount.rx++; 28248a6092fSMaxime Coquelin 28348a6092fSMaxime Coquelin if (sr & USART_SR_ERR_MASK) { 28448a6092fSMaxime Coquelin if (sr & USART_SR_LBD) { 28548a6092fSMaxime Coquelin port->icount.brk++; 28648a6092fSMaxime Coquelin if (uart_handle_break(port)) 28748a6092fSMaxime Coquelin continue; 28848a6092fSMaxime Coquelin } else if (sr & USART_SR_ORE) { 289*ada8618fSAlexandre TORGUE if (ofs->icr != UNDEF_REG) 290*ada8618fSAlexandre TORGUE writel_relaxed(USART_ICR_ORECF, 291*ada8618fSAlexandre TORGUE port->membase + 292*ada8618fSAlexandre TORGUE ofs->icr); 29348a6092fSMaxime Coquelin port->icount.overrun++; 29448a6092fSMaxime Coquelin } else if (sr & USART_SR_PE) { 29548a6092fSMaxime Coquelin port->icount.parity++; 29648a6092fSMaxime Coquelin } else if (sr & USART_SR_FE) { 29748a6092fSMaxime Coquelin port->icount.frame++; 29848a6092fSMaxime Coquelin } 29948a6092fSMaxime Coquelin 30048a6092fSMaxime Coquelin sr &= port->read_status_mask; 30148a6092fSMaxime Coquelin 30248a6092fSMaxime Coquelin if (sr & USART_SR_LBD) 30348a6092fSMaxime Coquelin flag = TTY_BREAK; 30448a6092fSMaxime Coquelin else if (sr & USART_SR_PE) 30548a6092fSMaxime Coquelin flag = TTY_PARITY; 30648a6092fSMaxime Coquelin else if (sr & USART_SR_FE) 30748a6092fSMaxime Coquelin flag = TTY_FRAME; 30848a6092fSMaxime Coquelin } 30948a6092fSMaxime Coquelin 31048a6092fSMaxime Coquelin if (uart_handle_sysrq_char(port, c)) 31148a6092fSMaxime Coquelin continue; 31248a6092fSMaxime Coquelin uart_insert_char(port, sr, USART_SR_ORE, c, flag); 31348a6092fSMaxime Coquelin } 31448a6092fSMaxime Coquelin 31548a6092fSMaxime Coquelin spin_unlock(&port->lock); 31648a6092fSMaxime Coquelin tty_flip_buffer_push(tport); 31748a6092fSMaxime Coquelin spin_lock(&port->lock); 31848a6092fSMaxime Coquelin } 31948a6092fSMaxime Coquelin 32048a6092fSMaxime Coquelin static void stm32_transmit_chars(struct uart_port *port) 32148a6092fSMaxime Coquelin { 322*ada8618fSAlexandre TORGUE struct stm32_port *stm32_port = to_stm32_port(port); 323*ada8618fSAlexandre TORGUE struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; 32448a6092fSMaxime Coquelin struct circ_buf *xmit = &port->state->xmit; 32548a6092fSMaxime Coquelin 32648a6092fSMaxime Coquelin if (port->x_char) { 327*ada8618fSAlexandre TORGUE writel_relaxed(port->x_char, port->membase + ofs->tdr); 32848a6092fSMaxime Coquelin port->x_char = 0; 32948a6092fSMaxime Coquelin port->icount.tx++; 33048a6092fSMaxime Coquelin return; 33148a6092fSMaxime Coquelin } 33248a6092fSMaxime Coquelin 33348a6092fSMaxime Coquelin if (uart_tx_stopped(port)) { 33448a6092fSMaxime Coquelin stm32_stop_tx(port); 33548a6092fSMaxime Coquelin return; 33648a6092fSMaxime Coquelin } 33748a6092fSMaxime Coquelin 33848a6092fSMaxime Coquelin if (uart_circ_empty(xmit)) { 33948a6092fSMaxime Coquelin stm32_stop_tx(port); 34048a6092fSMaxime Coquelin return; 34148a6092fSMaxime Coquelin } 34248a6092fSMaxime Coquelin 343*ada8618fSAlexandre TORGUE writel_relaxed(xmit->buf[xmit->tail], port->membase + ofs->tdr); 34448a6092fSMaxime Coquelin xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); 34548a6092fSMaxime Coquelin port->icount.tx++; 34648a6092fSMaxime Coquelin 34748a6092fSMaxime Coquelin if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) 34848a6092fSMaxime Coquelin uart_write_wakeup(port); 34948a6092fSMaxime Coquelin 35048a6092fSMaxime Coquelin if (uart_circ_empty(xmit)) 35148a6092fSMaxime Coquelin stm32_stop_tx(port); 35248a6092fSMaxime Coquelin } 35348a6092fSMaxime Coquelin 35448a6092fSMaxime Coquelin static irqreturn_t stm32_interrupt(int irq, void *ptr) 35548a6092fSMaxime Coquelin { 35648a6092fSMaxime Coquelin struct uart_port *port = ptr; 357*ada8618fSAlexandre TORGUE struct stm32_port *stm32_port = to_stm32_port(port); 358*ada8618fSAlexandre TORGUE struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; 35948a6092fSMaxime Coquelin u32 sr; 36048a6092fSMaxime Coquelin 36148a6092fSMaxime Coquelin spin_lock(&port->lock); 36248a6092fSMaxime Coquelin 363*ada8618fSAlexandre TORGUE sr = readl_relaxed(port->membase + ofs->isr); 36448a6092fSMaxime Coquelin 36548a6092fSMaxime Coquelin if (sr & USART_SR_RXNE) 36648a6092fSMaxime Coquelin stm32_receive_chars(port); 36748a6092fSMaxime Coquelin 36848a6092fSMaxime Coquelin if (sr & USART_SR_TXE) 36948a6092fSMaxime Coquelin stm32_transmit_chars(port); 37048a6092fSMaxime Coquelin 37148a6092fSMaxime Coquelin spin_unlock(&port->lock); 37248a6092fSMaxime Coquelin 37348a6092fSMaxime Coquelin return IRQ_HANDLED; 37448a6092fSMaxime Coquelin } 37548a6092fSMaxime Coquelin 37648a6092fSMaxime Coquelin static unsigned int stm32_tx_empty(struct uart_port *port) 37748a6092fSMaxime Coquelin { 378*ada8618fSAlexandre TORGUE struct stm32_port *stm32_port = to_stm32_port(port); 379*ada8618fSAlexandre TORGUE struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; 380*ada8618fSAlexandre TORGUE 381*ada8618fSAlexandre TORGUE return readl_relaxed(port->membase + ofs->isr) & USART_SR_TXE; 38248a6092fSMaxime Coquelin } 38348a6092fSMaxime Coquelin 38448a6092fSMaxime Coquelin static void stm32_set_mctrl(struct uart_port *port, unsigned int mctrl) 38548a6092fSMaxime Coquelin { 386*ada8618fSAlexandre TORGUE struct stm32_port *stm32_port = to_stm32_port(port); 387*ada8618fSAlexandre TORGUE struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; 388*ada8618fSAlexandre TORGUE 38948a6092fSMaxime Coquelin if ((mctrl & TIOCM_RTS) && (port->status & UPSTAT_AUTORTS)) 390*ada8618fSAlexandre TORGUE stm32_set_bits(port, ofs->cr3, USART_CR3_RTSE); 39148a6092fSMaxime Coquelin else 392*ada8618fSAlexandre TORGUE stm32_clr_bits(port, ofs->cr3, USART_CR3_RTSE); 39348a6092fSMaxime Coquelin } 39448a6092fSMaxime Coquelin 39548a6092fSMaxime Coquelin static unsigned int stm32_get_mctrl(struct uart_port *port) 39648a6092fSMaxime Coquelin { 39748a6092fSMaxime Coquelin /* This routine is used to get signals of: DCD, DSR, RI, and CTS */ 39848a6092fSMaxime Coquelin return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS; 39948a6092fSMaxime Coquelin } 40048a6092fSMaxime Coquelin 40148a6092fSMaxime Coquelin /* Transmit stop */ 40248a6092fSMaxime Coquelin static void stm32_stop_tx(struct uart_port *port) 40348a6092fSMaxime Coquelin { 404*ada8618fSAlexandre TORGUE struct stm32_port *stm32_port = to_stm32_port(port); 405*ada8618fSAlexandre TORGUE struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; 406*ada8618fSAlexandre TORGUE 407*ada8618fSAlexandre TORGUE stm32_clr_bits(port, ofs->cr1, USART_CR1_TXEIE); 40848a6092fSMaxime Coquelin } 40948a6092fSMaxime Coquelin 41048a6092fSMaxime Coquelin /* There are probably characters waiting to be transmitted. */ 41148a6092fSMaxime Coquelin static void stm32_start_tx(struct uart_port *port) 41248a6092fSMaxime Coquelin { 413*ada8618fSAlexandre TORGUE struct stm32_port *stm32_port = to_stm32_port(port); 414*ada8618fSAlexandre TORGUE struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; 41548a6092fSMaxime Coquelin struct circ_buf *xmit = &port->state->xmit; 41648a6092fSMaxime Coquelin 41748a6092fSMaxime Coquelin if (uart_circ_empty(xmit)) 41848a6092fSMaxime Coquelin return; 41948a6092fSMaxime Coquelin 420*ada8618fSAlexandre TORGUE stm32_set_bits(port, ofs->cr1, USART_CR1_TXEIE | USART_CR1_TE); 42148a6092fSMaxime Coquelin } 42248a6092fSMaxime Coquelin 42348a6092fSMaxime Coquelin /* Throttle the remote when input buffer is about to overflow. */ 42448a6092fSMaxime Coquelin static void stm32_throttle(struct uart_port *port) 42548a6092fSMaxime Coquelin { 426*ada8618fSAlexandre TORGUE struct stm32_port *stm32_port = to_stm32_port(port); 427*ada8618fSAlexandre TORGUE struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; 42848a6092fSMaxime Coquelin unsigned long flags; 42948a6092fSMaxime Coquelin 43048a6092fSMaxime Coquelin spin_lock_irqsave(&port->lock, flags); 431*ada8618fSAlexandre TORGUE stm32_clr_bits(port, ofs->cr1, USART_CR1_RXNEIE); 43248a6092fSMaxime Coquelin spin_unlock_irqrestore(&port->lock, flags); 43348a6092fSMaxime Coquelin } 43448a6092fSMaxime Coquelin 43548a6092fSMaxime Coquelin /* Unthrottle the remote, the input buffer can now accept data. */ 43648a6092fSMaxime Coquelin static void stm32_unthrottle(struct uart_port *port) 43748a6092fSMaxime Coquelin { 438*ada8618fSAlexandre TORGUE struct stm32_port *stm32_port = to_stm32_port(port); 439*ada8618fSAlexandre TORGUE struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; 44048a6092fSMaxime Coquelin unsigned long flags; 44148a6092fSMaxime Coquelin 44248a6092fSMaxime Coquelin spin_lock_irqsave(&port->lock, flags); 443*ada8618fSAlexandre TORGUE stm32_set_bits(port, ofs->cr1, USART_CR1_RXNEIE); 44448a6092fSMaxime Coquelin spin_unlock_irqrestore(&port->lock, flags); 44548a6092fSMaxime Coquelin } 44648a6092fSMaxime Coquelin 44748a6092fSMaxime Coquelin /* Receive stop */ 44848a6092fSMaxime Coquelin static void stm32_stop_rx(struct uart_port *port) 44948a6092fSMaxime Coquelin { 450*ada8618fSAlexandre TORGUE struct stm32_port *stm32_port = to_stm32_port(port); 451*ada8618fSAlexandre TORGUE struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; 452*ada8618fSAlexandre TORGUE 453*ada8618fSAlexandre TORGUE stm32_clr_bits(port, ofs->cr1, USART_CR1_RXNEIE); 45448a6092fSMaxime Coquelin } 45548a6092fSMaxime Coquelin 45648a6092fSMaxime Coquelin /* Handle breaks - ignored by us */ 45748a6092fSMaxime Coquelin static void stm32_break_ctl(struct uart_port *port, int break_state) 45848a6092fSMaxime Coquelin { 45948a6092fSMaxime Coquelin } 46048a6092fSMaxime Coquelin 46148a6092fSMaxime Coquelin static int stm32_startup(struct uart_port *port) 46248a6092fSMaxime Coquelin { 463*ada8618fSAlexandre TORGUE struct stm32_port *stm32_port = to_stm32_port(port); 464*ada8618fSAlexandre TORGUE struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; 46548a6092fSMaxime Coquelin const char *name = to_platform_device(port->dev)->name; 46648a6092fSMaxime Coquelin u32 val; 46748a6092fSMaxime Coquelin int ret; 46848a6092fSMaxime Coquelin 469616ea8d2SSudeep Holla ret = request_irq(port->irq, stm32_interrupt, 0, name, port); 47048a6092fSMaxime Coquelin if (ret) 47148a6092fSMaxime Coquelin return ret; 47248a6092fSMaxime Coquelin 47348a6092fSMaxime Coquelin val = USART_CR1_RXNEIE | USART_CR1_TE | USART_CR1_RE; 474*ada8618fSAlexandre TORGUE stm32_set_bits(port, ofs->cr1, val); 47548a6092fSMaxime Coquelin 47648a6092fSMaxime Coquelin return 0; 47748a6092fSMaxime Coquelin } 47848a6092fSMaxime Coquelin 47948a6092fSMaxime Coquelin static void stm32_shutdown(struct uart_port *port) 48048a6092fSMaxime Coquelin { 481*ada8618fSAlexandre TORGUE struct stm32_port *stm32_port = to_stm32_port(port); 482*ada8618fSAlexandre TORGUE struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; 48348a6092fSMaxime Coquelin u32 val; 48448a6092fSMaxime Coquelin 48548a6092fSMaxime Coquelin val = USART_CR1_TXEIE | USART_CR1_RXNEIE | USART_CR1_TE | USART_CR1_RE; 486*ada8618fSAlexandre TORGUE stm32_set_bits(port, ofs->cr1, val); 48748a6092fSMaxime Coquelin 48848a6092fSMaxime Coquelin free_irq(port->irq, port); 48948a6092fSMaxime Coquelin } 49048a6092fSMaxime Coquelin 49148a6092fSMaxime Coquelin static void stm32_set_termios(struct uart_port *port, struct ktermios *termios, 49248a6092fSMaxime Coquelin struct ktermios *old) 49348a6092fSMaxime Coquelin { 49448a6092fSMaxime Coquelin struct stm32_port *stm32_port = to_stm32_port(port); 495*ada8618fSAlexandre TORGUE struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; 496*ada8618fSAlexandre TORGUE struct stm32_usart_config *cfg = &stm32_port->info->cfg; 49748a6092fSMaxime Coquelin unsigned int baud; 49848a6092fSMaxime Coquelin u32 usartdiv, mantissa, fraction, oversampling; 49948a6092fSMaxime Coquelin tcflag_t cflag = termios->c_cflag; 50048a6092fSMaxime Coquelin u32 cr1, cr2, cr3; 50148a6092fSMaxime Coquelin unsigned long flags; 50248a6092fSMaxime Coquelin 50348a6092fSMaxime Coquelin if (!stm32_port->hw_flow_control) 50448a6092fSMaxime Coquelin cflag &= ~CRTSCTS; 50548a6092fSMaxime Coquelin 50648a6092fSMaxime Coquelin baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 8); 50748a6092fSMaxime Coquelin 50848a6092fSMaxime Coquelin spin_lock_irqsave(&port->lock, flags); 50948a6092fSMaxime Coquelin 51048a6092fSMaxime Coquelin /* Stop serial port and reset value */ 511*ada8618fSAlexandre TORGUE writel_relaxed(0, port->membase + ofs->cr1); 51248a6092fSMaxime Coquelin 513*ada8618fSAlexandre TORGUE cr1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_RXNEIE; 514*ada8618fSAlexandre TORGUE cr1 |= BIT(cfg->uart_enable_bit); 51548a6092fSMaxime Coquelin cr2 = 0; 51648a6092fSMaxime Coquelin cr3 = 0; 51748a6092fSMaxime Coquelin 51848a6092fSMaxime Coquelin if (cflag & CSTOPB) 51948a6092fSMaxime Coquelin cr2 |= USART_CR2_STOP_2B; 52048a6092fSMaxime Coquelin 52148a6092fSMaxime Coquelin if (cflag & PARENB) { 52248a6092fSMaxime Coquelin cr1 |= USART_CR1_PCE; 523*ada8618fSAlexandre TORGUE if ((cflag & CSIZE) == CS8) { 524*ada8618fSAlexandre TORGUE if (cfg->has_7bits_data) 525*ada8618fSAlexandre TORGUE cr1 |= USART_CR1_M0; 526*ada8618fSAlexandre TORGUE else 52748a6092fSMaxime Coquelin cr1 |= USART_CR1_M; 52848a6092fSMaxime Coquelin } 529*ada8618fSAlexandre TORGUE } 53048a6092fSMaxime Coquelin 53148a6092fSMaxime Coquelin if (cflag & PARODD) 53248a6092fSMaxime Coquelin cr1 |= USART_CR1_PS; 53348a6092fSMaxime Coquelin 53448a6092fSMaxime Coquelin port->status &= ~(UPSTAT_AUTOCTS | UPSTAT_AUTORTS); 53548a6092fSMaxime Coquelin if (cflag & CRTSCTS) { 53648a6092fSMaxime Coquelin port->status |= UPSTAT_AUTOCTS | UPSTAT_AUTORTS; 53748a6092fSMaxime Coquelin cr3 |= USART_CR3_CTSE; 53848a6092fSMaxime Coquelin } 53948a6092fSMaxime Coquelin 54048a6092fSMaxime Coquelin usartdiv = DIV_ROUND_CLOSEST(port->uartclk, baud); 54148a6092fSMaxime Coquelin 54248a6092fSMaxime Coquelin /* 54348a6092fSMaxime Coquelin * The USART supports 16 or 8 times oversampling. 54448a6092fSMaxime Coquelin * By default we prefer 16 times oversampling, so that the receiver 54548a6092fSMaxime Coquelin * has a better tolerance to clock deviations. 54648a6092fSMaxime Coquelin * 8 times oversampling is only used to achieve higher speeds. 54748a6092fSMaxime Coquelin */ 54848a6092fSMaxime Coquelin if (usartdiv < 16) { 54948a6092fSMaxime Coquelin oversampling = 8; 550*ada8618fSAlexandre TORGUE stm32_set_bits(port, ofs->cr1, USART_CR1_OVER8); 55148a6092fSMaxime Coquelin } else { 55248a6092fSMaxime Coquelin oversampling = 16; 553*ada8618fSAlexandre TORGUE stm32_clr_bits(port, ofs->cr1, USART_CR1_OVER8); 55448a6092fSMaxime Coquelin } 55548a6092fSMaxime Coquelin 55648a6092fSMaxime Coquelin mantissa = (usartdiv / oversampling) << USART_BRR_DIV_M_SHIFT; 55748a6092fSMaxime Coquelin fraction = usartdiv % oversampling; 558*ada8618fSAlexandre TORGUE writel_relaxed(mantissa | fraction, port->membase + ofs->brr); 55948a6092fSMaxime Coquelin 56048a6092fSMaxime Coquelin uart_update_timeout(port, cflag, baud); 56148a6092fSMaxime Coquelin 56248a6092fSMaxime Coquelin port->read_status_mask = USART_SR_ORE; 56348a6092fSMaxime Coquelin if (termios->c_iflag & INPCK) 56448a6092fSMaxime Coquelin port->read_status_mask |= USART_SR_PE | USART_SR_FE; 56548a6092fSMaxime Coquelin if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK)) 56648a6092fSMaxime Coquelin port->read_status_mask |= USART_SR_LBD; 56748a6092fSMaxime Coquelin 56848a6092fSMaxime Coquelin /* Characters to ignore */ 56948a6092fSMaxime Coquelin port->ignore_status_mask = 0; 57048a6092fSMaxime Coquelin if (termios->c_iflag & IGNPAR) 57148a6092fSMaxime Coquelin port->ignore_status_mask = USART_SR_PE | USART_SR_FE; 57248a6092fSMaxime Coquelin if (termios->c_iflag & IGNBRK) { 57348a6092fSMaxime Coquelin port->ignore_status_mask |= USART_SR_LBD; 57448a6092fSMaxime Coquelin /* 57548a6092fSMaxime Coquelin * If we're ignoring parity and break indicators, 57648a6092fSMaxime Coquelin * ignore overruns too (for real raw support). 57748a6092fSMaxime Coquelin */ 57848a6092fSMaxime Coquelin if (termios->c_iflag & IGNPAR) 57948a6092fSMaxime Coquelin port->ignore_status_mask |= USART_SR_ORE; 58048a6092fSMaxime Coquelin } 58148a6092fSMaxime Coquelin 58248a6092fSMaxime Coquelin /* Ignore all characters if CREAD is not set */ 58348a6092fSMaxime Coquelin if ((termios->c_cflag & CREAD) == 0) 58448a6092fSMaxime Coquelin port->ignore_status_mask |= USART_SR_DUMMY_RX; 58548a6092fSMaxime Coquelin 586*ada8618fSAlexandre TORGUE writel_relaxed(cr3, port->membase + ofs->cr3); 587*ada8618fSAlexandre TORGUE writel_relaxed(cr2, port->membase + ofs->cr2); 588*ada8618fSAlexandre TORGUE writel_relaxed(cr1, port->membase + ofs->cr1); 58948a6092fSMaxime Coquelin 59048a6092fSMaxime Coquelin spin_unlock_irqrestore(&port->lock, flags); 59148a6092fSMaxime Coquelin } 59248a6092fSMaxime Coquelin 59348a6092fSMaxime Coquelin static const char *stm32_type(struct uart_port *port) 59448a6092fSMaxime Coquelin { 59548a6092fSMaxime Coquelin return (port->type == PORT_STM32) ? DRIVER_NAME : NULL; 59648a6092fSMaxime Coquelin } 59748a6092fSMaxime Coquelin 59848a6092fSMaxime Coquelin static void stm32_release_port(struct uart_port *port) 59948a6092fSMaxime Coquelin { 60048a6092fSMaxime Coquelin } 60148a6092fSMaxime Coquelin 60248a6092fSMaxime Coquelin static int stm32_request_port(struct uart_port *port) 60348a6092fSMaxime Coquelin { 60448a6092fSMaxime Coquelin return 0; 60548a6092fSMaxime Coquelin } 60648a6092fSMaxime Coquelin 60748a6092fSMaxime Coquelin static void stm32_config_port(struct uart_port *port, int flags) 60848a6092fSMaxime Coquelin { 60948a6092fSMaxime Coquelin if (flags & UART_CONFIG_TYPE) 61048a6092fSMaxime Coquelin port->type = PORT_STM32; 61148a6092fSMaxime Coquelin } 61248a6092fSMaxime Coquelin 61348a6092fSMaxime Coquelin static int 61448a6092fSMaxime Coquelin stm32_verify_port(struct uart_port *port, struct serial_struct *ser) 61548a6092fSMaxime Coquelin { 61648a6092fSMaxime Coquelin /* No user changeable parameters */ 61748a6092fSMaxime Coquelin return -EINVAL; 61848a6092fSMaxime Coquelin } 61948a6092fSMaxime Coquelin 62048a6092fSMaxime Coquelin static void stm32_pm(struct uart_port *port, unsigned int state, 62148a6092fSMaxime Coquelin unsigned int oldstate) 62248a6092fSMaxime Coquelin { 62348a6092fSMaxime Coquelin struct stm32_port *stm32port = container_of(port, 62448a6092fSMaxime Coquelin struct stm32_port, port); 625*ada8618fSAlexandre TORGUE struct stm32_usart_offsets *ofs = &stm32port->info->ofs; 626*ada8618fSAlexandre TORGUE struct stm32_usart_config *cfg = &stm32port->info->cfg; 62748a6092fSMaxime Coquelin unsigned long flags = 0; 62848a6092fSMaxime Coquelin 62948a6092fSMaxime Coquelin switch (state) { 63048a6092fSMaxime Coquelin case UART_PM_STATE_ON: 63148a6092fSMaxime Coquelin clk_prepare_enable(stm32port->clk); 63248a6092fSMaxime Coquelin break; 63348a6092fSMaxime Coquelin case UART_PM_STATE_OFF: 63448a6092fSMaxime Coquelin spin_lock_irqsave(&port->lock, flags); 635*ada8618fSAlexandre TORGUE stm32_clr_bits(port, ofs->cr1, BIT(cfg->uart_enable_bit)); 63648a6092fSMaxime Coquelin spin_unlock_irqrestore(&port->lock, flags); 63748a6092fSMaxime Coquelin clk_disable_unprepare(stm32port->clk); 63848a6092fSMaxime Coquelin break; 63948a6092fSMaxime Coquelin } 64048a6092fSMaxime Coquelin } 64148a6092fSMaxime Coquelin 64248a6092fSMaxime Coquelin static const struct uart_ops stm32_uart_ops = { 64348a6092fSMaxime Coquelin .tx_empty = stm32_tx_empty, 64448a6092fSMaxime Coquelin .set_mctrl = stm32_set_mctrl, 64548a6092fSMaxime Coquelin .get_mctrl = stm32_get_mctrl, 64648a6092fSMaxime Coquelin .stop_tx = stm32_stop_tx, 64748a6092fSMaxime Coquelin .start_tx = stm32_start_tx, 64848a6092fSMaxime Coquelin .throttle = stm32_throttle, 64948a6092fSMaxime Coquelin .unthrottle = stm32_unthrottle, 65048a6092fSMaxime Coquelin .stop_rx = stm32_stop_rx, 65148a6092fSMaxime Coquelin .break_ctl = stm32_break_ctl, 65248a6092fSMaxime Coquelin .startup = stm32_startup, 65348a6092fSMaxime Coquelin .shutdown = stm32_shutdown, 65448a6092fSMaxime Coquelin .set_termios = stm32_set_termios, 65548a6092fSMaxime Coquelin .pm = stm32_pm, 65648a6092fSMaxime Coquelin .type = stm32_type, 65748a6092fSMaxime Coquelin .release_port = stm32_release_port, 65848a6092fSMaxime Coquelin .request_port = stm32_request_port, 65948a6092fSMaxime Coquelin .config_port = stm32_config_port, 66048a6092fSMaxime Coquelin .verify_port = stm32_verify_port, 66148a6092fSMaxime Coquelin }; 66248a6092fSMaxime Coquelin 66348a6092fSMaxime Coquelin static int stm32_init_port(struct stm32_port *stm32port, 66448a6092fSMaxime Coquelin struct platform_device *pdev) 66548a6092fSMaxime Coquelin { 66648a6092fSMaxime Coquelin struct uart_port *port = &stm32port->port; 66748a6092fSMaxime Coquelin struct resource *res; 66848a6092fSMaxime Coquelin int ret; 66948a6092fSMaxime Coquelin 67048a6092fSMaxime Coquelin port->iotype = UPIO_MEM; 67148a6092fSMaxime Coquelin port->flags = UPF_BOOT_AUTOCONF; 67248a6092fSMaxime Coquelin port->ops = &stm32_uart_ops; 67348a6092fSMaxime Coquelin port->dev = &pdev->dev; 67448a6092fSMaxime Coquelin port->irq = platform_get_irq(pdev, 0); 67548a6092fSMaxime Coquelin 67648a6092fSMaxime Coquelin res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 67748a6092fSMaxime Coquelin port->membase = devm_ioremap_resource(&pdev->dev, res); 67848a6092fSMaxime Coquelin if (IS_ERR(port->membase)) 67948a6092fSMaxime Coquelin return PTR_ERR(port->membase); 68048a6092fSMaxime Coquelin port->mapbase = res->start; 68148a6092fSMaxime Coquelin 68248a6092fSMaxime Coquelin spin_lock_init(&port->lock); 68348a6092fSMaxime Coquelin 68448a6092fSMaxime Coquelin stm32port->clk = devm_clk_get(&pdev->dev, NULL); 68548a6092fSMaxime Coquelin if (IS_ERR(stm32port->clk)) 68648a6092fSMaxime Coquelin return PTR_ERR(stm32port->clk); 68748a6092fSMaxime Coquelin 68848a6092fSMaxime Coquelin /* Ensure that clk rate is correct by enabling the clk */ 68948a6092fSMaxime Coquelin ret = clk_prepare_enable(stm32port->clk); 69048a6092fSMaxime Coquelin if (ret) 69148a6092fSMaxime Coquelin return ret; 69248a6092fSMaxime Coquelin 69348a6092fSMaxime Coquelin stm32port->port.uartclk = clk_get_rate(stm32port->clk); 69448a6092fSMaxime Coquelin if (!stm32port->port.uartclk) 69548a6092fSMaxime Coquelin ret = -EINVAL; 69648a6092fSMaxime Coquelin 69748a6092fSMaxime Coquelin clk_disable_unprepare(stm32port->clk); 69848a6092fSMaxime Coquelin 69948a6092fSMaxime Coquelin return ret; 70048a6092fSMaxime Coquelin } 70148a6092fSMaxime Coquelin 70248a6092fSMaxime Coquelin static struct stm32_port *stm32_of_get_stm32_port(struct platform_device *pdev) 70348a6092fSMaxime Coquelin { 70448a6092fSMaxime Coquelin struct device_node *np = pdev->dev.of_node; 70548a6092fSMaxime Coquelin int id; 70648a6092fSMaxime Coquelin 70748a6092fSMaxime Coquelin if (!np) 70848a6092fSMaxime Coquelin return NULL; 70948a6092fSMaxime Coquelin 71048a6092fSMaxime Coquelin id = of_alias_get_id(np, "serial"); 71148a6092fSMaxime Coquelin if (id < 0) 71248a6092fSMaxime Coquelin id = 0; 71348a6092fSMaxime Coquelin 71448a6092fSMaxime Coquelin if (WARN_ON(id >= STM32_MAX_PORTS)) 71548a6092fSMaxime Coquelin return NULL; 71648a6092fSMaxime Coquelin 71748a6092fSMaxime Coquelin stm32_ports[id].hw_flow_control = of_property_read_bool(np, 71848a6092fSMaxime Coquelin "auto-flow-control"); 71948a6092fSMaxime Coquelin stm32_ports[id].port.line = id; 72048a6092fSMaxime Coquelin return &stm32_ports[id]; 72148a6092fSMaxime Coquelin } 72248a6092fSMaxime Coquelin 72348a6092fSMaxime Coquelin #ifdef CONFIG_OF 72448a6092fSMaxime Coquelin static const struct of_device_id stm32_match[] = { 725*ada8618fSAlexandre TORGUE { .compatible = "st,stm32-usart", .data = &stm32f4_info}, 726*ada8618fSAlexandre TORGUE { .compatible = "st,stm32-uart", .data = &stm32f4_info}, 727*ada8618fSAlexandre TORGUE { .compatible = "st,stm32f7-usart", .data = &stm32f7_info}, 728*ada8618fSAlexandre TORGUE { .compatible = "st,stm32f7-uart", .data = &stm32f7_info}, 72948a6092fSMaxime Coquelin {}, 73048a6092fSMaxime Coquelin }; 73148a6092fSMaxime Coquelin 73248a6092fSMaxime Coquelin MODULE_DEVICE_TABLE(of, stm32_match); 73348a6092fSMaxime Coquelin #endif 73448a6092fSMaxime Coquelin 73548a6092fSMaxime Coquelin static int stm32_serial_probe(struct platform_device *pdev) 73648a6092fSMaxime Coquelin { 737*ada8618fSAlexandre TORGUE const struct of_device_id *match; 73848a6092fSMaxime Coquelin struct stm32_port *stm32port; 739*ada8618fSAlexandre TORGUE int ret; 74048a6092fSMaxime Coquelin 74148a6092fSMaxime Coquelin stm32port = stm32_of_get_stm32_port(pdev); 74248a6092fSMaxime Coquelin if (!stm32port) 74348a6092fSMaxime Coquelin return -ENODEV; 74448a6092fSMaxime Coquelin 745*ada8618fSAlexandre TORGUE match = of_match_device(stm32_match, &pdev->dev); 746*ada8618fSAlexandre TORGUE if (match && match->data) 747*ada8618fSAlexandre TORGUE stm32port->info = (struct stm32_usart_info *)match->data; 748*ada8618fSAlexandre TORGUE else 749*ada8618fSAlexandre TORGUE return -EINVAL; 750*ada8618fSAlexandre TORGUE 75148a6092fSMaxime Coquelin ret = stm32_init_port(stm32port, pdev); 75248a6092fSMaxime Coquelin if (ret) 75348a6092fSMaxime Coquelin return ret; 75448a6092fSMaxime Coquelin 75548a6092fSMaxime Coquelin ret = uart_add_one_port(&stm32_usart_driver, &stm32port->port); 75648a6092fSMaxime Coquelin if (ret) 75748a6092fSMaxime Coquelin return ret; 75848a6092fSMaxime Coquelin 75948a6092fSMaxime Coquelin platform_set_drvdata(pdev, &stm32port->port); 76048a6092fSMaxime Coquelin 76148a6092fSMaxime Coquelin return 0; 76248a6092fSMaxime Coquelin } 76348a6092fSMaxime Coquelin 76448a6092fSMaxime Coquelin static int stm32_serial_remove(struct platform_device *pdev) 76548a6092fSMaxime Coquelin { 76648a6092fSMaxime Coquelin struct uart_port *port = platform_get_drvdata(pdev); 76748a6092fSMaxime Coquelin 76848a6092fSMaxime Coquelin return uart_remove_one_port(&stm32_usart_driver, port); 76948a6092fSMaxime Coquelin } 77048a6092fSMaxime Coquelin 77148a6092fSMaxime Coquelin 77248a6092fSMaxime Coquelin #ifdef CONFIG_SERIAL_STM32_CONSOLE 77348a6092fSMaxime Coquelin static void stm32_console_putchar(struct uart_port *port, int ch) 77448a6092fSMaxime Coquelin { 775*ada8618fSAlexandre TORGUE struct stm32_port *stm32_port = to_stm32_port(port); 776*ada8618fSAlexandre TORGUE struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; 777*ada8618fSAlexandre TORGUE 778*ada8618fSAlexandre TORGUE while (!(readl_relaxed(port->membase + ofs->isr) & USART_SR_TXE)) 77948a6092fSMaxime Coquelin cpu_relax(); 78048a6092fSMaxime Coquelin 781*ada8618fSAlexandre TORGUE writel_relaxed(ch, port->membase + ofs->tdr); 78248a6092fSMaxime Coquelin } 78348a6092fSMaxime Coquelin 78448a6092fSMaxime Coquelin static void stm32_console_write(struct console *co, const char *s, unsigned cnt) 78548a6092fSMaxime Coquelin { 78648a6092fSMaxime Coquelin struct uart_port *port = &stm32_ports[co->index].port; 787*ada8618fSAlexandre TORGUE struct stm32_port *stm32_port = to_stm32_port(port); 788*ada8618fSAlexandre TORGUE struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; 78948a6092fSMaxime Coquelin unsigned long flags; 79048a6092fSMaxime Coquelin u32 old_cr1, new_cr1; 79148a6092fSMaxime Coquelin int locked = 1; 79248a6092fSMaxime Coquelin 79348a6092fSMaxime Coquelin local_irq_save(flags); 79448a6092fSMaxime Coquelin if (port->sysrq) 79548a6092fSMaxime Coquelin locked = 0; 79648a6092fSMaxime Coquelin else if (oops_in_progress) 79748a6092fSMaxime Coquelin locked = spin_trylock(&port->lock); 79848a6092fSMaxime Coquelin else 79948a6092fSMaxime Coquelin spin_lock(&port->lock); 80048a6092fSMaxime Coquelin 80148a6092fSMaxime Coquelin /* Save and disable interrupts */ 802*ada8618fSAlexandre TORGUE old_cr1 = readl_relaxed(port->membase + ofs->cr1); 80348a6092fSMaxime Coquelin new_cr1 = old_cr1 & ~USART_CR1_IE_MASK; 804*ada8618fSAlexandre TORGUE writel_relaxed(new_cr1, port->membase + ofs->cr1); 80548a6092fSMaxime Coquelin 80648a6092fSMaxime Coquelin uart_console_write(port, s, cnt, stm32_console_putchar); 80748a6092fSMaxime Coquelin 80848a6092fSMaxime Coquelin /* Restore interrupt state */ 809*ada8618fSAlexandre TORGUE writel_relaxed(old_cr1, port->membase + ofs->cr1); 81048a6092fSMaxime Coquelin 81148a6092fSMaxime Coquelin if (locked) 81248a6092fSMaxime Coquelin spin_unlock(&port->lock); 81348a6092fSMaxime Coquelin local_irq_restore(flags); 81448a6092fSMaxime Coquelin } 81548a6092fSMaxime Coquelin 81648a6092fSMaxime Coquelin static int stm32_console_setup(struct console *co, char *options) 81748a6092fSMaxime Coquelin { 81848a6092fSMaxime Coquelin struct stm32_port *stm32port; 81948a6092fSMaxime Coquelin int baud = 9600; 82048a6092fSMaxime Coquelin int bits = 8; 82148a6092fSMaxime Coquelin int parity = 'n'; 82248a6092fSMaxime Coquelin int flow = 'n'; 82348a6092fSMaxime Coquelin 82448a6092fSMaxime Coquelin if (co->index >= STM32_MAX_PORTS) 82548a6092fSMaxime Coquelin return -ENODEV; 82648a6092fSMaxime Coquelin 82748a6092fSMaxime Coquelin stm32port = &stm32_ports[co->index]; 82848a6092fSMaxime Coquelin 82948a6092fSMaxime Coquelin /* 83048a6092fSMaxime Coquelin * This driver does not support early console initialization 83148a6092fSMaxime Coquelin * (use ARM early printk support instead), so we only expect 83248a6092fSMaxime Coquelin * this to be called during the uart port registration when the 83348a6092fSMaxime Coquelin * driver gets probed and the port should be mapped at that point. 83448a6092fSMaxime Coquelin */ 83548a6092fSMaxime Coquelin if (stm32port->port.mapbase == 0 || stm32port->port.membase == NULL) 83648a6092fSMaxime Coquelin return -ENXIO; 83748a6092fSMaxime Coquelin 83848a6092fSMaxime Coquelin if (options) 83948a6092fSMaxime Coquelin uart_parse_options(options, &baud, &parity, &bits, &flow); 84048a6092fSMaxime Coquelin 84148a6092fSMaxime Coquelin return uart_set_options(&stm32port->port, co, baud, parity, bits, flow); 84248a6092fSMaxime Coquelin } 84348a6092fSMaxime Coquelin 84448a6092fSMaxime Coquelin static struct console stm32_console = { 84548a6092fSMaxime Coquelin .name = STM32_SERIAL_NAME, 84648a6092fSMaxime Coquelin .device = uart_console_device, 84748a6092fSMaxime Coquelin .write = stm32_console_write, 84848a6092fSMaxime Coquelin .setup = stm32_console_setup, 84948a6092fSMaxime Coquelin .flags = CON_PRINTBUFFER, 85048a6092fSMaxime Coquelin .index = -1, 85148a6092fSMaxime Coquelin .data = &stm32_usart_driver, 85248a6092fSMaxime Coquelin }; 85348a6092fSMaxime Coquelin 85448a6092fSMaxime Coquelin #define STM32_SERIAL_CONSOLE (&stm32_console) 85548a6092fSMaxime Coquelin 85648a6092fSMaxime Coquelin #else 85748a6092fSMaxime Coquelin #define STM32_SERIAL_CONSOLE NULL 85848a6092fSMaxime Coquelin #endif /* CONFIG_SERIAL_STM32_CONSOLE */ 85948a6092fSMaxime Coquelin 86048a6092fSMaxime Coquelin static struct uart_driver stm32_usart_driver = { 86148a6092fSMaxime Coquelin .driver_name = DRIVER_NAME, 86248a6092fSMaxime Coquelin .dev_name = STM32_SERIAL_NAME, 86348a6092fSMaxime Coquelin .major = 0, 86448a6092fSMaxime Coquelin .minor = 0, 86548a6092fSMaxime Coquelin .nr = STM32_MAX_PORTS, 86648a6092fSMaxime Coquelin .cons = STM32_SERIAL_CONSOLE, 86748a6092fSMaxime Coquelin }; 86848a6092fSMaxime Coquelin 86948a6092fSMaxime Coquelin static struct platform_driver stm32_serial_driver = { 87048a6092fSMaxime Coquelin .probe = stm32_serial_probe, 87148a6092fSMaxime Coquelin .remove = stm32_serial_remove, 87248a6092fSMaxime Coquelin .driver = { 87348a6092fSMaxime Coquelin .name = DRIVER_NAME, 87448a6092fSMaxime Coquelin .of_match_table = of_match_ptr(stm32_match), 87548a6092fSMaxime Coquelin }, 87648a6092fSMaxime Coquelin }; 87748a6092fSMaxime Coquelin 87848a6092fSMaxime Coquelin static int __init usart_init(void) 87948a6092fSMaxime Coquelin { 88048a6092fSMaxime Coquelin static char banner[] __initdata = "STM32 USART driver initialized"; 88148a6092fSMaxime Coquelin int ret; 88248a6092fSMaxime Coquelin 88348a6092fSMaxime Coquelin pr_info("%s\n", banner); 88448a6092fSMaxime Coquelin 88548a6092fSMaxime Coquelin ret = uart_register_driver(&stm32_usart_driver); 88648a6092fSMaxime Coquelin if (ret) 88748a6092fSMaxime Coquelin return ret; 88848a6092fSMaxime Coquelin 88948a6092fSMaxime Coquelin ret = platform_driver_register(&stm32_serial_driver); 89048a6092fSMaxime Coquelin if (ret) 89148a6092fSMaxime Coquelin uart_unregister_driver(&stm32_usart_driver); 89248a6092fSMaxime Coquelin 89348a6092fSMaxime Coquelin return ret; 89448a6092fSMaxime Coquelin } 89548a6092fSMaxime Coquelin 89648a6092fSMaxime Coquelin static void __exit usart_exit(void) 89748a6092fSMaxime Coquelin { 89848a6092fSMaxime Coquelin platform_driver_unregister(&stm32_serial_driver); 89948a6092fSMaxime Coquelin uart_unregister_driver(&stm32_usart_driver); 90048a6092fSMaxime Coquelin } 90148a6092fSMaxime Coquelin 90248a6092fSMaxime Coquelin module_init(usart_init); 90348a6092fSMaxime Coquelin module_exit(usart_exit); 90448a6092fSMaxime Coquelin 90548a6092fSMaxime Coquelin MODULE_ALIAS("platform:" DRIVER_NAME); 90648a6092fSMaxime Coquelin MODULE_DESCRIPTION("STMicroelectronics STM32 serial port driver"); 90748a6092fSMaxime Coquelin MODULE_LICENSE("GPL v2"); 908