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.c296
1 files changed, 231 insertions, 65 deletions
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c
index 9f460b175c50..7b5d1de9cfe3 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>
@@ -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 */
@@ -211,10 +217,20 @@ struct imx_port {
211 struct timer_list timer; 217 struct timer_list timer;
212 unsigned int old_status; 218 unsigned int old_status;
213 int txirq,rxirq,rtsirq; 219 int txirq,rxirq,rtsirq;
214 int have_rtscts:1; 220 unsigned int have_rtscts:1;
221 unsigned int use_irda:1;
222 unsigned int irda_inv_rx:1;
223 unsigned int irda_inv_tx:1;
224 unsigned short trcv_delay; /* transceiver delay */
215 struct clk *clk; 225 struct clk *clk;
216}; 226};
217 227
228#ifdef CONFIG_IRDA
229#define USE_IRDA(sport) ((sport)->use_irda)
230#else
231#define USE_IRDA(sport) (0)
232#endif
233
218/* 234/*
219 * Handle any change of modem status signal since we were last called. 235 * Handle any change of modem status signal since we were last called.
220 */ 236 */
@@ -268,6 +284,48 @@ static void imx_stop_tx(struct uart_port *port)
268 struct imx_port *sport = (struct imx_port *)port; 284 struct imx_port *sport = (struct imx_port *)port;
269 unsigned long temp; 285 unsigned long temp;
270 286
287 if (USE_IRDA(sport)) {
288 /* half duplex - wait for end of transmission */
289 int n = 256;
290 while ((--n > 0) &&
291 !(readl(sport->port.membase + USR2) & USR2_TXDC)) {
292 udelay(5);
293 barrier();
294 }
295 /*
296 * irda transceiver - wait a bit more to avoid
297 * cutoff, hardware dependent
298 */
299 udelay(sport->trcv_delay);
300
301 /*
302 * half duplex - reactivate receive mode,
303 * flush receive pipe echo crap
304 */
305 if (readl(sport->port.membase + USR2) & USR2_TXDC) {
306 temp = readl(sport->port.membase + UCR1);
307 temp &= ~(UCR1_TXMPTYEN | UCR1_TRDYEN);
308 writel(temp, sport->port.membase + UCR1);
309
310 temp = readl(sport->port.membase + UCR4);
311 temp &= ~(UCR4_TCEN);
312 writel(temp, sport->port.membase + UCR4);
313
314 while (readl(sport->port.membase + URXD0) &
315 URXD_CHARRDY)
316 barrier();
317
318 temp = readl(sport->port.membase + UCR1);
319 temp |= UCR1_RRDYEN;
320 writel(temp, sport->port.membase + UCR1);
321
322 temp = readl(sport->port.membase + UCR4);
323 temp |= UCR4_DREN;
324 writel(temp, sport->port.membase + UCR4);
325 }
326 return;
327 }
328
271 temp = readl(sport->port.membase + UCR1); 329 temp = readl(sport->port.membase + UCR1);
272 writel(temp & ~UCR1_TXMPTYEN, sport->port.membase + UCR1); 330 writel(temp & ~UCR1_TXMPTYEN, sport->port.membase + UCR1);
273} 331}
@@ -302,13 +360,15 @@ static inline void imx_transmit_buffer(struct imx_port *sport)
302 /* send xmit->buf[xmit->tail] 360 /* send xmit->buf[xmit->tail]
303 * out the port here */ 361 * out the port here */
304 writel(xmit->buf[xmit->tail], sport->port.membase + URTX0); 362 writel(xmit->buf[xmit->tail], sport->port.membase + URTX0);
305 xmit->tail = (xmit->tail + 1) & 363 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
306 (UART_XMIT_SIZE - 1);
307 sport->port.icount.tx++; 364 sport->port.icount.tx++;
308 if (uart_circ_empty(xmit)) 365 if (uart_circ_empty(xmit))
309 break; 366 break;
310 } 367 }
311 368
369 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
370 uart_write_wakeup(&sport->port);
371
312 if (uart_circ_empty(xmit)) 372 if (uart_circ_empty(xmit))
313 imx_stop_tx(&sport->port); 373 imx_stop_tx(&sport->port);
314} 374}
@@ -321,9 +381,30 @@ static void imx_start_tx(struct uart_port *port)
321 struct imx_port *sport = (struct imx_port *)port; 381 struct imx_port *sport = (struct imx_port *)port;
322 unsigned long temp; 382 unsigned long temp;
323 383
384 if (USE_IRDA(sport)) {
385 /* half duplex in IrDA mode; have to disable receive mode */
386 temp = readl(sport->port.membase + UCR4);
387 temp &= ~(UCR4_DREN);
388 writel(temp, sport->port.membase + UCR4);
389
390 temp = readl(sport->port.membase + UCR1);
391 temp &= ~(UCR1_RRDYEN);
392 writel(temp, sport->port.membase + UCR1);
393 }
394
324 temp = readl(sport->port.membase + UCR1); 395 temp = readl(sport->port.membase + UCR1);
325 writel(temp | UCR1_TXMPTYEN, sport->port.membase + UCR1); 396 writel(temp | UCR1_TXMPTYEN, sport->port.membase + UCR1);
326 397
398 if (USE_IRDA(sport)) {
399 temp = readl(sport->port.membase + UCR1);
400 temp |= UCR1_TRDYEN;
401 writel(temp, sport->port.membase + UCR1);
402
403 temp = readl(sport->port.membase + UCR4);
404 temp |= UCR4_TCEN;
405 writel(temp, sport->port.membase + UCR4);
406 }
407
327 if (readl(sport->port.membase + UTS) & UTS_TXEMPTY) 408 if (readl(sport->port.membase + UTS) & UTS_TXEMPTY)
328 imx_transmit_buffer(sport); 409 imx_transmit_buffer(sport);
329} 410}
@@ -395,8 +476,7 @@ static irqreturn_t imx_rxint(int irq, void *dev_id)
395 continue; 476 continue;
396 } 477 }
397 478
398 if (uart_handle_sysrq_char 479 if (uart_handle_sysrq_char(&sport->port, (unsigned char)rx))
399 (&sport->port, (unsigned char)rx))
400 continue; 480 continue;
401 481
402 if (rx & (URXD_PRERR | URXD_OVRRUN | URXD_FRMERR) ) { 482 if (rx & (URXD_PRERR | URXD_OVRRUN | URXD_FRMERR) ) {
@@ -471,26 +551,26 @@ static unsigned int imx_tx_empty(struct uart_port *port)
471 */ 551 */
472static unsigned int imx_get_mctrl(struct uart_port *port) 552static unsigned int imx_get_mctrl(struct uart_port *port)
473{ 553{
474 struct imx_port *sport = (struct imx_port *)port; 554 struct imx_port *sport = (struct imx_port *)port;
475 unsigned int tmp = TIOCM_DSR | TIOCM_CAR; 555 unsigned int tmp = TIOCM_DSR | TIOCM_CAR;
476 556
477 if (readl(sport->port.membase + USR1) & USR1_RTSS) 557 if (readl(sport->port.membase + USR1) & USR1_RTSS)
478 tmp |= TIOCM_CTS; 558 tmp |= TIOCM_CTS;
479 559
480 if (readl(sport->port.membase + UCR2) & UCR2_CTS) 560 if (readl(sport->port.membase + UCR2) & UCR2_CTS)
481 tmp |= TIOCM_RTS; 561 tmp |= TIOCM_RTS;
482 562
483 return tmp; 563 return tmp;
484} 564}
485 565
486static void imx_set_mctrl(struct uart_port *port, unsigned int mctrl) 566static void imx_set_mctrl(struct uart_port *port, unsigned int mctrl)
487{ 567{
488 struct imx_port *sport = (struct imx_port *)port; 568 struct imx_port *sport = (struct imx_port *)port;
489 unsigned long temp; 569 unsigned long temp;
490 570
491 temp = readl(sport->port.membase + UCR2) & ~UCR2_CTS; 571 temp = readl(sport->port.membase + UCR2) & ~UCR2_CTS;
492 572
493 if (mctrl & TIOCM_RTS) 573 if (mctrl & TIOCM_RTS)
494 temp |= UCR2_CTS; 574 temp |= UCR2_CTS;
495 575
496 writel(temp, sport->port.membase + UCR2); 576 writel(temp, sport->port.membase + UCR2);
@@ -534,12 +614,7 @@ static int imx_setup_ufcr(struct imx_port *sport, unsigned int mode)
534 if(!ufcr_rfdiv) 614 if(!ufcr_rfdiv)
535 ufcr_rfdiv = 1; 615 ufcr_rfdiv = 1;
536 616
537 if(ufcr_rfdiv >= 7) 617 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 618
544 writel(val, sport->port.membase + UFCR); 619 writel(val, sport->port.membase + UFCR);
545 620
@@ -558,8 +633,24 @@ static int imx_startup(struct uart_port *port)
558 * requesting IRQs 633 * requesting IRQs
559 */ 634 */
560 temp = readl(sport->port.membase + UCR4); 635 temp = readl(sport->port.membase + UCR4);
636
637 if (USE_IRDA(sport))
638 temp |= UCR4_IRSC;
639
561 writel(temp & ~UCR4_DREN, sport->port.membase + UCR4); 640 writel(temp & ~UCR4_DREN, sport->port.membase + UCR4);
562 641
642 if (USE_IRDA(sport)) {
643 /* reset fifo's and state machines */
644 int i = 100;
645 temp = readl(sport->port.membase + UCR2);
646 temp &= ~UCR2_SRST;
647 writel(temp, sport->port.membase + UCR2);
648 while (!(readl(sport->port.membase + UCR2) & UCR2_SRST) &&
649 (--i > 0)) {
650 udelay(1);
651 }
652 }
653
563 /* 654 /*
564 * Allocate the IRQ(s) i.MX1 has three interrupts whereas later 655 * Allocate the IRQ(s) i.MX1 has three interrupts whereas later
565 * chips only have one interrupt. 656 * chips only have one interrupt.
@@ -575,12 +666,16 @@ static int imx_startup(struct uart_port *port)
575 if (retval) 666 if (retval)
576 goto error_out2; 667 goto error_out2;
577 668
578 retval = request_irq(sport->rtsirq, imx_rtsint, 669 /* do not use RTS IRQ on IrDA */
579 (sport->rtsirq < MAX_INTERNAL_IRQ) ? 0 : 670 if (!USE_IRDA(sport)) {
580 IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, 671 retval = request_irq(sport->rtsirq, imx_rtsint,
581 DRIVER_NAME, sport); 672 (sport->rtsirq < MAX_INTERNAL_IRQ) ? 0 :
582 if (retval) 673 IRQF_TRIGGER_FALLING |
583 goto error_out3; 674 IRQF_TRIGGER_RISING,
675 DRIVER_NAME, sport);
676 if (retval)
677 goto error_out3;
678 }
584 } else { 679 } else {
585 retval = request_irq(sport->port.irq, imx_int, 0, 680 retval = request_irq(sport->port.irq, imx_int, 0,
586 DRIVER_NAME, sport); 681 DRIVER_NAME, sport);
@@ -597,18 +692,49 @@ static int imx_startup(struct uart_port *port)
597 692
598 temp = readl(sport->port.membase + UCR1); 693 temp = readl(sport->port.membase + UCR1);
599 temp |= UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN; 694 temp |= UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN;
695
696 if (USE_IRDA(sport)) {
697 temp |= UCR1_IREN;
698 temp &= ~(UCR1_RTSDEN);
699 }
700
600 writel(temp, sport->port.membase + UCR1); 701 writel(temp, sport->port.membase + UCR1);
601 702
602 temp = readl(sport->port.membase + UCR2); 703 temp = readl(sport->port.membase + UCR2);
603 temp |= (UCR2_RXEN | UCR2_TXEN); 704 temp |= (UCR2_RXEN | UCR2_TXEN);
604 writel(temp, sport->port.membase + UCR2); 705 writel(temp, sport->port.membase + UCR2);
605 706
707 if (USE_IRDA(sport)) {
708 /* clear RX-FIFO */
709 int i = 64;
710 while ((--i > 0) &&
711 (readl(sport->port.membase + URXD0) & URXD_CHARRDY)) {
712 barrier();
713 }
714 }
715
606#if defined CONFIG_ARCH_MX2 || defined CONFIG_ARCH_MX3 716#if defined CONFIG_ARCH_MX2 || defined CONFIG_ARCH_MX3
607 temp = readl(sport->port.membase + UCR3); 717 temp = readl(sport->port.membase + UCR3);
608 temp |= UCR3_RXDMUXSEL; 718 temp |= UCR3_RXDMUXSEL;
609 writel(temp, sport->port.membase + UCR3); 719 writel(temp, sport->port.membase + UCR3);
610#endif 720#endif
611 721
722 if (USE_IRDA(sport)) {
723 temp = readl(sport->port.membase + UCR4);
724 if (sport->irda_inv_rx)
725 temp |= UCR4_INVR;
726 else
727 temp &= ~(UCR4_INVR);
728 writel(temp | UCR4_DREN, sport->port.membase + UCR4);
729
730 temp = readl(sport->port.membase + UCR3);
731 if (sport->irda_inv_tx)
732 temp |= UCR3_INVT;
733 else
734 temp &= ~(UCR3_INVT);
735 writel(temp, sport->port.membase + UCR3);
736 }
737
612 /* 738 /*
613 * Enable modem status interrupts 739 * Enable modem status interrupts
614 */ 740 */
@@ -616,6 +742,16 @@ static int imx_startup(struct uart_port *port)
616 imx_enable_ms(&sport->port); 742 imx_enable_ms(&sport->port);
617 spin_unlock_irqrestore(&sport->port.lock,flags); 743 spin_unlock_irqrestore(&sport->port.lock,flags);
618 744
745 if (USE_IRDA(sport)) {
746 struct imxuart_platform_data *pdata;
747 pdata = sport->port.dev->platform_data;
748 sport->irda_inv_rx = pdata->irda_inv_rx;
749 sport->irda_inv_tx = pdata->irda_inv_tx;
750 sport->trcv_delay = pdata->transceiver_delay;
751 if (pdata->irda_enable)
752 pdata->irda_enable(1);
753 }
754
619 return 0; 755 return 0;
620 756
621error_out3: 757error_out3:
@@ -633,6 +769,17 @@ static void imx_shutdown(struct uart_port *port)
633 struct imx_port *sport = (struct imx_port *)port; 769 struct imx_port *sport = (struct imx_port *)port;
634 unsigned long temp; 770 unsigned long temp;
635 771
772 temp = readl(sport->port.membase + UCR2);
773 temp &= ~(UCR2_TXEN);
774 writel(temp, sport->port.membase + UCR2);
775
776 if (USE_IRDA(sport)) {
777 struct imxuart_platform_data *pdata;
778 pdata = sport->port.dev->platform_data;
779 if (pdata->irda_enable)
780 pdata->irda_enable(0);
781 }
782
636 /* 783 /*
637 * Stop our timer. 784 * Stop our timer.
638 */ 785 */
@@ -642,7 +789,8 @@ static void imx_shutdown(struct uart_port *port)
642 * Free the interrupts 789 * Free the interrupts
643 */ 790 */
644 if (sport->txirq > 0) { 791 if (sport->txirq > 0) {
645 free_irq(sport->rtsirq, sport); 792 if (!USE_IRDA(sport))
793 free_irq(sport->rtsirq, sport);
646 free_irq(sport->txirq, sport); 794 free_irq(sport->txirq, sport);
647 free_irq(sport->rxirq, sport); 795 free_irq(sport->rxirq, sport);
648 } else 796 } else
@@ -654,6 +802,9 @@ static void imx_shutdown(struct uart_port *port)
654 802
655 temp = readl(sport->port.membase + UCR1); 803 temp = readl(sport->port.membase + UCR1);
656 temp &= ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN); 804 temp &= ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN);
805 if (USE_IRDA(sport))
806 temp &= ~(UCR1_IREN);
807
657 writel(temp, sport->port.membase + UCR1); 808 writel(temp, sport->port.membase + UCR1);
658} 809}
659 810
@@ -665,7 +816,9 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios,
665 unsigned long flags; 816 unsigned long flags;
666 unsigned int ucr2, old_ucr1, old_txrxen, baud, quot; 817 unsigned int ucr2, old_ucr1, old_txrxen, baud, quot;
667 unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8; 818 unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8;
668 unsigned int div, num, denom, ufcr; 819 unsigned int div, ufcr;
820 unsigned long num, denom;
821 uint64_t tdiv64;
669 822
670 /* 823 /*
671 * If we don't support modem control lines, don't allow 824 * If we don't support modem control lines, don't allow
@@ -761,38 +914,39 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios,
761 sport->port.membase + UCR2); 914 sport->port.membase + UCR2);
762 old_txrxen &= (UCR2_TXEN | UCR2_RXEN); 915 old_txrxen &= (UCR2_TXEN | UCR2_RXEN);
763 916
764 div = sport->port.uartclk / (baud * 16); 917 if (USE_IRDA(sport)) {
765 if (div > 7) 918 /*
766 div = 7; 919 * use maximum available submodule frequency to
767 if (!div) 920 * avoid missing short pulses due to low sampling rate
921 */
768 div = 1; 922 div = 1;
769 923 } else {
770 num = baud; 924 div = sport->port.uartclk / (baud * 16);
771 denom = port->uartclk / div / 16; 925 if (div > 7)
772 926 div = 7;
773 /* shift num and denom right until they fit into 16 bits */ 927 if (!div)
774 while (num > 0x10000 || denom > 0x10000) { 928 div = 1;
775 num >>= 1;
776 denom >>= 1;
777 } 929 }
778 if (num > 0)
779 num -= 1;
780 if (denom > 0)
781 denom -= 1;
782 930
783 writel(num, sport->port.membase + UBIR); 931 rational_best_approximation(16 * div * baud, sport->port.uartclk,
784 writel(denom, sport->port.membase + UBMR); 932 1 << 16, 1 << 16, &num, &denom);
785 933
786 if (div == 7) 934 tdiv64 = sport->port.uartclk;
787 div = 6; /* 6 in RFDIV means divide by 7 */ 935 tdiv64 *= num;
788 else 936 do_div(tdiv64, denom * 16 * div);
789 div = 6 - div; 937 tty_encode_baud_rate(sport->port.info->port.tty,
938 (speed_t)tdiv64, (speed_t)tdiv64);
939
940 num -= 1;
941 denom -= 1;
790 942
791 ufcr = readl(sport->port.membase + UFCR); 943 ufcr = readl(sport->port.membase + UFCR);
792 ufcr = (ufcr & (~UFCR_RFDIV)) | 944 ufcr = (ufcr & (~UFCR_RFDIV)) | UFCR_RFDIV_REG(div);
793 (div << 7);
794 writel(ufcr, sport->port.membase + UFCR); 945 writel(ufcr, sport->port.membase + UFCR);
795 946
947 writel(num, sport->port.membase + UBIR);
948 writel(denom, sport->port.membase + UBMR);
949
796#ifdef ONEMS 950#ifdef ONEMS
797 writel(sport->port.uartclk / div / 1000, sport->port.membase + ONEMS); 951 writel(sport->port.uartclk / div / 1000, sport->port.membase + ONEMS);
798#endif 952#endif
@@ -1031,6 +1185,8 @@ imx_console_setup(struct console *co, char *options)
1031 if (co->index == -1 || co->index >= ARRAY_SIZE(imx_ports)) 1185 if (co->index == -1 || co->index >= ARRAY_SIZE(imx_ports))
1032 co->index = 0; 1186 co->index = 0;
1033 sport = imx_ports[co->index]; 1187 sport = imx_ports[co->index];
1188 if(sport == NULL)
1189 return -ENODEV;
1034 1190
1035 if (options) 1191 if (options)
1036 uart_parse_options(options, &baud, &parity, &bits, &flow); 1192 uart_parse_options(options, &baud, &parity, &bits, &flow);
@@ -1070,22 +1226,22 @@ static struct uart_driver imx_reg = {
1070 1226
1071static int serial_imx_suspend(struct platform_device *dev, pm_message_t state) 1227static int serial_imx_suspend(struct platform_device *dev, pm_message_t state)
1072{ 1228{
1073 struct imx_port *sport = platform_get_drvdata(dev); 1229 struct imx_port *sport = platform_get_drvdata(dev);
1074 1230
1075 if (sport) 1231 if (sport)
1076 uart_suspend_port(&imx_reg, &sport->port); 1232 uart_suspend_port(&imx_reg, &sport->port);
1077 1233
1078 return 0; 1234 return 0;
1079} 1235}
1080 1236
1081static int serial_imx_resume(struct platform_device *dev) 1237static int serial_imx_resume(struct platform_device *dev)
1082{ 1238{
1083 struct imx_port *sport = platform_get_drvdata(dev); 1239 struct imx_port *sport = platform_get_drvdata(dev);
1084 1240
1085 if (sport) 1241 if (sport)
1086 uart_resume_port(&imx_reg, &sport->port); 1242 uart_resume_port(&imx_reg, &sport->port);
1087 1243
1088 return 0; 1244 return 0;
1089} 1245}
1090 1246
1091static int serial_imx_probe(struct platform_device *pdev) 1247static int serial_imx_probe(struct platform_device *pdev)
@@ -1141,19 +1297,29 @@ static int serial_imx_probe(struct platform_device *pdev)
1141 imx_ports[pdev->id] = sport; 1297 imx_ports[pdev->id] = sport;
1142 1298
1143 pdata = pdev->dev.platform_data; 1299 pdata = pdev->dev.platform_data;
1144 if(pdata && (pdata->flags & IMXUART_HAVE_RTSCTS)) 1300 if (pdata && (pdata->flags & IMXUART_HAVE_RTSCTS))
1145 sport->have_rtscts = 1; 1301 sport->have_rtscts = 1;
1146 1302
1303#ifdef CONFIG_IRDA
1304 if (pdata && (pdata->flags & IMXUART_IRDA))
1305 sport->use_irda = 1;
1306#endif
1307
1147 if (pdata->init) { 1308 if (pdata->init) {
1148 ret = pdata->init(pdev); 1309 ret = pdata->init(pdev);
1149 if (ret) 1310 if (ret)
1150 goto clkput; 1311 goto clkput;
1151 } 1312 }
1152 1313
1153 uart_add_one_port(&imx_reg, &sport->port); 1314 ret = uart_add_one_port(&imx_reg, &sport->port);
1315 if (ret)
1316 goto deinit;
1154 platform_set_drvdata(pdev, &sport->port); 1317 platform_set_drvdata(pdev, &sport->port);
1155 1318
1156 return 0; 1319 return 0;
1320deinit:
1321 if (pdata->exit)
1322 pdata->exit(pdev);
1157clkput: 1323clkput:
1158 clk_put(sport->clk); 1324 clk_put(sport->clk);
1159 clk_disable(sport->clk); 1325 clk_disable(sport->clk);
@@ -1191,13 +1357,13 @@ static int serial_imx_remove(struct platform_device *pdev)
1191} 1357}
1192 1358
1193static struct platform_driver serial_imx_driver = { 1359static struct platform_driver serial_imx_driver = {
1194 .probe = serial_imx_probe, 1360 .probe = serial_imx_probe,
1195 .remove = serial_imx_remove, 1361 .remove = serial_imx_remove,
1196 1362
1197 .suspend = serial_imx_suspend, 1363 .suspend = serial_imx_suspend,
1198 .resume = serial_imx_resume, 1364 .resume = serial_imx_resume,
1199 .driver = { 1365 .driver = {
1200 .name = "imx-uart", 1366 .name = "imx-uart",
1201 .owner = THIS_MODULE, 1367 .owner = THIS_MODULE,
1202 }, 1368 },
1203}; 1369};