1*2ac4ad2aSVineet Gupta /* 2*2ac4ad2aSVineet Gupta * ARC On-Chip(fpga) UART Driver 3*2ac4ad2aSVineet Gupta * 4*2ac4ad2aSVineet Gupta * Copyright (C) 2010-2012 Synopsys, Inc. (www.synopsys.com) 5*2ac4ad2aSVineet Gupta * 6*2ac4ad2aSVineet Gupta * This program is free software; you can redistribute it and/or modify 7*2ac4ad2aSVineet Gupta * it under the terms of the GNU General Public License version 2 as 8*2ac4ad2aSVineet Gupta * published by the Free Software Foundation. 9*2ac4ad2aSVineet Gupta * 10*2ac4ad2aSVineet Gupta * vineetg: July 10th 2012 11*2ac4ad2aSVineet Gupta * -Decoupled the driver from arch/arc 12*2ac4ad2aSVineet Gupta * +Using platform_get_resource() for irq/membase (thx to bfin_uart.c) 13*2ac4ad2aSVineet Gupta * +Using early_platform_xxx() for early console (thx to mach-shmobile/xxx) 14*2ac4ad2aSVineet Gupta * 15*2ac4ad2aSVineet Gupta * Vineetg: Aug 21st 2010 16*2ac4ad2aSVineet Gupta * -Is uart_tx_stopped() not done in tty write path as it has already been 17*2ac4ad2aSVineet Gupta * taken care of, in serial core 18*2ac4ad2aSVineet Gupta * 19*2ac4ad2aSVineet Gupta * Vineetg: Aug 18th 2010 20*2ac4ad2aSVineet Gupta * -New Serial Core based ARC UART driver 21*2ac4ad2aSVineet Gupta * -Derived largely from blackfin driver albiet with some major tweaks 22*2ac4ad2aSVineet Gupta * 23*2ac4ad2aSVineet Gupta * TODO: 24*2ac4ad2aSVineet Gupta * -check if sysreq works 25*2ac4ad2aSVineet Gupta */ 26*2ac4ad2aSVineet Gupta 27*2ac4ad2aSVineet Gupta #if defined(CONFIG_SERIAL_ARC_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) 28*2ac4ad2aSVineet Gupta #define SUPPORT_SYSRQ 29*2ac4ad2aSVineet Gupta #endif 30*2ac4ad2aSVineet Gupta 31*2ac4ad2aSVineet Gupta #include <linux/module.h> 32*2ac4ad2aSVineet Gupta #include <linux/serial.h> 33*2ac4ad2aSVineet Gupta #include <linux/console.h> 34*2ac4ad2aSVineet Gupta #include <linux/sysrq.h> 35*2ac4ad2aSVineet Gupta #include <linux/platform_device.h> 36*2ac4ad2aSVineet Gupta #include <linux/tty.h> 37*2ac4ad2aSVineet Gupta #include <linux/tty_flip.h> 38*2ac4ad2aSVineet Gupta #include <linux/serial_core.h> 39*2ac4ad2aSVineet Gupta #include <linux/io.h> 40*2ac4ad2aSVineet Gupta 41*2ac4ad2aSVineet Gupta /************************************* 42*2ac4ad2aSVineet Gupta * ARC UART Hardware Specs 43*2ac4ad2aSVineet Gupta ************************************/ 44*2ac4ad2aSVineet Gupta #define ARC_UART_TX_FIFO_SIZE 1 45*2ac4ad2aSVineet Gupta 46*2ac4ad2aSVineet Gupta /* 47*2ac4ad2aSVineet Gupta * UART Register set (this is not a Standards Compliant IP) 48*2ac4ad2aSVineet Gupta * Also each reg is Word aligned, but only 8 bits wide 49*2ac4ad2aSVineet Gupta */ 50*2ac4ad2aSVineet Gupta #define R_ID0 0 51*2ac4ad2aSVineet Gupta #define R_ID1 4 52*2ac4ad2aSVineet Gupta #define R_ID2 8 53*2ac4ad2aSVineet Gupta #define R_ID3 12 54*2ac4ad2aSVineet Gupta #define R_DATA 16 55*2ac4ad2aSVineet Gupta #define R_STS 20 56*2ac4ad2aSVineet Gupta #define R_BAUDL 24 57*2ac4ad2aSVineet Gupta #define R_BAUDH 28 58*2ac4ad2aSVineet Gupta 59*2ac4ad2aSVineet Gupta /* Bits for UART Status Reg (R/W) */ 60*2ac4ad2aSVineet Gupta #define RXIENB 0x04 /* Receive Interrupt Enable */ 61*2ac4ad2aSVineet Gupta #define TXIENB 0x40 /* Transmit Interrupt Enable */ 62*2ac4ad2aSVineet Gupta 63*2ac4ad2aSVineet Gupta #define RXEMPTY 0x20 /* Receive FIFO Empty: No char receivede */ 64*2ac4ad2aSVineet Gupta #define TXEMPTY 0x80 /* Transmit FIFO Empty, thus char can be written into */ 65*2ac4ad2aSVineet Gupta 66*2ac4ad2aSVineet Gupta #define RXFULL 0x08 /* Receive FIFO full */ 67*2ac4ad2aSVineet Gupta #define RXFULL1 0x10 /* Receive FIFO has space for 1 char (tot space=4) */ 68*2ac4ad2aSVineet Gupta 69*2ac4ad2aSVineet Gupta #define RXFERR 0x01 /* Frame Error: Stop Bit not detected */ 70*2ac4ad2aSVineet Gupta #define RXOERR 0x02 /* OverFlow Err: Char recv but RXFULL still set */ 71*2ac4ad2aSVineet Gupta 72*2ac4ad2aSVineet Gupta /* Uart bit fiddling helpers: lowest level */ 73*2ac4ad2aSVineet Gupta #define RBASE(uart, reg) (uart->port.membase + reg) 74*2ac4ad2aSVineet Gupta #define UART_REG_SET(u, r, v) writeb((v), RBASE(u, r)) 75*2ac4ad2aSVineet Gupta #define UART_REG_GET(u, r) readb(RBASE(u, r)) 76*2ac4ad2aSVineet Gupta 77*2ac4ad2aSVineet Gupta #define UART_REG_OR(u, r, v) UART_REG_SET(u, r, UART_REG_GET(u, r) | (v)) 78*2ac4ad2aSVineet Gupta #define UART_REG_CLR(u, r, v) UART_REG_SET(u, r, UART_REG_GET(u, r) & ~(v)) 79*2ac4ad2aSVineet Gupta 80*2ac4ad2aSVineet Gupta /* Uart bit fiddling helpers: API level */ 81*2ac4ad2aSVineet Gupta #define UART_SET_DATA(uart, val) UART_REG_SET(uart, R_DATA, val) 82*2ac4ad2aSVineet Gupta #define UART_GET_DATA(uart) UART_REG_GET(uart, R_DATA) 83*2ac4ad2aSVineet Gupta 84*2ac4ad2aSVineet Gupta #define UART_SET_BAUDH(uart, val) UART_REG_SET(uart, R_BAUDH, val) 85*2ac4ad2aSVineet Gupta #define UART_SET_BAUDL(uart, val) UART_REG_SET(uart, R_BAUDL, val) 86*2ac4ad2aSVineet Gupta 87*2ac4ad2aSVineet Gupta #define UART_CLR_STATUS(uart, val) UART_REG_CLR(uart, R_STS, val) 88*2ac4ad2aSVineet Gupta #define UART_GET_STATUS(uart) UART_REG_GET(uart, R_STS) 89*2ac4ad2aSVineet Gupta 90*2ac4ad2aSVineet Gupta #define UART_ALL_IRQ_DISABLE(uart) UART_REG_CLR(uart, R_STS, RXIENB|TXIENB) 91*2ac4ad2aSVineet Gupta #define UART_RX_IRQ_DISABLE(uart) UART_REG_CLR(uart, R_STS, RXIENB) 92*2ac4ad2aSVineet Gupta #define UART_TX_IRQ_DISABLE(uart) UART_REG_CLR(uart, R_STS, TXIENB) 93*2ac4ad2aSVineet Gupta 94*2ac4ad2aSVineet Gupta #define UART_ALL_IRQ_ENABLE(uart) UART_REG_OR(uart, R_STS, RXIENB|TXIENB) 95*2ac4ad2aSVineet Gupta #define UART_RX_IRQ_ENABLE(uart) UART_REG_OR(uart, R_STS, RXIENB) 96*2ac4ad2aSVineet Gupta #define UART_TX_IRQ_ENABLE(uart) UART_REG_OR(uart, R_STS, TXIENB) 97*2ac4ad2aSVineet Gupta 98*2ac4ad2aSVineet Gupta #define ARC_SERIAL_DEV_NAME "ttyARC" 99*2ac4ad2aSVineet Gupta 100*2ac4ad2aSVineet Gupta struct arc_uart_port { 101*2ac4ad2aSVineet Gupta struct uart_port port; 102*2ac4ad2aSVineet Gupta unsigned long baud; 103*2ac4ad2aSVineet Gupta int is_emulated; /* H/w vs. Instruction Set Simulator */ 104*2ac4ad2aSVineet Gupta }; 105*2ac4ad2aSVineet Gupta 106*2ac4ad2aSVineet Gupta #define to_arc_port(uport) container_of(uport, struct arc_uart_port, port) 107*2ac4ad2aSVineet Gupta 108*2ac4ad2aSVineet Gupta static struct arc_uart_port arc_uart_ports[CONFIG_SERIAL_ARC_NR_PORTS]; 109*2ac4ad2aSVineet Gupta 110*2ac4ad2aSVineet Gupta #ifdef CONFIG_SERIAL_ARC_CONSOLE 111*2ac4ad2aSVineet Gupta static struct console arc_console; 112*2ac4ad2aSVineet Gupta #endif 113*2ac4ad2aSVineet Gupta 114*2ac4ad2aSVineet Gupta #define DRIVER_NAME "arc-uart" 115*2ac4ad2aSVineet Gupta 116*2ac4ad2aSVineet Gupta static struct uart_driver arc_uart_driver = { 117*2ac4ad2aSVineet Gupta .owner = THIS_MODULE, 118*2ac4ad2aSVineet Gupta .driver_name = DRIVER_NAME, 119*2ac4ad2aSVineet Gupta .dev_name = ARC_SERIAL_DEV_NAME, 120*2ac4ad2aSVineet Gupta .major = 0, 121*2ac4ad2aSVineet Gupta .minor = 0, 122*2ac4ad2aSVineet Gupta .nr = CONFIG_SERIAL_ARC_NR_PORTS, 123*2ac4ad2aSVineet Gupta #ifdef CONFIG_SERIAL_ARC_CONSOLE 124*2ac4ad2aSVineet Gupta .cons = &arc_console, 125*2ac4ad2aSVineet Gupta #endif 126*2ac4ad2aSVineet Gupta }; 127*2ac4ad2aSVineet Gupta 128*2ac4ad2aSVineet Gupta static void arc_serial_stop_rx(struct uart_port *port) 129*2ac4ad2aSVineet Gupta { 130*2ac4ad2aSVineet Gupta struct arc_uart_port *uart = to_arc_port(port); 131*2ac4ad2aSVineet Gupta 132*2ac4ad2aSVineet Gupta UART_RX_IRQ_DISABLE(uart); 133*2ac4ad2aSVineet Gupta } 134*2ac4ad2aSVineet Gupta 135*2ac4ad2aSVineet Gupta static void arc_serial_stop_tx(struct uart_port *port) 136*2ac4ad2aSVineet Gupta { 137*2ac4ad2aSVineet Gupta struct arc_uart_port *uart = to_arc_port(port); 138*2ac4ad2aSVineet Gupta 139*2ac4ad2aSVineet Gupta while (!(UART_GET_STATUS(uart) & TXEMPTY)) 140*2ac4ad2aSVineet Gupta cpu_relax(); 141*2ac4ad2aSVineet Gupta 142*2ac4ad2aSVineet Gupta UART_TX_IRQ_DISABLE(uart); 143*2ac4ad2aSVineet Gupta } 144*2ac4ad2aSVineet Gupta 145*2ac4ad2aSVineet Gupta /* 146*2ac4ad2aSVineet Gupta * Return TIOCSER_TEMT when transmitter is not busy. 147*2ac4ad2aSVineet Gupta */ 148*2ac4ad2aSVineet Gupta static unsigned int arc_serial_tx_empty(struct uart_port *port) 149*2ac4ad2aSVineet Gupta { 150*2ac4ad2aSVineet Gupta struct arc_uart_port *uart = to_arc_port(port); 151*2ac4ad2aSVineet Gupta unsigned int stat; 152*2ac4ad2aSVineet Gupta 153*2ac4ad2aSVineet Gupta stat = UART_GET_STATUS(uart); 154*2ac4ad2aSVineet Gupta if (stat & TXEMPTY) 155*2ac4ad2aSVineet Gupta return TIOCSER_TEMT; 156*2ac4ad2aSVineet Gupta 157*2ac4ad2aSVineet Gupta return 0; 158*2ac4ad2aSVineet Gupta } 159*2ac4ad2aSVineet Gupta 160*2ac4ad2aSVineet Gupta /* 161*2ac4ad2aSVineet Gupta * Driver internal routine, used by both tty(serial core) as well as tx-isr 162*2ac4ad2aSVineet Gupta * -Called under spinlock in either cases 163*2ac4ad2aSVineet Gupta * -also tty->stopped / tty->hw_stopped has already been checked 164*2ac4ad2aSVineet Gupta * = by uart_start( ) before calling us 165*2ac4ad2aSVineet Gupta * = tx_ist checks that too before calling 166*2ac4ad2aSVineet Gupta */ 167*2ac4ad2aSVineet Gupta static void arc_serial_tx_chars(struct arc_uart_port *uart) 168*2ac4ad2aSVineet Gupta { 169*2ac4ad2aSVineet Gupta struct circ_buf *xmit = &uart->port.state->xmit; 170*2ac4ad2aSVineet Gupta int sent = 0; 171*2ac4ad2aSVineet Gupta unsigned char ch; 172*2ac4ad2aSVineet Gupta 173*2ac4ad2aSVineet Gupta if (unlikely(uart->port.x_char)) { 174*2ac4ad2aSVineet Gupta UART_SET_DATA(uart, uart->port.x_char); 175*2ac4ad2aSVineet Gupta uart->port.icount.tx++; 176*2ac4ad2aSVineet Gupta uart->port.x_char = 0; 177*2ac4ad2aSVineet Gupta sent = 1; 178*2ac4ad2aSVineet Gupta } else if (xmit->tail != xmit->head) { /* TODO: uart_circ_empty */ 179*2ac4ad2aSVineet Gupta ch = xmit->buf[xmit->tail]; 180*2ac4ad2aSVineet Gupta xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); 181*2ac4ad2aSVineet Gupta uart->port.icount.tx++; 182*2ac4ad2aSVineet Gupta while (!(UART_GET_STATUS(uart) & TXEMPTY)) 183*2ac4ad2aSVineet Gupta cpu_relax(); 184*2ac4ad2aSVineet Gupta UART_SET_DATA(uart, ch); 185*2ac4ad2aSVineet Gupta sent = 1; 186*2ac4ad2aSVineet Gupta } 187*2ac4ad2aSVineet Gupta 188*2ac4ad2aSVineet Gupta /* 189*2ac4ad2aSVineet Gupta * If num chars in xmit buffer are too few, ask tty layer for more. 190*2ac4ad2aSVineet Gupta * By Hard ISR to schedule processing in software interrupt part 191*2ac4ad2aSVineet Gupta */ 192*2ac4ad2aSVineet Gupta if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) 193*2ac4ad2aSVineet Gupta uart_write_wakeup(&uart->port); 194*2ac4ad2aSVineet Gupta 195*2ac4ad2aSVineet Gupta if (sent) 196*2ac4ad2aSVineet Gupta UART_TX_IRQ_ENABLE(uart); 197*2ac4ad2aSVineet Gupta } 198*2ac4ad2aSVineet Gupta 199*2ac4ad2aSVineet Gupta /* 200*2ac4ad2aSVineet Gupta * port is locked and interrupts are disabled 201*2ac4ad2aSVineet Gupta * uart_start( ) calls us under the port spinlock irqsave 202*2ac4ad2aSVineet Gupta */ 203*2ac4ad2aSVineet Gupta static void arc_serial_start_tx(struct uart_port *port) 204*2ac4ad2aSVineet Gupta { 205*2ac4ad2aSVineet Gupta struct arc_uart_port *uart = to_arc_port(port); 206*2ac4ad2aSVineet Gupta 207*2ac4ad2aSVineet Gupta arc_serial_tx_chars(uart); 208*2ac4ad2aSVineet Gupta } 209*2ac4ad2aSVineet Gupta 210*2ac4ad2aSVineet Gupta static void arc_serial_rx_chars(struct arc_uart_port *uart) 211*2ac4ad2aSVineet Gupta { 212*2ac4ad2aSVineet Gupta struct tty_struct *tty = tty_port_tty_get(&uart->port.state->port); 213*2ac4ad2aSVineet Gupta unsigned int status, ch, flg = 0; 214*2ac4ad2aSVineet Gupta 215*2ac4ad2aSVineet Gupta if (!tty) 216*2ac4ad2aSVineet Gupta return; 217*2ac4ad2aSVineet Gupta 218*2ac4ad2aSVineet Gupta /* 219*2ac4ad2aSVineet Gupta * UART has 4 deep RX-FIFO. Driver's recongnition of this fact 220*2ac4ad2aSVineet Gupta * is very subtle. Here's how ... 221*2ac4ad2aSVineet Gupta * Upon getting a RX-Intr, such that RX-EMPTY=0, meaning data available, 222*2ac4ad2aSVineet Gupta * driver reads the DATA Reg and keeps doing that in a loop, until 223*2ac4ad2aSVineet Gupta * RX-EMPTY=1. Multiple chars being avail, with a single Interrupt, 224*2ac4ad2aSVineet Gupta * before RX-EMPTY=0, implies some sort of buffering going on in the 225*2ac4ad2aSVineet Gupta * controller, which is indeed the Rx-FIFO. 226*2ac4ad2aSVineet Gupta */ 227*2ac4ad2aSVineet Gupta while (!((status = UART_GET_STATUS(uart)) & RXEMPTY)) { 228*2ac4ad2aSVineet Gupta 229*2ac4ad2aSVineet Gupta ch = UART_GET_DATA(uart); 230*2ac4ad2aSVineet Gupta uart->port.icount.rx++; 231*2ac4ad2aSVineet Gupta 232*2ac4ad2aSVineet Gupta if (unlikely(status & (RXOERR | RXFERR))) { 233*2ac4ad2aSVineet Gupta if (status & RXOERR) { 234*2ac4ad2aSVineet Gupta uart->port.icount.overrun++; 235*2ac4ad2aSVineet Gupta flg = TTY_OVERRUN; 236*2ac4ad2aSVineet Gupta UART_CLR_STATUS(uart, RXOERR); 237*2ac4ad2aSVineet Gupta } 238*2ac4ad2aSVineet Gupta 239*2ac4ad2aSVineet Gupta if (status & RXFERR) { 240*2ac4ad2aSVineet Gupta uart->port.icount.frame++; 241*2ac4ad2aSVineet Gupta flg = TTY_FRAME; 242*2ac4ad2aSVineet Gupta UART_CLR_STATUS(uart, RXFERR); 243*2ac4ad2aSVineet Gupta } 244*2ac4ad2aSVineet Gupta } else 245*2ac4ad2aSVineet Gupta flg = TTY_NORMAL; 246*2ac4ad2aSVineet Gupta 247*2ac4ad2aSVineet Gupta if (unlikely(uart_handle_sysrq_char(&uart->port, ch))) 248*2ac4ad2aSVineet Gupta goto done; 249*2ac4ad2aSVineet Gupta 250*2ac4ad2aSVineet Gupta uart_insert_char(&uart->port, status, RXOERR, ch, flg); 251*2ac4ad2aSVineet Gupta 252*2ac4ad2aSVineet Gupta done: 253*2ac4ad2aSVineet Gupta tty_flip_buffer_push(tty); 254*2ac4ad2aSVineet Gupta } 255*2ac4ad2aSVineet Gupta 256*2ac4ad2aSVineet Gupta tty_kref_put(tty); 257*2ac4ad2aSVineet Gupta } 258*2ac4ad2aSVineet Gupta 259*2ac4ad2aSVineet Gupta /* 260*2ac4ad2aSVineet Gupta * A note on the Interrupt handling state machine of this driver 261*2ac4ad2aSVineet Gupta * 262*2ac4ad2aSVineet Gupta * kernel printk writes funnel thru the console driver framework and in order 263*2ac4ad2aSVineet Gupta * to keep things simple as well as efficient, it writes to UART in polled 264*2ac4ad2aSVineet Gupta * mode, in one shot, and exits. 265*2ac4ad2aSVineet Gupta * 266*2ac4ad2aSVineet Gupta * OTOH, Userland output (via tty layer), uses interrupt based writes as there 267*2ac4ad2aSVineet Gupta * can be undeterministic delay between char writes. 268*2ac4ad2aSVineet Gupta * 269*2ac4ad2aSVineet Gupta * Thus Rx-interrupts are always enabled, while tx-interrupts are by default 270*2ac4ad2aSVineet Gupta * disabled. 271*2ac4ad2aSVineet Gupta * 272*2ac4ad2aSVineet Gupta * When tty has some data to send out, serial core calls driver's start_tx 273*2ac4ad2aSVineet Gupta * which 274*2ac4ad2aSVineet Gupta * -checks-if-tty-buffer-has-char-to-send 275*2ac4ad2aSVineet Gupta * -writes-data-to-uart 276*2ac4ad2aSVineet Gupta * -enable-tx-intr 277*2ac4ad2aSVineet Gupta * 278*2ac4ad2aSVineet Gupta * Once data bits are pushed out, controller raises the Tx-room-avail-Interrupt. 279*2ac4ad2aSVineet Gupta * The first thing Tx ISR does is disable further Tx interrupts (as this could 280*2ac4ad2aSVineet Gupta * be the last char to send, before settling down into the quiet polled mode). 281*2ac4ad2aSVineet Gupta * It then calls the exact routine used by tty layer write to send out any 282*2ac4ad2aSVineet Gupta * more char in tty buffer. In case of sending, it re-enables Tx-intr. In case 283*2ac4ad2aSVineet Gupta * of no data, it remains disabled. 284*2ac4ad2aSVineet Gupta * This is how the transmit state machine is dynamically switched on/off 285*2ac4ad2aSVineet Gupta */ 286*2ac4ad2aSVineet Gupta 287*2ac4ad2aSVineet Gupta static irqreturn_t arc_serial_isr(int irq, void *dev_id) 288*2ac4ad2aSVineet Gupta { 289*2ac4ad2aSVineet Gupta struct arc_uart_port *uart = dev_id; 290*2ac4ad2aSVineet Gupta unsigned int status; 291*2ac4ad2aSVineet Gupta 292*2ac4ad2aSVineet Gupta status = UART_GET_STATUS(uart); 293*2ac4ad2aSVineet Gupta 294*2ac4ad2aSVineet Gupta /* 295*2ac4ad2aSVineet Gupta * Single IRQ for both Rx (data available) Tx (room available) Interrupt 296*2ac4ad2aSVineet Gupta * notifications from the UART Controller. 297*2ac4ad2aSVineet Gupta * To demultiplex between the two, we check the relevant bits 298*2ac4ad2aSVineet Gupta */ 299*2ac4ad2aSVineet Gupta if ((status & RXIENB) && !(status & RXEMPTY)) { 300*2ac4ad2aSVineet Gupta 301*2ac4ad2aSVineet Gupta /* already in ISR, no need of xx_irqsave */ 302*2ac4ad2aSVineet Gupta spin_lock(&uart->port.lock); 303*2ac4ad2aSVineet Gupta arc_serial_rx_chars(uart); 304*2ac4ad2aSVineet Gupta spin_unlock(&uart->port.lock); 305*2ac4ad2aSVineet Gupta } 306*2ac4ad2aSVineet Gupta 307*2ac4ad2aSVineet Gupta if ((status & TXIENB) && (status & TXEMPTY)) { 308*2ac4ad2aSVineet Gupta 309*2ac4ad2aSVineet Gupta /* Unconditionally disable further Tx-Interrupts. 310*2ac4ad2aSVineet Gupta * will be enabled by tx_chars() if needed. 311*2ac4ad2aSVineet Gupta */ 312*2ac4ad2aSVineet Gupta UART_TX_IRQ_DISABLE(uart); 313*2ac4ad2aSVineet Gupta 314*2ac4ad2aSVineet Gupta spin_lock(&uart->port.lock); 315*2ac4ad2aSVineet Gupta 316*2ac4ad2aSVineet Gupta if (!uart_tx_stopped(&uart->port)) 317*2ac4ad2aSVineet Gupta arc_serial_tx_chars(uart); 318*2ac4ad2aSVineet Gupta 319*2ac4ad2aSVineet Gupta spin_unlock(&uart->port.lock); 320*2ac4ad2aSVineet Gupta } 321*2ac4ad2aSVineet Gupta 322*2ac4ad2aSVineet Gupta return IRQ_HANDLED; 323*2ac4ad2aSVineet Gupta } 324*2ac4ad2aSVineet Gupta 325*2ac4ad2aSVineet Gupta static unsigned int arc_serial_get_mctrl(struct uart_port *port) 326*2ac4ad2aSVineet Gupta { 327*2ac4ad2aSVineet Gupta /* 328*2ac4ad2aSVineet Gupta * Pretend we have a Modem status reg and following bits are 329*2ac4ad2aSVineet Gupta * always set, to satify the serial core state machine 330*2ac4ad2aSVineet Gupta * (DSR) Data Set Ready 331*2ac4ad2aSVineet Gupta * (CTS) Clear To Send 332*2ac4ad2aSVineet Gupta * (CAR) Carrier Detect 333*2ac4ad2aSVineet Gupta */ 334*2ac4ad2aSVineet Gupta return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; 335*2ac4ad2aSVineet Gupta } 336*2ac4ad2aSVineet Gupta 337*2ac4ad2aSVineet Gupta static void arc_serial_set_mctrl(struct uart_port *port, unsigned int mctrl) 338*2ac4ad2aSVineet Gupta { 339*2ac4ad2aSVineet Gupta /* MCR not present */ 340*2ac4ad2aSVineet Gupta } 341*2ac4ad2aSVineet Gupta 342*2ac4ad2aSVineet Gupta /* Enable Modem Status Interrupts */ 343*2ac4ad2aSVineet Gupta 344*2ac4ad2aSVineet Gupta static void arc_serial_enable_ms(struct uart_port *port) 345*2ac4ad2aSVineet Gupta { 346*2ac4ad2aSVineet Gupta /* MSR not present */ 347*2ac4ad2aSVineet Gupta } 348*2ac4ad2aSVineet Gupta 349*2ac4ad2aSVineet Gupta static void arc_serial_break_ctl(struct uart_port *port, int break_state) 350*2ac4ad2aSVineet Gupta { 351*2ac4ad2aSVineet Gupta /* ARC UART doesn't support sending Break signal */ 352*2ac4ad2aSVineet Gupta } 353*2ac4ad2aSVineet Gupta 354*2ac4ad2aSVineet Gupta static int arc_serial_startup(struct uart_port *port) 355*2ac4ad2aSVineet Gupta { 356*2ac4ad2aSVineet Gupta struct arc_uart_port *uart = to_arc_port(port); 357*2ac4ad2aSVineet Gupta 358*2ac4ad2aSVineet Gupta /* Before we hook up the ISR, Disable all UART Interrupts */ 359*2ac4ad2aSVineet Gupta UART_ALL_IRQ_DISABLE(uart); 360*2ac4ad2aSVineet Gupta 361*2ac4ad2aSVineet Gupta if (request_irq(uart->port.irq, arc_serial_isr, 0, "arc uart rx-tx", 362*2ac4ad2aSVineet Gupta uart)) { 363*2ac4ad2aSVineet Gupta dev_warn(uart->port.dev, "Unable to attach ARC UART intr\n"); 364*2ac4ad2aSVineet Gupta return -EBUSY; 365*2ac4ad2aSVineet Gupta } 366*2ac4ad2aSVineet Gupta 367*2ac4ad2aSVineet Gupta UART_RX_IRQ_ENABLE(uart); /* Only Rx IRQ enabled to begin with */ 368*2ac4ad2aSVineet Gupta 369*2ac4ad2aSVineet Gupta return 0; 370*2ac4ad2aSVineet Gupta } 371*2ac4ad2aSVineet Gupta 372*2ac4ad2aSVineet Gupta /* This is not really needed */ 373*2ac4ad2aSVineet Gupta static void arc_serial_shutdown(struct uart_port *port) 374*2ac4ad2aSVineet Gupta { 375*2ac4ad2aSVineet Gupta struct arc_uart_port *uart = to_arc_port(port); 376*2ac4ad2aSVineet Gupta free_irq(uart->port.irq, uart); 377*2ac4ad2aSVineet Gupta } 378*2ac4ad2aSVineet Gupta 379*2ac4ad2aSVineet Gupta static void 380*2ac4ad2aSVineet Gupta arc_serial_set_termios(struct uart_port *port, struct ktermios *new, 381*2ac4ad2aSVineet Gupta struct ktermios *old) 382*2ac4ad2aSVineet Gupta { 383*2ac4ad2aSVineet Gupta struct arc_uart_port *uart = to_arc_port(port); 384*2ac4ad2aSVineet Gupta unsigned int baud, uartl, uarth, hw_val; 385*2ac4ad2aSVineet Gupta unsigned long flags; 386*2ac4ad2aSVineet Gupta 387*2ac4ad2aSVineet Gupta /* 388*2ac4ad2aSVineet Gupta * Use the generic handler so that any specially encoded baud rates 389*2ac4ad2aSVineet Gupta * such as SPD_xx flags or "%B0" can be handled 390*2ac4ad2aSVineet Gupta * Max Baud I suppose will not be more than current 115K * 4 391*2ac4ad2aSVineet Gupta * Formula for ARC UART is: hw-val = ((CLK/(BAUD*4)) -1) 392*2ac4ad2aSVineet Gupta * spread over two 8-bit registers 393*2ac4ad2aSVineet Gupta */ 394*2ac4ad2aSVineet Gupta baud = uart_get_baud_rate(port, new, old, 0, 460800); 395*2ac4ad2aSVineet Gupta 396*2ac4ad2aSVineet Gupta hw_val = port->uartclk / (uart->baud * 4) - 1; 397*2ac4ad2aSVineet Gupta uartl = hw_val & 0xFF; 398*2ac4ad2aSVineet Gupta uarth = (hw_val >> 8) & 0xFF; 399*2ac4ad2aSVineet Gupta 400*2ac4ad2aSVineet Gupta /* 401*2ac4ad2aSVineet Gupta * UART ISS(Instruction Set simulator) emulation has a subtle bug: 402*2ac4ad2aSVineet Gupta * A existing value of Baudh = 0 is used as a indication to startup 403*2ac4ad2aSVineet Gupta * it's internal state machine. 404*2ac4ad2aSVineet Gupta * Thus if baudh is set to 0, 2 times, it chokes. 405*2ac4ad2aSVineet Gupta * This happens with BAUD=115200 and the formaula above 406*2ac4ad2aSVineet Gupta * Until that is fixed, when running on ISS, we will set baudh to !0 407*2ac4ad2aSVineet Gupta */ 408*2ac4ad2aSVineet Gupta if (uart->is_emulated) 409*2ac4ad2aSVineet Gupta uarth = 1; 410*2ac4ad2aSVineet Gupta 411*2ac4ad2aSVineet Gupta spin_lock_irqsave(&port->lock, flags); 412*2ac4ad2aSVineet Gupta 413*2ac4ad2aSVineet Gupta UART_ALL_IRQ_DISABLE(uart); 414*2ac4ad2aSVineet Gupta 415*2ac4ad2aSVineet Gupta UART_SET_BAUDL(uart, uartl); 416*2ac4ad2aSVineet Gupta UART_SET_BAUDH(uart, uarth); 417*2ac4ad2aSVineet Gupta 418*2ac4ad2aSVineet Gupta UART_RX_IRQ_ENABLE(uart); 419*2ac4ad2aSVineet Gupta 420*2ac4ad2aSVineet Gupta /* 421*2ac4ad2aSVineet Gupta * UART doesn't support Parity/Hardware Flow Control; 422*2ac4ad2aSVineet Gupta * Only supports 8N1 character size 423*2ac4ad2aSVineet Gupta */ 424*2ac4ad2aSVineet Gupta new->c_cflag &= ~(CMSPAR|CRTSCTS|CSIZE); 425*2ac4ad2aSVineet Gupta new->c_cflag |= CS8; 426*2ac4ad2aSVineet Gupta 427*2ac4ad2aSVineet Gupta if (old) 428*2ac4ad2aSVineet Gupta tty_termios_copy_hw(new, old); 429*2ac4ad2aSVineet Gupta 430*2ac4ad2aSVineet Gupta /* Don't rewrite B0 */ 431*2ac4ad2aSVineet Gupta if (tty_termios_baud_rate(new)) 432*2ac4ad2aSVineet Gupta tty_termios_encode_baud_rate(new, baud, baud); 433*2ac4ad2aSVineet Gupta 434*2ac4ad2aSVineet Gupta uart_update_timeout(port, new->c_cflag, baud); 435*2ac4ad2aSVineet Gupta 436*2ac4ad2aSVineet Gupta spin_unlock_irqrestore(&port->lock, flags); 437*2ac4ad2aSVineet Gupta } 438*2ac4ad2aSVineet Gupta 439*2ac4ad2aSVineet Gupta static const char *arc_serial_type(struct uart_port *port) 440*2ac4ad2aSVineet Gupta { 441*2ac4ad2aSVineet Gupta struct arc_uart_port *uart = to_arc_port(port); 442*2ac4ad2aSVineet Gupta 443*2ac4ad2aSVineet Gupta return uart->port.type == PORT_ARC ? DRIVER_NAME : NULL; 444*2ac4ad2aSVineet Gupta } 445*2ac4ad2aSVineet Gupta 446*2ac4ad2aSVineet Gupta static void arc_serial_release_port(struct uart_port *port) 447*2ac4ad2aSVineet Gupta { 448*2ac4ad2aSVineet Gupta } 449*2ac4ad2aSVineet Gupta 450*2ac4ad2aSVineet Gupta static int arc_serial_request_port(struct uart_port *port) 451*2ac4ad2aSVineet Gupta { 452*2ac4ad2aSVineet Gupta return 0; 453*2ac4ad2aSVineet Gupta } 454*2ac4ad2aSVineet Gupta 455*2ac4ad2aSVineet Gupta /* 456*2ac4ad2aSVineet Gupta * Verify the new serial_struct (for TIOCSSERIAL). 457*2ac4ad2aSVineet Gupta */ 458*2ac4ad2aSVineet Gupta static int 459*2ac4ad2aSVineet Gupta arc_serial_verify_port(struct uart_port *port, struct serial_struct *ser) 460*2ac4ad2aSVineet Gupta { 461*2ac4ad2aSVineet Gupta if (port->type != PORT_UNKNOWN && ser->type != PORT_ARC) 462*2ac4ad2aSVineet Gupta return -EINVAL; 463*2ac4ad2aSVineet Gupta 464*2ac4ad2aSVineet Gupta return 0; 465*2ac4ad2aSVineet Gupta } 466*2ac4ad2aSVineet Gupta 467*2ac4ad2aSVineet Gupta /* 468*2ac4ad2aSVineet Gupta * Configure/autoconfigure the port. 469*2ac4ad2aSVineet Gupta */ 470*2ac4ad2aSVineet Gupta static void arc_serial_config_port(struct uart_port *port, int flags) 471*2ac4ad2aSVineet Gupta { 472*2ac4ad2aSVineet Gupta struct arc_uart_port *uart = to_arc_port(port); 473*2ac4ad2aSVineet Gupta 474*2ac4ad2aSVineet Gupta if (flags & UART_CONFIG_TYPE) 475*2ac4ad2aSVineet Gupta uart->port.type = PORT_ARC; 476*2ac4ad2aSVineet Gupta } 477*2ac4ad2aSVineet Gupta 478*2ac4ad2aSVineet Gupta #if defined(CONFIG_CONSOLE_POLL) || defined(CONFIG_SERIAL_ARC_CONSOLE) 479*2ac4ad2aSVineet Gupta 480*2ac4ad2aSVineet Gupta static void arc_serial_poll_putchar(struct uart_port *port, unsigned char chr) 481*2ac4ad2aSVineet Gupta { 482*2ac4ad2aSVineet Gupta struct arc_uart_port *uart = to_arc_port(port); 483*2ac4ad2aSVineet Gupta 484*2ac4ad2aSVineet Gupta while (!(UART_GET_STATUS(uart) & TXEMPTY)) 485*2ac4ad2aSVineet Gupta cpu_relax(); 486*2ac4ad2aSVineet Gupta 487*2ac4ad2aSVineet Gupta UART_SET_DATA(uart, chr); 488*2ac4ad2aSVineet Gupta } 489*2ac4ad2aSVineet Gupta #endif 490*2ac4ad2aSVineet Gupta 491*2ac4ad2aSVineet Gupta #ifdef CONFIG_CONSOLE_POLL 492*2ac4ad2aSVineet Gupta static int arc_serial_poll_getchar(struct uart_port *port) 493*2ac4ad2aSVineet Gupta { 494*2ac4ad2aSVineet Gupta struct arc_uart_port *uart = to_arc_port(port); 495*2ac4ad2aSVineet Gupta unsigned char chr; 496*2ac4ad2aSVineet Gupta 497*2ac4ad2aSVineet Gupta while (!(UART_GET_STATUS(uart) & RXEMPTY)) 498*2ac4ad2aSVineet Gupta cpu_relax(); 499*2ac4ad2aSVineet Gupta 500*2ac4ad2aSVineet Gupta chr = UART_GET_DATA(uart); 501*2ac4ad2aSVineet Gupta return chr; 502*2ac4ad2aSVineet Gupta } 503*2ac4ad2aSVineet Gupta #endif 504*2ac4ad2aSVineet Gupta 505*2ac4ad2aSVineet Gupta static struct uart_ops arc_serial_pops = { 506*2ac4ad2aSVineet Gupta .tx_empty = arc_serial_tx_empty, 507*2ac4ad2aSVineet Gupta .set_mctrl = arc_serial_set_mctrl, 508*2ac4ad2aSVineet Gupta .get_mctrl = arc_serial_get_mctrl, 509*2ac4ad2aSVineet Gupta .stop_tx = arc_serial_stop_tx, 510*2ac4ad2aSVineet Gupta .start_tx = arc_serial_start_tx, 511*2ac4ad2aSVineet Gupta .stop_rx = arc_serial_stop_rx, 512*2ac4ad2aSVineet Gupta .enable_ms = arc_serial_enable_ms, 513*2ac4ad2aSVineet Gupta .break_ctl = arc_serial_break_ctl, 514*2ac4ad2aSVineet Gupta .startup = arc_serial_startup, 515*2ac4ad2aSVineet Gupta .shutdown = arc_serial_shutdown, 516*2ac4ad2aSVineet Gupta .set_termios = arc_serial_set_termios, 517*2ac4ad2aSVineet Gupta .type = arc_serial_type, 518*2ac4ad2aSVineet Gupta .release_port = arc_serial_release_port, 519*2ac4ad2aSVineet Gupta .request_port = arc_serial_request_port, 520*2ac4ad2aSVineet Gupta .config_port = arc_serial_config_port, 521*2ac4ad2aSVineet Gupta .verify_port = arc_serial_verify_port, 522*2ac4ad2aSVineet Gupta #ifdef CONFIG_CONSOLE_POLL 523*2ac4ad2aSVineet Gupta .poll_put_char = arc_serial_poll_putchar, 524*2ac4ad2aSVineet Gupta .poll_get_char = arc_serial_poll_getchar, 525*2ac4ad2aSVineet Gupta #endif 526*2ac4ad2aSVineet Gupta }; 527*2ac4ad2aSVineet Gupta 528*2ac4ad2aSVineet Gupta static int __devinit 529*2ac4ad2aSVineet Gupta arc_uart_init_one(struct platform_device *pdev, struct arc_uart_port *uart) 530*2ac4ad2aSVineet Gupta { 531*2ac4ad2aSVineet Gupta struct resource *res, *res2; 532*2ac4ad2aSVineet Gupta unsigned long *plat_data; 533*2ac4ad2aSVineet Gupta 534*2ac4ad2aSVineet Gupta if (pdev->id < 0 || pdev->id >= CONFIG_SERIAL_ARC_NR_PORTS) { 535*2ac4ad2aSVineet Gupta dev_err(&pdev->dev, "Wrong uart platform device id.\n"); 536*2ac4ad2aSVineet Gupta return -ENOENT; 537*2ac4ad2aSVineet Gupta } 538*2ac4ad2aSVineet Gupta 539*2ac4ad2aSVineet Gupta plat_data = ((unsigned long *)(pdev->dev.platform_data)); 540*2ac4ad2aSVineet Gupta uart->baud = plat_data[0]; 541*2ac4ad2aSVineet Gupta 542*2ac4ad2aSVineet Gupta res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 543*2ac4ad2aSVineet Gupta if (!res) 544*2ac4ad2aSVineet Gupta return -ENODEV; 545*2ac4ad2aSVineet Gupta 546*2ac4ad2aSVineet Gupta res2 = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 547*2ac4ad2aSVineet Gupta if (!res2) 548*2ac4ad2aSVineet Gupta return -ENODEV; 549*2ac4ad2aSVineet Gupta 550*2ac4ad2aSVineet Gupta uart->port.mapbase = res->start; 551*2ac4ad2aSVineet Gupta uart->port.membase = ioremap_nocache(res->start, resource_size(res)); 552*2ac4ad2aSVineet Gupta if (!uart->port.membase) 553*2ac4ad2aSVineet Gupta /* No point of dev_err since UART itself is hosed here */ 554*2ac4ad2aSVineet Gupta return -ENXIO; 555*2ac4ad2aSVineet Gupta 556*2ac4ad2aSVineet Gupta uart->port.irq = res2->start; 557*2ac4ad2aSVineet Gupta uart->port.dev = &pdev->dev; 558*2ac4ad2aSVineet Gupta uart->port.iotype = UPIO_MEM; 559*2ac4ad2aSVineet Gupta uart->port.flags = UPF_BOOT_AUTOCONF; 560*2ac4ad2aSVineet Gupta uart->port.line = pdev->id; 561*2ac4ad2aSVineet Gupta uart->port.ops = &arc_serial_pops; 562*2ac4ad2aSVineet Gupta 563*2ac4ad2aSVineet Gupta uart->port.uartclk = plat_data[1]; 564*2ac4ad2aSVineet Gupta uart->port.fifosize = ARC_UART_TX_FIFO_SIZE; 565*2ac4ad2aSVineet Gupta 566*2ac4ad2aSVineet Gupta /* 567*2ac4ad2aSVineet Gupta * uart_insert_char( ) uses it in decideding whether to ignore a 568*2ac4ad2aSVineet Gupta * char or not. Explicitly setting it here, removes the subtelty 569*2ac4ad2aSVineet Gupta */ 570*2ac4ad2aSVineet Gupta uart->port.ignore_status_mask = 0; 571*2ac4ad2aSVineet Gupta 572*2ac4ad2aSVineet Gupta /* Real Hardware vs. emulated to work around a bug */ 573*2ac4ad2aSVineet Gupta uart->is_emulated = !!plat_data[2]; 574*2ac4ad2aSVineet Gupta 575*2ac4ad2aSVineet Gupta return 0; 576*2ac4ad2aSVineet Gupta } 577*2ac4ad2aSVineet Gupta 578*2ac4ad2aSVineet Gupta #ifdef CONFIG_SERIAL_ARC_CONSOLE 579*2ac4ad2aSVineet Gupta 580*2ac4ad2aSVineet Gupta static int __devinit arc_serial_console_setup(struct console *co, char *options) 581*2ac4ad2aSVineet Gupta { 582*2ac4ad2aSVineet Gupta struct uart_port *port; 583*2ac4ad2aSVineet Gupta int baud = 115200; 584*2ac4ad2aSVineet Gupta int bits = 8; 585*2ac4ad2aSVineet Gupta int parity = 'n'; 586*2ac4ad2aSVineet Gupta int flow = 'n'; 587*2ac4ad2aSVineet Gupta 588*2ac4ad2aSVineet Gupta if (co->index < 0 || co->index >= CONFIG_SERIAL_ARC_NR_PORTS) 589*2ac4ad2aSVineet Gupta return -ENODEV; 590*2ac4ad2aSVineet Gupta 591*2ac4ad2aSVineet Gupta /* 592*2ac4ad2aSVineet Gupta * The uart port backing the console (e.g. ttyARC1) might not have been 593*2ac4ad2aSVineet Gupta * init yet. If so, defer the console setup to after the port. 594*2ac4ad2aSVineet Gupta */ 595*2ac4ad2aSVineet Gupta port = &arc_uart_ports[co->index].port; 596*2ac4ad2aSVineet Gupta if (!port->membase) 597*2ac4ad2aSVineet Gupta return -ENODEV; 598*2ac4ad2aSVineet Gupta 599*2ac4ad2aSVineet Gupta if (options) 600*2ac4ad2aSVineet Gupta uart_parse_options(options, &baud, &parity, &bits, &flow); 601*2ac4ad2aSVineet Gupta 602*2ac4ad2aSVineet Gupta /* 603*2ac4ad2aSVineet Gupta * Serial core will call port->ops->set_termios( ) 604*2ac4ad2aSVineet Gupta * which will set the baud reg 605*2ac4ad2aSVineet Gupta */ 606*2ac4ad2aSVineet Gupta return uart_set_options(port, co, baud, parity, bits, flow); 607*2ac4ad2aSVineet Gupta } 608*2ac4ad2aSVineet Gupta 609*2ac4ad2aSVineet Gupta static void arc_serial_console_putchar(struct uart_port *port, int ch) 610*2ac4ad2aSVineet Gupta { 611*2ac4ad2aSVineet Gupta arc_serial_poll_putchar(port, (unsigned char)ch); 612*2ac4ad2aSVineet Gupta } 613*2ac4ad2aSVineet Gupta 614*2ac4ad2aSVineet Gupta /* 615*2ac4ad2aSVineet Gupta * Interrupts are disabled on entering 616*2ac4ad2aSVineet Gupta */ 617*2ac4ad2aSVineet Gupta static void arc_serial_console_write(struct console *co, const char *s, 618*2ac4ad2aSVineet Gupta unsigned int count) 619*2ac4ad2aSVineet Gupta { 620*2ac4ad2aSVineet Gupta struct uart_port *port = &arc_uart_ports[co->index].port; 621*2ac4ad2aSVineet Gupta unsigned long flags; 622*2ac4ad2aSVineet Gupta 623*2ac4ad2aSVineet Gupta spin_lock_irqsave(&port->lock, flags); 624*2ac4ad2aSVineet Gupta uart_console_write(port, s, count, arc_serial_console_putchar); 625*2ac4ad2aSVineet Gupta spin_unlock_irqrestore(&port->lock, flags); 626*2ac4ad2aSVineet Gupta } 627*2ac4ad2aSVineet Gupta 628*2ac4ad2aSVineet Gupta static struct console arc_console = { 629*2ac4ad2aSVineet Gupta .name = ARC_SERIAL_DEV_NAME, 630*2ac4ad2aSVineet Gupta .write = arc_serial_console_write, 631*2ac4ad2aSVineet Gupta .device = uart_console_device, 632*2ac4ad2aSVineet Gupta .setup = arc_serial_console_setup, 633*2ac4ad2aSVineet Gupta .flags = CON_PRINTBUFFER, 634*2ac4ad2aSVineet Gupta .index = -1, 635*2ac4ad2aSVineet Gupta .data = &arc_uart_driver 636*2ac4ad2aSVineet Gupta }; 637*2ac4ad2aSVineet Gupta 638*2ac4ad2aSVineet Gupta static __init void early_serial_write(struct console *con, const char *s, 639*2ac4ad2aSVineet Gupta unsigned int n) 640*2ac4ad2aSVineet Gupta { 641*2ac4ad2aSVineet Gupta struct uart_port *port = &arc_uart_ports[con->index].port; 642*2ac4ad2aSVineet Gupta unsigned int i; 643*2ac4ad2aSVineet Gupta 644*2ac4ad2aSVineet Gupta for (i = 0; i < n; i++, s++) { 645*2ac4ad2aSVineet Gupta if (*s == '\n') 646*2ac4ad2aSVineet Gupta arc_serial_poll_putchar(port, '\r'); 647*2ac4ad2aSVineet Gupta arc_serial_poll_putchar(port, *s); 648*2ac4ad2aSVineet Gupta } 649*2ac4ad2aSVineet Gupta } 650*2ac4ad2aSVineet Gupta 651*2ac4ad2aSVineet Gupta static struct __initdata console arc_early_serial_console = { 652*2ac4ad2aSVineet Gupta .name = "early_ARCuart", 653*2ac4ad2aSVineet Gupta .write = early_serial_write, 654*2ac4ad2aSVineet Gupta .flags = CON_PRINTBUFFER | CON_BOOT, 655*2ac4ad2aSVineet Gupta .index = -1 656*2ac4ad2aSVineet Gupta }; 657*2ac4ad2aSVineet Gupta 658*2ac4ad2aSVineet Gupta static int __devinit arc_serial_probe_earlyprintk(struct platform_device *pdev) 659*2ac4ad2aSVineet Gupta { 660*2ac4ad2aSVineet Gupta arc_early_serial_console.index = pdev->id; 661*2ac4ad2aSVineet Gupta 662*2ac4ad2aSVineet Gupta arc_uart_init_one(pdev, &arc_uart_ports[pdev->id]); 663*2ac4ad2aSVineet Gupta 664*2ac4ad2aSVineet Gupta arc_serial_console_setup(&arc_early_serial_console, NULL); 665*2ac4ad2aSVineet Gupta 666*2ac4ad2aSVineet Gupta register_console(&arc_early_serial_console); 667*2ac4ad2aSVineet Gupta return 0; 668*2ac4ad2aSVineet Gupta } 669*2ac4ad2aSVineet Gupta #else 670*2ac4ad2aSVineet Gupta static int __devinit arc_serial_probe_earlyprintk(struct platform_device *pdev) 671*2ac4ad2aSVineet Gupta { 672*2ac4ad2aSVineet Gupta return -ENODEV; 673*2ac4ad2aSVineet Gupta } 674*2ac4ad2aSVineet Gupta #endif /* CONFIG_SERIAL_ARC_CONSOLE */ 675*2ac4ad2aSVineet Gupta 676*2ac4ad2aSVineet Gupta static int __devinit arc_serial_probe(struct platform_device *pdev) 677*2ac4ad2aSVineet Gupta { 678*2ac4ad2aSVineet Gupta struct arc_uart_port *uart; 679*2ac4ad2aSVineet Gupta int rc; 680*2ac4ad2aSVineet Gupta 681*2ac4ad2aSVineet Gupta if (is_early_platform_device(pdev)) 682*2ac4ad2aSVineet Gupta return arc_serial_probe_earlyprintk(pdev); 683*2ac4ad2aSVineet Gupta 684*2ac4ad2aSVineet Gupta uart = &arc_uart_ports[pdev->id]; 685*2ac4ad2aSVineet Gupta rc = arc_uart_init_one(pdev, uart); 686*2ac4ad2aSVineet Gupta if (rc) 687*2ac4ad2aSVineet Gupta return rc; 688*2ac4ad2aSVineet Gupta 689*2ac4ad2aSVineet Gupta return uart_add_one_port(&arc_uart_driver, &uart->port); 690*2ac4ad2aSVineet Gupta } 691*2ac4ad2aSVineet Gupta 692*2ac4ad2aSVineet Gupta static int __devexit arc_serial_remove(struct platform_device *pdev) 693*2ac4ad2aSVineet Gupta { 694*2ac4ad2aSVineet Gupta /* This will never be called */ 695*2ac4ad2aSVineet Gupta return 0; 696*2ac4ad2aSVineet Gupta } 697*2ac4ad2aSVineet Gupta 698*2ac4ad2aSVineet Gupta static struct platform_driver arc_platform_driver = { 699*2ac4ad2aSVineet Gupta .probe = arc_serial_probe, 700*2ac4ad2aSVineet Gupta .remove = __devexit_p(arc_serial_remove), 701*2ac4ad2aSVineet Gupta .driver = { 702*2ac4ad2aSVineet Gupta .name = DRIVER_NAME, 703*2ac4ad2aSVineet Gupta .owner = THIS_MODULE, 704*2ac4ad2aSVineet Gupta }, 705*2ac4ad2aSVineet Gupta }; 706*2ac4ad2aSVineet Gupta 707*2ac4ad2aSVineet Gupta #ifdef CONFIG_SERIAL_ARC_CONSOLE 708*2ac4ad2aSVineet Gupta /* 709*2ac4ad2aSVineet Gupta * Register an early platform driver of "earlyprintk" class. 710*2ac4ad2aSVineet Gupta * ARCH platform code installs the driver and probes the early devices 711*2ac4ad2aSVineet Gupta * The installation could rely on user specifying earlyprintk=xyx in cmd line 712*2ac4ad2aSVineet Gupta * or it could be done independently, for all "earlyprintk" class drivers. 713*2ac4ad2aSVineet Gupta * [see arch/arc/plat-arcfpga/platform.c] 714*2ac4ad2aSVineet Gupta */ 715*2ac4ad2aSVineet Gupta early_platform_init("earlyprintk", &arc_platform_driver); 716*2ac4ad2aSVineet Gupta 717*2ac4ad2aSVineet Gupta #endif /* CONFIG_SERIAL_ARC_CONSOLE */ 718*2ac4ad2aSVineet Gupta 719*2ac4ad2aSVineet Gupta static int __init arc_serial_init(void) 720*2ac4ad2aSVineet Gupta { 721*2ac4ad2aSVineet Gupta int ret; 722*2ac4ad2aSVineet Gupta 723*2ac4ad2aSVineet Gupta ret = uart_register_driver(&arc_uart_driver); 724*2ac4ad2aSVineet Gupta if (ret) 725*2ac4ad2aSVineet Gupta return ret; 726*2ac4ad2aSVineet Gupta 727*2ac4ad2aSVineet Gupta ret = platform_driver_register(&arc_platform_driver); 728*2ac4ad2aSVineet Gupta if (ret) 729*2ac4ad2aSVineet Gupta uart_unregister_driver(&arc_uart_driver); 730*2ac4ad2aSVineet Gupta 731*2ac4ad2aSVineet Gupta return ret; 732*2ac4ad2aSVineet Gupta } 733*2ac4ad2aSVineet Gupta 734*2ac4ad2aSVineet Gupta static void __exit arc_serial_exit(void) 735*2ac4ad2aSVineet Gupta { 736*2ac4ad2aSVineet Gupta platform_driver_unregister(&arc_platform_driver); 737*2ac4ad2aSVineet Gupta uart_unregister_driver(&arc_uart_driver); 738*2ac4ad2aSVineet Gupta } 739*2ac4ad2aSVineet Gupta 740*2ac4ad2aSVineet Gupta module_init(arc_serial_init); 741*2ac4ad2aSVineet Gupta module_exit(arc_serial_exit); 742*2ac4ad2aSVineet Gupta 743*2ac4ad2aSVineet Gupta MODULE_LICENSE("GPL"); 744*2ac4ad2aSVineet Gupta MODULE_ALIAS("plat-arcfpga/uart"); 745*2ac4ad2aSVineet Gupta MODULE_AUTHOR("Vineet Gupta"); 746*2ac4ad2aSVineet Gupta MODULE_DESCRIPTION("ARC(Synopsys) On-Chip(fpga) serial driver"); 747