]>
Commit | Line | Data |
---|---|---|
e14c6eae MG |
1 | /* |
2 | * linux/drivers/serial/omap-serial.c | |
3 | * | |
4 | * Modified: Manasa Gangaiah | |
5 | * Copyright (C) 2009 Texas Instrument Inc. | |
6 | * | |
7 | * Initial driver: Juha Yrjola | |
8 | * Copyright (C) 2007 Nokia Corporation | |
9 | * | |
10 | * Based on drivers/serial/pxa.c by Nicolas Pitre. | |
11 | * Copyright (C) 2003 Monta Vista Software, Inc. | |
12 | * | |
13 | * This program is free software; you can redistribute it and/or modify | |
14 | * it under the terms of the GNU General Public License as published by | |
15 | * the Free Software Foundation; either version 2 of the License, or | |
16 | * (at your option) any later version. | |
17 | * | |
18 | */ | |
19 | ||
20 | #if defined(CONFIG_SERIAL_OMAP_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) | |
21 | #define SUPPORT_SYSRQ | |
22 | #endif | |
23 | ||
24 | #include <linux/module.h> | |
25 | #include <linux/init.h> | |
26 | #include <linux/console.h> | |
27 | #include <linux/serial_reg.h> | |
28 | #include <linux/delay.h> | |
29 | #include <linux/platform_device.h> | |
30 | #include <linux/tty.h> | |
31 | #include <linux/tty_flip.h> | |
32 | #include <linux/serial_core.h> | |
33 | #include <linux/io.h> | |
34 | #include <linux/dma-mapping.h> | |
35 | #include <linux/wakelock.h> | |
36 | #include <linux/workqueue.h> | |
37 | ||
38 | #include <asm/irq.h> | |
39 | #include <asm/dma.h> | |
40 | ||
41 | #include <plat/dmtimer.h> | |
42 | #include <plat/omap-serial.h> | |
43 | #include <mach/gpio.h> | |
44 | #include <plat/dma.h> | |
45 | #include <plat/io.h> | |
46 | #ifdef CONFIG_OMAP3_PM | |
47 | #include <../arch/arm/mach-omap2/ti-compat.h> | |
48 | #include <../arch/arm/mach-omap2/prcm-regs.h> | |
49 | #endif | |
50 | #include <asm/mach/serial_omap.h> | |
51 | ||
52 | unsigned long isr8250_activity; | |
53 | static int gps_port; | |
54 | ||
55 | void omap_uart_set_gps_port(int port) | |
56 | { | |
57 | gps_port = port; | |
58 | } | |
59 | ||
60 | #define CONSOLE_NAME "console=" | |
61 | ||
62 | #ifdef CONFIG_ARCH_OMAP34XX | |
63 | #define OMAP_MDR1_DISABLE 0x07 | |
64 | #define OMAP_MDR1_MODE13X 0x03 | |
65 | #define OMAP_MDR1_MODE16X 0x00 | |
66 | #define OMAP_MODE13X_SPEED 230400 | |
67 | #endif | |
68 | ||
69 | ||
70 | /* Debugging Macros */ | |
71 | #undef DEBUG | |
72 | ||
73 | #ifdef DEBUG | |
74 | #define DPRINTK printk | |
75 | #else | |
76 | #define DPRINTK(x...) | |
77 | #endif | |
78 | ||
79 | /* | |
80 | * We default to IRQ0 for the "no irq" hack. Some | |
81 | * machine types want others as well - they're free | |
82 | * to redefine this in their header file. | |
83 | */ | |
84 | #define is_real_interrupt(irq) ((irq) != 0) | |
85 | ||
86 | /* TBD: move this to header file */ | |
87 | static u8 uart_dma_tx[MAX_UARTS + 1] = | |
88 | { OMAP24XX_DMA_UART1_TX, OMAP24XX_DMA_UART2_TX, OMAP24XX_DMA_UART3_TX }; | |
89 | static u8 uart_dma_rx[MAX_UARTS + 1] = | |
90 | { OMAP24XX_DMA_UART1_RX, OMAP24XX_DMA_UART2_RX, OMAP24XX_DMA_UART3_RX }; | |
91 | ||
92 | ||
93 | struct uart_omap_dma { | |
94 | int rx_dma_channel; | |
95 | int tx_dma_channel; | |
96 | dma_addr_t rx_buf_dma_phys; /* Physical adress of RX DMA buffer */ | |
97 | dma_addr_t tx_buf_dma_phys; /* Physical adress of TX DMA buffer */ | |
98 | /* | |
99 | * Buffer for rx dma.It is not required for tx because the buffer | |
100 | * comes from port structure | |
101 | */ | |
102 | unsigned char *rx_buf; | |
103 | unsigned int prev_rx_dma_pos; | |
104 | int tx_buf_size; | |
105 | int tx_dma_state; | |
106 | int rx_dma_state; | |
107 | spinlock_t tx_lock; | |
108 | spinlock_t rx_lock; | |
109 | struct timer_list rx_timer;/* timer to poll activity on rx dma */ | |
110 | int rx_buf_size; | |
111 | int rx_timeout; | |
112 | }; | |
113 | ||
114 | struct uart_omap_port { | |
115 | struct uart_port port; | |
116 | struct uart_omap_dma uart_dma; | |
117 | struct platform_device *pdev; | |
118 | ||
119 | unsigned char ier; | |
120 | unsigned char lcr; | |
121 | unsigned char mcr; | |
122 | int use_dma; | |
123 | int is_buf_dma_alloced; | |
124 | int restore_autorts; | |
125 | /* | |
126 | * Some bits in registers are cleared on a read, so they must | |
127 | * be saved whenever the register is read but the bits will not | |
128 | * be immediately processed. | |
129 | */ | |
130 | unsigned int lsr_break_flag; | |
131 | #define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA | |
132 | unsigned char msr_saved_flags; | |
133 | char name[12]; | |
134 | int use_console; | |
135 | spinlock_t uart_lock; | |
136 | char dev_name[50]; | |
137 | #ifdef CONFIG_SERIAL_OMAP3430_HW_FLOW_CONTROL | |
138 | unsigned char ctsrts; | |
139 | #endif | |
140 | struct work_struct tty_work; | |
141 | }; | |
142 | ||
143 | static struct uart_omap_port *ui[MAX_UARTS + 1]; | |
144 | unsigned int fcr[MAX_UARTS]; | |
145 | ||
146 | static struct wake_lock omap_serial_wakelock; | |
147 | static struct workqueue_struct *omap_serial_workqueue; | |
148 | ||
149 | /* Forward declaration of dma callback functions */ | |
150 | static void uart_tx_dma_callback(int lch, u16 ch_status, void *data); | |
151 | static void serial_omap_display_reg(struct uart_port *port); | |
152 | static void serial_omap_rx_timeout(unsigned long uart_no); | |
153 | static void serial_omap_start_rxdma(struct uart_omap_port *up); | |
154 | static void serial_omap_set_autorts(struct uart_omap_port *p, int set); | |
155 | ||
156 | #define DBG_RX_DATA 0 | |
157 | ||
158 | int console_detect(char *str) | |
159 | { | |
160 | char *next, *start = NULL; | |
161 | int i; | |
162 | ||
163 | i = strlen(CONSOLE_NAME); | |
164 | next = "console=ttyS2,115200"; | |
165 | ||
166 | while ((next = strchr(next, 'c')) != NULL) { | |
167 | if (!strncmp(next, CONSOLE_NAME, i)) { | |
168 | start = next; | |
169 | break; | |
170 | } else { | |
171 | next++; | |
172 | } | |
173 | ||
174 | } | |
175 | if (!start) | |
176 | return -EPERM; | |
177 | i = 0; | |
178 | start = strchr(start, '=') + 1; | |
179 | while (*start != ',') { | |
180 | str[i++] = *start++; | |
181 | if (i > 6) { | |
182 | printk(KERN_ERR "Invalid Console Name\n"); | |
183 | return -EPERM; | |
184 | } | |
185 | } | |
186 | str[i] = '\0'; | |
187 | return 0; | |
188 | } | |
189 | ||
190 | static inline unsigned int serial_in(struct uart_omap_port *up, int offset) | |
191 | { | |
192 | offset <<= up->port.regshift; | |
193 | if (up->pdev->id != 4) | |
194 | return readb(up->port.membase + offset); | |
195 | else | |
196 | return readw(up->port.membase + offset); | |
197 | } | |
198 | ||
199 | static inline void serial_out(struct uart_omap_port *up, int offset, int value) | |
200 | { | |
201 | offset <<= up->port.regshift; | |
202 | if (up->pdev->id != 4) | |
203 | writeb(value, up->port.membase + offset); | |
204 | else | |
205 | writew(value, up->port.membase + offset); | |
206 | } | |
207 | ||
208 | static inline void serial_omap_clear_fifos(struct uart_omap_port *p) | |
209 | { | |
210 | serial_out(p, UART_FCR, UART_FCR_ENABLE_FIFO); | |
211 | serial_out(p, UART_FCR, UART_FCR_ENABLE_FIFO | | |
212 | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); | |
213 | serial_out(p, UART_FCR, 0); | |
214 | fcr[p->pdev->id - 1] = 0; | |
215 | } | |
216 | ||
217 | /* | |
218 | * We have written our own function to get the divisor so as to support | |
219 | * 13x mode. TBD see if this can be integrated with uart_get_divisor. | |
220 | */ | |
221 | static unsigned int | |
222 | serial_omap_get_divisor(struct uart_port *port, unsigned int baud) | |
223 | { | |
224 | unsigned int divisor; | |
225 | if (baud > OMAP_MODE13X_SPEED && baud != 3000000) | |
226 | divisor = 13; | |
227 | else | |
228 | divisor = 16; | |
229 | return port->uartclk/(baud * divisor); | |
230 | } | |
231 | ||
232 | static void serial_omap_stop_rxdma(struct uart_omap_port *up) | |
233 | { | |
234 | if (up->uart_dma.rx_dma_state) { | |
235 | del_timer(&up->uart_dma.rx_timer); | |
236 | omap_stop_dma(up->uart_dma.rx_dma_channel); | |
237 | omap_free_dma(up->uart_dma.rx_dma_channel); | |
238 | up->uart_dma.rx_dma_channel = 0xFF; | |
239 | up->uart_dma.rx_dma_state = 0x0; | |
240 | } | |
241 | } | |
242 | ||
243 | static void serial_omap_enable_ms(struct uart_port *port) | |
244 | { | |
245 | struct uart_omap_port *up = (struct uart_omap_port *)port; | |
246 | ||
247 | DPRINTK("serial_omap_enable_ms+%d\n", up->pdev->id); | |
248 | up->ier |= UART_IER_MSI; | |
249 | serial_out(up, UART_IER, up->ier); | |
250 | } | |
251 | ||
252 | static void serial_omap_stop_tx(struct uart_port *port) | |
253 | { | |
254 | struct uart_omap_port *up = (struct uart_omap_port *)port; | |
255 | if (up->use_dma && up->uart_dma.tx_dma_channel != 0xFF) { | |
256 | /* | |
257 | * Check if dma is still active . If yes do nothing, | |
258 | * return. Else stop dma. | |
259 | */ | |
260 | int status = omap_readl(OMAP34XX_DMA4_BASE + | |
261 | OMAP_DMA4_CCR(up->uart_dma.tx_dma_channel)); | |
262 | if (status & (1 << 7)) | |
263 | return; | |
264 | omap_stop_dma(up->uart_dma.tx_dma_channel); | |
265 | omap_free_dma(up->uart_dma.tx_dma_channel); | |
266 | up->uart_dma.tx_dma_channel = 0xFF; | |
267 | } | |
268 | ||
269 | if (up->ier & UART_IER_THRI) { | |
270 | up->ier &= ~UART_IER_THRI; | |
271 | serial_out(up, UART_IER, up->ier); | |
272 | } | |
273 | #ifdef CONFIG_PM | |
274 | if (!up->uart_dma.rx_dma_state) { | |
275 | unsigned int tmp; | |
276 | tmp = (serial_in(up, UART_OMAP_SYSC) & 0x7) | (2 << 3); | |
277 | serial_out(up, UART_OMAP_SYSC, tmp); /* smart-idle */ | |
278 | } | |
279 | #endif | |
280 | } | |
281 | ||
282 | static void serial_omap_stop_rx(struct uart_port *port) | |
283 | { | |
284 | struct uart_omap_port *up = (struct uart_omap_port *)port; | |
285 | serial_omap_stop_rxdma(up); | |
286 | up->ier &= ~UART_IER_RLSI; | |
287 | up->port.read_status_mask &= ~UART_LSR_DR; | |
288 | serial_out(up, UART_IER, up->ier); | |
289 | ||
290 | } | |
291 | ||
292 | static inline void receive_chars(struct uart_omap_port *up, int *status) | |
293 | { | |
294 | unsigned int ch, flag; | |
295 | int max_count = 256; | |
296 | ||
297 | #if DBG_RX_DATA | |
298 | printk("[RX]: "); | |
299 | #endif | |
300 | do { | |
301 | ch = serial_in(up, UART_RX); | |
302 | #if DBG_RX_DATA | |
303 | if ((ch >= 32) && (ch < 127)) | |
304 | printk("%c", ch); | |
305 | else | |
306 | printk("{0x%.2x}", ch); | |
307 | #endif | |
308 | flag = TTY_NORMAL; | |
309 | up->port.icount.rx++; | |
310 | ||
311 | if (unlikely(*status & (UART_LSR_BI | UART_LSR_PE | | |
312 | UART_LSR_FE | UART_LSR_OE))) { | |
313 | /* | |
314 | * For statistics only | |
315 | */ | |
316 | if (*status & UART_LSR_BI) { | |
317 | *status &= ~(UART_LSR_FE | UART_LSR_PE); | |
318 | up->port.icount.brk++; | |
319 | /* | |
320 | * We do the SysRQ and SAK checking | |
321 | * here because otherwise the break | |
322 | * may get masked by ignore_status_mask | |
323 | * or read_status_mask. | |
324 | */ | |
325 | if (uart_handle_break(&up->port)) | |
326 | goto ignore_char; | |
327 | } else if (*status & UART_LSR_PE) | |
328 | up->port.icount.parity++; | |
329 | else if (*status & UART_LSR_FE) | |
330 | up->port.icount.frame++; | |
331 | if (*status & UART_LSR_OE) | |
332 | up->port.icount.overrun++; | |
333 | ||
334 | /* | |
335 | * Mask off conditions which should be ignored. | |
336 | */ | |
337 | *status &= up->port.read_status_mask; | |
338 | ||
339 | #ifdef CONFIG_SERIAL_OMAP_CONSOLE | |
340 | if (up->port.line == up->port.cons->index) { | |
341 | /* Recover the break flag from console xmit */ | |
342 | *status |= up->lsr_break_flag; | |
343 | up->lsr_break_flag = 0; | |
344 | } | |
345 | #endif | |
346 | if (*status & UART_LSR_BI) | |
347 | flag = TTY_BREAK; | |
348 | else if (*status & UART_LSR_PE) | |
349 | flag = TTY_PARITY; | |
350 | else if (*status & UART_LSR_FE) | |
351 | flag = TTY_FRAME; | |
352 | } | |
353 | ||
354 | if (uart_handle_sysrq_char(&up->port, ch)) | |
355 | goto ignore_char; | |
356 | ||
357 | uart_insert_char(&up->port, *status, UART_LSR_OE, ch, flag); | |
358 | ||
359 | ignore_char: | |
360 | *status = serial_in(up, UART_LSR); | |
361 | } while ((*status & UART_LSR_DR) && (max_count-- > 0)); | |
362 | ||
363 | queue_work(omap_serial_workqueue, &up->tty_work); | |
364 | ||
365 | #if DBG_RX_DATA | |
366 | printk("\n"); | |
367 | #endif | |
368 | } | |
369 | ||
370 | static void tty_flip_buffer_work(struct work_struct *work) | |
371 | { | |
372 | struct uart_omap_port *up = | |
373 | container_of(work, struct uart_omap_port, tty_work); | |
374 | struct tty_struct *tty = up->port.state->port.tty; | |
375 | ||
376 | tty_flip_buffer_push(tty); | |
377 | } | |
378 | ||
379 | static void transmit_chars(struct uart_omap_port *up) | |
380 | { | |
381 | struct circ_buf *xmit = &up->port.state->xmit; | |
382 | int count; | |
383 | ||
384 | if (up->port.x_char) { | |
385 | serial_out(up, UART_TX, up->port.x_char); | |
386 | up->port.icount.tx++; | |
387 | up->port.x_char = 0; | |
388 | return; | |
389 | } | |
390 | if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) { | |
391 | serial_omap_stop_tx(&up->port); | |
392 | return; | |
393 | } | |
394 | ||
395 | count = up->port.fifosize / 4; | |
396 | ||
397 | do { | |
398 | serial_out(up, UART_TX, xmit->buf[xmit->tail]); | |
399 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | |
400 | up->port.icount.tx++; | |
401 | if (uart_circ_empty(xmit)) | |
402 | break; | |
403 | } while (--count > 0); | |
404 | ||
405 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | |
406 | uart_write_wakeup(&up->port); | |
407 | ||
408 | if (uart_circ_empty(xmit)) | |
409 | serial_omap_stop_tx(&up->port); | |
410 | } | |
411 | ||
412 | static void serial_omap_start_tx(struct uart_port *port) | |
413 | { | |
414 | struct uart_omap_port *up = (struct uart_omap_port *)port; | |
415 | #ifdef CONFIG_PM | |
416 | /* Disallow OCP bus idle. UART TX irqs are not seen during | |
417 | * bus idle. Alternative is to set kernel timer at fifo | |
418 | * drain rate. | |
419 | */ | |
420 | unsigned int tmp; | |
421 | tmp = (serial_in(up, UART_OMAP_SYSC) & 0x7) | (1 << 3); | |
422 | serial_out(up, UART_OMAP_SYSC, tmp); /* no-idle */ | |
423 | #endif | |
424 | ||
425 | if (up->use_dma && !(up->port.x_char)) { | |
426 | ||
427 | struct circ_buf *xmit = &up->port.state->xmit; | |
428 | unsigned int start = up->uart_dma.tx_buf_dma_phys + | |
429 | (xmit->tail & (UART_XMIT_SIZE - 1)); | |
430 | if (uart_circ_empty(xmit) || up->uart_dma.tx_dma_state) | |
431 | return; | |
432 | spin_lock(&(up->uart_dma.tx_lock)); | |
433 | up->uart_dma.tx_dma_state = 1; | |
434 | spin_unlock(&(up->uart_dma.tx_lock)); | |
435 | ||
436 | up->uart_dma.tx_buf_size = uart_circ_chars_pending(xmit); | |
437 | /* It is a circular buffer. See if the buffer has wounded back. | |
438 | * If yes it will have to be transferred in two separate dma | |
439 | * transfers */ | |
440 | if (start + up->uart_dma.tx_buf_size >= up->uart_dma.tx_buf_dma_phys + UART_XMIT_SIZE) | |
441 | up->uart_dma.tx_buf_size = (up->uart_dma.tx_buf_dma_phys + UART_XMIT_SIZE) - start; | |
442 | ||
443 | if (up->uart_dma.tx_dma_channel == 0xFF) { | |
444 | omap_request_dma(uart_dma_tx[up->pdev->id-1], | |
445 | "UART Tx DMA", | |
446 | (void *)uart_tx_dma_callback, up, | |
447 | &(up->uart_dma.tx_dma_channel)); | |
448 | } | |
449 | omap_set_dma_dest_params(up->uart_dma.tx_dma_channel, 0, | |
450 | OMAP_DMA_AMODE_CONSTANT, | |
451 | UART_BASE(up->pdev->id - 1), 0, 0); | |
452 | omap_set_dma_src_params(up->uart_dma.tx_dma_channel, 0, | |
453 | OMAP_DMA_AMODE_POST_INC, start, 0, 0); | |
454 | ||
455 | omap_set_dma_transfer_params(up->uart_dma.tx_dma_channel, | |
456 | OMAP_DMA_DATA_TYPE_S8, | |
457 | up->uart_dma.tx_buf_size, 1, | |
458 | OMAP_DMA_SYNC_ELEMENT, | |
459 | uart_dma_tx[(up->pdev->id)-1], 0); | |
460 | ||
461 | omap_start_dma(up->uart_dma.tx_dma_channel); | |
462 | ||
463 | } else if (!(up->ier & UART_IER_THRI)) { | |
464 | up->ier |= UART_IER_THRI; | |
465 | serial_out(up, UART_IER, up->ier); | |
466 | } | |
467 | ||
468 | if (up->restore_autorts) { | |
469 | serial_omap_set_autorts(up, 1); | |
470 | up->restore_autorts = 0; | |
471 | } | |
472 | } | |
473 | ||
474 | static unsigned int check_modem_status(struct uart_omap_port *up) | |
475 | { | |
476 | int status; | |
477 | status = serial_in(up, UART_MSR); | |
478 | ||
479 | status |= up->msr_saved_flags; | |
480 | up->msr_saved_flags = 0; | |
481 | ||
482 | if ((status & UART_MSR_ANY_DELTA) == 0) | |
483 | return status; | |
484 | if (status & UART_MSR_ANY_DELTA && up->ier & UART_IER_MSI && | |
485 | up->port.state != NULL) { | |
486 | if (status & UART_MSR_TERI) | |
487 | up->port.icount.rng++; | |
488 | if (status & UART_MSR_DDSR) | |
489 | up->port.icount.dsr++; | |
490 | if (status & UART_MSR_DDCD) | |
491 | uart_handle_dcd_change | |
492 | (&up->port, status & UART_MSR_DCD); | |
493 | if (status & UART_MSR_DCTS) | |
494 | uart_handle_cts_change | |
495 | (&up->port, status & UART_MSR_CTS); | |
496 | wake_up_interruptible(&up->port.state->port.delta_msr_wait); | |
497 | } | |
498 | ||
499 | return status; | |
500 | } | |
501 | ||
502 | /* | |
503 | * This handles the interrupt from one port. | |
504 | */ | |
505 | static inline irqreturn_t serial_omap_irq(int irq, void *dev_id) | |
506 | { | |
507 | struct uart_omap_port *up = dev_id; | |
508 | unsigned int iir, lsr; | |
509 | ||
510 | iir = serial_in(up, UART_IIR); | |
511 | if (iir & UART_IIR_NO_INT) | |
512 | return IRQ_NONE; | |
513 | lsr = serial_in(up, UART_LSR); | |
514 | if ((iir & 0x4) && up->use_dma) { | |
515 | up->ier &= ~UART_IER_RDI; | |
516 | serial_out(up, UART_IER, up->ier); | |
517 | serial_omap_start_rxdma(up); | |
518 | } else if (lsr & UART_LSR_DR) { | |
519 | receive_chars(up, &lsr); | |
520 | /* XXX: After driver resume optimization, lower this */ | |
521 | wake_lock_timeout(&omap_serial_wakelock, (HZ * 1)); | |
522 | } | |
523 | check_modem_status(up); | |
524 | if ((lsr & UART_LSR_THRE) && (iir & 0x2)) | |
525 | transmit_chars(up); | |
526 | isr8250_activity = jiffies; | |
527 | ||
528 | return IRQ_HANDLED; | |
529 | } | |
530 | ||
531 | static unsigned int serial_omap_tx_empty(struct uart_port *port) | |
532 | { | |
533 | struct uart_omap_port *up = (struct uart_omap_port *)port; | |
534 | unsigned long flags; | |
535 | unsigned int ret; | |
536 | ||
537 | DPRINTK("serial_omap_tx_empty+%d\n", up->pdev->id); | |
538 | spin_lock_irqsave(&up->port.lock, flags); | |
539 | ret = serial_in(up, UART_LSR) & UART_LSR_TEMT ? TIOCSER_TEMT : 0; | |
540 | spin_unlock_irqrestore(&up->port.lock, flags); | |
541 | ||
542 | return ret; | |
543 | } | |
544 | ||
545 | static unsigned int serial_omap_get_mctrl(struct uart_port *port) | |
546 | { | |
547 | struct uart_omap_port *up = (struct uart_omap_port *)port; | |
548 | unsigned char status; | |
549 | unsigned int ret; | |
550 | ||
551 | status = check_modem_status(up); | |
552 | DPRINTK("serial_omap_get_mctrl+%d\n", up->pdev->id); | |
553 | ||
554 | ret = 0; | |
555 | if (status & UART_MSR_DCD) | |
556 | ret |= TIOCM_CAR; | |
557 | if (status & UART_MSR_RI) | |
558 | ret |= TIOCM_RNG; | |
559 | if (status & UART_MSR_DSR) | |
560 | ret |= TIOCM_DSR; | |
561 | if (status & UART_MSR_CTS) | |
562 | ret |= TIOCM_CTS; | |
563 | return ret; | |
564 | } | |
565 | ||
566 | static void serial_omap_set_mctrl(struct uart_port *port, unsigned int mctrl) | |
567 | { | |
568 | struct uart_omap_port *up = (struct uart_omap_port *)port; | |
569 | unsigned char mcr = 0; | |
570 | ||
571 | DPRINTK("serial_omap_set_mctrl+%d\n", up->pdev->id); | |
572 | if (mctrl & TIOCM_RTS) { | |
573 | /* | |
574 | * We need to be careful not to cause | |
575 | * RTS to assert when we have a pending | |
576 | * auto-rts restore. | |
577 | */ | |
578 | if (!up->restore_autorts) | |
579 | mcr |= UART_MCR_RTS; | |
580 | } | |
581 | if (mctrl & TIOCM_DTR) | |
582 | mcr |= UART_MCR_DTR; | |
583 | if (mctrl & TIOCM_OUT1) | |
584 | mcr |= UART_MCR_OUT1; | |
585 | if (mctrl & TIOCM_OUT2) | |
586 | mcr |= UART_MCR_OUT2; | |
587 | if (mctrl & TIOCM_LOOP) | |
588 | mcr |= UART_MCR_LOOP; | |
589 | ||
590 | mcr |= up->mcr; | |
591 | serial_out(up, UART_MCR, mcr); | |
592 | } | |
593 | ||
594 | static void serial_omap_break_ctl(struct uart_port *port, int break_state) | |
595 | { | |
596 | struct uart_omap_port *up = (struct uart_omap_port *)port; | |
597 | unsigned long flags; | |
598 | ||
599 | DPRINTK("serial_omap_break_ctl+%d\n", up->pdev->id); | |
600 | spin_lock_irqsave(&up->port.lock, flags); | |
601 | if (break_state == -1) | |
602 | up->lcr |= UART_LCR_SBC; | |
603 | else | |
604 | up->lcr &= ~UART_LCR_SBC; | |
605 | serial_out(up, UART_LCR, up->lcr); | |
606 | spin_unlock_irqrestore(&up->port.lock, flags); | |
607 | } | |
608 | ||
609 | static void serial_omap_wake_peer(struct uart_port *port) | |
610 | { | |
611 | struct uart_omap_port *up = (struct uart_omap_port *)port; | |
612 | struct plat_serialomap_port *pd = up->pdev->dev.platform_data; | |
613 | if (pd->wake_gpio_strobe) { | |
614 | gpio_direction_output(pd->wake_gpio_strobe, 1); | |
615 | udelay(5); | |
616 | gpio_direction_output(pd->wake_gpio_strobe, 0); | |
617 | udelay(5); | |
618 | } | |
619 | } | |
620 | ||
621 | static void serial_omap_set_autorts(struct uart_omap_port *p, int set) | |
622 | { | |
623 | u8 lcr_val = 0, mcr_val = 0, efr_val = 0; | |
624 | u8 lcr_backup = 0, mcr_backup = 0, efr_backup = 0; | |
625 | ||
626 | lcr_val = serial_in(p, UART_LCR); | |
627 | lcr_backup = lcr_val; | |
628 | /* Enter Config mode B */ | |
629 | serial_out(p, UART_LCR, 0xbf); | |
630 | ||
631 | efr_val = serial_in(p, UART_EFR); | |
632 | efr_backup = efr_val; | |
633 | ||
634 | /* | |
635 | * Enhanced functions write enable. | |
636 | * Enables writes to IER[7:4], FCR[5:4], MCR[7:5] | |
637 | */ | |
638 | serial_out(p, UART_EFR, efr_val | 0x10); | |
639 | ||
640 | mcr_val = serial_in(p, UART_MCR); | |
641 | mcr_backup = mcr_val; | |
642 | /* Enable access to TCR_REG and TLR_REG */ | |
643 | serial_out(p, UART_MCR, mcr_val | 0x40); | |
644 | ||
645 | /* Set RX_FIFO_TRIG levels */ | |
646 | serial_out(p, 0x18, 0x0f); | |
647 | ||
648 | efr_val = serial_in(p, UART_EFR); | |
649 | if (set) | |
650 | serial_out(p, UART_EFR, efr_val | (1 << 6)); | |
651 | else | |
652 | serial_out(p, UART_EFR, efr_val & ~(1 << 6)); | |
653 | ||
654 | ||
655 | mcr_val = serial_in(p, UART_MCR); | |
656 | /* Restore original state of TCR_TLR access */ | |
657 | serial_out(p, UART_MCR, (mcr_val & ~0x40) | (mcr_backup & 0x40)); | |
658 | ||
659 | /* Enhanced function write disable. */ | |
660 | serial_out(p, UART_EFR, serial_in(p, UART_EFR) & ~0x10); | |
661 | ||
662 | /* Normal operation */ | |
663 | serial_out(p, UART_LCR, lcr_backup); | |
664 | } | |
665 | ||
666 | static int serial_omap_startup(struct uart_port *port) | |
667 | { | |
668 | struct uart_omap_port *up = (struct uart_omap_port *)port; | |
669 | unsigned long flags; | |
670 | int irq_flags = port->flags & UPF_SHARE_IRQ ? IRQF_SHARED : 0; | |
671 | int retval; | |
672 | ||
673 | /* Zoom2 has GPIO_102 connected to Serial device: | |
674 | * Active High | |
675 | */ | |
676 | ||
677 | if (up->port.flags & UPF_TRIGGER_HIGH) | |
678 | irq_flags |= IRQF_TRIGGER_HIGH; | |
679 | ||
680 | if (up->port.flags & UPF_SHARE_IRQ) | |
681 | irq_flags |= IRQF_SHARED; | |
682 | ||
683 | /* | |
684 | * Allocate the IRQ | |
685 | */ | |
686 | retval = request_irq(up->port.irq, serial_omap_irq, irq_flags, | |
687 | up->name, up); | |
688 | if (retval) { | |
689 | printk(KERN_ERR "%s: Failed to register IRQ %d for %s (%d)\n", | |
690 | __func__, up->port.irq, up->name, retval); | |
691 | return retval; | |
692 | } | |
693 | ||
694 | ||
695 | /* do not let tty layer execute RX in global workqueue, use a | |
696 | * dedicated workqueue managed by this driver */ | |
697 | port->state->port.tty->low_latency = 1; | |
698 | ||
699 | /* | |
700 | * Stop the baud clock and disable the UART. UART will be enabled | |
701 | * back in set_termios. This is essential for DMA mode operations. | |
702 | */ | |
703 | serial_out(up, UART_LCR, UART_LCR_DLAB); | |
704 | serial_out(up, UART_DLL, 0); | |
705 | serial_out(up, UART_DLM, 0); | |
706 | serial_out(up, UART_LCR, 0); | |
707 | serial_out(up, UART_OMAP_MDR1, OMAP_MDR1_DISABLE); | |
708 | ||
709 | /* | |
710 | * Clear the FIFO buffers and disable them. | |
711 | * (they will be reenabled in set_termios()) | |
712 | */ | |
713 | serial_omap_clear_fifos(up); | |
714 | serial_out(up, UART_SCR, 0x00); | |
715 | /* For Hardware flow control */ | |
716 | // serial_out(up, UART_MCR, 0x2); | |
717 | ||
718 | /* | |
719 | * Clear the interrupt registers. | |
720 | */ | |
721 | (void) serial_in(up, UART_LSR); | |
722 | if (serial_in(up, UART_LSR) & UART_LSR_DR) | |
723 | (void) serial_in(up, UART_RX); | |
724 | (void) serial_in(up, UART_IIR); | |
725 | (void) serial_in(up, UART_MSR); | |
726 | /* | |
727 | * Now, initialize the UART | |
728 | */ | |
729 | serial_out(up, UART_LCR, UART_LCR_WLEN8); | |
730 | spin_lock_irqsave(&up->port.lock, flags); | |
731 | if (up->port.flags & UPF_FOURPORT) { | |
732 | if (!is_real_interrupt(up->port.irq)) | |
733 | up->port.mctrl |= TIOCM_OUT1; | |
734 | } else { | |
735 | /* | |
736 | * Most PC uarts need OUT2 raised to enable interrupts. | |
737 | */ | |
738 | if (is_real_interrupt(up->port.irq)) | |
739 | up->port.mctrl |= TIOCM_OUT2; | |
740 | } | |
741 | serial_omap_set_mctrl(&up->port, up->port.mctrl); | |
742 | spin_unlock_irqrestore(&up->port.lock, flags); | |
743 | ||
744 | up->msr_saved_flags = 0; | |
745 | ||
746 | ||
747 | ||
748 | if (up->port.flags & UPF_FOURPORT) { | |
749 | unsigned int icp; | |
750 | /* | |
751 | * Enable interrupts on the AST Fourport board | |
752 | */ | |
753 | icp = (up->port.iobase & 0xfe0) | 0x01f; | |
754 | outb_p(0x80, icp); | |
755 | (void) inb_p(icp); | |
756 | } | |
757 | if (up->use_dma) { | |
758 | if (!up->is_buf_dma_alloced) { | |
759 | free_page((unsigned long)up->port.state->xmit.buf); | |
760 | up->port.state->xmit.buf = NULL; | |
761 | up->port.state->xmit.buf = dma_alloc_coherent(NULL, | |
762 | UART_XMIT_SIZE, | |
763 | (dma_addr_t *)&(up->uart_dma.tx_buf_dma_phys), 0); | |
764 | up->is_buf_dma_alloced = 1; | |
765 | } | |
766 | init_timer(&(up->uart_dma.rx_timer)); | |
767 | up->uart_dma.rx_timer.function = serial_omap_rx_timeout; | |
768 | up->uart_dma.rx_timer.data = up->pdev->id; | |
769 | /* Currently the buffer size is 4KB. Can increase it later*/ | |
770 | up->uart_dma.rx_buf = dma_alloc_coherent(NULL, | |
771 | up->uart_dma.rx_buf_size, | |
772 | (dma_addr_t *)&(up->uart_dma.rx_buf_dma_phys), 0); | |
773 | serial_omap_start_rxdma(up); | |
774 | } else { | |
775 | /* | |
776 | * Finally, enable interrupts. Note: Modem status interrupts | |
777 | * are set via set_termios(), which will be occurring imminently | |
778 | * anyway, so we don't enable them here. | |
779 | */ | |
780 | up->ier = UART_IER_RLSI | UART_IER_RDI; | |
781 | /*| UART_IER_RTOIE |UART_IER_THRI; */ | |
782 | serial_out(up, UART_IER, up->ier); | |
783 | } | |
784 | ||
785 | return 0; | |
786 | } | |
787 | ||
788 | static void serial_omap_shutdown(struct uart_port *port) | |
789 | { | |
790 | struct uart_omap_port *up = (struct uart_omap_port *)port; | |
791 | unsigned long flags; | |
792 | u8 lcr, efr; | |
793 | ||
794 | DPRINTK("serial_omap_shutdown+%d\n", up->pdev->id); | |
795 | /* | |
796 | * Disable interrupts from this port | |
797 | */ | |
798 | up->ier = 0; | |
799 | serial_out(up, UART_IER, 0); | |
800 | ||
801 | /* | |
802 | * If we're using auto-rts then disable it. | |
803 | */ | |
804 | lcr = serial_in(up, UART_LCR); | |
805 | serial_out(up, UART_LCR, 0xbf); | |
806 | efr = serial_in(up, UART_EFR); | |
807 | serial_out(up, UART_LCR, lcr); | |
808 | ||
809 | if (efr & UART_EFR_RTS) { | |
810 | serial_omap_set_autorts(up, 0); | |
811 | up->restore_autorts = 1; | |
812 | } | |
813 | ||
814 | spin_lock_irqsave(&up->port.lock, flags); | |
815 | if (up->port.flags & UPF_FOURPORT) { | |
816 | /* reset interrupts on the AST Fourport board */ | |
817 | inb((up->port.iobase & 0xfe0) | 0x1f); | |
818 | up->port.mctrl |= TIOCM_OUT1; | |
819 | } else | |
820 | up->port.mctrl &= ~TIOCM_OUT2; | |
821 | serial_omap_set_mctrl(&up->port, (up->port.mctrl & ~TIOCM_RTS)); | |
822 | spin_unlock_irqrestore(&up->port.lock, flags); | |
823 | ||
824 | if (up->pdev->id == gps_port) { | |
825 | serial_out(up, UART_LCR, UART_LCR_DLAB); | |
826 | serial_out(up, UART_DLL, 0); | |
827 | serial_out(up, UART_DLM, 0); | |
828 | serial_out(up, UART_LCR, 0); | |
829 | serial_out(up, UART_OMAP_MDR1, OMAP_MDR1_DISABLE); | |
830 | } | |
831 | ||
832 | /* | |
833 | * Disable break condition and FIFOs | |
834 | */ | |
835 | serial_out(up, UART_LCR, serial_in(up, UART_LCR) & ~UART_LCR_SBC); | |
836 | serial_omap_clear_fifos(up); | |
837 | ||
838 | /* | |
839 | * Read data port to reset things, and then free the irq | |
840 | */ | |
841 | if (serial_in(up, UART_LSR) & UART_LSR_DR) | |
842 | (void) serial_in(up, UART_RX); | |
843 | if (up->use_dma) { | |
844 | int tmp; | |
845 | if (up->is_buf_dma_alloced) { | |
846 | dma_free_coherent(up->port.dev, | |
847 | UART_XMIT_SIZE, | |
848 | up->port.state->xmit.buf, | |
849 | up->uart_dma.tx_buf_dma_phys); | |
850 | up->port.state->xmit.buf = NULL; | |
851 | up->is_buf_dma_alloced = 0; | |
852 | } | |
853 | /*TBD: Check if this is really needed here*/ | |
854 | serial_omap_stop_rx(port); | |
855 | dma_free_coherent(up->port.dev, | |
856 | up->uart_dma.rx_buf_size, | |
857 | up->uart_dma.rx_buf, up->uart_dma.rx_buf_dma_phys); | |
858 | up->uart_dma.rx_buf = NULL; | |
859 | tmp = serial_in(up, UART_OMAP_SYSC) & 0x7; | |
860 | serial_out(up, UART_OMAP_SYSC, tmp); /* force-idle */ | |
861 | } | |
862 | ||
863 | free_irq(up->port.irq, up); | |
864 | ||
865 | if (cancel_work_sync(&up->tty_work)) | |
866 | tty_flip_buffer_work(&up->tty_work); | |
867 | } | |
868 | ||
869 | static void | |
870 | serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, | |
871 | struct ktermios *old) | |
872 | { | |
873 | struct uart_omap_port *up = (struct uart_omap_port *)port; | |
874 | unsigned char cval; | |
875 | unsigned char efr = 0; | |
876 | unsigned long flags; | |
877 | unsigned int baud, quot; | |
878 | ||
879 | serial_out(up, UART_LCR, UART_LCR_DLAB); | |
880 | serial_out(up, UART_DLL, 0); | |
881 | serial_out(up, UART_DLM, 0); | |
882 | serial_out(up, UART_LCR, 0); | |
883 | serial_out(up, UART_OMAP_MDR1, OMAP_MDR1_DISABLE); | |
884 | switch (termios->c_cflag & CSIZE) { | |
885 | case CS5: | |
886 | cval = UART_LCR_WLEN5; | |
887 | break; | |
888 | case CS6: | |
889 | cval = UART_LCR_WLEN6; | |
890 | break; | |
891 | case CS7: | |
892 | cval = UART_LCR_WLEN7; | |
893 | break; | |
894 | default: | |
895 | case CS8: | |
896 | cval = UART_LCR_WLEN8; | |
897 | break; | |
898 | } | |
899 | ||
900 | if (termios->c_cflag & CSTOPB) | |
901 | cval |= UART_LCR_STOP; | |
902 | if (termios->c_cflag & PARENB) | |
903 | cval |= UART_LCR_PARITY; | |
904 | if (!(termios->c_cflag & PARODD)) | |
905 | cval |= UART_LCR_EPAR; | |
906 | ||
907 | /* | |
908 | * Ask the core to calculate the divisor for us. | |
909 | */ | |
910 | ||
911 | baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/13); | |
912 | quot = serial_omap_get_divisor(port, baud); | |
913 | ||
914 | if (up->use_dma) | |
915 | fcr[up->pdev->id - 1] = UART_FCR_ENABLE_FIFO | 0x1 << 6 | 0x1 << 4 | UART_FCR_DMA_SELECT; | |
916 | else | |
917 | fcr[up->pdev->id - 1] = UART_FCR_ENABLE_FIFO; | |
918 | ||
919 | /* | |
920 | * Ok, we're now changing the port state. Do it with | |
921 | * interrupts disabled. | |
922 | */ | |
923 | spin_lock_irqsave(&up->port.lock, flags); | |
924 | ||
925 | /* | |
926 | * Update the per-port timeout. | |
927 | */ | |
928 | uart_update_timeout(port, termios->c_cflag, baud); | |
929 | ||
930 | up->port.read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; | |
931 | if (termios->c_iflag & INPCK) | |
932 | up->port.read_status_mask |= UART_LSR_FE | UART_LSR_PE; | |
933 | if (termios->c_iflag & (BRKINT | PARMRK)) | |
934 | up->port.read_status_mask |= UART_LSR_BI; | |
935 | ||
936 | /* | |
937 | * Characters to ignore | |
938 | */ | |
939 | up->port.ignore_status_mask = 0; | |
940 | if (termios->c_iflag & IGNPAR) | |
941 | up->port.ignore_status_mask |= UART_LSR_PE | UART_LSR_FE; | |
942 | if (termios->c_iflag & IGNBRK) { | |
943 | up->port.ignore_status_mask |= UART_LSR_BI; | |
944 | /* | |
945 | * If we're ignoring parity and break indicators, | |
946 | * ignore overruns too (for real raw support). | |
947 | */ | |
948 | if (termios->c_iflag & IGNPAR) | |
949 | up->port.ignore_status_mask |= UART_LSR_OE; | |
950 | } | |
951 | ||
952 | /* | |
953 | * ignore all characters if CREAD is not set | |
954 | */ | |
955 | if ((termios->c_cflag & CREAD) == 0) | |
956 | up->port.ignore_status_mask |= UART_LSR_DR; | |
957 | ||
958 | /* | |
959 | * CTS flow control flag and modem status interrupts | |
960 | */ | |
961 | up->ier &= ~UART_IER_MSI; | |
962 | if (UART_ENABLE_MS(&up->port, termios->c_cflag)) | |
963 | up->ier |= UART_IER_MSI; | |
964 | serial_out(up, UART_IER, up->ier); | |
965 | ||
966 | if (termios->c_cflag & CRTSCTS) { | |
967 | #ifdef CONFIG_SERIAL_OMAP3430_HW_FLOW_CONTROL | |
968 | efr |= ((up->ctsrts & UART_EFR_CTS) | | |
969 | (up->restore_autorts ? 0 : UART_EFR_RTS)); | |
970 | #else | |
971 | efr |= (UART_EFR_CTS | (up->restore_autorts ? 0 : UART_EFR_RTS)); | |
972 | #endif | |
973 | } | |
974 | ||
975 | serial_out(up, UART_LCR, cval | UART_LCR_DLAB);/* set DLAB */ | |
976 | serial_out(up, UART_DLL, quot & 0xff); /* LS of divisor */ | |
977 | serial_out(up, UART_DLM, quot >> 8); /* MS of divisor */ | |
978 | ||
979 | serial_out(up, UART_LCR, cval); /* reset DLAB */ | |
980 | up->lcr = cval; /* Save LCR */ | |
981 | if (up->use_dma) | |
982 | serial_out(up, UART_OMAP_SCR , ((1 << 6) | (1 << 7))); | |
983 | ||
984 | serial_out(up, UART_LCR, 0xbf); /* Access EFR */ | |
985 | serial_out(up, UART_EFR, UART_EFR_ECB); | |
986 | serial_out(up, UART_LCR, 0x0); /* Access FCR */ | |
987 | serial_out(up, UART_FCR, fcr[up->pdev->id - 1]); | |
988 | serial_out(up, UART_LCR, 0xbf); /* Access EFR */ | |
989 | serial_out(up, UART_EFR, efr); | |
990 | serial_out(up, UART_LCR, cval); /* Access FCR */ | |
991 | ||
992 | serial_omap_set_mctrl(&up->port, up->port.mctrl); | |
993 | /* | |
994 | * Clear all the status registers and RX register before | |
995 | * enabling UART | |
996 | */ | |
997 | (void) serial_in(up, UART_LSR); | |
998 | if (serial_in(up, UART_LSR) & UART_LSR_DR) | |
999 | (void) serial_in(up, UART_RX); | |
1000 | (void) serial_in(up, UART_IIR); | |
1001 | (void) serial_in(up, UART_MSR); | |
1002 | ||
1003 | if (baud > 230400 && baud != 3000000) | |
1004 | serial_out(up, UART_OMAP_MDR1, OMAP_MDR1_MODE13X); | |
1005 | else | |
1006 | serial_out(up, UART_OMAP_MDR1, OMAP_MDR1_MODE16X); | |
1007 | spin_unlock_irqrestore(&up->port.lock, flags); | |
1008 | ||
1009 | DPRINTK("serial_omap_set_termios+%d\n", up->pdev->id); | |
1010 | serial_omap_display_reg(port); | |
1011 | } | |
1012 | ||
1013 | static void | |
1014 | serial_omap_pm(struct uart_port *port, unsigned int state, | |
1015 | unsigned int oldstate) | |
1016 | { | |
1017 | struct uart_omap_port *up = (struct uart_omap_port *)port; | |
1018 | unsigned char efr; | |
1019 | DPRINTK("serial_omap_pm+%d\n", up->pdev->id); | |
1020 | efr = serial_in(up, UART_EFR); | |
1021 | serial_out(up, UART_LCR, 0xBF); | |
1022 | serial_out(up, UART_EFR, efr | UART_EFR_ECB); | |
1023 | serial_out(up, UART_LCR, 0); | |
1024 | ||
1025 | serial_out(up, UART_IER, (state != 0) ? UART_IERX_SLEEP : 0); | |
1026 | serial_out(up, UART_LCR, 0xBF); | |
1027 | serial_out(up, UART_EFR, efr); | |
1028 | serial_out(up, UART_LCR, 0); | |
1029 | } | |
1030 | ||
1031 | static void serial_omap_release_port(struct uart_port *port) | |
1032 | { | |
1033 | DPRINTK("serial_omap_release_port+\n"); | |
1034 | } | |
1035 | ||
1036 | static int serial_omap_request_port(struct uart_port *port) | |
1037 | { | |
1038 | DPRINTK("serial_omap_request_port+\n"); | |
1039 | return 0; | |
1040 | } | |
1041 | ||
1042 | static void serial_omap_config_port(struct uart_port *port, int flags) | |
1043 | { | |
1044 | struct uart_omap_port *up = (struct uart_omap_port *)port; | |
1045 | ||
1046 | DPRINTK("serial_omap_config_port+%d\n", up->pdev->id); | |
1047 | up->port.type = PORT_OMAP; | |
1048 | } | |
1049 | ||
1050 | static int | |
1051 | serial_omap_verify_port(struct uart_port *port, struct serial_struct *ser) | |
1052 | { | |
1053 | /* we don't want the core code to modify any port params */ | |
1054 | DPRINTK("serial_omap_verify_port+\n"); | |
1055 | return -EINVAL; | |
1056 | } | |
1057 | ||
1058 | static const char * | |
1059 | serial_omap_type(struct uart_port *port) | |
1060 | { | |
1061 | struct uart_omap_port *up = (struct uart_omap_port *)port; | |
1062 | ||
1063 | DPRINTK("serial_omap_type+%d\n", up->pdev->id); | |
1064 | return up->name; | |
1065 | } | |
1066 | ||
1067 | #ifdef CONFIG_SERIAL_OMAP_CONSOLE | |
1068 | ||
1069 | static struct uart_omap_port *serial_omap_console_ports[4]; | |
1070 | ||
1071 | static struct uart_driver serial_omap_reg; | |
1072 | ||
1073 | #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) | |
1074 | ||
1075 | /* | |
1076 | * Wait for transmitter & holding register to empty | |
1077 | */ | |
1078 | static inline void wait_for_xmitr(struct uart_omap_port *up) | |
1079 | { | |
1080 | unsigned int status, tmout = 10000; | |
1081 | ||
1082 | /* Wait up to 10ms for the character(s) to be sent. */ | |
1083 | do { | |
1084 | status = serial_in(up, UART_LSR); | |
1085 | ||
1086 | if (status & UART_LSR_BI) | |
1087 | up->lsr_break_flag = UART_LSR_BI; | |
1088 | ||
1089 | if (--tmout == 0) | |
1090 | break; | |
1091 | udelay(1); | |
1092 | } while ((status & BOTH_EMPTY) != BOTH_EMPTY); | |
1093 | ||
1094 | /* Wait up to 1s for flow control if necessary */ | |
1095 | if (up->port.flags & UPF_CONS_FLOW) { | |
1096 | tmout = 1000000; | |
1097 | for (tmout = 1000000; tmout; tmout--) { | |
1098 | unsigned int msr = serial_in(up, UART_MSR); | |
1099 | up->msr_saved_flags |= msr & MSR_SAVE_FLAGS; | |
1100 | if (msr & UART_MSR_CTS) | |
1101 | break; | |
1102 | udelay(1); | |
1103 | } | |
1104 | } | |
1105 | } | |
1106 | ||
1107 | static void serial_omap_console_putchar(struct uart_port *port, int ch) | |
1108 | { | |
1109 | struct uart_omap_port *up = (struct uart_omap_port *)port; | |
1110 | ||
1111 | wait_for_xmitr(up); | |
1112 | serial_out(up, UART_TX, ch); | |
1113 | } | |
1114 | ||
1115 | /* | |
1116 | * Print a string to the serial port trying not to disturb | |
1117 | * any possible real use of the port... | |
1118 | * | |
1119 | * The console_lock must be held when we get here. | |
1120 | */ | |
1121 | static void | |
1122 | serial_omap_console_write(struct console *co, const char *s, | |
1123 | unsigned int count) | |
1124 | { | |
1125 | /* TBD: In 8250 interrupts were disabled in the beginning of this | |
1126 | * function and enabled in the end. We might need to do the same*/ | |
1127 | struct uart_omap_port *up = serial_omap_console_ports[co->index]; | |
1128 | unsigned int ier; | |
1129 | ||
1130 | /* | |
1131 | * First save the IER then disable the interrupts | |
1132 | */ | |
1133 | ier = serial_in(up, UART_IER); | |
1134 | serial_out(up, UART_IER, 0); | |
1135 | ||
1136 | uart_console_write(&up->port, s, count, serial_omap_console_putchar); | |
1137 | ||
1138 | /* | |
1139 | * Finally, wait for transmitter to become empty | |
1140 | * and restore the IER | |
1141 | */ | |
1142 | wait_for_xmitr(up); | |
1143 | serial_out(up, UART_IER, ier); | |
1144 | /* | |
1145 | * The receive handling will happen properly because the | |
1146 | * receive ready bit will still be set; it is not cleared | |
1147 | * on read. However, modem control will not, we must | |
1148 | * call it if we have saved something in the saved flags | |
1149 | * while processing with interrupts off. | |
1150 | */ | |
1151 | if (up->msr_saved_flags) | |
1152 | check_modem_status(up); | |
1153 | } | |
1154 | ||
1155 | static int | |
1156 | serial_omap_console_setup(struct console *co, char *options) | |
1157 | { | |
1158 | struct uart_omap_port *up; | |
1159 | int baud = 9600; | |
1160 | int bits = 8; | |
1161 | int parity = 'n'; | |
1162 | int flow = 'n'; | |
1163 | int r; | |
1164 | ||
1165 | if (serial_omap_console_ports[co->index] == NULL) | |
1166 | return -ENODEV; | |
1167 | up = serial_omap_console_ports[co->index]; | |
1168 | ||
1169 | if (options) | |
1170 | uart_parse_options(options, &baud, &parity, &bits, &flow); | |
1171 | ||
1172 | r = uart_set_options(&up->port, co, baud, parity, bits, flow); | |
1173 | ||
1174 | return r; | |
1175 | } | |
1176 | ||
1177 | static struct tty_driver *my_uart_console_device(struct console *co, int *index) | |
1178 | { | |
1179 | struct uart_driver *p = co->data; | |
1180 | *index = co->index; | |
1181 | return p->tty_driver; | |
1182 | } | |
1183 | ||
1184 | static struct console serial_omap_console = { | |
1185 | .name = "ttyS", | |
1186 | .write = serial_omap_console_write, | |
1187 | .device = my_uart_console_device, | |
1188 | .setup = serial_omap_console_setup, | |
1189 | .flags = CON_PRINTBUFFER, | |
1190 | .index = -1, | |
1191 | .data = &serial_omap_reg, | |
1192 | }; | |
1193 | ||
1194 | static void serial_omap_add_console_port(struct uart_omap_port *up) | |
1195 | { | |
1196 | serial_omap_console_ports[up->pdev->id - 1] = up; | |
1197 | } | |
1198 | ||
1199 | #define OMAP_CONSOLE (&serial_omap_console) | |
1200 | ||
1201 | #else | |
1202 | ||
1203 | #define OMAP_CONSOLE NULL | |
1204 | ||
1205 | static inline void serial_omap_add_console_port(struct uart_omap_port *up) {} | |
1206 | ||
1207 | #endif | |
1208 | ||
1209 | struct uart_ops serial_omap_pops = { | |
1210 | .tx_empty = serial_omap_tx_empty, | |
1211 | .set_mctrl = serial_omap_set_mctrl, | |
1212 | .get_mctrl = serial_omap_get_mctrl, | |
1213 | .stop_tx = serial_omap_stop_tx, | |
1214 | .start_tx = serial_omap_start_tx, | |
1215 | .stop_rx = serial_omap_stop_rx, | |
1216 | .enable_ms = serial_omap_enable_ms, | |
1217 | .break_ctl = serial_omap_break_ctl, | |
1218 | .startup = serial_omap_startup, | |
1219 | .shutdown = serial_omap_shutdown, | |
1220 | .set_termios = serial_omap_set_termios, | |
1221 | .pm = serial_omap_pm, | |
1222 | .type = serial_omap_type, | |
1223 | .release_port = serial_omap_release_port, | |
1224 | .request_port = serial_omap_request_port, | |
1225 | .config_port = serial_omap_config_port, | |
1226 | .verify_port = serial_omap_verify_port, | |
1227 | .wake_peer = serial_omap_wake_peer, | |
1228 | }; | |
1229 | ||
1230 | static struct uart_driver serial_omap_reg = { | |
1231 | .owner = THIS_MODULE, | |
1232 | .driver_name = "OMAP-HS-SERIAL", | |
1233 | .dev_name = "ttyS", | |
1234 | .major = TTY_MAJOR, | |
1235 | .minor = 64, | |
1236 | .nr = 4, | |
1237 | .cons = OMAP_CONSOLE, | |
1238 | }; | |
1239 | ||
1240 | static int serial_omap_remove(struct platform_device *dev); | |
1241 | static int serial_omap_suspend(struct platform_device *pdev, pm_message_t state) | |
1242 | { | |
1243 | struct uart_omap_port *up = platform_get_drvdata(pdev); | |
1244 | unsigned int tmp; | |
1245 | u8 lcr, efr; | |
1246 | static unsigned int fifo_suspendbrks; | |
1247 | ||
1248 | /* Disable interrupts from this port */ | |
1249 | serial_out(up, UART_IER, 0); | |
1250 | ||
1251 | /* If we're using auto-rts then disable it. */ | |
1252 | lcr = serial_in(up, UART_LCR); | |
1253 | serial_out(up, UART_LCR, 0xbf); | |
1254 | efr = serial_in(up, UART_EFR); | |
1255 | serial_out(up, UART_LCR, lcr); | |
1256 | ||
1257 | if (efr & UART_EFR_RTS) { | |
1258 | serial_omap_set_autorts(up, 0); | |
1259 | up->restore_autorts = 1; | |
1260 | /* | |
1261 | * Force RTS output to inactive (high) after disable autorts | |
1262 | * mode. This RTS bit might not be restored when enable autorts | |
1263 | * next time, since the RTS output controlled by hardware | |
1264 | * flow control. | |
1265 | */ | |
1266 | serial_omap_set_mctrl(&up->port, (up->port.mctrl & ~TIOCM_RTS)); | |
1267 | } | |
1268 | ||
1269 | /* | |
1270 | * There seems to be a window here where | |
1271 | * data could still be on the way to the | |
1272 | * fifo. This delay is ~1 byte time @ 115.2k | |
1273 | */ | |
1274 | udelay(80); | |
1275 | ||
1276 | if (are_driveromap_uarts_active(up->port.line)) { | |
1277 | fifo_suspendbrks++; | |
1278 | printk(KERN_WARNING "UART FIFO break suspend %d\n", | |
1279 | fifo_suspendbrks); | |
1280 | ||
1281 | if (up->restore_autorts) { | |
1282 | serial_omap_set_autorts(up, 1); | |
1283 | up->restore_autorts = 0; | |
1284 | } | |
1285 | serial_out(up, UART_IER, up->ier); | |
1286 | return -EBUSY; | |
1287 | } | |
1288 | ||
1289 | serial_out(up, UART_IER, up->ier); | |
1290 | ||
1291 | if (up) | |
1292 | uart_suspend_port(&serial_omap_reg, &up->port); | |
1293 | if (up->use_dma) { | |
1294 | /* | |
1295 | * Silicon Errata i291 workaround. | |
1296 | * UART Module has to be put in force idle if it is | |
1297 | * configured in DMA mode and when there is no activity | |
1298 | * expected. | |
1299 | */ | |
1300 | tmp = (serial_in(up, UART_OMAP_SYSC) & 0x7); | |
1301 | serial_out(up, UART_OMAP_SYSC, tmp); /* force-idle */ | |
1302 | } | |
1303 | return 0; | |
1304 | } | |
1305 | ||
1306 | static int serial_omap_resume(struct platform_device *dev) | |
1307 | { | |
1308 | struct uart_omap_port *up = platform_get_drvdata(dev); | |
1309 | if (up) | |
1310 | uart_resume_port(&serial_omap_reg, &up->port); | |
1311 | ||
1312 | return 0; | |
1313 | } | |
1314 | ||
1315 | static void serial_omap_rx_timeout(unsigned long uart_no) | |
1316 | { | |
1317 | struct uart_omap_port *up = ui[uart_no - 1]; | |
1318 | unsigned int curr_dma_pos; | |
1319 | curr_dma_pos = omap_readl(OMAP34XX_DMA4_BASE + OMAP_DMA4_CDAC(up->uart_dma.rx_dma_channel)); | |
1320 | if ((curr_dma_pos == up->uart_dma.prev_rx_dma_pos) || (curr_dma_pos == 0)) { | |
1321 | /* | |
1322 | * If there is no transfer rx happening for 10sec then stop the dma | |
1323 | * else just restart the timer. See if 10 sec can be improved. | |
1324 | */ | |
1325 | if (jiffies_to_msecs(jiffies - isr8250_activity) < 10000) | |
1326 | mod_timer(&up->uart_dma.rx_timer, jiffies + | |
1327 | usecs_to_jiffies(up->uart_dma.rx_timeout)); | |
1328 | else { | |
1329 | del_timer(&up->uart_dma.rx_timer); | |
1330 | serial_omap_stop_rxdma(up); | |
1331 | up->ier |= UART_IER_RDI; | |
1332 | serial_out(up, UART_IER, up->ier); | |
1333 | } | |
1334 | ||
1335 | return; | |
1336 | } else { | |
1337 | unsigned int curr_transmitted_size = curr_dma_pos - up->uart_dma.prev_rx_dma_pos; | |
1338 | up->port.icount.rx += curr_transmitted_size; | |
1339 | tty_insert_flip_string(up->port.state->port.tty, up->uart_dma.rx_buf + (up->uart_dma.prev_rx_dma_pos - up->uart_dma.rx_buf_dma_phys), curr_transmitted_size); | |
1340 | queue_work(omap_serial_workqueue, &up->tty_work); | |
1341 | up->uart_dma.prev_rx_dma_pos = curr_dma_pos; | |
1342 | if (up->uart_dma.rx_buf_size + up->uart_dma.rx_buf_dma_phys == curr_dma_pos) { | |
1343 | serial_omap_start_rxdma(up); | |
1344 | } else | |
1345 | mod_timer(&up->uart_dma.rx_timer, | |
1346 | jiffies + usecs_to_jiffies(up->uart_dma.rx_timeout)); | |
1347 | isr8250_activity = jiffies; | |
1348 | } | |
1349 | } | |
1350 | ||
1351 | static void uart_rx_dma_callback(int lch, u16 ch_status, void *data) | |
1352 | { | |
1353 | return; | |
1354 | } | |
1355 | ||
1356 | static void serial_omap_start_rxdma(struct uart_omap_port *up) | |
1357 | { | |
1358 | #ifdef CONFIG_PM | |
1359 | /* Disallow OCP bus idle. UART TX irqs are not seen during | |
1360 | * bus idle. Alternative is to set kernel timer at fifo | |
1361 | * drain rate. | |
1362 | */ | |
1363 | unsigned int tmp; | |
1364 | tmp = (serial_in(up, UART_OMAP_SYSC) & 0x7) | (1 << 3); | |
1365 | serial_out(up, UART_OMAP_SYSC, tmp); /* no-idle */ | |
1366 | #endif | |
1367 | if (up->uart_dma.rx_dma_channel == 0xFF) { | |
1368 | omap_request_dma(uart_dma_rx[up->pdev->id-1], "UART Rx DMA", | |
1369 | (void *)uart_rx_dma_callback, up, | |
1370 | &(up->uart_dma.rx_dma_channel)); | |
1371 | omap_set_dma_src_params(up->uart_dma.rx_dma_channel, 0, | |
1372 | OMAP_DMA_AMODE_CONSTANT, | |
1373 | UART_BASE(up->pdev->id - 1), 0, 0); | |
1374 | omap_set_dma_dest_params(up->uart_dma.rx_dma_channel, 0, | |
1375 | OMAP_DMA_AMODE_POST_INC, | |
1376 | up->uart_dma.rx_buf_dma_phys, 0, 0); | |
1377 | omap_set_dma_transfer_params(up->uart_dma.rx_dma_channel, | |
1378 | OMAP_DMA_DATA_TYPE_S8, | |
1379 | up->uart_dma.rx_buf_size, 1, | |
1380 | OMAP_DMA_SYNC_ELEMENT, | |
1381 | uart_dma_rx[up->pdev->id-1], 0); | |
1382 | } | |
1383 | up->uart_dma.prev_rx_dma_pos = up->uart_dma.rx_buf_dma_phys; | |
1384 | omap_writel(0, OMAP34XX_DMA4_BASE + | |
1385 | OMAP_DMA4_CDAC(up->uart_dma.rx_dma_channel)); | |
1386 | omap_start_dma(up->uart_dma.rx_dma_channel); | |
1387 | mod_timer(&up->uart_dma.rx_timer, jiffies + | |
1388 | usecs_to_jiffies(up->uart_dma.rx_timeout)); | |
1389 | up->uart_dma.rx_dma_state = 1; | |
1390 | } | |
1391 | ||
1392 | static void serial_omap_continue_tx(struct uart_omap_port *up) | |
1393 | { | |
1394 | struct circ_buf *xmit = &up->port.state->xmit; | |
1395 | int start = up->uart_dma.tx_buf_dma_phys + (xmit->tail & (UART_XMIT_SIZE - 1)); | |
1396 | if (uart_circ_empty(xmit)) | |
1397 | return; | |
1398 | ||
1399 | up->uart_dma.tx_buf_size = uart_circ_chars_pending(xmit); | |
1400 | /* It is a circular buffer. See if the buffer has wounded back. | |
1401 | * If yes it will have to be transferred in two separate dma | |
1402 | * transfers | |
1403 | */ | |
1404 | if (start + up->uart_dma.tx_buf_size >= | |
1405 | up->uart_dma.tx_buf_dma_phys + UART_XMIT_SIZE) | |
1406 | up->uart_dma.tx_buf_size = | |
1407 | (up->uart_dma.tx_buf_dma_phys + UART_XMIT_SIZE) - start; | |
1408 | omap_set_dma_dest_params(up->uart_dma.tx_dma_channel, 0, | |
1409 | OMAP_DMA_AMODE_CONSTANT, | |
1410 | UART_BASE(up->pdev->id - 1), 0, 0); | |
1411 | omap_set_dma_src_params(up->uart_dma.tx_dma_channel, 0, | |
1412 | OMAP_DMA_AMODE_POST_INC, start, 0, 0); | |
1413 | ||
1414 | omap_set_dma_transfer_params(up->uart_dma.tx_dma_channel, | |
1415 | OMAP_DMA_DATA_TYPE_S8, | |
1416 | up->uart_dma.tx_buf_size, 1, | |
1417 | OMAP_DMA_SYNC_ELEMENT, | |
1418 | uart_dma_tx[(up->pdev->id)-1], 0); | |
1419 | ||
1420 | omap_start_dma(up->uart_dma.tx_dma_channel); | |
1421 | } | |
1422 | ||
1423 | static void uart_tx_dma_callback(int lch, u16 ch_status, void *data) | |
1424 | { | |
1425 | struct uart_omap_port *up = (struct uart_omap_port *)data; | |
1426 | struct circ_buf *xmit = &up->port.state->xmit; | |
1427 | xmit->tail = (xmit->tail + up->uart_dma.tx_buf_size) & (UART_XMIT_SIZE - 1); | |
1428 | up->port.icount.tx += up->uart_dma.tx_buf_size; | |
1429 | ||
1430 | /* Revisit: Not sure about the below two steps. Seen some instabilities | |
1431 | * with them. might not be needed in the DMA path | |
1432 | */ | |
1433 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | |
1434 | uart_write_wakeup(&up->port); | |
1435 | ||
1436 | if (uart_circ_empty(xmit)) { | |
1437 | ||
1438 | spin_lock(&(up->uart_dma.tx_lock)); | |
1439 | serial_omap_stop_tx(&up->port); | |
1440 | up->uart_dma.tx_dma_state = 0; | |
1441 | spin_unlock(&(up->uart_dma.tx_lock)); | |
1442 | } else { | |
1443 | omap_stop_dma(up->uart_dma.tx_dma_channel); | |
1444 | serial_omap_continue_tx(up); | |
1445 | } | |
1446 | isr8250_activity = jiffies; | |
1447 | ||
1448 | return; | |
1449 | } | |
1450 | ||
1451 | static int serial_omap_probe(struct platform_device *pdev) | |
1452 | { | |
1453 | struct plat_serialomap_port *pdata = pdev->dev.platform_data; | |
1454 | struct uart_omap_port *up; | |
1455 | struct resource *mem, *irq; | |
1456 | int ret = -ENOSPC; | |
1457 | char str[7]; | |
1458 | ||
1459 | if (!pdata) { | |
1460 | dev_err(&pdev->dev, "no platform data?\n"); | |
1461 | return -ENODEV; | |
1462 | } | |
1463 | ||
1464 | if (pdata->disabled) { | |
1465 | dev_err(&pdev->dev, "device disabled\n"); | |
1466 | return -ENODEV; | |
1467 | } | |
1468 | ||
1469 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
1470 | if (!mem) { | |
1471 | dev_err(&pdev->dev, "no mem resource?\n"); | |
1472 | return -ENODEV; | |
1473 | } | |
1474 | irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | |
1475 | if (!irq) { | |
1476 | dev_err(&pdev->dev, "no irq resource?\n"); | |
1477 | return -ENODEV; | |
1478 | } | |
1479 | ||
1480 | ret = (int) request_mem_region(mem->start, (mem->end - mem->start) + 1, | |
1481 | pdev->dev.driver->name); | |
1482 | if (!ret) { | |
1483 | dev_err(&pdev->dev, "memory region already claimed\n"); | |
1484 | return -EBUSY; | |
1485 | } | |
1486 | up = kzalloc(sizeof(*up), GFP_KERNEL); | |
1487 | if (up == NULL) { | |
1488 | ret = -ENOMEM; | |
1489 | goto do_release_region; | |
1490 | } | |
1491 | sprintf(up->name, "OMAP UART%d", pdev->id); | |
1492 | ||
1493 | up->pdev = pdev; | |
1494 | up->port.dev = &pdev->dev; | |
1495 | up->port.type = PORT_OMAP; | |
1496 | up->port.iotype = UPIO_MEM; | |
1497 | up->port.mapbase = mem->start; | |
1498 | up->port.irq = irq->start; | |
1499 | up->port.fifosize = 64; | |
1500 | up->port.ops = &serial_omap_pops; | |
1501 | up->port.line = pdev->id - 1; | |
1502 | #define QUART_CLK (1843200) | |
1503 | if (pdev->id == 4) { | |
1504 | up->port.membase = ioremap_nocache(mem->start, 0x16 << 1); | |
1505 | up->port.flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP | | |
1506 | UPF_SHARE_IRQ | UPF_TRIGGER_HIGH; | |
1507 | up->port.uartclk = QUART_CLK; | |
1508 | up->port.regshift = 1; | |
1509 | } else { | |
1510 | up->port.membase = (void *) OMAP2_L4_IO_ADDRESS(mem->start); | |
1511 | up->port.flags = pdata->flags; | |
1512 | up->port.uartclk = 48000000; | |
1513 | up->port.regshift = 2; | |
1514 | #ifdef CONFIG_SERIAL_OMAP3430_HW_FLOW_CONTROL | |
1515 | up->ctsrts = pdata->ctsrts; | |
1516 | #endif | |
1517 | } | |
1518 | ||
1519 | ||
1520 | if (pdev->id == (UART1+1)) { | |
1521 | #ifdef CONFIG_SERIAL_OMAP_DMA_UART1 | |
1522 | up->use_dma = 1; | |
1523 | up->uart_dma.rx_buf_size = | |
1524 | CONFIG_SERIAL_OMAP_UART1_RXDMA_BUFSIZE; | |
1525 | up->uart_dma.rx_timeout = | |
1526 | CONFIG_SERIAL_OMAP_UART1_RXDMA_TIMEOUT; | |
1527 | #endif | |
1528 | } else if (pdev->id == (UART2+1)) { | |
1529 | #ifdef CONFIG_SERIAL_OMAP_DMA_UART2 | |
1530 | up->use_dma = 1; | |
1531 | up->uart_dma.rx_buf_size = | |
1532 | CONFIG_SERIAL_OMAP_UART2_RXDMA_BUFSIZE; | |
1533 | up->uart_dma.rx_timeout = | |
1534 | CONFIG_SERIAL_OMAP_UART2_RXDMA_TIMEOUT; | |
1535 | #endif | |
1536 | } else if (pdev->id == (UART3+1)) { | |
1537 | #ifdef CONFIG_SERIAL_OMAP_DMA_UART3 | |
1538 | up->use_dma = 1; | |
1539 | up->uart_dma.rx_buf_size = | |
1540 | CONFIG_SERIAL_OMAP_UART3_RXDMA_BUFSIZE; | |
1541 | up->uart_dma.rx_timeout = | |
1542 | CONFIG_SERIAL_OMAP_UART3_RXDMA_TIMEOUT; | |
1543 | #endif | |
1544 | } | |
1545 | ||
1546 | if (up->use_dma) { | |
1547 | spin_lock_init(&(up->uart_dma.tx_lock)); | |
1548 | spin_lock_init(&(up->uart_dma.rx_lock)); | |
1549 | up->uart_dma.tx_dma_channel = 0xFF; | |
1550 | up->uart_dma.rx_dma_channel = 0xFF; | |
1551 | } | |
1552 | if (console_detect(str)) | |
1553 | printk("Invalid console paramter. UART Library Init Failed!\n"); | |
1554 | up->use_console = 0; | |
1555 | fcr[pdev->id - 1] = 0; | |
1556 | if (!strcmp(str, "ttyS0")) | |
1557 | up->use_console = 1; | |
1558 | else if (!strcmp(str, "ttyS1")) | |
1559 | up->use_console = 1; | |
1560 | else if (!strcmp(str, "ttyS2")) | |
1561 | up->use_console = 1; | |
1562 | else if (!strcmp(str, "ttyS3")) | |
1563 | up->use_console = 1; | |
1564 | else | |
1565 | printk(KERN_INFO | |
1566 | "!!!!!!!! Unable to recongnize Console UART........\n"); | |
1567 | ui[pdev->id - 1] = up; | |
1568 | serial_omap_add_console_port(up); | |
1569 | serial_omap_clear_fifos(up); | |
1570 | ||
1571 | ret = uart_add_one_port(&serial_omap_reg, &up->port); | |
1572 | if (ret != 0) | |
1573 | goto do_release_region; | |
1574 | platform_set_drvdata(pdev, up); | |
1575 | ||
1576 | if (pdata->wake_gpio_strobe) { | |
1577 | if (gpio_request(pdata->wake_gpio_strobe, | |
1578 | "UART AP -> BP wakeup strobe")) { | |
1579 | printk(KERN_ERR "Error requesting GPIO\n"); | |
1580 | } else | |
1581 | gpio_direction_output(pdata->wake_gpio_strobe, 0); | |
1582 | } | |
1583 | ||
1584 | INIT_WORK(&up->tty_work, tty_flip_buffer_work); | |
1585 | ||
1586 | return 0; | |
1587 | do_release_region: | |
1588 | release_mem_region(mem->start, (mem->end - mem->start) + 1); | |
1589 | return ret; | |
1590 | } | |
1591 | ||
1592 | static int serial_omap_remove(struct platform_device *dev) | |
1593 | { | |
1594 | struct uart_omap_port *up = platform_get_drvdata(dev); | |
1595 | ||
1596 | platform_set_drvdata(dev, NULL); | |
1597 | if (up) { | |
1598 | uart_remove_one_port(&serial_omap_reg, &up->port); | |
1599 | kfree(up); | |
1600 | } | |
1601 | return 0; | |
1602 | } | |
1603 | ||
1604 | static struct platform_driver serial_omap_driver = { | |
1605 | .probe = serial_omap_probe, | |
1606 | .remove = serial_omap_remove, | |
1607 | ||
1608 | .suspend = serial_omap_suspend, | |
1609 | .resume = serial_omap_resume, | |
1610 | .driver = { | |
1611 | .name = "omap-hs-uart", | |
1612 | }, | |
1613 | }; | |
1614 | ||
1615 | int my_serial_omap_init(void) | |
1616 | { | |
1617 | int ret; | |
1618 | ||
1619 | wake_lock_init(&omap_serial_wakelock, WAKE_LOCK_SUSPEND, | |
1620 | "omap_hs_serial"); | |
1621 | omap_serial_workqueue = create_singlethread_workqueue("omap_hs_serial"); | |
1622 | ret = uart_register_driver(&serial_omap_reg); | |
1623 | if (ret != 0) | |
1624 | return ret; | |
1625 | ret = platform_driver_register(&serial_omap_driver); | |
1626 | if (ret != 0) | |
1627 | uart_unregister_driver(&serial_omap_reg); | |
1628 | return ret; | |
1629 | } | |
1630 | ||
1631 | void serial_omap_exit(void) | |
1632 | { | |
1633 | wake_lock_destroy(&omap_serial_wakelock); | |
1634 | destroy_workqueue(omap_serial_workqueue); | |
1635 | platform_driver_unregister(&serial_omap_driver); | |
1636 | uart_unregister_driver(&serial_omap_reg); | |
1637 | } | |
1638 | ||
1639 | #if defined(CONFIG_OMAP3_PM) | |
1640 | int omap24xx_uart_cts_wakeup(int uart_no, int state) | |
1641 | { | |
1642 | u32 *ptr; | |
1643 | unsigned char lcr, efr; | |
1644 | struct uart_omap_port *up = ui[uart_no]; | |
1645 | ||
1646 | if (unlikely(uart_no < 0 || uart_no > MAX_UARTS)) { | |
1647 | printk(KERN_INFO "Bad uart id %d \n", uart_no); | |
1648 | return -EPERM; | |
1649 | } | |
1650 | ||
1651 | if (state) { | |
1652 | /* | |
1653 | * Enable the CTS for io pad wakeup | |
1654 | */ | |
1655 | switch (uart_no) { | |
1656 | case UART1: | |
1657 | ptr = (u32 *) (&CONTROL_PADCONF_UART1_CTS); | |
1658 | break; | |
1659 | case UART2: | |
1660 | ptr = (u32 *) (&CONTROL_PADCONF_UART2_CTS); | |
1661 | break; | |
1662 | default: | |
1663 | printk(KERN_ERR | |
1664 | "Wakeup on Uart%d is not supported\n", uart_no); | |
1665 | return -EPERM; | |
1666 | } | |
1667 | *ptr |= (u32)((IO_PAD_WAKEUPENABLE | IO_PAD_OFFPULLUDENABLE | | |
1668 | IO_PAD_OFFOUTENABLE | IO_PAD_OFFENABLE | | |
1669 | IO_PAD_INPUTENABLE | IO_PAD_PULLUDENABLE| | |
1670 | IO_PAD_MUXMODE0) | |
1671 | ); | |
1672 | /* | |
1673 | * Enable the CTS for module level wakeup | |
1674 | */ | |
1675 | lcr = serial_in(up, UART_LCR); | |
1676 | serial_out(up, UART_LCR, 0xbf); | |
1677 | efr = serial_in(up, UART_EFR); | |
1678 | serial_out(up, UART_EFR, efr | UART_EFR_ECB); | |
1679 | serial_out(up, UART_LCR, lcr); | |
1680 | up->ier |= (1 << 7); | |
1681 | serial_out(up, UART_IER, up->ier); | |
1682 | serial_out(up, UART_OMAP_WER, | |
1683 | serial_in(up, UART_OMAP_WER) | 0x1); | |
1684 | serial_out(up, UART_LCR, 0xbf); | |
1685 | serial_out(up, UART_EFR, efr); | |
1686 | serial_out(up, UART_LCR, lcr); | |
1687 | ||
1688 | } else { | |
1689 | /* | |
1690 | * Disable the CTS capability for io pad wakeup | |
1691 | */ | |
1692 | switch (uart_no) { | |
1693 | case UART1: | |
1694 | ptr = (u32 *) (&CONTROL_PADCONF_UART1_CTS); | |
1695 | break; | |
1696 | case UART2: | |
1697 | ptr = (u32 *) (&CONTROL_PADCONF_UART2_CTS); | |
1698 | break; | |
1699 | default: | |
1700 | printk(KERN_ERR | |
1701 | "Wakeup on Uart%d is not supported\n", uart_no); | |
1702 | return -EPERM; | |
1703 | } | |
1704 | *ptr &= (u32) (~(IO_PAD_WAKEUPENABLE | IO_PAD_OFFPULLUDENABLE | | |
1705 | IO_PAD_OFFOUTENABLE | IO_PAD_OFFENABLE | | |
1706 | IO_PAD_INPUTENABLE | IO_PAD_PULLUDENABLE)); | |
1707 | *ptr |= IO_PAD_MUXMODE7; | |
1708 | ||
1709 | /* | |
1710 | * Disable the CTS for module level wakeup | |
1711 | */ | |
1712 | lcr = serial_in(up, UART_LCR); | |
1713 | serial_out(up, UART_LCR, 0xbf); | |
1714 | efr = serial_in(up, UART_EFR); | |
1715 | serial_out(up, UART_EFR, efr | UART_EFR_ECB); | |
1716 | serial_out(up, UART_LCR, lcr); | |
1717 | up->ier &= ~(1 << 7); | |
1718 | serial_out(up, UART_IER, up->ier); | |
1719 | /* TBD:Do we really want to disable module wake up for this in WER*/ | |
1720 | serial_out(up, UART_LCR, 0xbf); | |
1721 | serial_out(up, UART_EFR, efr); | |
1722 | serial_out(up, UART_LCR, lcr); | |
1723 | } | |
1724 | return 0; | |
1725 | } | |
1726 | EXPORT_SYMBOL(omap24xx_uart_cts_wakeup); | |
1727 | #endif | |
1728 | ||
1729 | #ifdef CONFIG_PM | |
1730 | #if 0 | |
1731 | /** | |
1732 | * are_driver8250_uarts_active() - Check if any ports managed by this | |
1733 | * driver are currently busy. This should be called with interrupts | |
1734 | * disabled. | |
1735 | */ | |
1736 | int are_driveromap_uarts_active(int num) | |
1737 | { | |
1738 | struct circ_buf *xmit; | |
1739 | unsigned int status; | |
1740 | struct uart_omap_port *up = ui[num]; | |
1741 | ||
1742 | if (!up) | |
1743 | return 0; | |
1744 | ||
1745 | /* check ownership of port */ | |
1746 | /* Check only ports managed by this driver and open */ | |
1747 | if ((up->port.dev == NULL) || (up->port.type == PORT_UNKNOWN)) | |
1748 | return 0; | |
1749 | ||
1750 | /* driver owns this port but it's closed */ | |
1751 | if (up->port.state == NULL) | |
1752 | return 0; | |
1753 | ||
1754 | /* check for any current pending activity */ | |
1755 | /* Any queued work in ring buffer which can be handled still? */ | |
1756 | xmit = &up->port.state->xmit; | |
1757 | if (!(uart_circ_empty(xmit) || uart_tx_stopped(&up->port))) | |
1758 | return 1; | |
1759 | status = serial_in(up, UART_LSR); | |
1760 | ||
1761 | /* TX hardware not empty */ | |
1762 | if (!(status & (UART_LSR_TEMT | UART_LSR_THRE))) | |
1763 | return 1; | |
1764 | ||
1765 | /* Any rx activity? */ | |
1766 | if (status & UART_LSR_DR) | |
1767 | return 1; | |
1768 | ||
1769 | if (up->use_dma) { | |
1770 | /* | |
1771 | * Silicon Errata i291 workaround. | |
1772 | * UART Module has to be put in force idle if it is | |
1773 | * configured in DMA mode and when there is no activity | |
1774 | * expected. | |
1775 | */ | |
1776 | unsigned int tmp; | |
1777 | del_timer(&up->uart_dma.rx_timer); | |
1778 | serial_omap_stop_rxdma(up); | |
1779 | up->ier |= UART_IER_RDI; | |
1780 | serial_out(up, UART_IER, up->ier); | |
1781 | tmp = (serial_in(up, UART_OMAP_SYSC) & 0x7); | |
1782 | serial_out(up, UART_OMAP_SYSC, tmp); /* force-idle */ | |
1783 | } | |
1784 | ||
1785 | return 0; | |
1786 | } | |
1787 | EXPORT_SYMBOL(are_driveromap_uarts_active); | |
1788 | ||
1789 | #endif | |
1790 | #endif | |
1791 | ||
1792 | static void serial_omap_display_reg(struct uart_port *port) | |
1793 | { | |
1794 | struct uart_omap_port *up = (struct uart_omap_port *)port; | |
1795 | unsigned int lcr, efr, mcr, dll, dlh, xon1, xon2, xoff1, xoff2; | |
1796 | unsigned int tcr, tlr, uasr; | |
1797 | DPRINTK("Register dump for UART%d\n", up->pdev->id); | |
1798 | DPRINTK("IER_REG=0x%x\n", serial_in(up, UART_IER)); | |
1799 | DPRINTK("IIR_REG=0x%x\n", serial_in(up, UART_IIR)); | |
1800 | lcr = serial_in(up, UART_LCR); | |
1801 | DPRINTK("LCR_REG=0x%x\n", lcr); | |
1802 | mcr = serial_in(up, UART_MCR); | |
1803 | DPRINTK("MCR_REG=0x%x\n", mcr); | |
1804 | DPRINTK("LSR_REG=0x%x\n", serial_in(up, UART_LSR)); | |
1805 | DPRINTK("MSR_REG=0x%x\n", serial_in(up, UART_MSR)); | |
1806 | DPRINTK("SPR_REG=0x%x\n", serial_in(up, UART_OMAP_SPR)); | |
1807 | DPRINTK("MDR1_REG=0x%x\n", serial_in(up, UART_OMAP_MDR1)); | |
1808 | DPRINTK("MDR2_REG=0x%x\n", serial_in(up, UART_OMAP_MDR2)); | |
1809 | DPRINTK("SCR_REG=0x%x\n", serial_in(up, UART_OMAP_SCR)); | |
1810 | DPRINTK("SSR_REG=0x%x\n", serial_in(up, UART_OMAP_SSR)); | |
1811 | DPRINTK("MVR_REG=0x%x\n", serial_in(up, UART_OMAP_MVER)); | |
1812 | DPRINTK("SYSC_REG=0x%x\n", serial_in(up, UART_OMAP_SYSC)); | |
1813 | DPRINTK("SYSS_REG=0x%x\n", serial_in(up, UART_OMAP_SYSS)); | |
1814 | DPRINTK("WER_REG=0x%x\n", serial_in(up, UART_OMAP_WER)); | |
1815 | ||
1816 | serial_out(up, UART_LCR, 0xBF); | |
1817 | dll = serial_in(up, UART_DLL); | |
1818 | dlh = serial_in(up, UART_DLM); | |
1819 | efr = serial_in(up, UART_EFR); | |
1820 | xon1 = serial_in(up, UART_XON1); | |
1821 | xon2 = serial_in(up, UART_XON2); | |
1822 | ||
1823 | serial_out(up, UART_EFR, efr | UART_EFR_ECB); | |
1824 | serial_out(up, UART_LCR, lcr); | |
1825 | serial_out(up, UART_MCR, mcr | UART_MCR_TCRTLR); | |
1826 | serial_out(up, UART_LCR, 0xBF); | |
1827 | ||
1828 | tcr = serial_in(up, UART_TI752_TCR); | |
1829 | tlr = serial_in(up, UART_TI752_TLR); | |
1830 | ||
1831 | serial_out(up, UART_LCR, lcr); | |
1832 | serial_out(up, UART_MCR, mcr); | |
1833 | serial_out(up, UART_LCR, 0xBF); | |
1834 | ||
1835 | xoff1 = serial_in(up, UART_XOFF1); | |
1836 | xoff2 = serial_in(up, UART_XOFF2); | |
1837 | uasr = serial_in(up, UART_OMAP_UASR); | |
1838 | ||
1839 | serial_out(up, UART_EFR, efr); | |
1840 | serial_out(up, UART_LCR, lcr); | |
1841 | ||
1842 | ||
1843 | DPRINTK("DLL_REG=0x%x\n", dll); | |
1844 | DPRINTK("DLH_REG=0x%x\n", dlh); | |
1845 | DPRINTK("EFR_REG=0x%x\n", efr); | |
1846 | ||
1847 | DPRINTK("XON1_ADDR_REG=0x%x\n", xon1); | |
1848 | DPRINTK("XON2_ADDR_REG=0x%x\n", xon2); | |
1849 | DPRINTK("TCR_REG=0x%x\n", tcr); | |
1850 | DPRINTK("TLR_REG=0x%x\n", tlr); | |
1851 | ||
1852 | ||
1853 | DPRINTK("XOFF1_REG=0x%x\n", xoff1); | |
1854 | DPRINTK("XOFF2_REG=0x%x\n", xoff2); | |
1855 | DPRINTK("UASR_REG=0x%x\n", uasr); | |
1856 | ||
1857 | } |