aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-04-21 18:40:55 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-21 18:40:55 -0400
commit85b375a613085b78531ec86369a51c2f3b922f95 (patch)
tree716437d598de92bbd7acaf24622e9a7d74fc209a /drivers/serial
parentec965350bb98bd291eb34f6ecddfdcfc36da1e6e (diff)
parentcf816ecb533ab96b883dfdc0db174598b5b5c4d2 (diff)
Merge branch 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm
* 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm: (212 commits) [ARM] pxa: Phycore pcm-990-specific code for the PXA270 Quick Capture driver [ARM] pxa: V4L2 soc_camera driver for PXA270 [ARM] pxa: restrict availability of pxa2xx PCMCIA drivers [ARM] 5005/1: BAST: Fix kset_name initialiser [ARM] 4967/1: Adds functions to set clkout rate for Samsung S3C2410 [ARM] 4988/1: Add GPIO lib support to the EP93xx [ARM] Add initial sparsemem support [ARM] pxa: initialise PXA devices before platform init code [ARM] 5002/1: tosa: add two more leds [ARM] 5004/1: Tosa: make several unreferenced structures static. [ARM] 5003/1: Shut up sparse warnings [ARM] 4977/2: soc - pxa2xx-ac97 - Add missing clk_enable() [ARM] 4976/1: zylonite: Configure GPIO for WM9713 IRQ line [ARM] 4974/1: Drop unused leds-tosa. [ARM] 4973/1: Tosa: use leds-gpio driver. [ARM] 4972/1: Tosa: convert scoop GPIOs usage to generic gpio code [ARM] 4971/1: pxaficp_ir: provide startup and shutdown hooks [ARM] pxa: lubbock: move mis-placed SPI info [ARM] 4970/1: tosa: correct gpio used for wake up. [ARM] 4966/1: magician: add MFP pin configuration ...
Diffstat (limited to 'drivers/serial')
-rw-r--r--drivers/serial/imx.c111
1 files changed, 53 insertions, 58 deletions
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c
index 16ba9ac7a566..5a375bf0ebf4 100644
--- a/drivers/serial/imx.c
+++ b/drivers/serial/imx.c
@@ -166,15 +166,6 @@
166#define SERIAL_IMX_MAJOR 204 166#define SERIAL_IMX_MAJOR 204
167#define MINOR_START 41 167#define MINOR_START 41
168 168
169#define NR_PORTS 2
170
171#define IMX_ISR_PASS_LIMIT 256
172
173/*
174 * This is the size of our serial port register set.
175 */
176#define UART_PORT_SIZE 0x100
177
178/* 169/*
179 * This determines how often we check the modem status signals 170 * This determines how often we check the modem status signals
180 * for any change. They generally aren't connected to an IRQ 171 * for any change. They generally aren't connected to an IRQ
@@ -358,66 +349,60 @@ static irqreturn_t imx_rxint(int irq, void *dev_id)
358 struct tty_struct *tty = sport->port.info->tty; 349 struct tty_struct *tty = sport->port.info->tty;
359 unsigned long flags, temp; 350 unsigned long flags, temp;
360 351
361 rx = readl(sport->port.membase + URXD0);
362 spin_lock_irqsave(&sport->port.lock,flags); 352 spin_lock_irqsave(&sport->port.lock,flags);
363 353
364 do { 354 while (readl(sport->port.membase + USR2) & USR2_RDR) {
365 flg = TTY_NORMAL; 355 flg = TTY_NORMAL;
366 sport->port.icount.rx++; 356 sport->port.icount.rx++;
367 357
358 rx = readl(sport->port.membase + URXD0);
359
368 temp = readl(sport->port.membase + USR2); 360 temp = readl(sport->port.membase + USR2);
369 if( temp & USR2_BRCD ) { 361 if (temp & USR2_BRCD) {
370 writel(temp | USR2_BRCD, sport->port.membase + USR2); 362 writel(temp | USR2_BRCD, sport->port.membase + USR2);
371 if(uart_handle_break(&sport->port)) 363 if (uart_handle_break(&sport->port))
372 goto ignore_char; 364 continue;
373 } 365 }
374 366
375 if (uart_handle_sysrq_char 367 if (uart_handle_sysrq_char
376 (&sport->port, (unsigned char)rx)) 368 (&sport->port, (unsigned char)rx))
377 goto ignore_char; 369 continue;
370
371 if (rx & (URXD_PRERR | URXD_OVRRUN | URXD_FRMERR) ) {
372 if (rx & URXD_PRERR)
373 sport->port.icount.parity++;
374 else if (rx & URXD_FRMERR)
375 sport->port.icount.frame++;
376 if (rx & URXD_OVRRUN)
377 sport->port.icount.overrun++;
378
379 if (rx & sport->port.ignore_status_mask) {
380 if (++ignored > 100)
381 goto out;
382 continue;
383 }
384
385 rx &= sport->port.read_status_mask;
386
387 if (rx & URXD_PRERR)
388 flg = TTY_PARITY;
389 else if (rx & URXD_FRMERR)
390 flg = TTY_FRAME;
391 if (rx & URXD_OVRRUN)
392 flg = TTY_OVERRUN;
378 393
379 if( rx & (URXD_PRERR | URXD_OVRRUN | URXD_FRMERR) ) 394#ifdef SUPPORT_SYSRQ
380 goto handle_error; 395 sport->port.sysrq = 0;
396#endif
397 }
381 398
382 error_return:
383 tty_insert_flip_char(tty, rx, flg); 399 tty_insert_flip_char(tty, rx, flg);
384 400 }
385 ignore_char:
386 rx = readl(sport->port.membase + URXD0);
387 } while(rx & URXD_CHARRDY);
388 401
389out: 402out:
390 spin_unlock_irqrestore(&sport->port.lock,flags); 403 spin_unlock_irqrestore(&sport->port.lock,flags);
391 tty_flip_buffer_push(tty); 404 tty_flip_buffer_push(tty);
392 return IRQ_HANDLED; 405 return IRQ_HANDLED;
393
394handle_error:
395 if (rx & URXD_PRERR)
396 sport->port.icount.parity++;
397 else if (rx & URXD_FRMERR)
398 sport->port.icount.frame++;
399 if (rx & URXD_OVRRUN)
400 sport->port.icount.overrun++;
401
402 if (rx & sport->port.ignore_status_mask) {
403 if (++ignored > 100)
404 goto out;
405 goto ignore_char;
406 }
407
408 rx &= sport->port.read_status_mask;
409
410 if (rx & URXD_PRERR)
411 flg = TTY_PARITY;
412 else if (rx & URXD_FRMERR)
413 flg = TTY_FRAME;
414 if (rx & URXD_OVRRUN)
415 flg = TTY_OVERRUN;
416
417#ifdef SUPPORT_SYSRQ
418 sport->port.sysrq = 0;
419#endif
420 goto error_return;
421} 406}
422 407
423/* 408/*
@@ -546,7 +531,7 @@ static int imx_startup(struct uart_port *port)
546 writel(USR1_RTSD, sport->port.membase + USR1); 531 writel(USR1_RTSD, sport->port.membase + USR1);
547 532
548 temp = readl(sport->port.membase + UCR1); 533 temp = readl(sport->port.membase + UCR1);
549 temp |= (UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN); 534 temp |= UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN;
550 writel(temp, sport->port.membase + UCR1); 535 writel(temp, sport->port.membase + UCR1);
551 536
552 temp = readl(sport->port.membase + UCR2); 537 temp = readl(sport->port.membase + UCR2);
@@ -731,9 +716,11 @@ static const char *imx_type(struct uart_port *port)
731 */ 716 */
732static void imx_release_port(struct uart_port *port) 717static void imx_release_port(struct uart_port *port)
733{ 718{
734 struct imx_port *sport = (struct imx_port *)port; 719 struct platform_device *pdev = to_platform_device(port->dev);
720 struct resource *mmres;
735 721
736 release_mem_region(sport->port.mapbase, UART_PORT_SIZE); 722 mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
723 release_mem_region(mmres->start, mmres->end - mmres->start + 1);
737} 724}
738 725
739/* 726/*
@@ -741,10 +728,18 @@ static void imx_release_port(struct uart_port *port)
741 */ 728 */
742static int imx_request_port(struct uart_port *port) 729static int imx_request_port(struct uart_port *port)
743{ 730{
744 struct imx_port *sport = (struct imx_port *)port; 731 struct platform_device *pdev = to_platform_device(port->dev);
732 struct resource *mmres;
733 void *ret;
734
735 mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
736 if (!mmres)
737 return -ENODEV;
738
739 ret = request_mem_region(mmres->start, mmres->end - mmres->start + 1,
740 "imx-uart");
745 741
746 return request_mem_region(sport->port.mapbase, UART_PORT_SIZE, 742 return ret ? 0 : -EBUSY;
747 "imx-uart") != NULL ? 0 : -EBUSY;
748} 743}
749 744
750/* 745/*
@@ -815,7 +810,7 @@ static struct imx_port imx_ports[] = {
815 .type = PORT_IMX, 810 .type = PORT_IMX,
816 .iotype = UPIO_MEM, 811 .iotype = UPIO_MEM,
817 .membase = (void *)IMX_UART1_BASE, 812 .membase = (void *)IMX_UART1_BASE,
818 .mapbase = IMX_UART1_BASE, /* FIXME */ 813 .mapbase = 0x00206000,
819 .irq = UART1_MINT_RX, 814 .irq = UART1_MINT_RX,
820 .uartclk = 16000000, 815 .uartclk = 16000000,
821 .fifosize = 32, 816 .fifosize = 32,
@@ -831,7 +826,7 @@ static struct imx_port imx_ports[] = {
831 .type = PORT_IMX, 826 .type = PORT_IMX,
832 .iotype = UPIO_MEM, 827 .iotype = UPIO_MEM,
833 .membase = (void *)IMX_UART2_BASE, 828 .membase = (void *)IMX_UART2_BASE,
834 .mapbase = IMX_UART2_BASE, /* FIXME */ 829 .mapbase = 0x00207000,
835 .irq = UART2_MINT_RX, 830 .irq = UART2_MINT_RX,
836 .uartclk = 16000000, 831 .uartclk = 16000000,
837 .fifosize = 32, 832 .fifosize = 32,