diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-21 18:40:55 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-21 18:40:55 -0400 |
commit | 85b375a613085b78531ec86369a51c2f3b922f95 (patch) | |
tree | 716437d598de92bbd7acaf24622e9a7d74fc209a /drivers/serial | |
parent | ec965350bb98bd291eb34f6ecddfdcfc36da1e6e (diff) | |
parent | cf816ecb533ab96b883dfdc0db174598b5b5c4d2 (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.c | 111 |
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 | ||
389 | out: | 402 | out: |
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 | |||
394 | handle_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 | */ |
732 | static void imx_release_port(struct uart_port *port) | 717 | static 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 | */ |
742 | static int imx_request_port(struct uart_port *port) | 729 | static 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, |