blob: ca54f038ab45913163921661eb1c10a702d3aca6 [file] [log] [blame]
Govindraj.Rb6126332010-09-27 20:20:49 +05301/*
2 * Driver for OMAP-UART controller.
3 * Based on drivers/serial/8250.c
4 *
5 * Copyright (C) 2010 Texas Instruments.
6 *
7 * Authors:
8 * Govindraj R <govindraj.raja@ti.com>
9 * Thara Gopinath <thara@ti.com>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
Lucas De Marchi25985ed2011-03-30 22:57:33 -030016 * Note: This driver is made separate from 8250 driver as we cannot
Govindraj.Rb6126332010-09-27 20:20:49 +053017 * over load 8250 driver with omap platform specific configuration for
18 * features like DMA, it makes easier to implement features like DMA and
19 * hardware flow control and software flow control configuration with
20 * this driver as required for the omap-platform.
21 */
22
Thomas Weber364a6ec2011-02-01 08:30:41 +010023#if defined(CONFIG_SERIAL_OMAP_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
24#define SUPPORT_SYSRQ
25#endif
26
Govindraj.Rb6126332010-09-27 20:20:49 +053027#include <linux/module.h>
28#include <linux/init.h>
29#include <linux/console.h>
30#include <linux/serial_reg.h>
31#include <linux/delay.h>
32#include <linux/slab.h>
33#include <linux/tty.h>
34#include <linux/tty_flip.h>
35#include <linux/io.h>
36#include <linux/dma-mapping.h>
37#include <linux/clk.h>
38#include <linux/serial_core.h>
39#include <linux/irq.h>
Govindraj.Rfcdca752011-02-28 18:12:23 +053040#include <linux/pm_runtime.h>
Rajendra Nayakd92b0df2011-12-14 17:25:45 +053041#include <linux/of.h>
Govindraj.Rb6126332010-09-27 20:20:49 +053042
43#include <plat/dma.h>
44#include <plat/dmtimer.h>
45#include <plat/omap-serial.h>
46
Rajendra Nayak8fe789d2011-12-14 17:25:44 +053047#define DEFAULT_CLK_SPEED 48000000 /* 48Mhz*/
48
Paul Walmsley0a697b22012-01-21 00:27:40 -070049/* SCR register bitmasks */
50#define OMAP_UART_SCR_RX_TRIG_GRANU1_MASK (1 << 7)
51#define OMAP_UART_SCR_TX_TRIG_GRANU1_MASK (1 << 6)
52
53/* FCR register bitmasks */
54#define OMAP_UART_FCR_RX_FIFO_TRIG_SHIFT 6
55#define OMAP_UART_FCR_RX_FIFO_TRIG_MASK (0x3 << 6)
56#define OMAP_UART_FCR_TX_FIFO_TRIG_SHIFT 4
57
58/* TLR register bitmasks */
59#define OMAP_UART_TLR_TX_FIFO_TRIG_DMA_SHIFT 0
60
Govindraj.Rb6126332010-09-27 20:20:49 +053061static struct uart_omap_port *ui[OMAP_MAX_HSUART_PORTS];
62
63/* Forward declaration of functions */
64static void uart_tx_dma_callback(int lch, u16 ch_status, void *data);
Jon Huntera9e210e2011-11-09 17:34:49 +053065static void serial_omap_rxdma_poll(unsigned long uart_no);
Govindraj.Rb6126332010-09-27 20:20:49 +053066static int serial_omap_start_rxdma(struct uart_omap_port *up);
Govindraj.R94734742011-11-07 19:00:33 +053067static void serial_omap_mdr1_errataset(struct uart_omap_port *up, u8 mdr1);
Govindraj.Rb6126332010-09-27 20:20:49 +053068
Govindraj.R2fd14962011-11-09 17:41:21 +053069static struct workqueue_struct *serial_omap_uart_wq;
Govindraj.Rb6126332010-09-27 20:20:49 +053070
71static inline unsigned int serial_in(struct uart_omap_port *up, int offset)
72{
73 offset <<= up->port.regshift;
74 return readw(up->port.membase + offset);
75}
76
77static inline void serial_out(struct uart_omap_port *up, int offset, int value)
78{
79 offset <<= up->port.regshift;
80 writew(value, up->port.membase + offset);
81}
82
83static inline void serial_omap_clear_fifos(struct uart_omap_port *up)
84{
85 serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO);
86 serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO |
87 UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
88 serial_out(up, UART_FCR, 0);
89}
90
91/*
92 * serial_omap_get_divisor - calculate divisor value
93 * @port: uart port info
94 * @baud: baudrate for which divisor needs to be calculated.
95 *
96 * We have written our own function to get the divisor so as to support
97 * 13x mode. 3Mbps Baudrate as an different divisor.
98 * Reference OMAP TRM Chapter 17:
99 * Table 17-1. UART Mode Baud Rates, Divisor Values, and Error Rates
100 * referring to oversampling - divisor value
101 * baudrate 460,800 to 3,686,400 all have divisor 13
102 * except 3,000,000 which has divisor value 16
103 */
104static unsigned int
105serial_omap_get_divisor(struct uart_port *port, unsigned int baud)
106{
107 unsigned int divisor;
108
109 if (baud > OMAP_MODE13X_SPEED && baud != 3000000)
110 divisor = 13;
111 else
112 divisor = 16;
113 return port->uartclk/(baud * divisor);
114}
115
116static void serial_omap_stop_rxdma(struct uart_omap_port *up)
117{
118 if (up->uart_dma.rx_dma_used) {
119 del_timer(&up->uart_dma.rx_timer);
120 omap_stop_dma(up->uart_dma.rx_dma_channel);
121 omap_free_dma(up->uart_dma.rx_dma_channel);
122 up->uart_dma.rx_dma_channel = OMAP_UART_DMA_CH_FREE;
123 up->uart_dma.rx_dma_used = false;
Govindraj.Rfcdca752011-02-28 18:12:23 +0530124 pm_runtime_mark_last_busy(&up->pdev->dev);
125 pm_runtime_put_autosuspend(&up->pdev->dev);
Govindraj.Rb6126332010-09-27 20:20:49 +0530126 }
127}
128
129static void serial_omap_enable_ms(struct uart_port *port)
130{
131 struct uart_omap_port *up = (struct uart_omap_port *)port;
132
Rajendra Nayakba774332011-12-14 17:25:43 +0530133 dev_dbg(up->port.dev, "serial_omap_enable_ms+%d\n", up->port.line);
Govindraj.Rfcdca752011-02-28 18:12:23 +0530134
135 pm_runtime_get_sync(&up->pdev->dev);
Govindraj.Rb6126332010-09-27 20:20:49 +0530136 up->ier |= UART_IER_MSI;
137 serial_out(up, UART_IER, up->ier);
Govindraj.Rfcdca752011-02-28 18:12:23 +0530138 pm_runtime_put(&up->pdev->dev);
Govindraj.Rb6126332010-09-27 20:20:49 +0530139}
140
141static void serial_omap_stop_tx(struct uart_port *port)
142{
143 struct uart_omap_port *up = (struct uart_omap_port *)port;
144
145 if (up->use_dma &&
146 up->uart_dma.tx_dma_channel != OMAP_UART_DMA_CH_FREE) {
147 /*
148 * Check if dma is still active. If yes do nothing,
149 * return. Else stop dma
150 */
151 if (omap_get_dma_active_status(up->uart_dma.tx_dma_channel))
152 return;
153 omap_stop_dma(up->uart_dma.tx_dma_channel);
154 omap_free_dma(up->uart_dma.tx_dma_channel);
155 up->uart_dma.tx_dma_channel = OMAP_UART_DMA_CH_FREE;
Govindraj.Rfcdca752011-02-28 18:12:23 +0530156 pm_runtime_mark_last_busy(&up->pdev->dev);
157 pm_runtime_put_autosuspend(&up->pdev->dev);
Govindraj.Rb6126332010-09-27 20:20:49 +0530158 }
159
Govindraj.Rfcdca752011-02-28 18:12:23 +0530160 pm_runtime_get_sync(&up->pdev->dev);
Govindraj.Rb6126332010-09-27 20:20:49 +0530161 if (up->ier & UART_IER_THRI) {
162 up->ier &= ~UART_IER_THRI;
163 serial_out(up, UART_IER, up->ier);
164 }
Govindraj.Rfcdca752011-02-28 18:12:23 +0530165
166 pm_runtime_mark_last_busy(&up->pdev->dev);
167 pm_runtime_put_autosuspend(&up->pdev->dev);
Govindraj.Rb6126332010-09-27 20:20:49 +0530168}
169
170static void serial_omap_stop_rx(struct uart_port *port)
171{
172 struct uart_omap_port *up = (struct uart_omap_port *)port;
173
Govindraj.Rfcdca752011-02-28 18:12:23 +0530174 pm_runtime_get_sync(&up->pdev->dev);
Govindraj.Rb6126332010-09-27 20:20:49 +0530175 if (up->use_dma)
176 serial_omap_stop_rxdma(up);
177 up->ier &= ~UART_IER_RLSI;
178 up->port.read_status_mask &= ~UART_LSR_DR;
179 serial_out(up, UART_IER, up->ier);
Govindraj.Rfcdca752011-02-28 18:12:23 +0530180 pm_runtime_mark_last_busy(&up->pdev->dev);
181 pm_runtime_put_autosuspend(&up->pdev->dev);
Govindraj.Rb6126332010-09-27 20:20:49 +0530182}
183
Govindraj.Rda274682011-12-14 21:24:11 +0530184static inline void receive_chars(struct uart_omap_port *up,
185 unsigned int *status)
Govindraj.Rb6126332010-09-27 20:20:49 +0530186{
187 struct tty_struct *tty = up->port.state->port.tty;
Govindraj.Rda274682011-12-14 21:24:11 +0530188 unsigned int flag, lsr = *status;
189 unsigned char ch = 0;
Govindraj.Rb6126332010-09-27 20:20:49 +0530190 int max_count = 256;
191
192 do {
193 if (likely(lsr & UART_LSR_DR))
194 ch = serial_in(up, UART_RX);
195 flag = TTY_NORMAL;
196 up->port.icount.rx++;
197
198 if (unlikely(lsr & UART_LSR_BRK_ERROR_BITS)) {
199 /*
200 * For statistics only
201 */
202 if (lsr & UART_LSR_BI) {
203 lsr &= ~(UART_LSR_FE | UART_LSR_PE);
204 up->port.icount.brk++;
205 /*
206 * We do the SysRQ and SAK checking
207 * here because otherwise the break
208 * may get masked by ignore_status_mask
209 * or read_status_mask.
210 */
211 if (uart_handle_break(&up->port))
212 goto ignore_char;
213 } else if (lsr & UART_LSR_PE) {
214 up->port.icount.parity++;
215 } else if (lsr & UART_LSR_FE) {
216 up->port.icount.frame++;
217 }
218
219 if (lsr & UART_LSR_OE)
220 up->port.icount.overrun++;
221
222 /*
223 * Mask off conditions which should be ignored.
224 */
225 lsr &= up->port.read_status_mask;
226
227#ifdef CONFIG_SERIAL_OMAP_CONSOLE
228 if (up->port.line == up->port.cons->index) {
229 /* Recover the break flag from console xmit */
230 lsr |= up->lsr_break_flag;
Govindraj.Rb6126332010-09-27 20:20:49 +0530231 }
232#endif
233 if (lsr & UART_LSR_BI)
234 flag = TTY_BREAK;
235 else if (lsr & UART_LSR_PE)
236 flag = TTY_PARITY;
237 else if (lsr & UART_LSR_FE)
238 flag = TTY_FRAME;
239 }
240
241 if (uart_handle_sysrq_char(&up->port, ch))
242 goto ignore_char;
243 uart_insert_char(&up->port, lsr, UART_LSR_OE, ch, flag);
244ignore_char:
245 lsr = serial_in(up, UART_LSR);
246 } while ((lsr & (UART_LSR_DR | UART_LSR_BI)) && (max_count-- > 0));
247 spin_unlock(&up->port.lock);
248 tty_flip_buffer_push(tty);
249 spin_lock(&up->port.lock);
250}
251
252static void transmit_chars(struct uart_omap_port *up)
253{
254 struct circ_buf *xmit = &up->port.state->xmit;
255 int count;
256
257 if (up->port.x_char) {
258 serial_out(up, UART_TX, up->port.x_char);
259 up->port.icount.tx++;
260 up->port.x_char = 0;
261 return;
262 }
263 if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) {
264 serial_omap_stop_tx(&up->port);
265 return;
266 }
Greg Kroah-Hartmanaf681ca2012-01-26 11:14:42 -0800267 count = up->port.fifosize / 4;
Govindraj.Rb6126332010-09-27 20:20:49 +0530268 do {
269 serial_out(up, UART_TX, xmit->buf[xmit->tail]);
270 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
271 up->port.icount.tx++;
272 if (uart_circ_empty(xmit))
273 break;
274 } while (--count > 0);
275
276 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
277 uart_write_wakeup(&up->port);
278
279 if (uart_circ_empty(xmit))
280 serial_omap_stop_tx(&up->port);
281}
282
283static inline void serial_omap_enable_ier_thri(struct uart_omap_port *up)
284{
285 if (!(up->ier & UART_IER_THRI)) {
286 up->ier |= UART_IER_THRI;
287 serial_out(up, UART_IER, up->ier);
288 }
289}
290
291static void serial_omap_start_tx(struct uart_port *port)
292{
293 struct uart_omap_port *up = (struct uart_omap_port *)port;
294 struct circ_buf *xmit;
295 unsigned int start;
296 int ret = 0;
297
298 if (!up->use_dma) {
Govindraj.Rfcdca752011-02-28 18:12:23 +0530299 pm_runtime_get_sync(&up->pdev->dev);
Govindraj.Rb6126332010-09-27 20:20:49 +0530300 serial_omap_enable_ier_thri(up);
Govindraj.Rfcdca752011-02-28 18:12:23 +0530301 pm_runtime_mark_last_busy(&up->pdev->dev);
302 pm_runtime_put_autosuspend(&up->pdev->dev);
Govindraj.Rb6126332010-09-27 20:20:49 +0530303 return;
304 }
305
306 if (up->uart_dma.tx_dma_used)
307 return;
308
309 xmit = &up->port.state->xmit;
310
311 if (up->uart_dma.tx_dma_channel == OMAP_UART_DMA_CH_FREE) {
Govindraj.Rfcdca752011-02-28 18:12:23 +0530312 pm_runtime_get_sync(&up->pdev->dev);
Govindraj.Rb6126332010-09-27 20:20:49 +0530313 ret = omap_request_dma(up->uart_dma.uart_dma_tx,
314 "UART Tx DMA",
315 (void *)uart_tx_dma_callback, up,
316 &(up->uart_dma.tx_dma_channel));
317
318 if (ret < 0) {
319 serial_omap_enable_ier_thri(up);
320 return;
321 }
322 }
323 spin_lock(&(up->uart_dma.tx_lock));
324 up->uart_dma.tx_dma_used = true;
325 spin_unlock(&(up->uart_dma.tx_lock));
326
327 start = up->uart_dma.tx_buf_dma_phys +
328 (xmit->tail & (UART_XMIT_SIZE - 1));
329
330 up->uart_dma.tx_buf_size = uart_circ_chars_pending(xmit);
331 /*
332 * It is a circular buffer. See if the buffer has wounded back.
333 * If yes it will have to be transferred in two separate dma
334 * transfers
335 */
336 if (start + up->uart_dma.tx_buf_size >=
337 up->uart_dma.tx_buf_dma_phys + UART_XMIT_SIZE)
338 up->uart_dma.tx_buf_size =
339 (up->uart_dma.tx_buf_dma_phys +
340 UART_XMIT_SIZE) - start;
341
342 omap_set_dma_dest_params(up->uart_dma.tx_dma_channel, 0,
343 OMAP_DMA_AMODE_CONSTANT,
344 up->uart_dma.uart_base, 0, 0);
345 omap_set_dma_src_params(up->uart_dma.tx_dma_channel, 0,
346 OMAP_DMA_AMODE_POST_INC, start, 0, 0);
347 omap_set_dma_transfer_params(up->uart_dma.tx_dma_channel,
348 OMAP_DMA_DATA_TYPE_S8,
349 up->uart_dma.tx_buf_size, 1,
350 OMAP_DMA_SYNC_ELEMENT,
351 up->uart_dma.uart_dma_tx, 0);
352 /* FIXME: Cache maintenance needed here? */
353 omap_start_dma(up->uart_dma.tx_dma_channel);
354}
355
356static unsigned int check_modem_status(struct uart_omap_port *up)
357{
358 unsigned int status;
359
360 status = serial_in(up, UART_MSR);
361 status |= up->msr_saved_flags;
362 up->msr_saved_flags = 0;
363 if ((status & UART_MSR_ANY_DELTA) == 0)
364 return status;
365
366 if (status & UART_MSR_ANY_DELTA && up->ier & UART_IER_MSI &&
367 up->port.state != NULL) {
368 if (status & UART_MSR_TERI)
369 up->port.icount.rng++;
370 if (status & UART_MSR_DDSR)
371 up->port.icount.dsr++;
372 if (status & UART_MSR_DDCD)
373 uart_handle_dcd_change
374 (&up->port, status & UART_MSR_DCD);
375 if (status & UART_MSR_DCTS)
376 uart_handle_cts_change
377 (&up->port, status & UART_MSR_CTS);
378 wake_up_interruptible(&up->port.state->port.delta_msr_wait);
379 }
380
381 return status;
382}
383
384/**
385 * serial_omap_irq() - This handles the interrupt from one port
386 * @irq: uart port irq number
387 * @dev_id: uart port info
388 */
389static inline irqreturn_t serial_omap_irq(int irq, void *dev_id)
390{
391 struct uart_omap_port *up = dev_id;
392 unsigned int iir, lsr;
393 unsigned long flags;
394
Govindraj.Rfcdca752011-02-28 18:12:23 +0530395 pm_runtime_get_sync(&up->pdev->dev);
Govindraj.Rb6126332010-09-27 20:20:49 +0530396 iir = serial_in(up, UART_IIR);
Govindraj.Rfcdca752011-02-28 18:12:23 +0530397 if (iir & UART_IIR_NO_INT) {
398 pm_runtime_mark_last_busy(&up->pdev->dev);
399 pm_runtime_put_autosuspend(&up->pdev->dev);
Govindraj.Rb6126332010-09-27 20:20:49 +0530400 return IRQ_NONE;
Govindraj.Rfcdca752011-02-28 18:12:23 +0530401 }
Govindraj.Rb6126332010-09-27 20:20:49 +0530402
403 spin_lock_irqsave(&up->port.lock, flags);
404 lsr = serial_in(up, UART_LSR);
405 if (iir & UART_IIR_RLSI) {
406 if (!up->use_dma) {
407 if (lsr & UART_LSR_DR)
408 receive_chars(up, &lsr);
409 } else {
410 up->ier &= ~(UART_IER_RDI | UART_IER_RLSI);
411 serial_out(up, UART_IER, up->ier);
412 if ((serial_omap_start_rxdma(up) != 0) &&
413 (lsr & UART_LSR_DR))
414 receive_chars(up, &lsr);
415 }
416 }
417
418 check_modem_status(up);
419 if ((lsr & UART_LSR_THRE) && (iir & UART_IIR_THRI))
420 transmit_chars(up);
421
422 spin_unlock_irqrestore(&up->port.lock, flags);
Govindraj.Rfcdca752011-02-28 18:12:23 +0530423 pm_runtime_mark_last_busy(&up->pdev->dev);
424 pm_runtime_put_autosuspend(&up->pdev->dev);
425
Govindraj.Rb6126332010-09-27 20:20:49 +0530426 up->port_activity = jiffies;
427 return IRQ_HANDLED;
428}
429
430static unsigned int serial_omap_tx_empty(struct uart_port *port)
431{
432 struct uart_omap_port *up = (struct uart_omap_port *)port;
433 unsigned long flags = 0;
434 unsigned int ret = 0;
435
Govindraj.Rfcdca752011-02-28 18:12:23 +0530436 pm_runtime_get_sync(&up->pdev->dev);
Rajendra Nayakba774332011-12-14 17:25:43 +0530437 dev_dbg(up->port.dev, "serial_omap_tx_empty+%d\n", up->port.line);
Govindraj.Rb6126332010-09-27 20:20:49 +0530438 spin_lock_irqsave(&up->port.lock, flags);
439 ret = serial_in(up, UART_LSR) & UART_LSR_TEMT ? TIOCSER_TEMT : 0;
440 spin_unlock_irqrestore(&up->port.lock, flags);
Govindraj.Rfcdca752011-02-28 18:12:23 +0530441 pm_runtime_put(&up->pdev->dev);
Govindraj.Rb6126332010-09-27 20:20:49 +0530442 return ret;
443}
444
445static unsigned int serial_omap_get_mctrl(struct uart_port *port)
446{
447 struct uart_omap_port *up = (struct uart_omap_port *)port;
Shubhrajyoti D514f31d2011-11-21 15:43:28 +0530448 unsigned int status;
Govindraj.Rb6126332010-09-27 20:20:49 +0530449 unsigned int ret = 0;
450
Govindraj.Rfcdca752011-02-28 18:12:23 +0530451 pm_runtime_get_sync(&up->pdev->dev);
Govindraj.Rb6126332010-09-27 20:20:49 +0530452 status = check_modem_status(up);
Govindraj.Rfcdca752011-02-28 18:12:23 +0530453 pm_runtime_put(&up->pdev->dev);
454
Rajendra Nayakba774332011-12-14 17:25:43 +0530455 dev_dbg(up->port.dev, "serial_omap_get_mctrl+%d\n", up->port.line);
Govindraj.Rb6126332010-09-27 20:20:49 +0530456
457 if (status & UART_MSR_DCD)
458 ret |= TIOCM_CAR;
459 if (status & UART_MSR_RI)
460 ret |= TIOCM_RNG;
461 if (status & UART_MSR_DSR)
462 ret |= TIOCM_DSR;
463 if (status & UART_MSR_CTS)
464 ret |= TIOCM_CTS;
465 return ret;
466}
467
468static void serial_omap_set_mctrl(struct uart_port *port, unsigned int mctrl)
469{
470 struct uart_omap_port *up = (struct uart_omap_port *)port;
471 unsigned char mcr = 0;
472
Rajendra Nayakba774332011-12-14 17:25:43 +0530473 dev_dbg(up->port.dev, "serial_omap_set_mctrl+%d\n", up->port.line);
Govindraj.Rb6126332010-09-27 20:20:49 +0530474 if (mctrl & TIOCM_RTS)
475 mcr |= UART_MCR_RTS;
476 if (mctrl & TIOCM_DTR)
477 mcr |= UART_MCR_DTR;
478 if (mctrl & TIOCM_OUT1)
479 mcr |= UART_MCR_OUT1;
480 if (mctrl & TIOCM_OUT2)
481 mcr |= UART_MCR_OUT2;
482 if (mctrl & TIOCM_LOOP)
483 mcr |= UART_MCR_LOOP;
484
Govindraj.Rfcdca752011-02-28 18:12:23 +0530485 pm_runtime_get_sync(&up->pdev->dev);
Govindraj.Rc538d202011-11-07 18:57:03 +0530486 up->mcr = serial_in(up, UART_MCR);
487 up->mcr |= mcr;
488 serial_out(up, UART_MCR, up->mcr);
Govindraj.Rfcdca752011-02-28 18:12:23 +0530489 pm_runtime_put(&up->pdev->dev);
Govindraj.Rb6126332010-09-27 20:20:49 +0530490}
491
492static void serial_omap_break_ctl(struct uart_port *port, int break_state)
493{
494 struct uart_omap_port *up = (struct uart_omap_port *)port;
495 unsigned long flags = 0;
496
Rajendra Nayakba774332011-12-14 17:25:43 +0530497 dev_dbg(up->port.dev, "serial_omap_break_ctl+%d\n", up->port.line);
Govindraj.Rfcdca752011-02-28 18:12:23 +0530498 pm_runtime_get_sync(&up->pdev->dev);
Govindraj.Rb6126332010-09-27 20:20:49 +0530499 spin_lock_irqsave(&up->port.lock, flags);
500 if (break_state == -1)
501 up->lcr |= UART_LCR_SBC;
502 else
503 up->lcr &= ~UART_LCR_SBC;
504 serial_out(up, UART_LCR, up->lcr);
505 spin_unlock_irqrestore(&up->port.lock, flags);
Govindraj.Rfcdca752011-02-28 18:12:23 +0530506 pm_runtime_put(&up->pdev->dev);
Govindraj.Rb6126332010-09-27 20:20:49 +0530507}
508
509static int serial_omap_startup(struct uart_port *port)
510{
511 struct uart_omap_port *up = (struct uart_omap_port *)port;
512 unsigned long flags = 0;
513 int retval;
514
515 /*
516 * Allocate the IRQ
517 */
518 retval = request_irq(up->port.irq, serial_omap_irq, up->port.irqflags,
519 up->name, up);
520 if (retval)
521 return retval;
522
Rajendra Nayakba774332011-12-14 17:25:43 +0530523 dev_dbg(up->port.dev, "serial_omap_startup+%d\n", up->port.line);
Govindraj.Rb6126332010-09-27 20:20:49 +0530524
Govindraj.Rfcdca752011-02-28 18:12:23 +0530525 pm_runtime_get_sync(&up->pdev->dev);
Govindraj.Rb6126332010-09-27 20:20:49 +0530526 /*
527 * Clear the FIFO buffers and disable them.
528 * (they will be reenabled in set_termios())
529 */
530 serial_omap_clear_fifos(up);
531 /* For Hardware flow control */
532 serial_out(up, UART_MCR, UART_MCR_RTS);
533
534 /*
535 * Clear the interrupt registers.
536 */
537 (void) serial_in(up, UART_LSR);
538 if (serial_in(up, UART_LSR) & UART_LSR_DR)
539 (void) serial_in(up, UART_RX);
540 (void) serial_in(up, UART_IIR);
541 (void) serial_in(up, UART_MSR);
542
543 /*
544 * Now, initialize the UART
545 */
546 serial_out(up, UART_LCR, UART_LCR_WLEN8);
547 spin_lock_irqsave(&up->port.lock, flags);
548 /*
549 * Most PC uarts need OUT2 raised to enable interrupts.
550 */
551 up->port.mctrl |= TIOCM_OUT2;
552 serial_omap_set_mctrl(&up->port, up->port.mctrl);
553 spin_unlock_irqrestore(&up->port.lock, flags);
554
555 up->msr_saved_flags = 0;
556 if (up->use_dma) {
557 free_page((unsigned long)up->port.state->xmit.buf);
558 up->port.state->xmit.buf = dma_alloc_coherent(NULL,
559 UART_XMIT_SIZE,
560 (dma_addr_t *)&(up->uart_dma.tx_buf_dma_phys),
561 0);
562 init_timer(&(up->uart_dma.rx_timer));
Jon Huntera9e210e2011-11-09 17:34:49 +0530563 up->uart_dma.rx_timer.function = serial_omap_rxdma_poll;
Rajendra Nayakba774332011-12-14 17:25:43 +0530564 up->uart_dma.rx_timer.data = up->port.line;
Govindraj.Rb6126332010-09-27 20:20:49 +0530565 /* Currently the buffer size is 4KB. Can increase it */
566 up->uart_dma.rx_buf = dma_alloc_coherent(NULL,
567 up->uart_dma.rx_buf_size,
568 (dma_addr_t *)&(up->uart_dma.rx_buf_dma_phys), 0);
569 }
570 /*
571 * Finally, enable interrupts. Note: Modem status interrupts
572 * are set via set_termios(), which will be occurring imminently
573 * anyway, so we don't enable them here.
574 */
575 up->ier = UART_IER_RLSI | UART_IER_RDI;
576 serial_out(up, UART_IER, up->ier);
577
Jarkko Nikula78841462011-01-24 17:51:22 +0200578 /* Enable module level wake up */
579 serial_out(up, UART_OMAP_WER, OMAP_UART_WER_MOD_WKUP);
580
Govindraj.Rfcdca752011-02-28 18:12:23 +0530581 pm_runtime_mark_last_busy(&up->pdev->dev);
582 pm_runtime_put_autosuspend(&up->pdev->dev);
Govindraj.Rb6126332010-09-27 20:20:49 +0530583 up->port_activity = jiffies;
584 return 0;
585}
586
587static void serial_omap_shutdown(struct uart_port *port)
588{
589 struct uart_omap_port *up = (struct uart_omap_port *)port;
590 unsigned long flags = 0;
591
Rajendra Nayakba774332011-12-14 17:25:43 +0530592 dev_dbg(up->port.dev, "serial_omap_shutdown+%d\n", up->port.line);
Govindraj.Rfcdca752011-02-28 18:12:23 +0530593
594 pm_runtime_get_sync(&up->pdev->dev);
Govindraj.Rb6126332010-09-27 20:20:49 +0530595 /*
596 * Disable interrupts from this port
597 */
598 up->ier = 0;
599 serial_out(up, UART_IER, 0);
600
601 spin_lock_irqsave(&up->port.lock, flags);
602 up->port.mctrl &= ~TIOCM_OUT2;
603 serial_omap_set_mctrl(&up->port, up->port.mctrl);
604 spin_unlock_irqrestore(&up->port.lock, flags);
605
606 /*
607 * Disable break condition and FIFOs
608 */
609 serial_out(up, UART_LCR, serial_in(up, UART_LCR) & ~UART_LCR_SBC);
610 serial_omap_clear_fifos(up);
611
612 /*
613 * Read data port to reset things, and then free the irq
614 */
615 if (serial_in(up, UART_LSR) & UART_LSR_DR)
616 (void) serial_in(up, UART_RX);
617 if (up->use_dma) {
618 dma_free_coherent(up->port.dev,
619 UART_XMIT_SIZE, up->port.state->xmit.buf,
620 up->uart_dma.tx_buf_dma_phys);
621 up->port.state->xmit.buf = NULL;
622 serial_omap_stop_rx(port);
623 dma_free_coherent(up->port.dev,
624 up->uart_dma.rx_buf_size, up->uart_dma.rx_buf,
625 up->uart_dma.rx_buf_dma_phys);
626 up->uart_dma.rx_buf = NULL;
627 }
Govindraj.Rfcdca752011-02-28 18:12:23 +0530628
629 pm_runtime_put(&up->pdev->dev);
Govindraj.Rb6126332010-09-27 20:20:49 +0530630 free_irq(up->port.irq, up);
631}
632
633static inline void
634serial_omap_configure_xonxoff
635 (struct uart_omap_port *up, struct ktermios *termios)
636{
Govindraj.Rb6126332010-09-27 20:20:49 +0530637 up->lcr = serial_in(up, UART_LCR);
Andrei Emeltchenko662b083a2010-11-30 14:11:49 -0800638 serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
Govindraj.Rb6126332010-09-27 20:20:49 +0530639 up->efr = serial_in(up, UART_EFR);
640 serial_out(up, UART_EFR, up->efr & ~UART_EFR_ECB);
641
642 serial_out(up, UART_XON1, termios->c_cc[VSTART]);
643 serial_out(up, UART_XOFF1, termios->c_cc[VSTOP]);
644
645 /* clear SW control mode bits */
Govindraj.Rc538d202011-11-07 18:57:03 +0530646 up->efr &= OMAP_UART_SW_CLR;
Govindraj.Rb6126332010-09-27 20:20:49 +0530647
648 /*
649 * IXON Flag:
650 * Enable XON/XOFF flow control on output.
651 * Transmit XON1, XOFF1
652 */
653 if (termios->c_iflag & IXON)
Govindraj.Rc538d202011-11-07 18:57:03 +0530654 up->efr |= OMAP_UART_SW_TX;
Govindraj.Rb6126332010-09-27 20:20:49 +0530655
656 /*
657 * IXOFF Flag:
658 * Enable XON/XOFF flow control on input.
659 * Receiver compares XON1, XOFF1.
660 */
661 if (termios->c_iflag & IXOFF)
Govindraj.Rc538d202011-11-07 18:57:03 +0530662 up->efr |= OMAP_UART_SW_RX;
Govindraj.Rb6126332010-09-27 20:20:49 +0530663
664 serial_out(up, UART_EFR, up->efr | UART_EFR_ECB);
Andrei Emeltchenko662b083a2010-11-30 14:11:49 -0800665 serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);
Govindraj.Rb6126332010-09-27 20:20:49 +0530666
667 up->mcr = serial_in(up, UART_MCR);
668
669 /*
670 * IXANY Flag:
671 * Enable any character to restart output.
672 * Operation resumes after receiving any
673 * character after recognition of the XOFF character
674 */
675 if (termios->c_iflag & IXANY)
676 up->mcr |= UART_MCR_XONANY;
677
678 serial_out(up, UART_MCR, up->mcr | UART_MCR_TCRTLR);
Andrei Emeltchenko662b083a2010-11-30 14:11:49 -0800679 serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
Govindraj.Rb6126332010-09-27 20:20:49 +0530680 serial_out(up, UART_TI752_TCR, OMAP_UART_TCR_TRIG);
681 /* Enable special char function UARTi.EFR_REG[5] and
682 * load the new software flow control mode IXON or IXOFF
683 * and restore the UARTi.EFR_REG[4] ENHANCED_EN value.
684 */
Govindraj.Rc538d202011-11-07 18:57:03 +0530685 serial_out(up, UART_EFR, up->efr | UART_EFR_SCD);
Andrei Emeltchenko662b083a2010-11-30 14:11:49 -0800686 serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);
Govindraj.Rb6126332010-09-27 20:20:49 +0530687
688 serial_out(up, UART_MCR, up->mcr & ~UART_MCR_TCRTLR);
689 serial_out(up, UART_LCR, up->lcr);
690}
691
Govindraj.R2fd14962011-11-09 17:41:21 +0530692static void serial_omap_uart_qos_work(struct work_struct *work)
693{
694 struct uart_omap_port *up = container_of(work, struct uart_omap_port,
695 qos_work);
696
697 pm_qos_update_request(&up->pm_qos_request, up->latency);
698}
699
Govindraj.Rb6126332010-09-27 20:20:49 +0530700static void
701serial_omap_set_termios(struct uart_port *port, struct ktermios *termios,
702 struct ktermios *old)
703{
704 struct uart_omap_port *up = (struct uart_omap_port *)port;
705 unsigned char cval = 0;
706 unsigned char efr = 0;
707 unsigned long flags = 0;
708 unsigned int baud, quot;
Paul Walmsley0a697b22012-01-21 00:27:40 -0700709 u32 tlr;
Govindraj.Rb6126332010-09-27 20:20:49 +0530710
711 switch (termios->c_cflag & CSIZE) {
712 case CS5:
713 cval = UART_LCR_WLEN5;
714 break;
715 case CS6:
716 cval = UART_LCR_WLEN6;
717 break;
718 case CS7:
719 cval = UART_LCR_WLEN7;
720 break;
721 default:
722 case CS8:
723 cval = UART_LCR_WLEN8;
724 break;
725 }
726
727 if (termios->c_cflag & CSTOPB)
728 cval |= UART_LCR_STOP;
729 if (termios->c_cflag & PARENB)
730 cval |= UART_LCR_PARITY;
731 if (!(termios->c_cflag & PARODD))
732 cval |= UART_LCR_EPAR;
733
734 /*
735 * Ask the core to calculate the divisor for us.
736 */
737
738 baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/13);
739 quot = serial_omap_get_divisor(port, baud);
740
Govindraj.R2fd14962011-11-09 17:41:21 +0530741 /* calculate wakeup latency constraint */
742 up->calc_latency = (1000000 * up->port.fifosize) /
743 (1000 * baud / 8);
744 up->latency = up->calc_latency;
745 schedule_work(&up->qos_work);
746
Govindraj.Rc538d202011-11-07 18:57:03 +0530747 up->dll = quot & 0xff;
748 up->dlh = quot >> 8;
749 up->mdr1 = UART_OMAP_MDR1_DISABLE;
750
Govindraj.Rb6126332010-09-27 20:20:49 +0530751 up->fcr = UART_FCR_R_TRIG_01 | UART_FCR_T_TRIG_01 |
752 UART_FCR_ENABLE_FIFO;
753 if (up->use_dma)
754 up->fcr |= UART_FCR_DMA_SELECT;
755
756 /*
757 * Ok, we're now changing the port state. Do it with
758 * interrupts disabled.
759 */
Govindraj.Rfcdca752011-02-28 18:12:23 +0530760 pm_runtime_get_sync(&up->pdev->dev);
Govindraj.Rb6126332010-09-27 20:20:49 +0530761 spin_lock_irqsave(&up->port.lock, flags);
762
763 /*
764 * Update the per-port timeout.
765 */
766 uart_update_timeout(port, termios->c_cflag, baud);
767
768 up->port.read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;
769 if (termios->c_iflag & INPCK)
770 up->port.read_status_mask |= UART_LSR_FE | UART_LSR_PE;
771 if (termios->c_iflag & (BRKINT | PARMRK))
772 up->port.read_status_mask |= UART_LSR_BI;
773
774 /*
775 * Characters to ignore
776 */
777 up->port.ignore_status_mask = 0;
778 if (termios->c_iflag & IGNPAR)
779 up->port.ignore_status_mask |= UART_LSR_PE | UART_LSR_FE;
780 if (termios->c_iflag & IGNBRK) {
781 up->port.ignore_status_mask |= UART_LSR_BI;
782 /*
783 * If we're ignoring parity and break indicators,
784 * ignore overruns too (for real raw support).
785 */
786 if (termios->c_iflag & IGNPAR)
787 up->port.ignore_status_mask |= UART_LSR_OE;
788 }
789
790 /*
791 * ignore all characters if CREAD is not set
792 */
793 if ((termios->c_cflag & CREAD) == 0)
794 up->port.ignore_status_mask |= UART_LSR_DR;
795
796 /*
797 * Modem status interrupts
798 */
799 up->ier &= ~UART_IER_MSI;
800 if (UART_ENABLE_MS(&up->port, termios->c_cflag))
801 up->ier |= UART_IER_MSI;
802 serial_out(up, UART_IER, up->ier);
803 serial_out(up, UART_LCR, cval); /* reset DLAB */
Govindraj.Rc538d202011-11-07 18:57:03 +0530804 up->lcr = cval;
Govindraj.R32212892011-11-07 18:58:55 +0530805 up->scr = OMAP_UART_SCR_TX_EMPTY;
Govindraj.Rb6126332010-09-27 20:20:49 +0530806
807 /* FIFOs and DMA Settings */
808
809 /* FCR can be changed only when the
810 * baud clock is not running
811 * DLL_REG and DLH_REG set to 0.
812 */
Andrei Emeltchenko662b083a2010-11-30 14:11:49 -0800813 serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);
Govindraj.Rb6126332010-09-27 20:20:49 +0530814 serial_out(up, UART_DLL, 0);
815 serial_out(up, UART_DLM, 0);
816 serial_out(up, UART_LCR, 0);
817
Andrei Emeltchenko662b083a2010-11-30 14:11:49 -0800818 serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
Govindraj.Rb6126332010-09-27 20:20:49 +0530819
820 up->efr = serial_in(up, UART_EFR);
821 serial_out(up, UART_EFR, up->efr | UART_EFR_ECB);
822
Andrei Emeltchenko662b083a2010-11-30 14:11:49 -0800823 serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);
Govindraj.Rb6126332010-09-27 20:20:49 +0530824 up->mcr = serial_in(up, UART_MCR);
825 serial_out(up, UART_MCR, up->mcr | UART_MCR_TCRTLR);
826 /* FIFO ENABLE, DMA MODE */
Paul Walmsley0a697b22012-01-21 00:27:40 -0700827
828 up->scr |= OMAP_UART_SCR_TX_TRIG_GRANU1_MASK;
829 up->scr |= OMAP_UART_SCR_RX_TRIG_GRANU1_MASK;
Govindraj.Rb6126332010-09-27 20:20:49 +0530830
831 if (up->use_dma) {
Paul Walmsley0a697b22012-01-21 00:27:40 -0700832 tlr = 0;
833 } else {
834 up->scr &= ~OMAP_UART_SCR_TX_EMPTY;
835
836 /* Set receive FIFO threshold to 1 */
837 up->fcr &= ~OMAP_UART_FCR_RX_FIFO_TRIG_MASK;
838 up->fcr |= (0x1 << OMAP_UART_FCR_RX_FIFO_TRIG_SHIFT);
839
840 /* Set TX FIFO threshold to "63" (actually 1) */
841 up->fcr |= (0x3 << OMAP_UART_FCR_TX_FIFO_TRIG_SHIFT);
842 tlr = (0xf << OMAP_UART_TLR_TX_FIFO_TRIG_DMA_SHIFT);
Govindraj.Rb6126332010-09-27 20:20:49 +0530843 }
844
Paul Walmsley0a697b22012-01-21 00:27:40 -0700845 serial_out(up, UART_TI752_TLR, tlr);
846 serial_out(up, UART_FCR, up->fcr);
847 serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
848
Govindraj.Rc538d202011-11-07 18:57:03 +0530849 serial_out(up, UART_OMAP_SCR, up->scr);
850
Govindraj.Rb6126332010-09-27 20:20:49 +0530851 serial_out(up, UART_EFR, up->efr);
Andrei Emeltchenko662b083a2010-11-30 14:11:49 -0800852 serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);
Govindraj.Rb6126332010-09-27 20:20:49 +0530853 serial_out(up, UART_MCR, up->mcr);
854
855 /* Protocol, Baud Rate, and Interrupt Settings */
856
Govindraj.R94734742011-11-07 19:00:33 +0530857 if (up->errata & UART_ERRATA_i202_MDR1_ACCESS)
858 serial_omap_mdr1_errataset(up, up->mdr1);
859 else
860 serial_out(up, UART_OMAP_MDR1, up->mdr1);
861
Andrei Emeltchenko662b083a2010-11-30 14:11:49 -0800862 serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
Govindraj.Rb6126332010-09-27 20:20:49 +0530863
864 up->efr = serial_in(up, UART_EFR);
865 serial_out(up, UART_EFR, up->efr | UART_EFR_ECB);
866
867 serial_out(up, UART_LCR, 0);
868 serial_out(up, UART_IER, 0);
Andrei Emeltchenko662b083a2010-11-30 14:11:49 -0800869 serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
Govindraj.Rb6126332010-09-27 20:20:49 +0530870
Govindraj.Rc538d202011-11-07 18:57:03 +0530871 serial_out(up, UART_DLL, up->dll); /* LS of divisor */
872 serial_out(up, UART_DLM, up->dlh); /* MS of divisor */
Govindraj.Rb6126332010-09-27 20:20:49 +0530873
874 serial_out(up, UART_LCR, 0);
875 serial_out(up, UART_IER, up->ier);
Andrei Emeltchenko662b083a2010-11-30 14:11:49 -0800876 serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
Govindraj.Rb6126332010-09-27 20:20:49 +0530877
878 serial_out(up, UART_EFR, up->efr);
879 serial_out(up, UART_LCR, cval);
880
881 if (baud > 230400 && baud != 3000000)
Govindraj.Rc538d202011-11-07 18:57:03 +0530882 up->mdr1 = UART_OMAP_MDR1_13X_MODE;
Govindraj.Rb6126332010-09-27 20:20:49 +0530883 else
Govindraj.Rc538d202011-11-07 18:57:03 +0530884 up->mdr1 = UART_OMAP_MDR1_16X_MODE;
885
Govindraj.R94734742011-11-07 19:00:33 +0530886 if (up->errata & UART_ERRATA_i202_MDR1_ACCESS)
887 serial_omap_mdr1_errataset(up, up->mdr1);
888 else
889 serial_out(up, UART_OMAP_MDR1, up->mdr1);
Govindraj.Rb6126332010-09-27 20:20:49 +0530890
891 /* Hardware Flow Control Configuration */
892
893 if (termios->c_cflag & CRTSCTS) {
894 efr |= (UART_EFR_CTS | UART_EFR_RTS);
Andrei Emeltchenko662b083a2010-11-30 14:11:49 -0800895 serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);
Govindraj.Rb6126332010-09-27 20:20:49 +0530896
897 up->mcr = serial_in(up, UART_MCR);
898 serial_out(up, UART_MCR, up->mcr | UART_MCR_TCRTLR);
899
Andrei Emeltchenko662b083a2010-11-30 14:11:49 -0800900 serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
Govindraj.Rb6126332010-09-27 20:20:49 +0530901 up->efr = serial_in(up, UART_EFR);
902 serial_out(up, UART_EFR, up->efr | UART_EFR_ECB);
903
904 serial_out(up, UART_TI752_TCR, OMAP_UART_TCR_TRIG);
905 serial_out(up, UART_EFR, efr); /* Enable AUTORTS and AUTOCTS */
Andrei Emeltchenko662b083a2010-11-30 14:11:49 -0800906 serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);
Govindraj.Rb6126332010-09-27 20:20:49 +0530907 serial_out(up, UART_MCR, up->mcr | UART_MCR_RTS);
908 serial_out(up, UART_LCR, cval);
909 }
910
911 serial_omap_set_mctrl(&up->port, up->port.mctrl);
912 /* Software Flow Control Configuration */
Nick Pellyb280a972011-07-15 13:53:08 -0700913 serial_omap_configure_xonxoff(up, termios);
Govindraj.Rb6126332010-09-27 20:20:49 +0530914
915 spin_unlock_irqrestore(&up->port.lock, flags);
Govindraj.Rfcdca752011-02-28 18:12:23 +0530916 pm_runtime_put(&up->pdev->dev);
Rajendra Nayakba774332011-12-14 17:25:43 +0530917 dev_dbg(up->port.dev, "serial_omap_set_termios+%d\n", up->port.line);
Govindraj.Rb6126332010-09-27 20:20:49 +0530918}
919
920static void
921serial_omap_pm(struct uart_port *port, unsigned int state,
922 unsigned int oldstate)
923{
924 struct uart_omap_port *up = (struct uart_omap_port *)port;
925 unsigned char efr;
926
Rajendra Nayakba774332011-12-14 17:25:43 +0530927 dev_dbg(up->port.dev, "serial_omap_pm+%d\n", up->port.line);
Govindraj.Rfcdca752011-02-28 18:12:23 +0530928
929 pm_runtime_get_sync(&up->pdev->dev);
Andrei Emeltchenko662b083a2010-11-30 14:11:49 -0800930 serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
Govindraj.Rb6126332010-09-27 20:20:49 +0530931 efr = serial_in(up, UART_EFR);
932 serial_out(up, UART_EFR, efr | UART_EFR_ECB);
933 serial_out(up, UART_LCR, 0);
934
935 serial_out(up, UART_IER, (state != 0) ? UART_IERX_SLEEP : 0);
Andrei Emeltchenko662b083a2010-11-30 14:11:49 -0800936 serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
Govindraj.Rb6126332010-09-27 20:20:49 +0530937 serial_out(up, UART_EFR, efr);
938 serial_out(up, UART_LCR, 0);
Govindraj.Rfcdca752011-02-28 18:12:23 +0530939
940 if (!device_may_wakeup(&up->pdev->dev)) {
941 if (!state)
942 pm_runtime_forbid(&up->pdev->dev);
943 else
944 pm_runtime_allow(&up->pdev->dev);
945 }
946
947 pm_runtime_put(&up->pdev->dev);
Govindraj.Rb6126332010-09-27 20:20:49 +0530948}
949
950static void serial_omap_release_port(struct uart_port *port)
951{
952 dev_dbg(port->dev, "serial_omap_release_port+\n");
953}
954
955static int serial_omap_request_port(struct uart_port *port)
956{
957 dev_dbg(port->dev, "serial_omap_request_port+\n");
958 return 0;
959}
960
961static void serial_omap_config_port(struct uart_port *port, int flags)
962{
963 struct uart_omap_port *up = (struct uart_omap_port *)port;
964
965 dev_dbg(up->port.dev, "serial_omap_config_port+%d\n",
Rajendra Nayakba774332011-12-14 17:25:43 +0530966 up->port.line);
Govindraj.Rb6126332010-09-27 20:20:49 +0530967 up->port.type = PORT_OMAP;
968}
969
970static int
971serial_omap_verify_port(struct uart_port *port, struct serial_struct *ser)
972{
973 /* we don't want the core code to modify any port params */
974 dev_dbg(port->dev, "serial_omap_verify_port+\n");
975 return -EINVAL;
976}
977
978static const char *
979serial_omap_type(struct uart_port *port)
980{
981 struct uart_omap_port *up = (struct uart_omap_port *)port;
982
Rajendra Nayakba774332011-12-14 17:25:43 +0530983 dev_dbg(up->port.dev, "serial_omap_type+%d\n", up->port.line);
Govindraj.Rb6126332010-09-27 20:20:49 +0530984 return up->name;
985}
986
Govindraj.Rb6126332010-09-27 20:20:49 +0530987#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
988
989static inline void wait_for_xmitr(struct uart_omap_port *up)
990{
991 unsigned int status, tmout = 10000;
992
993 /* Wait up to 10ms for the character(s) to be sent. */
994 do {
995 status = serial_in(up, UART_LSR);
996
997 if (status & UART_LSR_BI)
998 up->lsr_break_flag = UART_LSR_BI;
999
1000 if (--tmout == 0)
1001 break;
1002 udelay(1);
1003 } while ((status & BOTH_EMPTY) != BOTH_EMPTY);
1004
1005 /* Wait up to 1s for flow control if necessary */
1006 if (up->port.flags & UPF_CONS_FLOW) {
1007 tmout = 1000000;
1008 for (tmout = 1000000; tmout; tmout--) {
1009 unsigned int msr = serial_in(up, UART_MSR);
1010
1011 up->msr_saved_flags |= msr & MSR_SAVE_FLAGS;
1012 if (msr & UART_MSR_CTS)
1013 break;
1014
1015 udelay(1);
1016 }
1017 }
1018}
1019
Cosmin Cojocar1b41dbc2010-12-05 16:15:10 +01001020#ifdef CONFIG_CONSOLE_POLL
1021
1022static void serial_omap_poll_put_char(struct uart_port *port, unsigned char ch)
1023{
1024 struct uart_omap_port *up = (struct uart_omap_port *)port;
Govindraj.Rfcdca752011-02-28 18:12:23 +05301025
1026 pm_runtime_get_sync(&up->pdev->dev);
Cosmin Cojocar1b41dbc2010-12-05 16:15:10 +01001027 wait_for_xmitr(up);
1028 serial_out(up, UART_TX, ch);
Govindraj.Rfcdca752011-02-28 18:12:23 +05301029 pm_runtime_put(&up->pdev->dev);
Cosmin Cojocar1b41dbc2010-12-05 16:15:10 +01001030}
1031
1032static int serial_omap_poll_get_char(struct uart_port *port)
1033{
1034 struct uart_omap_port *up = (struct uart_omap_port *)port;
Govindraj.Rfcdca752011-02-28 18:12:23 +05301035 unsigned int status;
Cosmin Cojocar1b41dbc2010-12-05 16:15:10 +01001036
Govindraj.Rfcdca752011-02-28 18:12:23 +05301037 pm_runtime_get_sync(&up->pdev->dev);
1038 status = serial_in(up, UART_LSR);
Cosmin Cojocar1b41dbc2010-12-05 16:15:10 +01001039 if (!(status & UART_LSR_DR))
1040 return NO_POLL_CHAR;
1041
Govindraj.Rfcdca752011-02-28 18:12:23 +05301042 status = serial_in(up, UART_RX);
1043 pm_runtime_put(&up->pdev->dev);
1044 return status;
Cosmin Cojocar1b41dbc2010-12-05 16:15:10 +01001045}
1046
1047#endif /* CONFIG_CONSOLE_POLL */
1048
1049#ifdef CONFIG_SERIAL_OMAP_CONSOLE
1050
1051static struct uart_omap_port *serial_omap_console_ports[4];
1052
1053static struct uart_driver serial_omap_reg;
1054
Govindraj.Rb6126332010-09-27 20:20:49 +05301055static void serial_omap_console_putchar(struct uart_port *port, int ch)
1056{
1057 struct uart_omap_port *up = (struct uart_omap_port *)port;
1058
1059 wait_for_xmitr(up);
1060 serial_out(up, UART_TX, ch);
1061}
1062
1063static void
1064serial_omap_console_write(struct console *co, const char *s,
1065 unsigned int count)
1066{
1067 struct uart_omap_port *up = serial_omap_console_ports[co->index];
1068 unsigned long flags;
1069 unsigned int ier;
1070 int locked = 1;
1071
Govindraj.Rfcdca752011-02-28 18:12:23 +05301072 pm_runtime_get_sync(&up->pdev->dev);
1073
Govindraj.Rb6126332010-09-27 20:20:49 +05301074 local_irq_save(flags);
1075 if (up->port.sysrq)
1076 locked = 0;
1077 else if (oops_in_progress)
1078 locked = spin_trylock(&up->port.lock);
1079 else
1080 spin_lock(&up->port.lock);
1081
1082 /*
1083 * First save the IER then disable the interrupts
1084 */
1085 ier = serial_in(up, UART_IER);
1086 serial_out(up, UART_IER, 0);
1087
1088 uart_console_write(&up->port, s, count, serial_omap_console_putchar);
1089
1090 /*
1091 * Finally, wait for transmitter to become empty
1092 * and restore the IER
1093 */
1094 wait_for_xmitr(up);
1095 serial_out(up, UART_IER, ier);
1096 /*
1097 * The receive handling will happen properly because the
1098 * receive ready bit will still be set; it is not cleared
1099 * on read. However, modem control will not, we must
1100 * call it if we have saved something in the saved flags
1101 * while processing with interrupts off.
1102 */
1103 if (up->msr_saved_flags)
1104 check_modem_status(up);
1105
Govindraj.Rfcdca752011-02-28 18:12:23 +05301106 pm_runtime_mark_last_busy(&up->pdev->dev);
1107 pm_runtime_put_autosuspend(&up->pdev->dev);
Govindraj.Rb6126332010-09-27 20:20:49 +05301108 if (locked)
1109 spin_unlock(&up->port.lock);
1110 local_irq_restore(flags);
1111}
1112
1113static int __init
1114serial_omap_console_setup(struct console *co, char *options)
1115{
1116 struct uart_omap_port *up;
1117 int baud = 115200;
1118 int bits = 8;
1119 int parity = 'n';
1120 int flow = 'n';
1121
1122 if (serial_omap_console_ports[co->index] == NULL)
1123 return -ENODEV;
1124 up = serial_omap_console_ports[co->index];
1125
1126 if (options)
1127 uart_parse_options(options, &baud, &parity, &bits, &flow);
1128
1129 return uart_set_options(&up->port, co, baud, parity, bits, flow);
1130}
1131
1132static struct console serial_omap_console = {
1133 .name = OMAP_SERIAL_NAME,
1134 .write = serial_omap_console_write,
1135 .device = uart_console_device,
1136 .setup = serial_omap_console_setup,
1137 .flags = CON_PRINTBUFFER,
1138 .index = -1,
1139 .data = &serial_omap_reg,
1140};
1141
1142static void serial_omap_add_console_port(struct uart_omap_port *up)
1143{
Rajendra Nayakba774332011-12-14 17:25:43 +05301144 serial_omap_console_ports[up->port.line] = up;
Govindraj.Rb6126332010-09-27 20:20:49 +05301145}
1146
1147#define OMAP_CONSOLE (&serial_omap_console)
1148
1149#else
1150
1151#define OMAP_CONSOLE NULL
1152
1153static inline void serial_omap_add_console_port(struct uart_omap_port *up)
1154{}
1155
1156#endif
1157
1158static struct uart_ops serial_omap_pops = {
1159 .tx_empty = serial_omap_tx_empty,
1160 .set_mctrl = serial_omap_set_mctrl,
1161 .get_mctrl = serial_omap_get_mctrl,
1162 .stop_tx = serial_omap_stop_tx,
1163 .start_tx = serial_omap_start_tx,
1164 .stop_rx = serial_omap_stop_rx,
1165 .enable_ms = serial_omap_enable_ms,
1166 .break_ctl = serial_omap_break_ctl,
1167 .startup = serial_omap_startup,
1168 .shutdown = serial_omap_shutdown,
1169 .set_termios = serial_omap_set_termios,
1170 .pm = serial_omap_pm,
1171 .type = serial_omap_type,
1172 .release_port = serial_omap_release_port,
1173 .request_port = serial_omap_request_port,
1174 .config_port = serial_omap_config_port,
1175 .verify_port = serial_omap_verify_port,
Cosmin Cojocar1b41dbc2010-12-05 16:15:10 +01001176#ifdef CONFIG_CONSOLE_POLL
1177 .poll_put_char = serial_omap_poll_put_char,
1178 .poll_get_char = serial_omap_poll_get_char,
1179#endif
Govindraj.Rb6126332010-09-27 20:20:49 +05301180};
1181
1182static struct uart_driver serial_omap_reg = {
1183 .owner = THIS_MODULE,
1184 .driver_name = "OMAP-SERIAL",
1185 .dev_name = OMAP_SERIAL_NAME,
1186 .nr = OMAP_MAX_HSUART_PORTS,
1187 .cons = OMAP_CONSOLE,
1188};
1189
Shubhrajyoti D3bc4f0d2012-01-16 15:52:36 +05301190#ifdef CONFIG_PM_SLEEP
Govindraj.Rfcdca752011-02-28 18:12:23 +05301191static int serial_omap_suspend(struct device *dev)
Govindraj.Rb6126332010-09-27 20:20:49 +05301192{
Govindraj.Rfcdca752011-02-28 18:12:23 +05301193 struct uart_omap_port *up = dev_get_drvdata(dev);
Govindraj.Rb6126332010-09-27 20:20:49 +05301194
Govindraj.R2fd14962011-11-09 17:41:21 +05301195 if (up) {
Govindraj.Rb6126332010-09-27 20:20:49 +05301196 uart_suspend_port(&serial_omap_reg, &up->port);
Govindraj.R2fd14962011-11-09 17:41:21 +05301197 flush_work_sync(&up->qos_work);
1198 }
1199
Govindraj.Rb6126332010-09-27 20:20:49 +05301200 return 0;
1201}
1202
Govindraj.Rfcdca752011-02-28 18:12:23 +05301203static int serial_omap_resume(struct device *dev)
Govindraj.Rb6126332010-09-27 20:20:49 +05301204{
Govindraj.Rfcdca752011-02-28 18:12:23 +05301205 struct uart_omap_port *up = dev_get_drvdata(dev);
Govindraj.Rb6126332010-09-27 20:20:49 +05301206
1207 if (up)
1208 uart_resume_port(&serial_omap_reg, &up->port);
1209 return 0;
1210}
Govindraj.Rfcdca752011-02-28 18:12:23 +05301211#endif
Govindraj.Rb6126332010-09-27 20:20:49 +05301212
Jon Huntera9e210e2011-11-09 17:34:49 +05301213static void serial_omap_rxdma_poll(unsigned long uart_no)
Govindraj.Rb6126332010-09-27 20:20:49 +05301214{
1215 struct uart_omap_port *up = ui[uart_no];
1216 unsigned int curr_dma_pos, curr_transmitted_size;
Vasiliy Kulikov79fc3e22010-10-10 21:28:35 +04001217 int ret = 0;
Govindraj.Rb6126332010-09-27 20:20:49 +05301218
1219 curr_dma_pos = omap_get_dma_dst_pos(up->uart_dma.rx_dma_channel);
1220 if ((curr_dma_pos == up->uart_dma.prev_rx_dma_pos) ||
1221 (curr_dma_pos == 0)) {
1222 if (jiffies_to_msecs(jiffies - up->port_activity) <
Jon Huntera9e210e2011-11-09 17:34:49 +05301223 up->uart_dma.rx_timeout) {
Govindraj.Rb6126332010-09-27 20:20:49 +05301224 mod_timer(&up->uart_dma.rx_timer, jiffies +
Jon Huntera9e210e2011-11-09 17:34:49 +05301225 usecs_to_jiffies(up->uart_dma.rx_poll_rate));
Govindraj.Rb6126332010-09-27 20:20:49 +05301226 } else {
1227 serial_omap_stop_rxdma(up);
1228 up->ier |= (UART_IER_RDI | UART_IER_RLSI);
1229 serial_out(up, UART_IER, up->ier);
1230 }
1231 return;
1232 }
1233
1234 curr_transmitted_size = curr_dma_pos -
1235 up->uart_dma.prev_rx_dma_pos;
1236 up->port.icount.rx += curr_transmitted_size;
1237 tty_insert_flip_string(up->port.state->port.tty,
1238 up->uart_dma.rx_buf +
1239 (up->uart_dma.prev_rx_dma_pos -
1240 up->uart_dma.rx_buf_dma_phys),
1241 curr_transmitted_size);
1242 tty_flip_buffer_push(up->port.state->port.tty);
1243 up->uart_dma.prev_rx_dma_pos = curr_dma_pos;
1244 if (up->uart_dma.rx_buf_size +
1245 up->uart_dma.rx_buf_dma_phys == curr_dma_pos) {
1246 ret = serial_omap_start_rxdma(up);
1247 if (ret < 0) {
1248 serial_omap_stop_rxdma(up);
1249 up->ier |= (UART_IER_RDI | UART_IER_RLSI);
1250 serial_out(up, UART_IER, up->ier);
1251 }
1252 } else {
1253 mod_timer(&up->uart_dma.rx_timer, jiffies +
Jon Huntera9e210e2011-11-09 17:34:49 +05301254 usecs_to_jiffies(up->uart_dma.rx_poll_rate));
Govindraj.Rb6126332010-09-27 20:20:49 +05301255 }
1256 up->port_activity = jiffies;
1257}
1258
1259static void uart_rx_dma_callback(int lch, u16 ch_status, void *data)
1260{
1261 return;
1262}
1263
1264static int serial_omap_start_rxdma(struct uart_omap_port *up)
1265{
1266 int ret = 0;
1267
1268 if (up->uart_dma.rx_dma_channel == -1) {
Govindraj.Rfcdca752011-02-28 18:12:23 +05301269 pm_runtime_get_sync(&up->pdev->dev);
Govindraj.Rb6126332010-09-27 20:20:49 +05301270 ret = omap_request_dma(up->uart_dma.uart_dma_rx,
1271 "UART Rx DMA",
1272 (void *)uart_rx_dma_callback, up,
1273 &(up->uart_dma.rx_dma_channel));
1274 if (ret < 0)
1275 return ret;
1276
1277 omap_set_dma_src_params(up->uart_dma.rx_dma_channel, 0,
1278 OMAP_DMA_AMODE_CONSTANT,
1279 up->uart_dma.uart_base, 0, 0);
1280 omap_set_dma_dest_params(up->uart_dma.rx_dma_channel, 0,
1281 OMAP_DMA_AMODE_POST_INC,
1282 up->uart_dma.rx_buf_dma_phys, 0, 0);
1283 omap_set_dma_transfer_params(up->uart_dma.rx_dma_channel,
1284 OMAP_DMA_DATA_TYPE_S8,
1285 up->uart_dma.rx_buf_size, 1,
1286 OMAP_DMA_SYNC_ELEMENT,
1287 up->uart_dma.uart_dma_rx, 0);
1288 }
1289 up->uart_dma.prev_rx_dma_pos = up->uart_dma.rx_buf_dma_phys;
1290 /* FIXME: Cache maintenance needed here? */
1291 omap_start_dma(up->uart_dma.rx_dma_channel);
1292 mod_timer(&up->uart_dma.rx_timer, jiffies +
Jon Huntera9e210e2011-11-09 17:34:49 +05301293 usecs_to_jiffies(up->uart_dma.rx_poll_rate));
Govindraj.Rb6126332010-09-27 20:20:49 +05301294 up->uart_dma.rx_dma_used = true;
1295 return ret;
1296}
1297
1298static void serial_omap_continue_tx(struct uart_omap_port *up)
1299{
1300 struct circ_buf *xmit = &up->port.state->xmit;
1301 unsigned int start = up->uart_dma.tx_buf_dma_phys
1302 + (xmit->tail & (UART_XMIT_SIZE - 1));
1303
1304 if (uart_circ_empty(xmit))
1305 return;
1306
1307 up->uart_dma.tx_buf_size = uart_circ_chars_pending(xmit);
1308 /*
1309 * It is a circular buffer. See if the buffer has wounded back.
1310 * If yes it will have to be transferred in two separate dma
1311 * transfers
1312 */
1313 if (start + up->uart_dma.tx_buf_size >=
1314 up->uart_dma.tx_buf_dma_phys + UART_XMIT_SIZE)
1315 up->uart_dma.tx_buf_size =
1316 (up->uart_dma.tx_buf_dma_phys + UART_XMIT_SIZE) - start;
1317 omap_set_dma_dest_params(up->uart_dma.tx_dma_channel, 0,
1318 OMAP_DMA_AMODE_CONSTANT,
1319 up->uart_dma.uart_base, 0, 0);
1320 omap_set_dma_src_params(up->uart_dma.tx_dma_channel, 0,
1321 OMAP_DMA_AMODE_POST_INC, start, 0, 0);
1322 omap_set_dma_transfer_params(up->uart_dma.tx_dma_channel,
1323 OMAP_DMA_DATA_TYPE_S8,
1324 up->uart_dma.tx_buf_size, 1,
1325 OMAP_DMA_SYNC_ELEMENT,
1326 up->uart_dma.uart_dma_tx, 0);
1327 /* FIXME: Cache maintenance needed here? */
1328 omap_start_dma(up->uart_dma.tx_dma_channel);
1329}
1330
1331static void uart_tx_dma_callback(int lch, u16 ch_status, void *data)
1332{
1333 struct uart_omap_port *up = (struct uart_omap_port *)data;
1334 struct circ_buf *xmit = &up->port.state->xmit;
1335
1336 xmit->tail = (xmit->tail + up->uart_dma.tx_buf_size) & \
1337 (UART_XMIT_SIZE - 1);
1338 up->port.icount.tx += up->uart_dma.tx_buf_size;
1339
1340 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
1341 uart_write_wakeup(&up->port);
1342
1343 if (uart_circ_empty(xmit)) {
1344 spin_lock(&(up->uart_dma.tx_lock));
1345 serial_omap_stop_tx(&up->port);
1346 up->uart_dma.tx_dma_used = false;
1347 spin_unlock(&(up->uart_dma.tx_lock));
1348 } else {
1349 omap_stop_dma(up->uart_dma.tx_dma_channel);
1350 serial_omap_continue_tx(up);
1351 }
1352 up->port_activity = jiffies;
1353 return;
1354}
1355
Rajendra Nayakd92b0df2011-12-14 17:25:45 +05301356static struct omap_uart_port_info *of_get_uart_port_info(struct device *dev)
1357{
1358 struct omap_uart_port_info *omap_up_info;
1359
1360 omap_up_info = devm_kzalloc(dev, sizeof(*omap_up_info), GFP_KERNEL);
1361 if (!omap_up_info)
1362 return NULL; /* out of memory */
1363
1364 of_property_read_u32(dev->of_node, "clock-frequency",
1365 &omap_up_info->uartclk);
1366 return omap_up_info;
1367}
1368
Govindraj.Rb6126332010-09-27 20:20:49 +05301369static int serial_omap_probe(struct platform_device *pdev)
1370{
1371 struct uart_omap_port *up;
1372 struct resource *mem, *irq, *dma_tx, *dma_rx;
1373 struct omap_uart_port_info *omap_up_info = pdev->dev.platform_data;
1374 int ret = -ENOSPC;
1375
Rajendra Nayakd92b0df2011-12-14 17:25:45 +05301376 if (pdev->dev.of_node)
1377 omap_up_info = of_get_uart_port_info(&pdev->dev);
1378
Govindraj.Rb6126332010-09-27 20:20:49 +05301379 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1380 if (!mem) {
1381 dev_err(&pdev->dev, "no mem resource?\n");
1382 return -ENODEV;
1383 }
1384
1385 irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
1386 if (!irq) {
1387 dev_err(&pdev->dev, "no irq resource?\n");
1388 return -ENODEV;
1389 }
1390
Joe Perches28f65c112011-06-09 09:13:32 -07001391 if (!request_mem_region(mem->start, resource_size(mem),
1392 pdev->dev.driver->name)) {
Govindraj.Rb6126332010-09-27 20:20:49 +05301393 dev_err(&pdev->dev, "memory region already claimed\n");
1394 return -EBUSY;
1395 }
1396
1397 dma_rx = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx");
1398 if (!dma_rx) {
1399 ret = -EINVAL;
1400 goto err;
1401 }
1402
1403 dma_tx = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx");
1404 if (!dma_tx) {
1405 ret = -EINVAL;
1406 goto err;
1407 }
1408
1409 up = kzalloc(sizeof(*up), GFP_KERNEL);
1410 if (up == NULL) {
1411 ret = -ENOMEM;
1412 goto do_release_region;
1413 }
Govindraj.Rb6126332010-09-27 20:20:49 +05301414 up->pdev = pdev;
1415 up->port.dev = &pdev->dev;
1416 up->port.type = PORT_OMAP;
1417 up->port.iotype = UPIO_MEM;
1418 up->port.irq = irq->start;
1419
1420 up->port.regshift = 2;
1421 up->port.fifosize = 64;
1422 up->port.ops = &serial_omap_pops;
Govindraj.Rb6126332010-09-27 20:20:49 +05301423
Rajendra Nayakd92b0df2011-12-14 17:25:45 +05301424 if (pdev->dev.of_node)
1425 up->port.line = of_alias_get_id(pdev->dev.of_node, "serial");
1426 else
1427 up->port.line = pdev->id;
1428
1429 if (up->port.line < 0) {
1430 dev_err(&pdev->dev, "failed to get alias/pdev id, errno %d\n",
1431 up->port.line);
1432 ret = -ENODEV;
1433 goto err;
1434 }
1435
1436 sprintf(up->name, "OMAP UART%d", up->port.line);
Govindraj.Redd70ad2011-10-11 14:55:41 +05301437 up->port.mapbase = mem->start;
1438 up->port.membase = ioremap(mem->start, resource_size(mem));
1439 if (!up->port.membase) {
1440 dev_err(&pdev->dev, "can't ioremap UART\n");
1441 ret = -ENOMEM;
1442 goto err;
1443 }
1444
Govindraj.Rb6126332010-09-27 20:20:49 +05301445 up->port.flags = omap_up_info->flags;
Govindraj.Rb6126332010-09-27 20:20:49 +05301446 up->port.uartclk = omap_up_info->uartclk;
Rajendra Nayak8fe789d2011-12-14 17:25:44 +05301447 if (!up->port.uartclk) {
1448 up->port.uartclk = DEFAULT_CLK_SPEED;
1449 dev_warn(&pdev->dev, "No clock speed specified: using default:"
1450 "%d\n", DEFAULT_CLK_SPEED);
1451 }
Govindraj.Rb6126332010-09-27 20:20:49 +05301452 up->uart_dma.uart_base = mem->start;
Govindraj.R94734742011-11-07 19:00:33 +05301453 up->errata = omap_up_info->errata;
Govindraj.Rb6126332010-09-27 20:20:49 +05301454
1455 if (omap_up_info->dma_enabled) {
1456 up->uart_dma.uart_dma_tx = dma_tx->start;
1457 up->uart_dma.uart_dma_rx = dma_rx->start;
1458 up->use_dma = 1;
Deepak Kc86845db2011-11-09 17:33:38 +05301459 up->uart_dma.rx_buf_size = omap_up_info->dma_rx_buf_size;
1460 up->uart_dma.rx_timeout = omap_up_info->dma_rx_timeout;
Jon Huntera9e210e2011-11-09 17:34:49 +05301461 up->uart_dma.rx_poll_rate = omap_up_info->dma_rx_poll_rate;
Govindraj.Rb6126332010-09-27 20:20:49 +05301462 spin_lock_init(&(up->uart_dma.tx_lock));
1463 spin_lock_init(&(up->uart_dma.rx_lock));
1464 up->uart_dma.tx_dma_channel = OMAP_UART_DMA_CH_FREE;
1465 up->uart_dma.rx_dma_channel = OMAP_UART_DMA_CH_FREE;
1466 }
1467
Govindraj.R2fd14962011-11-09 17:41:21 +05301468 up->latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE;
1469 up->calc_latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE;
1470 pm_qos_add_request(&up->pm_qos_request,
1471 PM_QOS_CPU_DMA_LATENCY, up->latency);
1472 serial_omap_uart_wq = create_singlethread_workqueue(up->name);
1473 INIT_WORK(&up->qos_work, serial_omap_uart_qos_work);
1474
Govindraj.Rfcdca752011-02-28 18:12:23 +05301475 pm_runtime_use_autosuspend(&pdev->dev);
1476 pm_runtime_set_autosuspend_delay(&pdev->dev,
Deepak Kc86845db2011-11-09 17:33:38 +05301477 omap_up_info->autosuspend_timeout);
Govindraj.Rfcdca752011-02-28 18:12:23 +05301478
1479 pm_runtime_irq_safe(&pdev->dev);
1480 pm_runtime_enable(&pdev->dev);
1481 pm_runtime_get_sync(&pdev->dev);
1482
Rajendra Nayakba774332011-12-14 17:25:43 +05301483 ui[up->port.line] = up;
Govindraj.Rb6126332010-09-27 20:20:49 +05301484 serial_omap_add_console_port(up);
1485
1486 ret = uart_add_one_port(&serial_omap_reg, &up->port);
1487 if (ret != 0)
1488 goto do_release_region;
1489
Govindraj.Rfcdca752011-02-28 18:12:23 +05301490 pm_runtime_put(&pdev->dev);
Govindraj.Rb6126332010-09-27 20:20:49 +05301491 platform_set_drvdata(pdev, up);
1492 return 0;
1493err:
1494 dev_err(&pdev->dev, "[UART%d]: failure [%s]: %d\n",
1495 pdev->id, __func__, ret);
1496do_release_region:
Joe Perches28f65c112011-06-09 09:13:32 -07001497 release_mem_region(mem->start, resource_size(mem));
Govindraj.Rb6126332010-09-27 20:20:49 +05301498 return ret;
1499}
1500
1501static int serial_omap_remove(struct platform_device *dev)
1502{
1503 struct uart_omap_port *up = platform_get_drvdata(dev);
1504
Govindraj.Rb6126332010-09-27 20:20:49 +05301505 if (up) {
Govindraj.Rfcdca752011-02-28 18:12:23 +05301506 pm_runtime_disable(&up->pdev->dev);
Govindraj.Rb6126332010-09-27 20:20:49 +05301507 uart_remove_one_port(&serial_omap_reg, &up->port);
Govindraj.R2fd14962011-11-09 17:41:21 +05301508 pm_qos_remove_request(&up->pm_qos_request);
1509
Govindraj.Rb6126332010-09-27 20:20:49 +05301510 kfree(up);
1511 }
Govindraj.Rfcdca752011-02-28 18:12:23 +05301512
1513 platform_set_drvdata(dev, NULL);
Govindraj.Rb6126332010-09-27 20:20:49 +05301514 return 0;
1515}
1516
Govindraj.R94734742011-11-07 19:00:33 +05301517/*
1518 * Work Around for Errata i202 (2430, 3430, 3630, 4430 and 4460)
1519 * The access to uart register after MDR1 Access
1520 * causes UART to corrupt data.
1521 *
1522 * Need a delay =
1523 * 5 L4 clock cycles + 5 UART functional clock cycle (@48MHz = ~0.2uS)
1524 * give 10 times as much
1525 */
1526static void serial_omap_mdr1_errataset(struct uart_omap_port *up, u8 mdr1)
1527{
1528 u8 timeout = 255;
1529
1530 serial_out(up, UART_OMAP_MDR1, mdr1);
1531 udelay(2);
1532 serial_out(up, UART_FCR, up->fcr | UART_FCR_CLEAR_XMIT |
1533 UART_FCR_CLEAR_RCVR);
1534 /*
1535 * Wait for FIFO to empty: when empty, RX_FIFO_E bit is 0 and
1536 * TX_FIFO_E bit is 1.
1537 */
1538 while (UART_LSR_THRE != (serial_in(up, UART_LSR) &
1539 (UART_LSR_THRE | UART_LSR_DR))) {
1540 timeout--;
1541 if (!timeout) {
1542 /* Should *never* happen. we warn and carry on */
1543 dev_crit(&up->pdev->dev, "Errata i202: timedout %x\n",
1544 serial_in(up, UART_LSR));
1545 break;
1546 }
1547 udelay(1);
1548 }
1549}
1550
Shubhrajyoti Db5148852012-01-16 15:52:37 +05301551#ifdef CONFIG_PM_RUNTIME
Govindraj.R9f9ac1e2011-11-07 18:56:12 +05301552static void serial_omap_restore_context(struct uart_omap_port *up)
1553{
Govindraj.R94734742011-11-07 19:00:33 +05301554 if (up->errata & UART_ERRATA_i202_MDR1_ACCESS)
1555 serial_omap_mdr1_errataset(up, UART_OMAP_MDR1_DISABLE);
1556 else
1557 serial_out(up, UART_OMAP_MDR1, UART_OMAP_MDR1_DISABLE);
1558
Govindraj.R9f9ac1e2011-11-07 18:56:12 +05301559 serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); /* Config B mode */
1560 serial_out(up, UART_EFR, UART_EFR_ECB);
1561 serial_out(up, UART_LCR, 0x0); /* Operational mode */
1562 serial_out(up, UART_IER, 0x0);
1563 serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); /* Config B mode */
Govindraj.Rc538d202011-11-07 18:57:03 +05301564 serial_out(up, UART_DLL, up->dll);
1565 serial_out(up, UART_DLM, up->dlh);
Govindraj.R9f9ac1e2011-11-07 18:56:12 +05301566 serial_out(up, UART_LCR, 0x0); /* Operational mode */
1567 serial_out(up, UART_IER, up->ier);
1568 serial_out(up, UART_FCR, up->fcr);
1569 serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);
1570 serial_out(up, UART_MCR, up->mcr);
1571 serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); /* Config B mode */
Govindraj.Rc538d202011-11-07 18:57:03 +05301572 serial_out(up, UART_OMAP_SCR, up->scr);
Govindraj.R9f9ac1e2011-11-07 18:56:12 +05301573 serial_out(up, UART_EFR, up->efr);
1574 serial_out(up, UART_LCR, up->lcr);
Govindraj.R94734742011-11-07 19:00:33 +05301575 if (up->errata & UART_ERRATA_i202_MDR1_ACCESS)
1576 serial_omap_mdr1_errataset(up, up->mdr1);
1577 else
1578 serial_out(up, UART_OMAP_MDR1, up->mdr1);
Govindraj.R9f9ac1e2011-11-07 18:56:12 +05301579}
1580
Govindraj.Rfcdca752011-02-28 18:12:23 +05301581static int serial_omap_runtime_suspend(struct device *dev)
1582{
Govindraj.Rec3bebc2011-10-11 19:11:27 +05301583 struct uart_omap_port *up = dev_get_drvdata(dev);
1584 struct omap_uart_port_info *pdata = dev->platform_data;
1585
1586 if (!up)
1587 return -EINVAL;
1588
Rajendra Nayakd92b0df2011-12-14 17:25:45 +05301589 if (!pdata || !pdata->enable_wakeup)
Govindraj.R62f3ec5f2011-10-13 14:11:09 +05301590 return 0;
1591
Govindraj.Rec3bebc2011-10-11 19:11:27 +05301592 if (pdata->get_context_loss_count)
1593 up->context_loss_cnt = pdata->get_context_loss_count(dev);
1594
Govindraj.R62f3ec5f2011-10-13 14:11:09 +05301595 if (device_may_wakeup(dev)) {
1596 if (!up->wakeups_enabled) {
1597 pdata->enable_wakeup(up->pdev, true);
1598 up->wakeups_enabled = true;
1599 }
1600 } else {
1601 if (up->wakeups_enabled) {
1602 pdata->enable_wakeup(up->pdev, false);
1603 up->wakeups_enabled = false;
1604 }
1605 }
1606
Govindraj.R94734742011-11-07 19:00:33 +05301607 /* Errata i291 */
1608 if (up->use_dma && pdata->set_forceidle &&
1609 (up->errata & UART_ERRATA_i291_DMA_FORCEIDLE))
1610 pdata->set_forceidle(up->pdev);
1611
Govindraj.R2fd14962011-11-09 17:41:21 +05301612 up->latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE;
1613 schedule_work(&up->qos_work);
1614
Govindraj.Rfcdca752011-02-28 18:12:23 +05301615 return 0;
1616}
1617
1618static int serial_omap_runtime_resume(struct device *dev)
1619{
Govindraj.R9f9ac1e2011-11-07 18:56:12 +05301620 struct uart_omap_port *up = dev_get_drvdata(dev);
Govindraj.Rec3bebc2011-10-11 19:11:27 +05301621 struct omap_uart_port_info *pdata = dev->platform_data;
Govindraj.R9f9ac1e2011-11-07 18:56:12 +05301622
Govindraj.Rec3bebc2011-10-11 19:11:27 +05301623 if (up) {
1624 if (pdata->get_context_loss_count) {
1625 u32 loss_cnt = pdata->get_context_loss_count(dev);
1626
1627 if (up->context_loss_cnt != loss_cnt)
1628 serial_omap_restore_context(up);
1629 }
Govindraj.R94734742011-11-07 19:00:33 +05301630
1631 /* Errata i291 */
1632 if (up->use_dma && pdata->set_noidle &&
1633 (up->errata & UART_ERRATA_i291_DMA_FORCEIDLE))
1634 pdata->set_noidle(up->pdev);
Govindraj.R2fd14962011-11-09 17:41:21 +05301635
1636 up->latency = up->calc_latency;
1637 schedule_work(&up->qos_work);
Govindraj.Rec3bebc2011-10-11 19:11:27 +05301638 }
Govindraj.R9f9ac1e2011-11-07 18:56:12 +05301639
Govindraj.Rfcdca752011-02-28 18:12:23 +05301640 return 0;
1641}
1642#endif
1643
1644static const struct dev_pm_ops serial_omap_dev_pm_ops = {
1645 SET_SYSTEM_SLEEP_PM_OPS(serial_omap_suspend, serial_omap_resume)
1646 SET_RUNTIME_PM_OPS(serial_omap_runtime_suspend,
1647 serial_omap_runtime_resume, NULL)
1648};
1649
Rajendra Nayakd92b0df2011-12-14 17:25:45 +05301650#if defined(CONFIG_OF)
1651static const struct of_device_id omap_serial_of_match[] = {
1652 { .compatible = "ti,omap2-uart" },
1653 { .compatible = "ti,omap3-uart" },
1654 { .compatible = "ti,omap4-uart" },
1655 {},
1656};
1657MODULE_DEVICE_TABLE(of, omap_serial_of_match);
1658#endif
1659
Govindraj.Rb6126332010-09-27 20:20:49 +05301660static struct platform_driver serial_omap_driver = {
1661 .probe = serial_omap_probe,
1662 .remove = serial_omap_remove,
Govindraj.Rb6126332010-09-27 20:20:49 +05301663 .driver = {
1664 .name = DRIVER_NAME,
Govindraj.Rfcdca752011-02-28 18:12:23 +05301665 .pm = &serial_omap_dev_pm_ops,
Rajendra Nayakd92b0df2011-12-14 17:25:45 +05301666 .of_match_table = of_match_ptr(omap_serial_of_match),
Govindraj.Rb6126332010-09-27 20:20:49 +05301667 },
1668};
1669
1670static int __init serial_omap_init(void)
1671{
1672 int ret;
1673
1674 ret = uart_register_driver(&serial_omap_reg);
1675 if (ret != 0)
1676 return ret;
1677 ret = platform_driver_register(&serial_omap_driver);
1678 if (ret != 0)
1679 uart_unregister_driver(&serial_omap_reg);
1680 return ret;
1681}
1682
1683static void __exit serial_omap_exit(void)
1684{
1685 platform_driver_unregister(&serial_omap_driver);
1686 uart_unregister_driver(&serial_omap_reg);
1687}
1688
1689module_init(serial_omap_init);
1690module_exit(serial_omap_exit);
1691
1692MODULE_DESCRIPTION("OMAP High Speed UART driver");
1693MODULE_LICENSE("GPL");
1694MODULE_AUTHOR("Texas Instruments Inc");