aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial/imx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/serial/imx.c')
-rw-r--r--drivers/serial/imx.c309
1 files changed, 234 insertions, 75 deletions
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c
index 9f460b175c50..285b414f3054 100644
--- a/drivers/serial/imx.c
+++ b/drivers/serial/imx.c
@@ -8,6 +8,9 @@
8 * Author: Sascha Hauer <sascha@saschahauer.de> 8 * Author: Sascha Hauer <sascha@saschahauer.de>
9 * Copyright (C) 2004 Pengutronix 9 * Copyright (C) 2004 Pengutronix
10 * 10 *
11 * Copyright (C) 2009 emlix GmbH
12 * Author: Fabian Godehardt (added IrDA support for iMX)
13 *
11 * This program is free software; you can redistribute it and/or modify 14 * 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 15 * 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 16 * the Free Software Foundation; either version 2 of the License, or
@@ -41,6 +44,8 @@
41#include <linux/serial_core.h> 44#include <linux/serial_core.h>
42#include <linux/serial.h> 45#include <linux/serial.h>
43#include <linux/clk.h> 46#include <linux/clk.h>
47#include <linux/delay.h>
48#include <linux/rational.h>
44 49
45#include <asm/io.h> 50#include <asm/io.h>
46#include <asm/irq.h> 51#include <asm/irq.h>
@@ -66,7 +71,7 @@
66#define ONEMS 0xb0 /* One Millisecond register */ 71#define ONEMS 0xb0 /* One Millisecond register */
67#define UTS 0xb4 /* UART Test Register */ 72#define UTS 0xb4 /* UART Test Register */
68#endif 73#endif
69#if defined(CONFIG_ARCH_IMX) || defined(CONFIG_ARCH_MX1) 74#ifdef CONFIG_ARCH_MX1
70#define BIPR1 0xb0 /* Incremental Preset Register 1 */ 75#define BIPR1 0xb0 /* Incremental Preset Register 1 */
71#define BIPR2 0xb4 /* Incremental Preset Register 2 */ 76#define BIPR2 0xb4 /* Incremental Preset Register 2 */
72#define BIPR3 0xb8 /* Incremental Preset Register 3 */ 77#define BIPR3 0xb8 /* Incremental Preset Register 3 */
@@ -96,7 +101,7 @@
96#define UCR1_RTSDEN (1<<5) /* RTS delta interrupt enable */ 101#define UCR1_RTSDEN (1<<5) /* RTS delta interrupt enable */
97#define UCR1_SNDBRK (1<<4) /* Send break */ 102#define UCR1_SNDBRK (1<<4) /* Send break */
98#define UCR1_TDMAEN (1<<3) /* Transmitter ready DMA enable */ 103#define UCR1_TDMAEN (1<<3) /* Transmitter ready DMA enable */
99#if defined(CONFIG_ARCH_IMX) || defined(CONFIG_ARCH_MX1) 104#ifdef CONFIG_ARCH_MX1
100#define UCR1_UARTCLKEN (1<<2) /* UART clock enabled */ 105#define UCR1_UARTCLKEN (1<<2) /* UART clock enabled */
101#endif 106#endif
102#if defined CONFIG_ARCH_MX3 || defined CONFIG_ARCH_MX2 107#if defined CONFIG_ARCH_MX3 || defined CONFIG_ARCH_MX2
@@ -127,7 +132,7 @@
127#define UCR3_RXDSEN (1<<6) /* Receive status interrupt enable */ 132#define UCR3_RXDSEN (1<<6) /* Receive status interrupt enable */
128#define UCR3_AIRINTEN (1<<5) /* Async IR wake interrupt enable */ 133#define UCR3_AIRINTEN (1<<5) /* Async IR wake interrupt enable */
129#define UCR3_AWAKEN (1<<4) /* Async wake interrupt enable */ 134#define UCR3_AWAKEN (1<<4) /* Async wake interrupt enable */
130#ifdef CONFIG_ARCH_IMX 135#ifdef CONFIG_ARCH_MX1
131#define UCR3_REF25 (1<<3) /* Ref freq 25 MHz, only on mx1 */ 136#define UCR3_REF25 (1<<3) /* Ref freq 25 MHz, only on mx1 */
132#define UCR3_REF30 (1<<2) /* Ref Freq 30 MHz, only on mx1 */ 137#define UCR3_REF30 (1<<2) /* Ref Freq 30 MHz, only on mx1 */
133#endif 138#endif
@@ -148,6 +153,7 @@
148#define UCR4_DREN (1<<0) /* Recv data ready interrupt enable */ 153#define UCR4_DREN (1<<0) /* Recv data ready interrupt enable */
149#define UFCR_RXTL_SHF 0 /* Receiver trigger level shift */ 154#define UFCR_RXTL_SHF 0 /* Receiver trigger level shift */
150#define UFCR_RFDIV (7<<7) /* Reference freq divider mask */ 155#define UFCR_RFDIV (7<<7) /* Reference freq divider mask */
156#define UFCR_RFDIV_REG(x) (((x) < 7 ? 6 - (x) : 6) << 7)
151#define UFCR_TXTL_SHF 10 /* Transmitter trigger level shift */ 157#define UFCR_TXTL_SHF 10 /* Transmitter trigger level shift */
152#define USR1_PARITYERR (1<<15) /* Parity error interrupt flag */ 158#define USR1_PARITYERR (1<<15) /* Parity error interrupt flag */
153#define USR1_RTSS (1<<14) /* RTS pin status */ 159#define USR1_RTSS (1<<14) /* RTS pin status */
@@ -180,13 +186,6 @@
180#define UTS_SOFTRST (1<<0) /* Software reset */ 186#define UTS_SOFTRST (1<<0) /* Software reset */
181 187
182/* We've been assigned a range on the "Low-density serial ports" major */ 188/* We've been assigned a range on the "Low-density serial ports" major */
183#ifdef CONFIG_ARCH_IMX
184#define SERIAL_IMX_MAJOR 204
185#define MINOR_START 41
186#define DEV_NAME "ttySMX"
187#define MAX_INTERNAL_IRQ IMX_IRQS
188#endif
189
190#ifdef CONFIG_ARCH_MXC 189#ifdef CONFIG_ARCH_MXC
191#define SERIAL_IMX_MAJOR 207 190#define SERIAL_IMX_MAJOR 207
192#define MINOR_START 16 191#define MINOR_START 16
@@ -211,10 +210,20 @@ struct imx_port {
211 struct timer_list timer; 210 struct timer_list timer;
212 unsigned int old_status; 211 unsigned int old_status;
213 int txirq,rxirq,rtsirq; 212 int txirq,rxirq,rtsirq;
214 int have_rtscts:1; 213 unsigned int have_rtscts:1;
214 unsigned int use_irda:1;
215 unsigned int irda_inv_rx:1;
216 unsigned int irda_inv_tx:1;
217 unsigned short trcv_delay; /* transceiver delay */
215 struct clk *clk; 218 struct clk *clk;
216}; 219};
217 220
221#ifdef CONFIG_IRDA
222#define USE_IRDA(sport) ((sport)->use_irda)
223#else
224#define USE_IRDA(sport) (0)
225#endif
226
218/* 227/*
219 * Handle any change of modem status signal since we were last called. 228 * Handle any change of modem status signal since we were last called.
220 */ 229 */
@@ -268,6 +277,48 @@ static void imx_stop_tx(struct uart_port *port)
268 struct imx_port *sport = (struct imx_port *)port; 277 struct imx_port *sport = (struct imx_port *)port;
269 unsigned long temp; 278 unsigned long temp;
270 279
280 if (USE_IRDA(sport)) {
281 /* half duplex - wait for end of transmission */
282 int n = 256;
283 while ((--n > 0) &&
284 !(readl(sport->port.membase + USR2) & USR2_TXDC)) {
285 udelay(5);
286 barrier();
287 }
288 /*
289 * irda transceiver - wait a bit more to avoid
290 * cutoff, hardware dependent
291 */
292 udelay(sport->trcv_delay);
293
294 /*
295 * half duplex - reactivate receive mode,
296 * flush receive pipe echo crap
297 */
298 if (readl(sport->port.membase + USR2) & USR2_TXDC) {
299 temp = readl(sport->port.membase + UCR1);
300 temp &= ~(UCR1_TXMPTYEN | UCR1_TRDYEN);
301 writel(temp, sport->port.membase + UCR1);
302
303 temp = readl(sport->port.membase + UCR4);
304 temp &= ~(UCR4_TCEN);
305 writel(temp, sport->port.membase + UCR4);
306
307 while (readl(sport->port.membase + URXD0) &
308 URXD_CHARRDY)
309 barrier();
310
311 temp = readl(sport->port.membase + UCR1);
312 temp |= UCR1_RRDYEN;
313 writel(temp, sport->port.membase + UCR1);
314
315 temp = readl(sport->port.membase + UCR4);
316 temp |= UCR4_DREN;
317 writel(temp, sport->port.membase + UCR4);
318 }
319 return;
320 }
321
271 temp = readl(sport->port.membase + UCR1); 322 temp = readl(sport->port.membase + UCR1);
272 writel(temp & ~UCR1_TXMPTYEN, sport->port.membase + UCR1); 323 writel(temp & ~UCR1_TXMPTYEN, sport->port.membase + UCR1);
273} 324}
@@ -302,13 +353,15 @@ static inline void imx_transmit_buffer(struct imx_port *sport)
302 /* send xmit->buf[xmit->tail] 353 /* send xmit->buf[xmit->tail]
303 * out the port here */ 354 * out the port here */
304 writel(xmit->buf[xmit->tail], sport->port.membase + URTX0); 355 writel(xmit->buf[xmit->tail], sport->port.membase + URTX0);
305 xmit->tail = (xmit->tail + 1) & 356 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
306 (UART_XMIT_SIZE - 1);
307 sport->port.icount.tx++; 357 sport->port.icount.tx++;
308 if (uart_circ_empty(xmit)) 358 if (uart_circ_empty(xmit))
309 break; 359 break;
310 } 360 }
311 361
362 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
363 uart_write_wakeup(&sport->port);
364
312 if (uart_circ_empty(xmit)) 365 if (uart_circ_empty(xmit))
313 imx_stop_tx(&sport->port); 366 imx_stop_tx(&sport->port);
314} 367}
@@ -321,9 +374,30 @@ static void imx_start_tx(struct uart_port *port)
321 struct imx_port *sport = (struct imx_port *)port; 374 struct imx_port *sport = (struct imx_port *)port;
322 unsigned long temp; 375 unsigned long temp;
323 376
377 if (USE_IRDA(sport)) {
378 /* half duplex in IrDA mode; have to disable receive mode */
379 temp = readl(sport->port.membase + UCR4);
380 temp &= ~(UCR4_DREN);
381 writel(temp, sport->port.membase + UCR4);
382
383 temp = readl(sport->port.membase + UCR1);
384 temp &= ~(UCR1_RRDYEN);
385 writel(temp, sport->port.membase + UCR1);
386 }
387
324 temp = readl(sport->port.membase + UCR1); 388 temp = readl(sport->port.membase + UCR1);
325 writel(temp | UCR1_TXMPTYEN, sport->port.membase + UCR1); 389 writel(temp | UCR1_TXMPTYEN, sport->port.membase + UCR1);
326 390
391 if (USE_IRDA(sport)) {
392 temp = readl(sport->port.membase + UCR1);
393 temp |= UCR1_TRDYEN;
394 writel(temp, sport->port.membase + UCR1);
395
396 temp = readl(sport->port.membase + UCR4);
397 temp |= UCR4_TCEN;
398 writel(temp, sport->port.membase + UCR4);
399 }
400
327 if (readl(sport->port.membase + UTS) & UTS_TXEMPTY) 401 if (readl(sport->port.membase + UTS) & UTS_TXEMPTY)
328 imx_transmit_buffer(sport); 402 imx_transmit_buffer(sport);
329} 403}
@@ -395,8 +469,7 @@ static irqreturn_t imx_rxint(int irq, void *dev_id)
395 continue; 469 continue;
396 } 470 }
397 471
398 if (uart_handle_sysrq_char 472 if (uart_handle_sysrq_char(&sport->port, (unsigned char)rx))
399 (&sport->port, (unsigned char)rx))
400 continue; 473 continue;
401 474
402 if (rx & (URXD_PRERR | URXD_OVRRUN | URXD_FRMERR) ) { 475 if (rx & (URXD_PRERR | URXD_OVRRUN | URXD_FRMERR) ) {
@@ -471,26 +544,26 @@ static unsigned int imx_tx_empty(struct uart_port *port)
471 */ 544 */
472static unsigned int imx_get_mctrl(struct uart_port *port) 545static unsigned int imx_get_mctrl(struct uart_port *port)
473{ 546{
474 struct imx_port *sport = (struct imx_port *)port; 547 struct imx_port *sport = (struct imx_port *)port;
475 unsigned int tmp = TIOCM_DSR | TIOCM_CAR; 548 unsigned int tmp = TIOCM_DSR | TIOCM_CAR;
476 549
477 if (readl(sport->port.membase + USR1) & USR1_RTSS) 550 if (readl(sport->port.membase + USR1) & USR1_RTSS)
478 tmp |= TIOCM_CTS; 551 tmp |= TIOCM_CTS;
479 552
480 if (readl(sport->port.membase + UCR2) & UCR2_CTS) 553 if (readl(sport->port.membase + UCR2) & UCR2_CTS)
481 tmp |= TIOCM_RTS; 554 tmp |= TIOCM_RTS;
482 555
483 return tmp; 556 return tmp;
484} 557}
485 558
486static void imx_set_mctrl(struct uart_port *port, unsigned int mctrl) 559static void imx_set_mctrl(struct uart_port *port, unsigned int mctrl)
487{ 560{
488 struct imx_port *sport = (struct imx_port *)port; 561 struct imx_port *sport = (struct imx_port *)port;
489 unsigned long temp; 562 unsigned long temp;
490 563
491 temp = readl(sport->port.membase + UCR2) & ~UCR2_CTS; 564 temp = readl(sport->port.membase + UCR2) & ~UCR2_CTS;
492 565
493 if (mctrl & TIOCM_RTS) 566 if (mctrl & TIOCM_RTS)
494 temp |= UCR2_CTS; 567 temp |= UCR2_CTS;
495 568
496 writel(temp, sport->port.membase + UCR2); 569 writel(temp, sport->port.membase + UCR2);
@@ -534,12 +607,7 @@ static int imx_setup_ufcr(struct imx_port *sport, unsigned int mode)
534 if(!ufcr_rfdiv) 607 if(!ufcr_rfdiv)
535 ufcr_rfdiv = 1; 608 ufcr_rfdiv = 1;
536 609
537 if(ufcr_rfdiv >= 7) 610 val |= UFCR_RFDIV_REG(ufcr_rfdiv);
538 ufcr_rfdiv = 6;
539 else
540 ufcr_rfdiv = 6 - ufcr_rfdiv;
541
542 val |= UFCR_RFDIV & (ufcr_rfdiv << 7);
543 611
544 writel(val, sport->port.membase + UFCR); 612 writel(val, sport->port.membase + UFCR);
545 613
@@ -558,8 +626,24 @@ static int imx_startup(struct uart_port *port)
558 * requesting IRQs 626 * requesting IRQs
559 */ 627 */
560 temp = readl(sport->port.membase + UCR4); 628 temp = readl(sport->port.membase + UCR4);
629
630 if (USE_IRDA(sport))
631 temp |= UCR4_IRSC;
632
561 writel(temp & ~UCR4_DREN, sport->port.membase + UCR4); 633 writel(temp & ~UCR4_DREN, sport->port.membase + UCR4);
562 634
635 if (USE_IRDA(sport)) {
636 /* reset fifo's and state machines */
637 int i = 100;
638 temp = readl(sport->port.membase + UCR2);
639 temp &= ~UCR2_SRST;
640 writel(temp, sport->port.membase + UCR2);
641 while (!(readl(sport->port.membase + UCR2) & UCR2_SRST) &&
642 (--i > 0)) {
643 udelay(1);
644 }
645 }
646
563 /* 647 /*
564 * Allocate the IRQ(s) i.MX1 has three interrupts whereas later 648 * Allocate the IRQ(s) i.MX1 has three interrupts whereas later
565 * chips only have one interrupt. 649 * chips only have one interrupt.
@@ -575,12 +659,16 @@ static int imx_startup(struct uart_port *port)
575 if (retval) 659 if (retval)
576 goto error_out2; 660 goto error_out2;
577 661
578 retval = request_irq(sport->rtsirq, imx_rtsint, 662 /* do not use RTS IRQ on IrDA */
579 (sport->rtsirq < MAX_INTERNAL_IRQ) ? 0 : 663 if (!USE_IRDA(sport)) {
580 IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, 664 retval = request_irq(sport->rtsirq, imx_rtsint,
581 DRIVER_NAME, sport); 665 (sport->rtsirq < MAX_INTERNAL_IRQ) ? 0 :
582 if (retval) 666 IRQF_TRIGGER_FALLING |
583 goto error_out3; 667 IRQF_TRIGGER_RISING,
668 DRIVER_NAME, sport);
669 if (retval)
670 goto error_out3;
671 }
584 } else { 672 } else {
585 retval = request_irq(sport->port.irq, imx_int, 0, 673 retval = request_irq(sport->port.irq, imx_int, 0,
586 DRIVER_NAME, sport); 674 DRIVER_NAME, sport);
@@ -597,18 +685,49 @@ static int imx_startup(struct uart_port *port)
597 685
598 temp = readl(sport->port.membase + UCR1); 686 temp = readl(sport->port.membase + UCR1);
599 temp |= UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN; 687 temp |= UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN;
688
689 if (USE_IRDA(sport)) {
690 temp |= UCR1_IREN;
691 temp &= ~(UCR1_RTSDEN);
692 }
693
600 writel(temp, sport->port.membase + UCR1); 694 writel(temp, sport->port.membase + UCR1);
601 695
602 temp = readl(sport->port.membase + UCR2); 696 temp = readl(sport->port.membase + UCR2);
603 temp |= (UCR2_RXEN | UCR2_TXEN); 697 temp |= (UCR2_RXEN | UCR2_TXEN);
604 writel(temp, sport->port.membase + UCR2); 698 writel(temp, sport->port.membase + UCR2);
605 699
700 if (USE_IRDA(sport)) {
701 /* clear RX-FIFO */
702 int i = 64;
703 while ((--i > 0) &&
704 (readl(sport->port.membase + URXD0) & URXD_CHARRDY)) {
705 barrier();
706 }
707 }
708
606#if defined CONFIG_ARCH_MX2 || defined CONFIG_ARCH_MX3 709#if defined CONFIG_ARCH_MX2 || defined CONFIG_ARCH_MX3
607 temp = readl(sport->port.membase + UCR3); 710 temp = readl(sport->port.membase + UCR3);
608 temp |= UCR3_RXDMUXSEL; 711 temp |= UCR3_RXDMUXSEL;
609 writel(temp, sport->port.membase + UCR3); 712 writel(temp, sport->port.membase + UCR3);
610#endif 713#endif
611 714
715 if (USE_IRDA(sport)) {
716 temp = readl(sport->port.membase + UCR4);
717 if (sport->irda_inv_rx)
718 temp |= UCR4_INVR;
719 else
720 temp &= ~(UCR4_INVR);
721 writel(temp | UCR4_DREN, sport->port.membase + UCR4);
722
723 temp = readl(sport->port.membase + UCR3);
724 if (sport->irda_inv_tx)
725 temp |= UCR3_INVT;
726 else
727 temp &= ~(UCR3_INVT);
728 writel(temp, sport->port.membase + UCR3);
729 }
730
612 /* 731 /*
613 * Enable modem status interrupts 732 * Enable modem status interrupts
614 */ 733 */
@@ -616,6 +735,16 @@ static int imx_startup(struct uart_port *port)
616 imx_enable_ms(&sport->port); 735 imx_enable_ms(&sport->port);
617 spin_unlock_irqrestore(&sport->port.lock,flags); 736 spin_unlock_irqrestore(&sport->port.lock,flags);
618 737
738 if (USE_IRDA(sport)) {
739 struct imxuart_platform_data *pdata;
740 pdata = sport->port.dev->platform_data;
741 sport->irda_inv_rx = pdata->irda_inv_rx;
742 sport->irda_inv_tx = pdata->irda_inv_tx;
743 sport->trcv_delay = pdata->transceiver_delay;
744 if (pdata->irda_enable)
745 pdata->irda_enable(1);
746 }
747
619 return 0; 748 return 0;
620 749
621error_out3: 750error_out3:
@@ -633,6 +762,17 @@ static void imx_shutdown(struct uart_port *port)
633 struct imx_port *sport = (struct imx_port *)port; 762 struct imx_port *sport = (struct imx_port *)port;
634 unsigned long temp; 763 unsigned long temp;
635 764
765 temp = readl(sport->port.membase + UCR2);
766 temp &= ~(UCR2_TXEN);
767 writel(temp, sport->port.membase + UCR2);
768
769 if (USE_IRDA(sport)) {
770 struct imxuart_platform_data *pdata;
771 pdata = sport->port.dev->platform_data;
772 if (pdata->irda_enable)
773 pdata->irda_enable(0);
774 }
775
636 /* 776 /*
637 * Stop our timer. 777 * Stop our timer.
638 */ 778 */
@@ -642,7 +782,8 @@ static void imx_shutdown(struct uart_port *port)
642 * Free the interrupts 782 * Free the interrupts
643 */ 783 */
644 if (sport->txirq > 0) { 784 if (sport->txirq > 0) {
645 free_irq(sport->rtsirq, sport); 785 if (!USE_IRDA(sport))
786 free_irq(sport->rtsirq, sport);
646 free_irq(sport->txirq, sport); 787 free_irq(sport->txirq, sport);
647 free_irq(sport->rxirq, sport); 788 free_irq(sport->rxirq, sport);
648 } else 789 } else
@@ -654,6 +795,9 @@ static void imx_shutdown(struct uart_port *port)
654 795
655 temp = readl(sport->port.membase + UCR1); 796 temp = readl(sport->port.membase + UCR1);
656 temp &= ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN); 797 temp &= ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN);
798 if (USE_IRDA(sport))
799 temp &= ~(UCR1_IREN);
800
657 writel(temp, sport->port.membase + UCR1); 801 writel(temp, sport->port.membase + UCR1);
658} 802}
659 803
@@ -665,7 +809,9 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios,
665 unsigned long flags; 809 unsigned long flags;
666 unsigned int ucr2, old_ucr1, old_txrxen, baud, quot; 810 unsigned int ucr2, old_ucr1, old_txrxen, baud, quot;
667 unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8; 811 unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8;
668 unsigned int div, num, denom, ufcr; 812 unsigned int div, ufcr;
813 unsigned long num, denom;
814 uint64_t tdiv64;
669 815
670 /* 816 /*
671 * If we don't support modem control lines, don't allow 817 * If we don't support modem control lines, don't allow
@@ -761,38 +907,39 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios,
761 sport->port.membase + UCR2); 907 sport->port.membase + UCR2);
762 old_txrxen &= (UCR2_TXEN | UCR2_RXEN); 908 old_txrxen &= (UCR2_TXEN | UCR2_RXEN);
763 909
764 div = sport->port.uartclk / (baud * 16); 910 if (USE_IRDA(sport)) {
765 if (div > 7) 911 /*
766 div = 7; 912 * use maximum available submodule frequency to
767 if (!div) 913 * avoid missing short pulses due to low sampling rate
914 */
768 div = 1; 915 div = 1;
769 916 } else {
770 num = baud; 917 div = sport->port.uartclk / (baud * 16);
771 denom = port->uartclk / div / 16; 918 if (div > 7)
772 919 div = 7;
773 /* shift num and denom right until they fit into 16 bits */ 920 if (!div)
774 while (num > 0x10000 || denom > 0x10000) { 921 div = 1;
775 num >>= 1;
776 denom >>= 1;
777 } 922 }
778 if (num > 0)
779 num -= 1;
780 if (denom > 0)
781 denom -= 1;
782 923
783 writel(num, sport->port.membase + UBIR); 924 rational_best_approximation(16 * div * baud, sport->port.uartclk,
784 writel(denom, sport->port.membase + UBMR); 925 1 << 16, 1 << 16, &num, &denom);
785 926
786 if (div == 7) 927 tdiv64 = sport->port.uartclk;
787 div = 6; /* 6 in RFDIV means divide by 7 */ 928 tdiv64 *= num;
788 else 929 do_div(tdiv64, denom * 16 * div);
789 div = 6 - div; 930 tty_encode_baud_rate(sport->port.info->port.tty,
931 (speed_t)tdiv64, (speed_t)tdiv64);
932
933 num -= 1;
934 denom -= 1;
790 935
791 ufcr = readl(sport->port.membase + UFCR); 936 ufcr = readl(sport->port.membase + UFCR);
792 ufcr = (ufcr & (~UFCR_RFDIV)) | 937 ufcr = (ufcr & (~UFCR_RFDIV)) | UFCR_RFDIV_REG(div);
793 (div << 7);
794 writel(ufcr, sport->port.membase + UFCR); 938 writel(ufcr, sport->port.membase + UFCR);
795 939
940 writel(num, sport->port.membase + UBIR);
941 writel(denom, sport->port.membase + UBMR);
942
796#ifdef ONEMS 943#ifdef ONEMS
797 writel(sport->port.uartclk / div / 1000, sport->port.membase + ONEMS); 944 writel(sport->port.uartclk / div / 1000, sport->port.membase + ONEMS);
798#endif 945#endif
@@ -1031,6 +1178,8 @@ imx_console_setup(struct console *co, char *options)
1031 if (co->index == -1 || co->index >= ARRAY_SIZE(imx_ports)) 1178 if (co->index == -1 || co->index >= ARRAY_SIZE(imx_ports))
1032 co->index = 0; 1179 co->index = 0;
1033 sport = imx_ports[co->index]; 1180 sport = imx_ports[co->index];
1181 if(sport == NULL)
1182 return -ENODEV;
1034 1183
1035 if (options) 1184 if (options)
1036 uart_parse_options(options, &baud, &parity, &bits, &flow); 1185 uart_parse_options(options, &baud, &parity, &bits, &flow);
@@ -1070,22 +1219,22 @@ static struct uart_driver imx_reg = {
1070 1219
1071static int serial_imx_suspend(struct platform_device *dev, pm_message_t state) 1220static int serial_imx_suspend(struct platform_device *dev, pm_message_t state)
1072{ 1221{
1073 struct imx_port *sport = platform_get_drvdata(dev); 1222 struct imx_port *sport = platform_get_drvdata(dev);
1074 1223
1075 if (sport) 1224 if (sport)
1076 uart_suspend_port(&imx_reg, &sport->port); 1225 uart_suspend_port(&imx_reg, &sport->port);
1077 1226
1078 return 0; 1227 return 0;
1079} 1228}
1080 1229
1081static int serial_imx_resume(struct platform_device *dev) 1230static int serial_imx_resume(struct platform_device *dev)
1082{ 1231{
1083 struct imx_port *sport = platform_get_drvdata(dev); 1232 struct imx_port *sport = platform_get_drvdata(dev);
1084 1233
1085 if (sport) 1234 if (sport)
1086 uart_resume_port(&imx_reg, &sport->port); 1235 uart_resume_port(&imx_reg, &sport->port);
1087 1236
1088 return 0; 1237 return 0;
1089} 1238}
1090 1239
1091static int serial_imx_probe(struct platform_device *pdev) 1240static int serial_imx_probe(struct platform_device *pdev)
@@ -1141,19 +1290,29 @@ static int serial_imx_probe(struct platform_device *pdev)
1141 imx_ports[pdev->id] = sport; 1290 imx_ports[pdev->id] = sport;
1142 1291
1143 pdata = pdev->dev.platform_data; 1292 pdata = pdev->dev.platform_data;
1144 if(pdata && (pdata->flags & IMXUART_HAVE_RTSCTS)) 1293 if (pdata && (pdata->flags & IMXUART_HAVE_RTSCTS))
1145 sport->have_rtscts = 1; 1294 sport->have_rtscts = 1;
1146 1295
1296#ifdef CONFIG_IRDA
1297 if (pdata && (pdata->flags & IMXUART_IRDA))
1298 sport->use_irda = 1;
1299#endif
1300
1147 if (pdata->init) { 1301 if (pdata->init) {
1148 ret = pdata->init(pdev); 1302 ret = pdata->init(pdev);
1149 if (ret) 1303 if (ret)
1150 goto clkput; 1304 goto clkput;
1151 } 1305 }
1152 1306
1153 uart_add_one_port(&imx_reg, &sport->port); 1307 ret = uart_add_one_port(&imx_reg, &sport->port);
1308 if (ret)
1309 goto deinit;
1154 platform_set_drvdata(pdev, &sport->port); 1310 platform_set_drvdata(pdev, &sport->port);
1155 1311
1156 return 0; 1312 return 0;
1313deinit:
1314 if (pdata->exit)
1315 pdata->exit(pdev);
1157clkput: 1316clkput:
1158 clk_put(sport->clk); 1317 clk_put(sport->clk);
1159 clk_disable(sport->clk); 1318 clk_disable(sport->clk);
@@ -1191,13 +1350,13 @@ static int serial_imx_remove(struct platform_device *pdev)
1191} 1350}
1192 1351
1193static struct platform_driver serial_imx_driver = { 1352static struct platform_driver serial_imx_driver = {
1194 .probe = serial_imx_probe, 1353 .probe = serial_imx_probe,
1195 .remove = serial_imx_remove, 1354 .remove = serial_imx_remove,
1196 1355
1197 .suspend = serial_imx_suspend, 1356 .suspend = serial_imx_suspend,
1198 .resume = serial_imx_resume, 1357 .resume = serial_imx_resume,
1199 .driver = { 1358 .driver = {
1200 .name = "imx-uart", 1359 .name = "imx-uart",
1201 .owner = THIS_MODULE, 1360 .owner = THIS_MODULE,
1202 }, 1361 },
1203}; 1362};