diff for duplicates of <4BA335A8.1000205@evidence.eu.com> diff --git a/a/1.txt b/N1/1.txt index e90b14f..c0c8fe0 100644 --- a/a/1.txt +++ b/N1/1.txt @@ -9,11 +9,3 @@ Feedback (comments, suggestions, further testing) is welcome. Many thanks, Claudio - --------------- next part -------------- -A non-text attachment was scrubbed... -Name: atmel_serial_rs485.patch -Type: text/x-patch -Size: 15692 bytes -Desc: not available -URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20100319/fbb49b36/attachment-0001.bin> diff --git a/N1/2.hdr b/N1/2.hdr new file mode 100644 index 0000000..ff1d333 --- /dev/null +++ b/N1/2.hdr @@ -0,0 +1,5 @@ +Content-Type: text/x-patch; + name="atmel_serial_rs485.patch" +Content-Transfer-Encoding: 7bit +Content-Disposition: inline; + filename="atmel_serial_rs485.patch" diff --git a/N1/2.txt b/N1/2.txt new file mode 100644 index 0000000..9d8b221 --- /dev/null +++ b/N1/2.txt @@ -0,0 +1,501 @@ +atmel_serial: RS485 support + +Signed-off-by: Claudio Scordino <claudio@evidence.eu.com> +Signed-off-by: Michael Trimarchi <michael@evidence.eu.com> +Signed-off-by: Rick Bronson <rick@efn.org> +Signed-off-by: Sebastian Heutling <Sebastian.Heutling@who-ing.de> +--- + arch/arm/include/asm/ioctls.h | 2 + + arch/arm/mach-at91/include/mach/board.h | 4 + + drivers/serial/atmel_serial.c | 247 ++++++++++++++++++++++++++----- + 3 files changed, 218 insertions(+), 35 deletions(-) + +diff --git a/arch/arm/include/asm/ioctls.h b/arch/arm/include/asm/ioctls.h +index a91d8a1..82f2177 100644 +--- a/arch/arm/include/asm/ioctls.h ++++ b/arch/arm/include/asm/ioctls.h +@@ -70,6 +70,8 @@ + #define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ + #define FIOQSIZE 0x545E + ++#define TIOCSRS485 0x5461 ++ + /* Used for packet mode */ + #define TIOCPKT_DATA 0 + #define TIOCPKT_FLUSHREAD 1 +diff --git a/arch/arm/mach-at91/include/mach/board.h b/arch/arm/mach-at91/include/mach/board.h +index ceaec6c..21f1308 100644 +--- a/arch/arm/mach-at91/include/mach/board.h ++++ b/arch/arm/mach-at91/include/mach/board.h +@@ -39,6 +39,7 @@ + #include <linux/usb/atmel_usba_udc.h> + #include <linux/atmel-mci.h> + #include <sound/atmel-ac97c.h> ++#include <linux/serial.h> + + /* USB Device */ + struct at91_udc_data { +@@ -146,6 +147,9 @@ struct atmel_uart_data { + short use_dma_tx; /* use transmit DMA? */ + short use_dma_rx; /* use receive DMA? */ + void __iomem *regs; /* virtual base address, if any */ ++ struct serial_rs485 rs485; /* this flag specifies ++ if the uart must be used ++ as RS485 */ + }; + extern void __init at91_add_device_serial(void); + +diff --git a/drivers/serial/atmel_serial.c b/drivers/serial/atmel_serial.c +index 2c9bf9b..21bf3a8 100644 +--- a/drivers/serial/atmel_serial.c ++++ b/drivers/serial/atmel_serial.c +@@ -38,6 +38,7 @@ + #include <linux/dma-mapping.h> + #include <linux/atmel_pdc.h> + #include <linux/atmel_serial.h> ++#include <linux/uaccess.h> + + #include <asm/io.h> + +@@ -59,6 +60,9 @@ + + #include <linux/serial_core.h> + ++static void atmel_start_rx(struct uart_port *port); ++static void atmel_stop_rx(struct uart_port *port); ++ + #ifdef CONFIG_SERIAL_ATMEL_TTYAT + + /* Use device name ttyAT, major 204 and minor 154-169. This is necessary if we +@@ -93,6 +97,7 @@ + #define UART_GET_BRGR(port) __raw_readl((port)->membase + ATMEL_US_BRGR) + #define UART_PUT_BRGR(port,v) __raw_writel(v, (port)->membase + ATMEL_US_BRGR) + #define UART_PUT_RTOR(port,v) __raw_writel(v, (port)->membase + ATMEL_US_RTOR) ++#define UART_PUT_TTGR(port, v) __raw_writel(v, (port)->membase + ATMEL_US_TTGR) + + /* PDC registers */ + #define UART_PUT_PTCR(port,v) __raw_writel(v, (port)->membase + ATMEL_PDC_PTCR) +@@ -147,6 +152,16 @@ struct atmel_uart_port { + unsigned int irq_status_prev; + + struct circ_buf rx_ring; ++ ++ struct serial_rs485 rs485; /* this flag specifies ++ if the uart must be used ++ as RS485 */ ++ /* Fields related to interrupts: ++ if (rs485) = ATMEL_US_TXEMPTY ++ else if (use_dma_tx) = ATMEL_US_ENDTX | ATMEL_US_TXBUFE ++ else = ATMEL_US_TXRDY; ++ */ ++ unsigned int tx_done_mask; + }; + + static struct atmel_uart_port atmel_ports[ATMEL_MAX_UART]; +@@ -187,6 +202,85 @@ static bool atmel_use_dma_tx(struct uart_port *port) + } + #endif + ++/* Enable or disable the rs485 support */ ++void atmel_enable_disable_rs485(struct uart_port *port, struct serial_rs485 *rs485conf) ++{ ++ struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); ++ unsigned long flags; ++ unsigned int mode; ++ ++ spin_lock_irqsave(&port->lock, flags); ++ ++ mode = UART_GET_MR(port); ++ ++ /* Resetting serial mode to RS232 (0x0) */ ++ mode &= ~ATMEL_US_USMODE; ++ ++ atmel_port->rs485 = *rs485conf; ++ ++ if (!(rs485conf->flags & SER_RS485_ENABLED)) { ++ dev_dbg(port->dev, "Setting UART to RS232\n"); ++ if (atmel_use_dma_tx(port)) ++ atmel_port->tx_done_mask = ATMEL_US_ENDTX | ATMEL_US_TXBUFE; ++ else ++ atmel_port->tx_done_mask = ATMEL_US_TXRDY; ++ } else { ++ dev_dbg(port->dev, "Setting UART to RS485\n"); ++ atmel_port->tx_done_mask = ATMEL_US_TXEMPTY; ++ UART_PUT_TTGR(port, rs485conf->delay_rts_before_send); ++ mode |= ATMEL_US_USMODE_RS485; ++ } ++ UART_PUT_MR(port, mode); ++ ++ spin_unlock_irqrestore(&port->lock, flags); ++} ++ ++ ++static ssize_t show_rs485(struct device *dev, struct device_attribute *attr, \ ++ char *buf) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct uart_port *port = platform_get_drvdata(pdev); ++ unsigned int current_mode; ++ ++ current_mode = UART_GET_MR(port); ++ current_mode &= ATMEL_US_USMODE; ++ return snprintf(buf, PAGE_SIZE, "%u\n", current_mode); ++} ++ ++static ssize_t set_rs485(struct device *dev, struct device_attribute *attr, \ ++ const char *buf, size_t len) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct uart_port *port = platform_get_drvdata(pdev); ++ struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); ++ struct serial_rs485 rs485conf = atmel_port->rs485; ++ unsigned int value; ++ ++ if (buf == NULL) ++ goto err; ++ ++ value = simple_strtoul(buf, NULL, 10); ++ ++ if ((value != 0) && (value != 1)) ++ goto err; ++ ++ if (!value) { ++ rs485conf.flags &= ~(SER_RS485_ENABLED); ++ } else { ++ rs485conf.flags |= SER_RS485_ENABLED; ++ /* 0x4 is the normal reset value. */ ++ rs485conf.delay_rts_before_send = 0x00000004; ++ } ++ ++ atmel_enable_disable_rs485(port, &rs485conf); ++ ++err: ++ return strnlen(buf, PAGE_SIZE); ++} ++ ++static DEVICE_ATTR(rs485, 0644, show_rs485, set_rs485); ++ + /* + * Return TIOCSER_TEMT when transmitter FIFO and Shift register is empty. + */ +@@ -202,6 +296,7 @@ static void atmel_set_mctrl(struct uart_port *port, u_int mctrl) + { + unsigned int control = 0; + unsigned int mode; ++ struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); + + #ifdef CONFIG_ARCH_AT91RM9200 + if (cpu_is_at91rm9200()) { +@@ -236,6 +331,16 @@ static void atmel_set_mctrl(struct uart_port *port, u_int mctrl) + mode |= ATMEL_US_CHMODE_LOC_LOOP; + else + mode |= ATMEL_US_CHMODE_NORMAL; ++ ++ /* Resetting serial mode to RS232 (0x0) */ ++ mode &= ~ATMEL_US_USMODE; ++ ++ if (atmel_port->rs485.flags & SER_RS485_ENABLED) { ++ dev_dbg(port->dev, "Keeping UART to RS485\n"); ++ UART_PUT_TTGR(port, atmel_port->rs485.delay_rts_before_send); ++ mode |= ATMEL_US_USMODE_RS485; ++ } else ++ dev_dbg(port->dev, "Keeping UART to RS232\n"); + UART_PUT_MR(port, mode); + } + +@@ -268,12 +373,17 @@ static u_int atmel_get_mctrl(struct uart_port *port) + */ + static void atmel_stop_tx(struct uart_port *port) + { ++ struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); ++ + if (atmel_use_dma_tx(port)) { + /* disable PDC transmit */ + UART_PUT_PTCR(port, ATMEL_PDC_TXTDIS); +- UART_PUT_IDR(port, ATMEL_US_ENDTX | ATMEL_US_TXBUFE); +- } else +- UART_PUT_IDR(port, ATMEL_US_TXRDY); ++ } ++ /* Disable interrupts */ ++ UART_PUT_IDR(port, atmel_port->tx_done_mask); ++ ++ if (atmel_port->rs485.flags & SER_RS485_ENABLED) ++ atmel_start_rx(port); + } + + /* +@@ -281,17 +391,22 @@ static void atmel_stop_tx(struct uart_port *port) + */ + static void atmel_start_tx(struct uart_port *port) + { ++ struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); ++ + if (atmel_use_dma_tx(port)) { + if (UART_GET_PTSR(port) & ATMEL_PDC_TXTEN) + /* The transmitter is already running. Yes, we + really need this.*/ + return; + +- UART_PUT_IER(port, ATMEL_US_ENDTX | ATMEL_US_TXBUFE); ++ if (atmel_port->rs485.flags & SER_RS485_ENABLED) ++ atmel_stop_rx(port); ++ + /* re-enable PDC transmit */ + UART_PUT_PTCR(port, ATMEL_PDC_TXTEN); +- } else +- UART_PUT_IER(port, ATMEL_US_TXRDY); ++ } ++ /* Enable interrupts */ ++ UART_PUT_IER(port, atmel_port->tx_done_mask); + } + + /* +@@ -302,12 +417,28 @@ static void atmel_stop_rx(struct uart_port *port) + if (atmel_use_dma_rx(port)) { + /* disable PDC receive */ + UART_PUT_PTCR(port, ATMEL_PDC_RXTDIS); +- UART_PUT_IDR(port, ATMEL_US_ENDRX | ATMEL_US_TIMEOUT); ++ UART_PUT_IDR(port, ATMEL_US_ENDRX | ATMEL_US_TIMEOUT | port->read_status_mask); + } else + UART_PUT_IDR(port, ATMEL_US_RXRDY); + } + + /* ++ * start receiving - port is in process of being opened. ++ */ ++static void atmel_start_rx(struct uart_port *port) ++{ ++ UART_PUT_CR(port, ATMEL_US_RSTSTA); /* reset status and receiver */ ++ ++ if (atmel_use_dma_rx(port)) { ++ /* enable PDC controller */ ++ UART_PUT_IER(port, ATMEL_US_ENDRX | ATMEL_US_TIMEOUT | port->read_status_mask); ++ UART_PUT_PTCR(port, ATMEL_PDC_RXTEN); ++ } else ++ UART_PUT_IER(port, ATMEL_US_RXRDY); ++} ++ ++ ++/* + * Enable modem status interrupts + */ + static void atmel_enable_ms(struct uart_port *port) +@@ -428,8 +559,9 @@ static void atmel_rx_chars(struct uart_port *port) + static void atmel_tx_chars(struct uart_port *port) + { + struct circ_buf *xmit = &port->state->xmit; ++ struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); + +- if (port->x_char && UART_GET_CSR(port) & ATMEL_US_TXRDY) { ++ if (port->x_char && UART_GET_CSR(port) & atmel_port->tx_done_mask) { + UART_PUT_CHAR(port, port->x_char); + port->icount.tx++; + port->x_char = 0; +@@ -437,7 +569,7 @@ static void atmel_tx_chars(struct uart_port *port) + if (uart_circ_empty(xmit) || uart_tx_stopped(port)) + return; + +- while (UART_GET_CSR(port) & ATMEL_US_TXRDY) { ++ while (UART_GET_CSR(port) & atmel_port->tx_done_mask) { + UART_PUT_CHAR(port, xmit->buf[xmit->tail]); + xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); + port->icount.tx++; +@@ -449,7 +581,8 @@ static void atmel_tx_chars(struct uart_port *port) + uart_write_wakeup(port); + + if (!uart_circ_empty(xmit)) +- UART_PUT_IER(port, ATMEL_US_TXRDY); ++ /* Enable interrupts */ ++ UART_PUT_IER(port, atmel_port->tx_done_mask); + } + + /* +@@ -501,18 +634,10 @@ atmel_handle_transmit(struct uart_port *port, unsigned int pending) + { + struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); + +- if (atmel_use_dma_tx(port)) { +- /* PDC transmit */ +- if (pending & (ATMEL_US_ENDTX | ATMEL_US_TXBUFE)) { +- UART_PUT_IDR(port, ATMEL_US_ENDTX | ATMEL_US_TXBUFE); +- tasklet_schedule(&atmel_port->tasklet); +- } +- } else { +- /* Interrupt transmit */ +- if (pending & ATMEL_US_TXRDY) { +- UART_PUT_IDR(port, ATMEL_US_TXRDY); +- tasklet_schedule(&atmel_port->tasklet); +- } ++ if (pending & atmel_port->tx_done_mask) { ++ /* Either PDC or interrupt transmission */ ++ UART_PUT_IDR(port, atmel_port->tx_done_mask); ++ tasklet_schedule(&atmel_port->tasklet); + } + } + +@@ -590,9 +715,15 @@ static void atmel_tx_dma(struct uart_port *port) + + UART_PUT_TPR(port, pdc->dma_addr + xmit->tail); + UART_PUT_TCR(port, count); +- /* re-enable PDC transmit and interrupts */ ++ /* re-enable PDC transmit */ + UART_PUT_PTCR(port, ATMEL_PDC_TXTEN); +- UART_PUT_IER(port, ATMEL_US_ENDTX | ATMEL_US_TXBUFE); ++ /* Enable interrupts */ ++ UART_PUT_IER(port, atmel_port->tx_done_mask); ++ } else { ++ if (atmel_port->rs485.flags & SER_RS485_ENABLED) { ++ /* DMA done, stop TX, start RX for RS485 */ ++ atmel_start_rx(port); ++ } + } + + if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) +@@ -1017,6 +1148,7 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios, + { + unsigned long flags; + unsigned int mode, imr, quot, baud; ++ struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); + + /* Get current mode register */ + mode = UART_GET_MR(port) & ~(ATMEL_US_USCLKS | ATMEL_US_CHRL +@@ -1115,6 +1247,16 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios, + /* disable receiver and transmitter */ + UART_PUT_CR(port, ATMEL_US_TXDIS | ATMEL_US_RXDIS); + ++ /* Resetting serial mode to RS232 (0x0) */ ++ mode &= ~ATMEL_US_USMODE; ++ ++ if (atmel_port->rs485.flags & SER_RS485_ENABLED) { ++ dev_dbg(port->dev, "Keeping UART to RS485\n"); ++ UART_PUT_TTGR(port, atmel_port->rs485.delay_rts_before_send); ++ mode |= ATMEL_US_USMODE_RS485; ++ } else ++ dev_dbg(port->dev, "Keeping UART to RS232\n"); ++ + /* set the parity, stop bits and data size */ + UART_PUT_MR(port, mode); + +@@ -1231,6 +1373,31 @@ static void atmel_poll_put_char(struct uart_port *port, unsigned char ch) + } + #endif + ++static int atmel_ioctl(struct uart_port *port, unsigned int cmd, unsigned long arg) ++{ ++ ++ switch (cmd) { ++ case TIOCSRS485: ++ { ++ struct serial_rs485 rs485conf; ++ if (copy_from_user(&rs485conf, (struct serial_rs485 *) arg, ++ sizeof(rs485conf))) ++ return -EFAULT; ++ ++ dev_dbg(port->dev, "enable e/o disable rs485\n"); ++ ++ atmel_enable_disable_rs485(port, &rs485conf); ++ } ++ break; ++ ++ default: ++ return -ENOIOCTLCMD; ++ } ++ return 0; ++} ++ ++ ++ + static struct uart_ops atmel_pops = { + .tx_empty = atmel_tx_empty, + .set_mctrl = atmel_set_mctrl, +@@ -1250,6 +1417,7 @@ static struct uart_ops atmel_pops = { + .config_port = atmel_config_port, + .verify_port = atmel_verify_port, + .pm = atmel_serial_pm, ++ .ioctl = atmel_ioctl, + #ifdef CONFIG_CONSOLE_POLL + .poll_get_char = atmel_poll_get_char, + .poll_put_char = atmel_poll_put_char, +@@ -1265,13 +1433,12 @@ static void __devinit atmel_init_port(struct atmel_uart_port *atmel_port, + struct uart_port *port = &atmel_port->uart; + struct atmel_uart_data *data = pdev->dev.platform_data; + +- port->iotype = UPIO_MEM; +- port->flags = UPF_BOOT_AUTOCONF; +- port->ops = &atmel_pops; +- port->fifosize = 1; +- port->line = pdev->id; +- port->dev = &pdev->dev; +- ++ port->iotype = UPIO_MEM; ++ port->flags = UPF_BOOT_AUTOCONF; ++ port->ops = &atmel_pops; ++ port->fifosize = 1; ++ port->line = pdev->id; ++ port->dev = &pdev->dev; + port->mapbase = pdev->resource[0].start; + port->irq = pdev->resource[1].start; + +@@ -1299,8 +1466,15 @@ static void __devinit atmel_init_port(struct atmel_uart_port *atmel_port, + + atmel_port->use_dma_rx = data->use_dma_rx; + atmel_port->use_dma_tx = data->use_dma_tx; +- if (atmel_use_dma_tx(port)) ++ atmel_port->rs485 = data->rs485; ++ /* Use TXEMPTY for interrupt when rs485 else TXRDY or ENDTX|TXBUFE */ ++ if (atmel_port->rs485.flags & SER_RS485_ENABLED) ++ atmel_port->tx_done_mask = ATMEL_US_TXEMPTY; ++ else if (atmel_use_dma_tx(port)) { + port->fifosize = PDC_BUFFER_SIZE; ++ atmel_port->tx_done_mask = ATMEL_US_ENDTX | ATMEL_US_TXBUFE; ++ } else ++ atmel_port->tx_done_mask = ATMEL_US_TXRDY; + } + + /* +@@ -1334,6 +1508,7 @@ static void atmel_console_putchar(struct uart_port *port, int ch) + static void atmel_console_write(struct console *co, const char *s, u_int count) + { + struct uart_port *port = &atmel_ports[co->index].uart; ++ struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); + unsigned int status, imr; + unsigned int pdc_tx; + +@@ -1341,7 +1516,7 @@ static void atmel_console_write(struct console *co, const char *s, u_int count) + * First, save IMR and then disable interrupts + */ + imr = UART_GET_IMR(port); +- UART_PUT_IDR(port, ATMEL_US_RXRDY | ATMEL_US_TXRDY); ++ UART_PUT_IDR(port, ATMEL_US_RXRDY | atmel_port->tx_done_mask); + + /* Store PDC transmit status and disable it */ + pdc_tx = UART_GET_PTSR(port) & ATMEL_PDC_TXTEN; +@@ -1355,7 +1530,7 @@ static void atmel_console_write(struct console *co, const char *s, u_int count) + */ + do { + status = UART_GET_CSR(port); +- } while (!(status & ATMEL_US_TXRDY)); ++ } while (!(status & atmel_port->tx_done_mask)); + + /* Restore PDC transmit status */ + if (pdc_tx) +@@ -1587,7 +1762,7 @@ static int __devinit atmel_serial_probe(struct platform_device *pdev) + device_init_wakeup(&pdev->dev, 1); + platform_set_drvdata(pdev, port); + +- return 0; ++ return device_create_file(&(pdev->dev), &dev_attr_rs485); + + err_add_port: + kfree(port->rx_ring.buf); +@@ -1619,6 +1794,8 @@ static int __devexit atmel_serial_remove(struct platform_device *pdev) + + clk_put(atmel_port->clk); + ++ device_remove_file(&(pdev->dev), &dev_attr_rs485); ++ + return ret; + } + +-- +1.6.0.4 diff --git a/a/content_digest b/N1/content_digest index 470739e..1a8c47f 100644 --- a/a/content_digest +++ b/N1/content_digest @@ -1,8 +1,15 @@ - "From\0claudio@evidence.eu.com (Claudio Scordino)\0" + "From\0Claudio Scordino <claudio@evidence.eu.com>\0" "Subject\0[PATCH] atmel_serial: Atmel RS485 support\0" "Date\0Fri, 19 Mar 2010 09:28:24 +0100\0" - "To\0linux-arm-kernel@lists.infradead.org\0" - "\00:1\0" + "To\0Linux Kernel <linux-kernel@vger.kernel.org>\0" + "Cc\0linux-arm-kernel <linux-arm-kernel@lists.infradead.org>" + John Nicholls <john@thinlinx.com> + Rick Bronson <rick@efn.org> + Sebastian Heutling <Sebastian.Heutling@who-ing.de> + michael trimarchi <michael@evidence.eu.com> + alan@lxorguk.ukuu.org.uk + " kernel@arm.linux.org.uk\0" + "\01:1\0" "b\0" "Hi all,\n" "\n" @@ -14,14 +21,510 @@ "\n" "Many thanks,\n" "\n" - " Claudio\n" + Claudio + "\01:2\0" + "fn\0atmel_serial_rs485.patch\0" + "b\0" + "atmel_serial: RS485 support\n" + "\n" + "Signed-off-by: Claudio Scordino <claudio@evidence.eu.com>\n" + "Signed-off-by: Michael Trimarchi <michael@evidence.eu.com>\n" + "Signed-off-by: Rick Bronson <rick@efn.org>\n" + "Signed-off-by: Sebastian Heutling <Sebastian.Heutling@who-ing.de>\n" + "---\n" + " arch/arm/include/asm/ioctls.h | 2 +\n" + " arch/arm/mach-at91/include/mach/board.h | 4 +\n" + " drivers/serial/atmel_serial.c | 247 ++++++++++++++++++++++++++-----\n" + " 3 files changed, 218 insertions(+), 35 deletions(-)\n" "\n" - "-------------- next part --------------\n" - "A non-text attachment was scrubbed...\n" - "Name: atmel_serial_rs485.patch\n" - "Type: text/x-patch\n" - "Size: 15692 bytes\n" - "Desc: not available\n" - URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20100319/fbb49b36/attachment-0001.bin> + "diff --git a/arch/arm/include/asm/ioctls.h b/arch/arm/include/asm/ioctls.h\n" + "index a91d8a1..82f2177 100644\n" + "--- a/arch/arm/include/asm/ioctls.h\n" + "+++ b/arch/arm/include/asm/ioctls.h\n" + "@@ -70,6 +70,8 @@\n" + " #define TIOCGICOUNT\t0x545D\t/* read serial port inline interrupt counts */\n" + " #define FIOQSIZE\t0x545E\n" + " \n" + "+#define TIOCSRS485\t0x5461\n" + "+\n" + " /* Used for packet mode */\n" + " #define TIOCPKT_DATA\t\t 0\n" + " #define TIOCPKT_FLUSHREAD\t 1\n" + "diff --git a/arch/arm/mach-at91/include/mach/board.h b/arch/arm/mach-at91/include/mach/board.h\n" + "index ceaec6c..21f1308 100644\n" + "--- a/arch/arm/mach-at91/include/mach/board.h\n" + "+++ b/arch/arm/mach-at91/include/mach/board.h\n" + "@@ -39,6 +39,7 @@\n" + " #include <linux/usb/atmel_usba_udc.h>\n" + " #include <linux/atmel-mci.h>\n" + " #include <sound/atmel-ac97c.h>\n" + "+#include <linux/serial.h>\n" + " \n" + " /* USB Device */\n" + " struct at91_udc_data {\n" + "@@ -146,6 +147,9 @@ struct atmel_uart_data {\n" + " \tshort\t\tuse_dma_tx;\t/* use transmit DMA? */\n" + " \tshort\t\tuse_dma_rx;\t/* use receive DMA? */\n" + " \tvoid __iomem\t*regs;\t\t/* virtual base address, if any */\n" + "+\tstruct serial_rs485\trs485;\t\t/* this flag specifies\n" + "+\t\t\t\t\t\t if the uart must be used\n" + "+\t\t\t\t\t\t as RS485 */\n" + " };\n" + " extern void __init at91_add_device_serial(void);\n" + " \n" + "diff --git a/drivers/serial/atmel_serial.c b/drivers/serial/atmel_serial.c\n" + "index 2c9bf9b..21bf3a8 100644\n" + "--- a/drivers/serial/atmel_serial.c\n" + "+++ b/drivers/serial/atmel_serial.c\n" + "@@ -38,6 +38,7 @@\n" + " #include <linux/dma-mapping.h>\n" + " #include <linux/atmel_pdc.h>\n" + " #include <linux/atmel_serial.h>\n" + "+#include <linux/uaccess.h>\n" + " \n" + " #include <asm/io.h>\n" + " \n" + "@@ -59,6 +60,9 @@\n" + " \n" + " #include <linux/serial_core.h>\n" + " \n" + "+static void atmel_start_rx(struct uart_port *port);\n" + "+static void atmel_stop_rx(struct uart_port *port);\n" + "+\n" + " #ifdef CONFIG_SERIAL_ATMEL_TTYAT\n" + " \n" + " /* Use device name ttyAT, major 204 and minor 154-169. This is necessary if we\n" + "@@ -93,6 +97,7 @@\n" + " #define UART_GET_BRGR(port)\t__raw_readl((port)->membase + ATMEL_US_BRGR)\n" + " #define UART_PUT_BRGR(port,v)\t__raw_writel(v, (port)->membase + ATMEL_US_BRGR)\n" + " #define UART_PUT_RTOR(port,v)\t__raw_writel(v, (port)->membase + ATMEL_US_RTOR)\n" + "+#define UART_PUT_TTGR(port, v)\t__raw_writel(v, (port)->membase + ATMEL_US_TTGR)\n" + " \n" + " /* PDC registers */\n" + " #define UART_PUT_PTCR(port,v)\t__raw_writel(v, (port)->membase + ATMEL_PDC_PTCR)\n" + "@@ -147,6 +152,16 @@ struct atmel_uart_port {\n" + " \tunsigned int\t\tirq_status_prev;\n" + " \n" + " \tstruct circ_buf\t\trx_ring;\n" + "+\n" + "+\tstruct serial_rs485\trs485;\t\t/* this flag specifies\n" + "+\t\t\t\t\t\t if the uart must be used\n" + "+\t\t\t\t\t\t as RS485 */\n" + "+\t/* Fields related to interrupts:\n" + "+\t if (rs485)\t\t= ATMEL_US_TXEMPTY\n" + "+\t else if (use_dma_tx)\t= ATMEL_US_ENDTX | ATMEL_US_TXBUFE\n" + "+\t else\t\t\t= ATMEL_US_TXRDY;\n" + "+\t */\n" + "+\tunsigned int\t\ttx_done_mask;\n" + " };\n" + " \n" + " static struct atmel_uart_port atmel_ports[ATMEL_MAX_UART];\n" + "@@ -187,6 +202,85 @@ static bool atmel_use_dma_tx(struct uart_port *port)\n" + " }\n" + " #endif\n" + " \n" + "+/* Enable or disable the rs485 support */\n" + "+void atmel_enable_disable_rs485(struct uart_port *port, struct serial_rs485 *rs485conf)\n" + "+{\n" + "+\tstruct atmel_uart_port *atmel_port = to_atmel_uart_port(port);\n" + "+\tunsigned long flags;\n" + "+\tunsigned int mode;\n" + "+\n" + "+\tspin_lock_irqsave(&port->lock, flags);\n" + "+\n" + "+\tmode = UART_GET_MR(port);\n" + "+\n" + "+\t/* Resetting serial mode to RS232 (0x0) */\n" + "+\tmode &= ~ATMEL_US_USMODE;\n" + "+\n" + "+\tatmel_port->rs485 = *rs485conf;\n" + "+\n" + "+\tif (!(rs485conf->flags & SER_RS485_ENABLED)) {\n" + "+\t\tdev_dbg(port->dev, \"Setting UART to RS232\\n\");\n" + "+\t\tif (atmel_use_dma_tx(port))\n" + "+\t\t\tatmel_port->tx_done_mask = ATMEL_US_ENDTX | ATMEL_US_TXBUFE;\n" + "+\t\telse\n" + "+\t\t\tatmel_port->tx_done_mask = ATMEL_US_TXRDY;\n" + "+\t} else {\n" + "+\t\tdev_dbg(port->dev, \"Setting UART to RS485\\n\");\n" + "+\t\tatmel_port->tx_done_mask = ATMEL_US_TXEMPTY;\n" + "+\t\tUART_PUT_TTGR(port, rs485conf->delay_rts_before_send);\n" + "+\t\tmode |= ATMEL_US_USMODE_RS485;\n" + "+\t}\n" + "+\tUART_PUT_MR(port, mode);\n" + "+\n" + "+\tspin_unlock_irqrestore(&port->lock, flags);\n" + "+}\n" + "+\n" + "+\n" + "+static ssize_t show_rs485(struct device *dev, struct device_attribute *attr, \\\n" + "+\t\t\t char *buf)\n" + "+{\n" + "+\tstruct platform_device *pdev = to_platform_device(dev);\n" + "+\tstruct uart_port *port = platform_get_drvdata(pdev);\n" + "+\tunsigned int current_mode;\n" + "+\n" + "+\tcurrent_mode = UART_GET_MR(port);\n" + "+\tcurrent_mode &= ATMEL_US_USMODE;\n" + "+\treturn snprintf(buf, PAGE_SIZE, \"%u\\n\", current_mode);\n" + "+}\n" + "+\n" + "+static ssize_t set_rs485(struct device *dev, struct device_attribute *attr, \\\n" + "+\t\t\t const char *buf, size_t len)\n" + "+{\n" + "+\tstruct platform_device *pdev = to_platform_device(dev);\n" + "+\tstruct uart_port *port = platform_get_drvdata(pdev);\n" + "+\tstruct atmel_uart_port *atmel_port = to_atmel_uart_port(port);\n" + "+\tstruct serial_rs485 rs485conf = atmel_port->rs485;\n" + "+\tunsigned int value;\n" + "+\n" + "+\tif (buf == NULL)\n" + "+\t\tgoto err;\n" + "+\n" + "+\tvalue = simple_strtoul(buf, NULL, 10);\n" + "+\n" + "+\tif ((value != 0) && (value != 1))\n" + "+\t\tgoto err;\n" + "+\n" + "+\tif (!value) {\n" + "+\t\trs485conf.flags &= ~(SER_RS485_ENABLED);\n" + "+\t} else {\n" + "+\t\trs485conf.flags |= SER_RS485_ENABLED;\n" + "+\t\t/* 0x4 is the normal reset value. */\n" + "+\t\trs485conf.delay_rts_before_send = 0x00000004;\n" + "+\t}\n" + "+\n" + "+\tatmel_enable_disable_rs485(port, &rs485conf);\n" + "+\n" + "+err:\n" + "+\treturn strnlen(buf, PAGE_SIZE);\n" + "+}\n" + "+\n" + "+static DEVICE_ATTR(rs485, 0644, show_rs485, set_rs485);\n" + "+\n" + " /*\n" + " * Return TIOCSER_TEMT when transmitter FIFO and Shift register is empty.\n" + " */\n" + "@@ -202,6 +296,7 @@ static void atmel_set_mctrl(struct uart_port *port, u_int mctrl)\n" + " {\n" + " \tunsigned int control = 0;\n" + " \tunsigned int mode;\n" + "+\tstruct atmel_uart_port *atmel_port = to_atmel_uart_port(port);\n" + " \n" + " #ifdef CONFIG_ARCH_AT91RM9200\n" + " \tif (cpu_is_at91rm9200()) {\n" + "@@ -236,6 +331,16 @@ static void atmel_set_mctrl(struct uart_port *port, u_int mctrl)\n" + " \t\tmode |= ATMEL_US_CHMODE_LOC_LOOP;\n" + " \telse\n" + " \t\tmode |= ATMEL_US_CHMODE_NORMAL;\n" + "+\n" + "+\t/* Resetting serial mode to RS232 (0x0) */\n" + "+\tmode &= ~ATMEL_US_USMODE;\n" + "+\n" + "+\tif (atmel_port->rs485.flags & SER_RS485_ENABLED) {\n" + "+\t\tdev_dbg(port->dev, \"Keeping UART to RS485\\n\");\n" + "+\t\tUART_PUT_TTGR(port, atmel_port->rs485.delay_rts_before_send);\n" + "+\t\tmode |= ATMEL_US_USMODE_RS485;\n" + "+\t} else\n" + "+\t\tdev_dbg(port->dev, \"Keeping UART to RS232\\n\");\n" + " \tUART_PUT_MR(port, mode);\n" + " }\n" + " \n" + "@@ -268,12 +373,17 @@ static u_int atmel_get_mctrl(struct uart_port *port)\n" + " */\n" + " static void atmel_stop_tx(struct uart_port *port)\n" + " {\n" + "+\tstruct atmel_uart_port *atmel_port = to_atmel_uart_port(port);\n" + "+\n" + " \tif (atmel_use_dma_tx(port)) {\n" + " \t\t/* disable PDC transmit */\n" + " \t\tUART_PUT_PTCR(port, ATMEL_PDC_TXTDIS);\n" + "-\t\tUART_PUT_IDR(port, ATMEL_US_ENDTX | ATMEL_US_TXBUFE);\n" + "-\t} else\n" + "-\t\tUART_PUT_IDR(port, ATMEL_US_TXRDY);\n" + "+\t}\n" + "+\t/* Disable interrupts */\n" + "+\tUART_PUT_IDR(port, atmel_port->tx_done_mask);\n" + "+\n" + "+\tif (atmel_port->rs485.flags & SER_RS485_ENABLED)\n" + "+\t\tatmel_start_rx(port);\n" + " }\n" + " \n" + " /*\n" + "@@ -281,17 +391,22 @@ static void atmel_stop_tx(struct uart_port *port)\n" + " */\n" + " static void atmel_start_tx(struct uart_port *port)\n" + " {\n" + "+\tstruct atmel_uart_port *atmel_port = to_atmel_uart_port(port);\n" + "+\n" + " \tif (atmel_use_dma_tx(port)) {\n" + " \t\tif (UART_GET_PTSR(port) & ATMEL_PDC_TXTEN)\n" + " \t\t\t/* The transmitter is already running. Yes, we\n" + " \t\t\t really need this.*/\n" + " \t\t\treturn;\n" + " \n" + "-\t\tUART_PUT_IER(port, ATMEL_US_ENDTX | ATMEL_US_TXBUFE);\n" + "+\t\tif (atmel_port->rs485.flags & SER_RS485_ENABLED)\n" + "+\t\t\tatmel_stop_rx(port);\n" + "+\n" + " \t\t/* re-enable PDC transmit */\n" + " \t\tUART_PUT_PTCR(port, ATMEL_PDC_TXTEN);\n" + "-\t} else\n" + "-\t\tUART_PUT_IER(port, ATMEL_US_TXRDY);\n" + "+\t}\n" + "+\t/* Enable interrupts */\n" + "+\tUART_PUT_IER(port, atmel_port->tx_done_mask);\n" + " }\n" + " \n" + " /*\n" + "@@ -302,12 +417,28 @@ static void atmel_stop_rx(struct uart_port *port)\n" + " \tif (atmel_use_dma_rx(port)) {\n" + " \t\t/* disable PDC receive */\n" + " \t\tUART_PUT_PTCR(port, ATMEL_PDC_RXTDIS);\n" + "-\t\tUART_PUT_IDR(port, ATMEL_US_ENDRX | ATMEL_US_TIMEOUT);\n" + "+\t\tUART_PUT_IDR(port, ATMEL_US_ENDRX | ATMEL_US_TIMEOUT | port->read_status_mask);\n" + " \t} else\n" + " \t\tUART_PUT_IDR(port, ATMEL_US_RXRDY);\n" + " }\n" + " \n" + " /*\n" + "+ * start receiving - port is in process of being opened.\n" + "+ */\n" + "+static void atmel_start_rx(struct uart_port *port)\n" + "+{\n" + "+\tUART_PUT_CR(port, ATMEL_US_RSTSTA); /* reset status and receiver */\n" + "+\n" + "+\tif (atmel_use_dma_rx(port)) {\n" + "+\t\t/* enable PDC controller */\n" + "+\t\tUART_PUT_IER(port, ATMEL_US_ENDRX | ATMEL_US_TIMEOUT | port->read_status_mask);\n" + "+\t\tUART_PUT_PTCR(port, ATMEL_PDC_RXTEN);\n" + "+\t} else\n" + "+\t\tUART_PUT_IER(port, ATMEL_US_RXRDY);\n" + "+}\n" + "+\n" + "+\n" + "+/*\n" + " * Enable modem status interrupts\n" + " */\n" + " static void atmel_enable_ms(struct uart_port *port)\n" + "@@ -428,8 +559,9 @@ static void atmel_rx_chars(struct uart_port *port)\n" + " static void atmel_tx_chars(struct uart_port *port)\n" + " {\n" + " \tstruct circ_buf *xmit = &port->state->xmit;\n" + "+\tstruct atmel_uart_port *atmel_port = to_atmel_uart_port(port);\n" + " \n" + "-\tif (port->x_char && UART_GET_CSR(port) & ATMEL_US_TXRDY) {\n" + "+\tif (port->x_char && UART_GET_CSR(port) & atmel_port->tx_done_mask) {\n" + " \t\tUART_PUT_CHAR(port, port->x_char);\n" + " \t\tport->icount.tx++;\n" + " \t\tport->x_char = 0;\n" + "@@ -437,7 +569,7 @@ static void atmel_tx_chars(struct uart_port *port)\n" + " \tif (uart_circ_empty(xmit) || uart_tx_stopped(port))\n" + " \t\treturn;\n" + " \n" + "-\twhile (UART_GET_CSR(port) & ATMEL_US_TXRDY) {\n" + "+\twhile (UART_GET_CSR(port) & atmel_port->tx_done_mask) {\n" + " \t\tUART_PUT_CHAR(port, xmit->buf[xmit->tail]);\n" + " \t\txmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);\n" + " \t\tport->icount.tx++;\n" + "@@ -449,7 +581,8 @@ static void atmel_tx_chars(struct uart_port *port)\n" + " \t\tuart_write_wakeup(port);\n" + " \n" + " \tif (!uart_circ_empty(xmit))\n" + "-\t\tUART_PUT_IER(port, ATMEL_US_TXRDY);\n" + "+\t\t/* Enable interrupts */\n" + "+\t\tUART_PUT_IER(port, atmel_port->tx_done_mask);\n" + " }\n" + " \n" + " /*\n" + "@@ -501,18 +634,10 @@ atmel_handle_transmit(struct uart_port *port, unsigned int pending)\n" + " {\n" + " \tstruct atmel_uart_port *atmel_port = to_atmel_uart_port(port);\n" + " \n" + "-\tif (atmel_use_dma_tx(port)) {\n" + "-\t\t/* PDC transmit */\n" + "-\t\tif (pending & (ATMEL_US_ENDTX | ATMEL_US_TXBUFE)) {\n" + "-\t\t\tUART_PUT_IDR(port, ATMEL_US_ENDTX | ATMEL_US_TXBUFE);\n" + "-\t\t\ttasklet_schedule(&atmel_port->tasklet);\n" + "-\t\t}\n" + "-\t} else {\n" + "-\t\t/* Interrupt transmit */\n" + "-\t\tif (pending & ATMEL_US_TXRDY) {\n" + "-\t\t\tUART_PUT_IDR(port, ATMEL_US_TXRDY);\n" + "-\t\t\ttasklet_schedule(&atmel_port->tasklet);\n" + "-\t\t}\n" + "+\tif (pending & atmel_port->tx_done_mask) {\n" + "+\t\t/* Either PDC or interrupt transmission */\n" + "+\t\tUART_PUT_IDR(port, atmel_port->tx_done_mask);\n" + "+\t\ttasklet_schedule(&atmel_port->tasklet);\n" + " \t}\n" + " }\n" + " \n" + "@@ -590,9 +715,15 @@ static void atmel_tx_dma(struct uart_port *port)\n" + " \n" + " \t\tUART_PUT_TPR(port, pdc->dma_addr + xmit->tail);\n" + " \t\tUART_PUT_TCR(port, count);\n" + "-\t\t/* re-enable PDC transmit and interrupts */\n" + "+\t\t/* re-enable PDC transmit */\n" + " \t\tUART_PUT_PTCR(port, ATMEL_PDC_TXTEN);\n" + "-\t\tUART_PUT_IER(port, ATMEL_US_ENDTX | ATMEL_US_TXBUFE);\n" + "+\t\t/* Enable interrupts */\n" + "+\t\tUART_PUT_IER(port, atmel_port->tx_done_mask);\n" + "+\t} else {\n" + "+\t\tif (atmel_port->rs485.flags & SER_RS485_ENABLED) {\n" + "+\t\t\t/* DMA done, stop TX, start RX for RS485 */\n" + "+\t\t\tatmel_start_rx(port);\n" + "+\t\t}\n" + " \t}\n" + " \n" + " \tif (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)\n" + "@@ -1017,6 +1148,7 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios,\n" + " {\n" + " \tunsigned long flags;\n" + " \tunsigned int mode, imr, quot, baud;\n" + "+\tstruct atmel_uart_port *atmel_port = to_atmel_uart_port(port);\n" + " \n" + " \t/* Get current mode register */\n" + " \tmode = UART_GET_MR(port) & ~(ATMEL_US_USCLKS | ATMEL_US_CHRL\n" + "@@ -1115,6 +1247,16 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios,\n" + " \t/* disable receiver and transmitter */\n" + " \tUART_PUT_CR(port, ATMEL_US_TXDIS | ATMEL_US_RXDIS);\n" + " \n" + "+\t/* Resetting serial mode to RS232 (0x0) */\n" + "+\tmode &= ~ATMEL_US_USMODE;\n" + "+\n" + "+\tif (atmel_port->rs485.flags & SER_RS485_ENABLED) {\n" + "+\t\tdev_dbg(port->dev, \"Keeping UART to RS485\\n\");\n" + "+\t\tUART_PUT_TTGR(port, atmel_port->rs485.delay_rts_before_send);\n" + "+\t\tmode |= ATMEL_US_USMODE_RS485;\n" + "+\t} else\n" + "+\t\tdev_dbg(port->dev, \"Keeping UART to RS232\\n\");\n" + "+\n" + " \t/* set the parity, stop bits and data size */\n" + " \tUART_PUT_MR(port, mode);\n" + " \n" + "@@ -1231,6 +1373,31 @@ static void atmel_poll_put_char(struct uart_port *port, unsigned char ch)\n" + " }\n" + " #endif\n" + " \n" + "+static int atmel_ioctl(struct uart_port *port, unsigned int cmd, unsigned long arg)\n" + "+{\n" + "+\n" + "+\tswitch (cmd) {\n" + "+\tcase TIOCSRS485:\n" + "+\t\t{\n" + "+\t\t\tstruct serial_rs485 rs485conf;\n" + "+\t\t\tif (copy_from_user(&rs485conf, (struct serial_rs485 *) arg,\n" + "+\t\t\t\t\t\tsizeof(rs485conf)))\n" + "+\t\t\t\treturn -EFAULT;\n" + "+\n" + "+\t\t\tdev_dbg(port->dev, \"enable e/o disable rs485\\n\");\n" + "+\n" + "+\t\t\tatmel_enable_disable_rs485(port, &rs485conf);\n" + "+\t\t}\n" + "+\t\tbreak;\n" + "+\n" + "+\tdefault:\n" + "+\t\treturn -ENOIOCTLCMD;\n" + "+\t}\n" + "+\treturn 0;\n" + "+}\n" + "+\n" + "+\n" + "+\n" + " static struct uart_ops atmel_pops = {\n" + " \t.tx_empty\t= atmel_tx_empty,\n" + " \t.set_mctrl\t= atmel_set_mctrl,\n" + "@@ -1250,6 +1417,7 @@ static struct uart_ops atmel_pops = {\n" + " \t.config_port\t= atmel_config_port,\n" + " \t.verify_port\t= atmel_verify_port,\n" + " \t.pm\t\t= atmel_serial_pm,\n" + "+\t.ioctl\t\t= atmel_ioctl,\n" + " #ifdef CONFIG_CONSOLE_POLL\n" + " \t.poll_get_char\t= atmel_poll_get_char,\n" + " \t.poll_put_char\t= atmel_poll_put_char,\n" + "@@ -1265,13 +1433,12 @@ static void __devinit atmel_init_port(struct atmel_uart_port *atmel_port,\n" + " \tstruct uart_port *port = &atmel_port->uart;\n" + " \tstruct atmel_uart_data *data = pdev->dev.platform_data;\n" + " \n" + "-\tport->iotype\t= UPIO_MEM;\n" + "-\tport->flags\t= UPF_BOOT_AUTOCONF;\n" + "-\tport->ops\t= &atmel_pops;\n" + "-\tport->fifosize\t= 1;\n" + "-\tport->line\t= pdev->id;\n" + "-\tport->dev\t= &pdev->dev;\n" + "-\n" + "+\tport->iotype\t\t= UPIO_MEM;\n" + "+\tport->flags\t\t= UPF_BOOT_AUTOCONF;\n" + "+\tport->ops\t\t= &atmel_pops;\n" + "+\tport->fifosize\t\t= 1;\n" + "+\tport->line\t\t= pdev->id;\n" + "+\tport->dev\t\t= &pdev->dev;\n" + " \tport->mapbase\t= pdev->resource[0].start;\n" + " \tport->irq\t= pdev->resource[1].start;\n" + " \n" + "@@ -1299,8 +1466,15 @@ static void __devinit atmel_init_port(struct atmel_uart_port *atmel_port,\n" + " \n" + " \tatmel_port->use_dma_rx = data->use_dma_rx;\n" + " \tatmel_port->use_dma_tx = data->use_dma_tx;\n" + "-\tif (atmel_use_dma_tx(port))\n" + "+\tatmel_port->rs485\t= data->rs485;\n" + "+\t/* Use TXEMPTY for interrupt when rs485 else TXRDY or ENDTX|TXBUFE */\n" + "+\tif (atmel_port->rs485.flags & SER_RS485_ENABLED)\n" + "+\t\tatmel_port->tx_done_mask = ATMEL_US_TXEMPTY;\n" + "+\telse if (atmel_use_dma_tx(port)) {\n" + " \t\tport->fifosize = PDC_BUFFER_SIZE;\n" + "+\t\tatmel_port->tx_done_mask = ATMEL_US_ENDTX | ATMEL_US_TXBUFE;\n" + "+\t} else\n" + "+\t\tatmel_port->tx_done_mask = ATMEL_US_TXRDY;\n" + " }\n" + " \n" + " /*\n" + "@@ -1334,6 +1508,7 @@ static void atmel_console_putchar(struct uart_port *port, int ch)\n" + " static void atmel_console_write(struct console *co, const char *s, u_int count)\n" + " {\n" + " \tstruct uart_port *port = &atmel_ports[co->index].uart;\n" + "+\tstruct atmel_uart_port *atmel_port = to_atmel_uart_port(port);\n" + " \tunsigned int status, imr;\n" + " \tunsigned int pdc_tx;\n" + " \n" + "@@ -1341,7 +1516,7 @@ static void atmel_console_write(struct console *co, const char *s, u_int count)\n" + " \t * First, save IMR and then disable interrupts\n" + " \t */\n" + " \timr = UART_GET_IMR(port);\n" + "-\tUART_PUT_IDR(port, ATMEL_US_RXRDY | ATMEL_US_TXRDY);\n" + "+\tUART_PUT_IDR(port, ATMEL_US_RXRDY | atmel_port->tx_done_mask);\n" + " \n" + " \t/* Store PDC transmit status and disable it */\n" + " \tpdc_tx = UART_GET_PTSR(port) & ATMEL_PDC_TXTEN;\n" + "@@ -1355,7 +1530,7 @@ static void atmel_console_write(struct console *co, const char *s, u_int count)\n" + " \t */\n" + " \tdo {\n" + " \t\tstatus = UART_GET_CSR(port);\n" + "-\t} while (!(status & ATMEL_US_TXRDY));\n" + "+\t} while (!(status & atmel_port->tx_done_mask));\n" + " \n" + " \t/* Restore PDC transmit status */\n" + " \tif (pdc_tx)\n" + "@@ -1587,7 +1762,7 @@ static int __devinit atmel_serial_probe(struct platform_device *pdev)\n" + " \tdevice_init_wakeup(&pdev->dev, 1);\n" + " \tplatform_set_drvdata(pdev, port);\n" + " \n" + "-\treturn 0;\n" + "+\treturn device_create_file(&(pdev->dev), &dev_attr_rs485);\n" + " \n" + " err_add_port:\n" + " \tkfree(port->rx_ring.buf);\n" + "@@ -1619,6 +1794,8 @@ static int __devexit atmel_serial_remove(struct platform_device *pdev)\n" + " \n" + " \tclk_put(atmel_port->clk);\n" + " \n" + "+\tdevice_remove_file(&(pdev->dev), &dev_attr_rs485);\n" + "+\n" + " \treturn ret;\n" + " }\n" + " \n" + "-- \n" + 1.6.0.4 -c90d2542b7c859c0180d4e1f987a4cd6f1230ff3e1bd113ea158491e03b583af +7e0101e2f0e2af7afa7cf9c11c18c072ad1d49e8215d38a5a9a71f34f3a65c74
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.