832 lines · c
1// SPDX-License-Identifier: GPL-2.0+2/*3 * MA35D1 serial driver4 * Copyright (C) 2023 Nuvoton Technology Corp.5 */6 7#include <linux/bitfield.h>8#include <linux/clk.h>9#include <linux/delay.h>10#include <linux/of.h>11#include <linux/platform_device.h>12#include <linux/iopoll.h>13#include <linux/serial_core.h>14#include <linux/slab.h>15#include <linux/tty_flip.h>16#include <linux/units.h>17 18#define MA35_UART_NR 1719 20#define MA35_RBR_REG 0x0021#define MA35_THR_REG 0x0022#define MA35_IER_REG 0x0423#define MA35_FCR_REG 0x0824#define MA35_LCR_REG 0x0C25#define MA35_MCR_REG 0x1026#define MA35_MSR_REG 0x1427#define MA35_FSR_REG 0x1828#define MA35_ISR_REG 0x1C29#define MA35_TOR_REG 0x2030#define MA35_BAUD_REG 0x2431#define MA35_ALTCTL_REG 0x2C32#define MA35_FUN_SEL_REG 0x3033#define MA35_WKCTL_REG 0x4034#define MA35_WKSTS_REG 0x4435 36/* MA35_IER_REG - Interrupt Enable Register */37#define MA35_IER_RDA_IEN BIT(0) /* RBR Available Interrupt Enable */38#define MA35_IER_THRE_IEN BIT(1) /* THR Empty Interrupt Enable */39#define MA35_IER_RLS_IEN BIT(2) /* RX Line Status Interrupt Enable */40#define MA35_IER_RTO_IEN BIT(4) /* RX Time-out Interrupt Enable */41#define MA35_IER_BUFERR_IEN BIT(5) /* Buffer Error Interrupt Enable */42#define MA35_IER_TIME_OUT_EN BIT(11) /* RX Buffer Time-out Counter Enable */43#define MA35_IER_AUTO_RTS BIT(12) /* nRTS Auto-flow Control Enable */44#define MA35_IER_AUTO_CTS BIT(13) /* nCTS Auto-flow Control Enable */45 46/* MA35_FCR_REG - FIFO Control Register */47#define MA35_FCR_RFR BIT(1) /* RX Field Software Reset */48#define MA35_FCR_TFR BIT(2) /* TX Field Software Reset */49#define MA35_FCR_RFITL_MASK GENMASK(7, 4) /* RX FIFO Interrupt Trigger Level */50#define MA35_FCR_RFITL_1BYTE FIELD_PREP(MA35_FCR_RFITL_MASK, 0)51#define MA35_FCR_RFITL_4BYTES FIELD_PREP(MA35_FCR_RFITL_MASK, 1)52#define MA35_FCR_RFITL_8BYTES FIELD_PREP(MA35_FCR_RFITL_MASK, 2)53#define MA35_FCR_RFITL_14BYTES FIELD_PREP(MA35_FCR_RFITL_MASK, 3)54#define MA35_FCR_RFITL_30BYTES FIELD_PREP(MA35_FCR_RFITL_MASK, 4)55#define MA35_FCR_RTSTL_MASK GENMASK(19, 16) /* nRTS Trigger Level */56#define MA35_FCR_RTSTL_1BYTE FIELD_PREP(MA35_FCR_RTSTL_MASK, 0)57#define MA35_FCR_RTSTL_4BYTES FIELD_PREP(MA35_FCR_RTSTL_MASK, 1)58#define MA35_FCR_RTSTL_8BYTES FIELD_PREP(MA35_FCR_RTSTL_MASK, 2)59#define MA35_FCR_RTSTL_14BYTES FIELD_PREP(MA35_FCR_RTSTL_MASK, 3)60#define MA35_FCR_RTSTLL_30BYTES FIELD_PREP(MA35_FCR_RTSTL_MASK, 4)61 62/* MA35_LCR_REG - Line Control Register */63#define MA35_LCR_NSB BIT(2) /* Number of “STOP Bit” */64#define MA35_LCR_PBE BIT(3) /* Parity Bit Enable */65#define MA35_LCR_EPE BIT(4) /* Even Parity Enable */66#define MA35_LCR_SPE BIT(5) /* Stick Parity Enable */67#define MA35_LCR_BREAK BIT(6) /* Break Control */68#define MA35_LCR_WLS_MASK GENMASK(1, 0) /* Word Length Selection */69#define MA35_LCR_WLS_5BITS FIELD_PREP(MA35_LCR_WLS_MASK, 0)70#define MA35_LCR_WLS_6BITS FIELD_PREP(MA35_LCR_WLS_MASK, 1)71#define MA35_LCR_WLS_7BITS FIELD_PREP(MA35_LCR_WLS_MASK, 2)72#define MA35_LCR_WLS_8BITS FIELD_PREP(MA35_LCR_WLS_MASK, 3)73 74/* MA35_MCR_REG - Modem Control Register */75#define MA35_MCR_RTS_CTRL BIT(1) /* nRTS Signal Control */76#define MA35_MCR_RTSACTLV BIT(9) /* nRTS Pin Active Level */77#define MA35_MCR_RTSSTS BIT(13) /* nRTS Pin Status (Read Only) */78 79/* MA35_MSR_REG - Modem Status Register */80#define MA35_MSR_CTSDETF BIT(0) /* Detect nCTS State Change Flag */81#define MA35_MSR_CTSSTS BIT(4) /* nCTS Pin Status (Read Only) */82#define MA35_MSR_CTSACTLV BIT(8) /* nCTS Pin Active Level */83 84/* MA35_FSR_REG - FIFO Status Register */85#define MA35_FSR_RX_OVER_IF BIT(0) /* RX Overflow Error Interrupt Flag */86#define MA35_FSR_PEF BIT(4) /* Parity Error Flag*/87#define MA35_FSR_FEF BIT(5) /* Framing Error Flag */88#define MA35_FSR_BIF BIT(6) /* Break Interrupt Flag */89#define MA35_FSR_RX_EMPTY BIT(14) /* Receiver FIFO Empty (Read Only) */90#define MA35_FSR_RX_FULL BIT(15) /* Receiver FIFO Full (Read Only) */91#define MA35_FSR_TX_EMPTY BIT(22) /* Transmitter FIFO Empty (Read Only) */92#define MA35_FSR_TX_FULL BIT(23) /* Transmitter FIFO Full (Read Only) */93#define MA35_FSR_TX_OVER_IF BIT(24) /* TX Overflow Error Interrupt Flag */94#define MA35_FSR_TE_FLAG BIT(28) /* Transmitter Empty Flag (Read Only) */95#define MA35_FSR_RXPTR_MSK GENMASK(13, 8) /* TX FIFO Pointer mask */96#define MA35_FSR_TXPTR_MSK GENMASK(21, 16) /* RX FIFO Pointer mask */97 98/* MA35_ISR_REG - Interrupt Status Register */99#define MA35_ISR_RDA_IF BIT(0) /* RBR Available Interrupt Flag */100#define MA35_ISR_THRE_IF BIT(1) /* THR Empty Interrupt Flag */101#define MA35_ISR_RLSIF BIT(2) /* Receive Line Interrupt Flag */102#define MA35_ISR_MODEMIF BIT(3) /* MODEM Interrupt Flag */103#define MA35_ISR_RXTO_IF BIT(4) /* RX Time-out Interrupt Flag */104#define MA35_ISR_BUFEIF BIT(5) /* Buffer Error Interrupt Flag */105#define MA35_ISR_WK_IF BIT(6) /* UART Wake-up Interrupt Flag */106#define MA35_ISR_RDAINT BIT(8) /* RBR Available Interrupt Indicator */107#define MA35_ISR_THRE_INT BIT(9) /* THR Empty Interrupt Indicator */108#define MA35_ISR_ALL 0xFFFFFFFF109 110/* MA35_BAUD_REG - Baud Rate Divider Register */111#define MA35_BAUD_MODE_MASK GENMASK(29, 28)112#define MA35_BAUD_MODE0 FIELD_PREP(MA35_BAUD_MODE_MASK, 0)113#define MA35_BAUD_MODE1 FIELD_PREP(MA35_BAUD_MODE_MASK, 2)114#define MA35_BAUD_MODE2 FIELD_PREP(MA35_BAUD_MODE_MASK, 3)115#define MA35_BAUD_MASK GENMASK(15, 0)116 117/* MA35_ALTCTL_REG - Alternate Control/Status Register */118#define MA35_ALTCTL_RS485AUD BIT(10) /* RS-485 Auto Direction Function */119 120/* MA35_FUN_SEL_REG - Function Select Register */121#define MA35_FUN_SEL_MASK GENMASK(2, 0)122#define MA35_FUN_SEL_UART FIELD_PREP(MA35_FUN_SEL_MASK, 0)123#define MA35_FUN_SEL_RS485 FIELD_PREP(MA35_FUN_SEL_MASK, 3)124 125/* The constrain for MA35D1 UART baud rate divider */126#define MA35_BAUD_DIV_MAX 0xFFFF127#define MA35_BAUD_DIV_MIN 11128 129/* UART FIFO depth */130#define MA35_UART_FIFO_DEPTH 32131/* UART console clock */132#define MA35_UART_CONSOLE_CLK (24 * HZ_PER_MHZ)133/* UART register ioremap size */134#define MA35_UART_REG_SIZE 0x100135/* Rx Timeout */136#define MA35_UART_RX_TOUT 0x40137 138#define MA35_IER_CONFIG (MA35_IER_RTO_IEN | MA35_IER_RDA_IEN | \139 MA35_IER_TIME_OUT_EN | MA35_IER_BUFERR_IEN)140 141#define MA35_ISR_IF_CHECK (MA35_ISR_RDA_IF | MA35_ISR_RXTO_IF | \142 MA35_ISR_THRE_INT | MA35_ISR_BUFEIF)143 144#define MA35_FSR_TX_BOTH_EMPTY (MA35_FSR_TE_FLAG | MA35_FSR_TX_EMPTY)145 146static struct uart_driver ma35d1serial_reg;147 148struct uart_ma35d1_port {149 struct uart_port port;150 struct clk *clk;151 u16 capabilities; /* port capabilities */152 u8 ier;153 u8 lcr;154 u8 mcr;155 u32 baud_rate;156 u32 console_baud_rate;157 u32 console_line;158 u32 console_int;159};160 161static struct uart_ma35d1_port ma35d1serial_ports[MA35_UART_NR];162 163static struct uart_ma35d1_port *to_ma35d1_uart_port(struct uart_port *uart)164{165 return container_of(uart, struct uart_ma35d1_port, port);166}167 168static u32 serial_in(struct uart_ma35d1_port *p, u32 offset)169{170 return readl_relaxed(p->port.membase + offset);171}172 173static void serial_out(struct uart_ma35d1_port *p, u32 offset, u32 value)174{175 writel_relaxed(value, p->port.membase + offset);176}177 178static void __stop_tx(struct uart_ma35d1_port *p)179{180 u32 ier;181 182 ier = serial_in(p, MA35_IER_REG);183 if (ier & MA35_IER_THRE_IEN)184 serial_out(p, MA35_IER_REG, ier & ~MA35_IER_THRE_IEN);185}186 187static void ma35d1serial_stop_tx(struct uart_port *port)188{189 struct uart_ma35d1_port *up = to_ma35d1_uart_port(port);190 191 __stop_tx(up);192}193 194static void transmit_chars(struct uart_ma35d1_port *up)195{196 u32 count;197 u8 ch;198 199 if (uart_tx_stopped(&up->port)) {200 ma35d1serial_stop_tx(&up->port);201 return;202 }203 count = MA35_UART_FIFO_DEPTH - FIELD_GET(MA35_FSR_TXPTR_MSK,204 serial_in(up, MA35_FSR_REG));205 uart_port_tx_limited(&up->port, ch, count,206 !(serial_in(up, MA35_FSR_REG) & MA35_FSR_TX_FULL),207 serial_out(up, MA35_THR_REG, ch),208 ({}));209}210 211static void ma35d1serial_start_tx(struct uart_port *port)212{213 struct uart_ma35d1_port *up = to_ma35d1_uart_port(port);214 u32 ier;215 216 ier = serial_in(up, MA35_IER_REG);217 serial_out(up, MA35_IER_REG, ier & ~MA35_IER_THRE_IEN);218 transmit_chars(up);219 serial_out(up, MA35_IER_REG, ier | MA35_IER_THRE_IEN);220}221 222static void ma35d1serial_stop_rx(struct uart_port *port)223{224 struct uart_ma35d1_port *up = to_ma35d1_uart_port(port);225 u32 ier;226 227 ier = serial_in(up, MA35_IER_REG);228 ier &= ~MA35_IER_RDA_IEN;229 serial_out(up, MA35_IER_REG, ier);230}231 232static void receive_chars(struct uart_ma35d1_port *up)233{234 int max_count = 256;235 u8 ch, flag;236 u32 fsr;237 238 fsr = serial_in(up, MA35_FSR_REG);239 do {240 flag = TTY_NORMAL;241 up->port.icount.rx++;242 243 if (unlikely(fsr & (MA35_FSR_BIF | MA35_FSR_FEF |244 MA35_FSR_PEF | MA35_FSR_RX_OVER_IF))) {245 if (fsr & MA35_FSR_BIF) {246 up->port.icount.brk++;247 if (uart_handle_break(&up->port))248 continue;249 }250 if (fsr & MA35_FSR_FEF)251 up->port.icount.frame++;252 if (fsr & MA35_FSR_PEF)253 up->port.icount.parity++;254 if (fsr & MA35_FSR_RX_OVER_IF)255 up->port.icount.overrun++;256 257 serial_out(up, MA35_FSR_REG,258 fsr & (MA35_FSR_BIF | MA35_FSR_FEF |259 MA35_FSR_PEF | MA35_FSR_RX_OVER_IF));260 if (fsr & MA35_FSR_BIF)261 flag = TTY_BREAK;262 else if (fsr & MA35_FSR_PEF)263 flag = TTY_PARITY;264 else if (fsr & MA35_FSR_FEF)265 flag = TTY_FRAME;266 }267 268 ch = serial_in(up, MA35_RBR_REG);269 if (uart_handle_sysrq_char(&up->port, ch))270 continue;271 272 uart_port_lock(&up->port);273 uart_insert_char(&up->port, fsr, MA35_FSR_RX_OVER_IF, ch, flag);274 uart_port_unlock(&up->port);275 276 fsr = serial_in(up, MA35_FSR_REG);277 } while (!(fsr & MA35_FSR_RX_EMPTY) && (max_count-- > 0));278 279 uart_port_lock(&up->port);280 tty_flip_buffer_push(&up->port.state->port);281 uart_port_unlock(&up->port);282}283 284static irqreturn_t ma35d1serial_interrupt(int irq, void *dev_id)285{286 struct uart_port *port = dev_id;287 struct uart_ma35d1_port *up = to_ma35d1_uart_port(port);288 u32 isr, fsr;289 290 isr = serial_in(up, MA35_ISR_REG);291 fsr = serial_in(up, MA35_FSR_REG);292 293 if (!(isr & MA35_ISR_IF_CHECK))294 return IRQ_NONE;295 296 if (isr & (MA35_ISR_RDA_IF | MA35_ISR_RXTO_IF))297 receive_chars(up);298 if (isr & MA35_ISR_THRE_INT)299 transmit_chars(up);300 if (fsr & MA35_FSR_TX_OVER_IF)301 serial_out(up, MA35_FSR_REG, MA35_FSR_TX_OVER_IF);302 303 return IRQ_HANDLED;304}305 306static u32 ma35d1serial_tx_empty(struct uart_port *port)307{308 struct uart_ma35d1_port *up = to_ma35d1_uart_port(port);309 u32 fsr;310 311 fsr = serial_in(up, MA35_FSR_REG);312 if ((fsr & MA35_FSR_TX_BOTH_EMPTY) == MA35_FSR_TX_BOTH_EMPTY)313 return TIOCSER_TEMT;314 else315 return 0;316}317 318static u32 ma35d1serial_get_mctrl(struct uart_port *port)319{320 struct uart_ma35d1_port *up = to_ma35d1_uart_port(port);321 u32 status;322 u32 ret = 0;323 324 status = serial_in(up, MA35_MSR_REG);325 if (!(status & MA35_MSR_CTSSTS))326 ret |= TIOCM_CTS;327 return ret;328}329 330static void ma35d1serial_set_mctrl(struct uart_port *port, u32 mctrl)331{332 struct uart_ma35d1_port *up = to_ma35d1_uart_port(port);333 u32 mcr, msr, ier;334 335 mcr = serial_in(up, MA35_MCR_REG);336 mcr &= ~MA35_MCR_RTS_CTRL;337 338 if (mctrl & TIOCM_RTS)339 mcr |= MA35_MCR_RTSACTLV;340 else341 mcr &= ~MA35_MCR_RTSACTLV;342 343 if (up->mcr & UART_MCR_AFE) {344 ier = serial_in(up, MA35_IER_REG);345 ier |= MA35_IER_AUTO_RTS | MA35_IER_AUTO_CTS;346 serial_out(up, MA35_IER_REG, ier);347 up->port.flags |= UPF_HARD_FLOW;348 } else {349 ier = serial_in(up, MA35_IER_REG);350 ier &= ~(MA35_IER_AUTO_RTS | MA35_IER_AUTO_CTS);351 serial_out(up, MA35_IER_REG, ier);352 up->port.flags &= ~UPF_HARD_FLOW;353 }354 355 msr = serial_in(up, MA35_MSR_REG);356 msr |= MA35_MSR_CTSACTLV;357 serial_out(up, MA35_MSR_REG, msr);358 serial_out(up, MA35_MCR_REG, mcr);359}360 361static void ma35d1serial_break_ctl(struct uart_port *port, int break_state)362{363 struct uart_ma35d1_port *up = to_ma35d1_uart_port(port);364 unsigned long flags;365 u32 lcr;366 367 uart_port_lock_irqsave(&up->port, &flags);368 lcr = serial_in(up, MA35_LCR_REG);369 if (break_state != 0)370 lcr |= MA35_LCR_BREAK;371 else372 lcr &= ~MA35_LCR_BREAK;373 serial_out(up, MA35_LCR_REG, lcr);374 uart_port_unlock_irqrestore(&up->port, flags);375}376 377static int ma35d1serial_startup(struct uart_port *port)378{379 struct uart_ma35d1_port *up = to_ma35d1_uart_port(port);380 u32 fcr;381 int retval;382 383 /* Reset FIFO */384 serial_out(up, MA35_FCR_REG, MA35_FCR_TFR | MA35_FCR_RFR);385 386 /* Clear pending interrupts */387 serial_out(up, MA35_ISR_REG, MA35_ISR_ALL);388 389 retval = request_irq(port->irq, ma35d1serial_interrupt, 0,390 dev_name(port->dev), port);391 if (retval) {392 dev_err(up->port.dev, "request irq failed.\n");393 return retval;394 }395 396 fcr = serial_in(up, MA35_FCR_REG);397 fcr |= MA35_FCR_RFITL_4BYTES | MA35_FCR_RTSTL_8BYTES;398 serial_out(up, MA35_FCR_REG, fcr);399 serial_out(up, MA35_LCR_REG, MA35_LCR_WLS_8BITS);400 serial_out(up, MA35_TOR_REG, MA35_UART_RX_TOUT);401 serial_out(up, MA35_IER_REG, MA35_IER_CONFIG);402 return 0;403}404 405static void ma35d1serial_shutdown(struct uart_port *port)406{407 struct uart_ma35d1_port *up = to_ma35d1_uart_port(port);408 409 serial_out(up, MA35_IER_REG, 0);410 free_irq(port->irq, port);411}412 413static void ma35d1serial_set_termios(struct uart_port *port,414 struct ktermios *termios,415 const struct ktermios *old)416{417 struct uart_ma35d1_port *up = to_ma35d1_uart_port(port);418 unsigned long flags;419 u32 baud, quot;420 u32 lcr = 0;421 422 lcr = UART_LCR_WLEN(tty_get_char_size(termios->c_cflag));423 424 if (termios->c_cflag & CSTOPB)425 lcr |= MA35_LCR_NSB;426 if (termios->c_cflag & PARENB)427 lcr |= MA35_LCR_PBE;428 if (!(termios->c_cflag & PARODD))429 lcr |= MA35_LCR_EPE;430 if (termios->c_cflag & CMSPAR)431 lcr |= MA35_LCR_SPE;432 433 baud = uart_get_baud_rate(port, termios, old,434 port->uartclk / MA35_BAUD_DIV_MAX,435 port->uartclk / MA35_BAUD_DIV_MIN);436 437 /* MA35D1 UART baud rate equation: baudrate = UART_CLK / (quot + 2) */438 quot = (port->uartclk / baud) - 2;439 440 /*441 * Ok, we're now changing the port state. Do it with442 * interrupts disabled.443 */444 uart_port_lock_irqsave(&up->port, &flags);445 446 up->port.read_status_mask = MA35_FSR_RX_OVER_IF;447 if (termios->c_iflag & INPCK)448 up->port.read_status_mask |= MA35_FSR_FEF | MA35_FSR_PEF;449 if (termios->c_iflag & (BRKINT | PARMRK))450 up->port.read_status_mask |= MA35_FSR_BIF;451 452 /* Characteres to ignore */453 up->port.ignore_status_mask = 0;454 if (termios->c_iflag & IGNPAR)455 up->port.ignore_status_mask |= MA35_FSR_FEF | MA35_FSR_PEF;456 if (termios->c_iflag & IGNBRK) {457 up->port.ignore_status_mask |= MA35_FSR_BIF;458 /*459 * If we're ignoring parity and break indicators,460 * ignore overruns too (for real raw support).461 */462 if (termios->c_iflag & IGNPAR)463 up->port.ignore_status_mask |= MA35_FSR_RX_OVER_IF;464 }465 if (termios->c_cflag & CRTSCTS)466 up->mcr |= UART_MCR_AFE;467 else468 up->mcr &= ~UART_MCR_AFE;469 470 uart_update_timeout(port, termios->c_cflag, baud);471 472 ma35d1serial_set_mctrl(&up->port, up->port.mctrl);473 474 serial_out(up, MA35_BAUD_REG, MA35_BAUD_MODE2 | FIELD_PREP(MA35_BAUD_MASK, quot));475 476 serial_out(up, MA35_LCR_REG, lcr);477 478 uart_port_unlock_irqrestore(&up->port, flags);479}480 481static const char *ma35d1serial_type(struct uart_port *port)482{483 return "ma35d1-uart";484}485 486static void ma35d1serial_config_port(struct uart_port *port, int flags)487{488 /*489 * Driver core for serial ports forces a non-zero value for port type.490 * Write an arbitrary value here to accommodate the serial core driver,491 * as ID part of UAPI is redundant.492 */493 port->type = 1;494}495 496static int ma35d1serial_verify_port(struct uart_port *port, struct serial_struct *ser)497{498 if (port->type != PORT_UNKNOWN && ser->type != 1)499 return -EINVAL;500 501 return 0;502}503 504static const struct uart_ops ma35d1serial_ops = {505 .tx_empty = ma35d1serial_tx_empty,506 .set_mctrl = ma35d1serial_set_mctrl,507 .get_mctrl = ma35d1serial_get_mctrl,508 .stop_tx = ma35d1serial_stop_tx,509 .start_tx = ma35d1serial_start_tx,510 .stop_rx = ma35d1serial_stop_rx,511 .break_ctl = ma35d1serial_break_ctl,512 .startup = ma35d1serial_startup,513 .shutdown = ma35d1serial_shutdown,514 .set_termios = ma35d1serial_set_termios,515 .type = ma35d1serial_type,516 .config_port = ma35d1serial_config_port,517 .verify_port = ma35d1serial_verify_port,518};519 520static const struct of_device_id ma35d1_serial_of_match[] = {521 { .compatible = "nuvoton,ma35d1-uart" },522 {},523};524MODULE_DEVICE_TABLE(of, ma35d1_serial_of_match);525 526#ifdef CONFIG_SERIAL_NUVOTON_MA35D1_CONSOLE527 528static struct device_node *ma35d1serial_uart_nodes[MA35_UART_NR];529 530static void wait_for_xmitr(struct uart_ma35d1_port *up)531{532 unsigned int reg = 0;533 534 read_poll_timeout_atomic(serial_in, reg, reg & MA35_FSR_TX_EMPTY,535 1, 10000, false,536 up, MA35_FSR_REG);537}538 539static void ma35d1serial_console_putchar(struct uart_port *port, unsigned char ch)540{541 struct uart_ma35d1_port *up = to_ma35d1_uart_port(port);542 543 wait_for_xmitr(up);544 serial_out(up, MA35_THR_REG, ch);545}546 547/*548 * Print a string to the serial port trying not to disturb549 * any possible real use of the port...550 *551 * The console_lock must be held when we get here.552 */553static void ma35d1serial_console_write(struct console *co, const char *s, u32 count)554{555 struct uart_ma35d1_port *up;556 unsigned long flags;557 int locked = 1;558 u32 ier;559 560 if ((co->index < 0) || (co->index >= MA35_UART_NR)) {561 pr_warn("Failed to write on console port %x, out of range\n",562 co->index);563 return;564 }565 566 up = &ma35d1serial_ports[co->index];567 568 if (up->port.sysrq)569 locked = 0;570 else if (oops_in_progress)571 locked = uart_port_trylock_irqsave(&up->port, &flags);572 else573 uart_port_lock_irqsave(&up->port, &flags);574 575 /*576 * First save the IER then disable the interrupts577 */578 ier = serial_in(up, MA35_IER_REG);579 serial_out(up, MA35_IER_REG, 0);580 581 uart_console_write(&up->port, s, count, ma35d1serial_console_putchar);582 583 wait_for_xmitr(up);584 serial_out(up, MA35_IER_REG, ier);585 586 if (locked)587 uart_port_unlock_irqrestore(&up->port, flags);588}589 590static int __init ma35d1serial_console_setup(struct console *co, char *options)591{592 struct device_node *np;593 struct uart_ma35d1_port *p;594 u32 val32[4];595 struct uart_port *port;596 int baud = 115200;597 int bits = 8;598 int parity = 'n';599 int flow = 'n';600 601 if ((co->index < 0) || (co->index >= MA35_UART_NR)) {602 pr_debug("Console Port%x out of range\n", co->index);603 return -EINVAL;604 }605 606 np = ma35d1serial_uart_nodes[co->index];607 p = &ma35d1serial_ports[co->index];608 if (!np || !p)609 return -ENODEV;610 611 if (of_property_read_u32_array(np, "reg", val32, ARRAY_SIZE(val32)) != 0)612 return -EINVAL;613 614 p->port.iobase = val32[1];615 p->port.membase = ioremap(p->port.iobase, MA35_UART_REG_SIZE);616 if (!p->port.membase)617 return -ENOMEM;618 619 p->port.ops = &ma35d1serial_ops;620 p->port.line = 0;621 p->port.uartclk = MA35_UART_CONSOLE_CLK;622 623 port = &ma35d1serial_ports[co->index].port;624 625 if (options)626 uart_parse_options(options, &baud, &parity, &bits, &flow);627 628 return uart_set_options(port, co, baud, parity, bits, flow);629}630 631static struct console ma35d1serial_console = {632 .name = "ttyNVT",633 .write = ma35d1serial_console_write,634 .device = uart_console_device,635 .setup = ma35d1serial_console_setup,636 .flags = CON_PRINTBUFFER | CON_ENABLED,637 .index = -1,638 .data = &ma35d1serial_reg,639};640 641static void ma35d1serial_console_init_port(void)642{643 u32 i = 0;644 struct device_node *np;645 646 for_each_matching_node(np, ma35d1_serial_of_match) {647 if (ma35d1serial_uart_nodes[i] == NULL) {648 of_node_get(np);649 ma35d1serial_uart_nodes[i] = np;650 i++;651 if (i == MA35_UART_NR)652 break;653 }654 }655}656 657static int __init ma35d1serial_console_init(void)658{659 ma35d1serial_console_init_port();660 register_console(&ma35d1serial_console);661 return 0;662}663console_initcall(ma35d1serial_console_init);664 665#define MA35D1SERIAL_CONSOLE (&ma35d1serial_console)666#else667#define MA35D1SERIAL_CONSOLE NULL668#endif669 670static struct uart_driver ma35d1serial_reg = {671 .owner = THIS_MODULE,672 .driver_name = "serial",673 .dev_name = "ttyNVT",674 .major = TTY_MAJOR,675 .minor = 64,676 .cons = MA35D1SERIAL_CONSOLE,677 .nr = MA35_UART_NR,678};679 680/*681 * Register a set of serial devices attached to a platform device.682 * The list is terminated with a zero flags entry, which means we expect683 * all entries to have at least UPF_BOOT_AUTOCONF set.684 */685static int ma35d1serial_probe(struct platform_device *pdev)686{687 struct resource *res_mem;688 struct uart_ma35d1_port *up;689 int ret = 0;690 691 if (!pdev->dev.of_node)692 return -ENODEV;693 694 ret = of_alias_get_id(pdev->dev.of_node, "serial");695 if (ret < 0) {696 dev_err(&pdev->dev, "failed to get alias/pdev id, errno %d\n", ret);697 return ret;698 }699 up = &ma35d1serial_ports[ret];700 up->port.line = ret;701 res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);702 if (!res_mem)703 return -ENODEV;704 705 up->port.iobase = res_mem->start;706 up->port.membase = ioremap(up->port.iobase, MA35_UART_REG_SIZE);707 if (!up->port.membase)708 return -ENOMEM;709 710 up->port.ops = &ma35d1serial_ops;711 712 spin_lock_init(&up->port.lock);713 714 up->clk = of_clk_get(pdev->dev.of_node, 0);715 if (IS_ERR(up->clk)) {716 ret = PTR_ERR(up->clk);717 dev_err(&pdev->dev, "failed to get core clk: %d\n", ret);718 goto err_iounmap;719 }720 721 ret = clk_prepare_enable(up->clk);722 if (ret)723 goto err_iounmap;724 725 if (up->port.line != 0)726 up->port.uartclk = clk_get_rate(up->clk);727 728 ret = platform_get_irq(pdev, 0);729 if (ret < 0)730 goto err_clk_disable;731 732 up->port.irq = ret;733 up->port.dev = &pdev->dev;734 up->port.flags = UPF_BOOT_AUTOCONF;735 736 platform_set_drvdata(pdev, up);737 738 ret = uart_add_one_port(&ma35d1serial_reg, &up->port);739 if (ret < 0)740 goto err_free_irq;741 742 return 0;743 744err_free_irq:745 free_irq(up->port.irq, &up->port);746 747err_clk_disable:748 clk_disable_unprepare(up->clk);749 750err_iounmap:751 iounmap(up->port.membase);752 return ret;753}754 755/*756 * Remove serial ports registered against a platform device.757 */758static void ma35d1serial_remove(struct platform_device *dev)759{760 struct uart_port *port = platform_get_drvdata(dev);761 struct uart_ma35d1_port *up = to_ma35d1_uart_port(port);762 763 uart_remove_one_port(&ma35d1serial_reg, port);764 clk_disable_unprepare(up->clk);765}766 767static int ma35d1serial_suspend(struct platform_device *dev, pm_message_t state)768{769 struct uart_port *port = platform_get_drvdata(dev);770 struct uart_ma35d1_port *up = to_ma35d1_uart_port(port);771 772 uart_suspend_port(&ma35d1serial_reg, &up->port);773 if (up->port.line == 0) {774 up->console_baud_rate = serial_in(up, MA35_BAUD_REG);775 up->console_line = serial_in(up, MA35_LCR_REG);776 up->console_int = serial_in(up, MA35_IER_REG);777 }778 return 0;779}780 781static int ma35d1serial_resume(struct platform_device *dev)782{783 struct uart_port *port = platform_get_drvdata(dev);784 struct uart_ma35d1_port *up = to_ma35d1_uart_port(port);785 786 if (up->port.line == 0) {787 serial_out(up, MA35_BAUD_REG, up->console_baud_rate);788 serial_out(up, MA35_LCR_REG, up->console_line);789 serial_out(up, MA35_IER_REG, up->console_int);790 }791 uart_resume_port(&ma35d1serial_reg, &up->port);792 return 0;793}794 795static struct platform_driver ma35d1serial_driver = {796 .probe = ma35d1serial_probe,797 .remove_new = ma35d1serial_remove,798 .suspend = ma35d1serial_suspend,799 .resume = ma35d1serial_resume,800 .driver = {801 .name = "ma35d1-uart",802 .of_match_table = of_match_ptr(ma35d1_serial_of_match),803 },804};805 806static int __init ma35d1serial_init(void)807{808 int ret;809 810 ret = uart_register_driver(&ma35d1serial_reg);811 if (ret)812 return ret;813 814 ret = platform_driver_register(&ma35d1serial_driver);815 if (ret)816 uart_unregister_driver(&ma35d1serial_reg);817 818 return ret;819}820 821static void __exit ma35d1serial_exit(void)822{823 platform_driver_unregister(&ma35d1serial_driver);824 uart_unregister_driver(&ma35d1serial_reg);825}826 827module_init(ma35d1serial_init);828module_exit(ma35d1serial_exit);829 830MODULE_LICENSE("GPL");831MODULE_DESCRIPTION("MA35D1 serial driver");832